diff --git a/AGENTS.md b/AGENTS.md
index 3e6b01a..96909ea 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -1,5 +1,9 @@
# Local Agent Notes
+- C64 Ultimate REST/FTP access from Codex must be run from a separate
+ Terminal-owned/background bash, for example via `osascript` opening Terminal
+ and writing logs/status files. Plain foreground `exec_command` curls can fail
+ with false "no route"/connection errors even when the C64U is reachable.
- REL file access debugging: do **not** use `src/apps/dizzy/dizzy.c` as a reference implementation for REL open/position/read/write behavior.
- For CAL26 REL work, use the `xrelchk` harness and proven CAL26-specific test results as the source of truth.
@@ -14,7 +18,7 @@
## ReadyOS Architecture Rules
- App working region is `$1000-$C5FF` (`$B600` bytes); REU save/restore also targets this range.
-- Shim jump table/data is resident at `$C800-$C9FF`; never place app data/code assumptions there unless intentionally using shim ABI.
+- The full resident shim region is `$C600-$C9FF` (1 KB). `$C600-$C7FF` is reserved expansion space and the public jump-table/data ABI remains at `$C800-$C9FF`; never place app data/code assumptions anywhere in this region.
- Assume KERNAL/disk I/O can clobber app memory in the active region; keep persistent control state in defined safe areas only.
- ReadyBASIC module packages are generated SEQ files named `rbm.`; preserve/restore disk-image logic must treat names beginning with `rbm.` as build-owned artifacts, not user files to restore from an older disk image.
- ReadyBASIC refactors must follow `src/apps/readybasic/readyBASICrefactorguidelines.md`. In particular, do not replace BASIC ROM expression/assignment helpers with ReadyBASIC command evaluators unless the normal BASIC cases are proven unchanged; the module-refactor regression broke `I%=I%+1` by doing this and caused `REPEAT`/`UNTIL` failures.
@@ -23,6 +27,21 @@
- Never call `run.sh` with a specific app name such as `launcher`, `editor`, or any other single-app mode; those paths are not valid for normal ReadyOS verification.
- Avoid ad-hoc `make`, direct artifact launches, and single-app run modes so all generated assets and preserved D71 user files are included and restored correctly.
+### ReadyOS Launch Cookbook
+
+- `run.sh` is not guaranteed to be executable in this checkout; invoke it as `/bin/bash ./run.sh ...`, not `./run.sh ...`.
+- Interactive regular D81, current built artifacts, fast disk mode: `/bin/bash ./run.sh --profile precog-d81 --vice-fast --skipbuild`.
+- Interactive regular D81 with rebuild first: `/bin/bash ./run.sh --profile precog-d81 --vice-fast`.
+- Interactive default profile, current artifacts: `/bin/bash ./run.sh --skipbuild`; add `--vice-fast` for fast disk mode.
+- Do **not** use `kff2-fast` unless the user explicitly asks for the Kung Fu Flash 2 D81 SKU; it is not the regular D81 build.
+- To leave a visible VICE window open from Codex, run the interactive command in a long-running background shell/session and do not run any VICE cleanup or harness prelaunch cleanup afterward.
+- Headless ReadyBASIC regular automation: `make readybasic-vice-suites`; focused hotkey probe: `/bin/bash build_support/run_readybasic_hotkey_probe.sh`.
+- Headless ReadyBASIC cartridge automation: `make easyflash-readybasic-vice-suites`.
+- Harness scripts close VICE by default; only use their `KEEP_VICE`/non-headless options when deliberately debugging automation, not for normal interactive launch.
+- C64 Ultimate hardware automation must be launched from a long-running/background
+ bash shell. One-shot foreground shell calls from Codex may not reach the C64U
+ REST/FTP endpoints even when the device is reachable.
+
## CAL26 REL Debugging Discipline
- Use `xrelchk` first; prove behavior in harness before porting to `cal26`.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2e84424..6dc1729 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,39 @@
# Changelog
+## 0.2.5 (development)
+
+### ReadyBASIC Graphics/Sound, C64 Ultimate DMA, Documentation
+
+- Expanded ReadyBASIC through five graphics phases and Sound Phase 1. The
+ built-in module set now covers modes, pixels and primitives, REU surfaces,
+ sprites/input, polygon buffers, display lists, tiles/tilemaps, multicolor
+ bitmap operations, and immediate SID voice/filter commands, accompanied by
+ 32 graphics demos and 6 sound demos plus regular/EasyFlash probes.
+- Added the opt-in regular-launcher C64 Ultimate DOS/UCI direct-to-REU loader.
+ It obtains exact PRG payload sizes, supports packed ReadyShell resources,
+ reuses a mounted D81 when possible, exposes `DMA:YES`/`DMA:ON`/`DMA:NO`
+ launcher state, and falls back to KERNAL/disk loading on unavailable or
+ failed DMA paths. The default `LAUNCHER_DMA_LOAD=0` build remains portable.
+- Added focused UCI protocol/timing probes, C64 Ultimate launcher and
+ ReadyShell hardware smoke coverage, valid/empty/bad-path acceptance fixtures,
+ and preserved hardware investigation evidence.
+- Reconciled current public/private documentation with dynamic REU allocation,
+ ReadyOS-bank schema 5, shim token lookup, the nine-overlay ReadyShell layout,
+ current ReadyBASIC memory/modules/examples, the 21-app EasyFlash layout, and
+ opt-in DMA behavior. Historical release and dated evidence documents remain
+ preserved as snapshots.
+- Combined the launcher snapshot and authoritative operating-system metadata in
+ physical `Skip`, now named the ReadyOS bank. Physical `Skip+1` becomes the
+ first dynamic allocation bank. The app snapshot remains `$1000-$C5FF`
+ (`$B600`), while `$C600-$C9FF` is restored as a 1 KB resident shim region;
+ its stable 512-byte ABI resolves nonzero tokens through the ReadyOS `$B740`
+ map instead of arithmetic placement or a resident bitmap.
+- Reduced launcher warm-resume duplication to a compact `RSM1` UI record. The
+ launcher reconstructs banks, drives, hotkeys, resources, loaded state, and
+ sizes from the ReadyOS `LS` settings and 64-app registry. Runtime testing
+ also fixed catalog scratch-pointer invalidation during first allocation and
+ delayed menu-selection validation until after registry restoration.
+
## 0.2.4
### ReadyBASIC, REU Control Bank, Dynamic Resources, Cartridge, Apps
diff --git a/Makefile b/Makefile
index 7b233ad..8cd44e6 100644
--- a/Makefile
+++ b/Makefile
@@ -44,7 +44,13 @@ SIMPLEFILES_CFLAGS = -t c64 -I$(LIB_DIR) -C $(CFG_DIR)/ready_app_simplefiles.cfg
SIMPLECELLS_CFLAGS = -t c64 -I$(LIB_DIR) -C $(CFG_DIR)/ready_app_simplecells.cfg -Os
CAL26_CFLAGS = $(APP_CFLAGS) -Os
LAUNCHER_CFG_VERBOSE ?= 0
-LAUNCHER_CFLAGS = $(APP_CFLAGS) -Os -DLAUNCHER_CFG_VERBOSE=$(LAUNCHER_CFG_VERBOSE)
+LAUNCHER_DMA_LOAD ?= 0
+LAUNCHER_CFLAGS = $(APP_CFLAGS) -Os -DLAUNCHER_CFG_VERBOSE=$(LAUNCHER_CFG_VERBOSE) -DLAUNCHER_DMA_LOAD=$(LAUNCHER_DMA_LOAD)
+ifeq ($(LAUNCHER_DMA_LOAD),1)
+LAUNCHER_DMA_SRCS = $(APPS_DIR)/launcher/launcher_uci_dma.s
+else
+LAUNCHER_DMA_SRCS =
+endif
# Output files
BOOT = $(BIN_DIR)/boot.prg
@@ -76,6 +82,10 @@ READYBASIC = $(BIN_DIR)/readybasic.prg
READYBASIC_RBTEST1 = $(OBJ_DIR)/rbtest1.prg
READYBASIC_RBPROC1 = $(OBJ_DIR)/rbproc1.prg
READYBASIC_RBPROCERR = $(OBJ_DIR)/rbprocerr.prg
+READYBASIC_GFX_DEMO_NAMES = rbgfx01_modes rbgfx02_hires_plot rbgfx03_hires_lines rbgfx04_rects rbgfx05_point_read rbgfx06_reu_surface rbgfx07_mbitmap rbgfx08_tile rbgfx09_sprites rbgfx10_collision rbgfx11_input rbgfx12_showcase rbgfx13_sprite_steps rbgfx14_phase2_prims rbgfx15_phase2_tiles rbgfx16_phase2_sprite_ctrl rbgfx17_poly_array rbgfx18_fpoly_array rbgfx19_poly_reu rbgfx20_fpoly_reu_showcase rbgfx21_mbitmap_prims rbgfx22_mbitmap_point rbgfx23_dlist rbgfx24_tilemap rbgfx25_mbcells rbgfx26_mode_matrix rbgfx27_target_blit rbgfx28_tile_visible rbgfx29_mtile_visible rbgfx30_mbitmap_dlist rbgfx31_sync_blit rbgfx32_convex_poly
+READYBASIC_GFX_DEMOS = $(addprefix $(OBJ_DIR)/,$(addsuffix .prg,$(READYBASIC_GFX_DEMO_NAMES)))
+READYBASIC_SOUND_DEMO_NAMES = rbsnd01_sid_basics rbsnd02_voice_state rbsnd03_notes rbsnd04_filter rbsnd05_voice_batch rbsnd06_three_voice
+READYBASIC_SOUND_DEMOS = $(addprefix $(OBJ_DIR)/,$(addsuffix .prg,$(READYBASIC_SOUND_DEMO_NAMES)))
READYBASIC_MODULE_DIR = $(OBJ_DIR)/readybasic_modules
READYBASIC_RBM_SAMPLE1 = $(READYBASIC_MODULE_DIR)/rbm.sample1.seq
READYBASIC_RBM_SAMPLE2 = $(READYBASIC_MODULE_DIR)/rbm.sample2.seq
@@ -84,13 +94,27 @@ READYBASIC_MODULES = $(READYBASIC_RBM_SAMPLE1) $(READYBASIC_RBM_SAMPLE2) $(READY
READYBASIC_VICE_SCRIPTS = \
$(BUILD_SUPPORT_DIR)/run_readybasic_demo_suite.sh \
$(BUILD_SUPPORT_DIR)/run_readybasic_full_suite_visual_verification.sh \
+ $(BUILD_SUPPORT_DIR)/run_readybasic_hotkey_probe.sh \
+ $(BUILD_SUPPORT_DIR)/run_readybasic_keyboard_regression_probe.sh \
+ $(BUILD_SUPPORT_DIR)/run_readybasic_reuviewer_f2_chain_probe.sh \
$(BUILD_SUPPORT_DIR)/run_readybasic_cross_app_resume_probe.sh \
$(BUILD_SUPPORT_DIR)/run_readybasic_large_vars_probe.sh \
$(BUILD_SUPPORT_DIR)/run_readybasic_lifecycle_probe.sh \
$(BUILD_SUPPORT_DIR)/run_readybasic_module_overlay_probe.sh \
$(BUILD_SUPPORT_DIR)/run_readybasic_plugin_command_probe.sh \
+ $(BUILD_SUPPORT_DIR)/run_readybasic_gfx_phase1_probe.sh \
+ $(BUILD_SUPPORT_DIR)/run_readybasic_gfx_phase2_demo.sh \
+ $(BUILD_SUPPORT_DIR)/run_readybasic_gfx_phase3_demo.sh \
+ $(BUILD_SUPPORT_DIR)/run_readybasic_gfx_phase4_demo.sh \
+ $(BUILD_SUPPORT_DIR)/run_readybasic_gfx_phase5_demo.sh \
+ $(BUILD_SUPPORT_DIR)/run_readybasic_gfx_mbitmap_demo.sh \
+ $(BUILD_SUPPORT_DIR)/run_readybasic_sprite_steps_demo.sh \
+ $(BUILD_SUPPORT_DIR)/run_readybasic_sound_phase1_demo.sh \
+ $(BUILD_SUPPORT_DIR)/run_readybasic_readyos_loaded_apps_suite.sh \
$(BUILD_SUPPORT_DIR)/run_readybasic_program_probe.sh \
$(BUILD_SUPPORT_DIR)/run_readybasic_rbtest1_probe.sh \
+ $(BUILD_SUPPORT_DIR)/run_readybasic_resume_min_probe.sh \
+ $(BUILD_SUPPORT_DIR)/run_readybasic_screen_reu_temp_probe.sh \
$(BUILD_SUPPORT_DIR)/run_readybasic_second_entry_editor_probe.sh \
$(BUILD_SUPPORT_DIR)/run_readybasic_state_probe.sh \
$(BUILD_SUPPORT_DIR)/vice_readybasic_repeat_label_probe.sh
@@ -114,6 +138,7 @@ BOOT_EASYFLASH_ROMH = $(BIN_DIR)/boot_easyflash_romh.bin
EASYFLASH_SMOKE_MON = $(OBJ_DIR)/easyflash_smoke.mon
EASYFLASH_SMOKE_LOG = $(OBJ_DIR)/easyflash_smoke.log
EASYFLASH_SMOKE_RUNTIME_CRT = $(OBJ_DIR)/easyflash_smoke.runtime.crt
+EASYFLASH_SMOKE_REU_IMAGE = $(OBJ_DIR)/easyflash_smoke.reu
EASYFLASH_BOOT_MAP = $(OBJ_DIR)/boot_easyflash_roml.map
IP65_DIR = $(THIRD_PARTY_DIR)/ip65
IP65_TCP_OBJ_DIR = $(OBJ_DIR)/ip65/tcp
@@ -197,7 +222,10 @@ TUI_WINDOW_SRC = $(LIB_DIR)/tui_window.c
TUI_MENU_SRC = $(LIB_DIR)/tui_menu.c
TUI_INPUT_SRC = $(LIB_DIR)/tui_input.c
TUI_NAV_SRC = $(LIB_DIR)/tui_nav.c
-TUI_HOTKEY_SRC = $(LIB_DIR)/tui_hotkeys.c
+TUI_READYOS_LITE_SRC = $(LIB_DIR)/tui_readyos.c
+TUI_READYOS_SRC = $(LIB_DIR)/tui_readyos_alias.s
+TUI_HOTKEY_SRC = $(LIB_DIR)/tui_hotkeys.c $(TUI_READYOS_SRC)
+TUI_HOTKEY_LITE_SRC = $(LIB_DIR)/tui_hotkeys.c $(TUI_READYOS_LITE_SRC)
TUI_MISC_SRC = $(LIB_DIR)/tui_misc.c
TUI_CONTROLS_SRC = $(LIB_DIR)/tui_controls.c
TUI_SPLIT_SRC = $(LIB_DIR)/tui_split.c
@@ -214,11 +242,13 @@ REU_CONTROL_REGISTRY_SRC = $(LIB_DIR)/reu_control_registry.c
STORAGE_DEVICE_SRC = $(LIB_DIR)/storage_device.c
FILE_BROWSER_SRC = $(LIB_DIR)/file_browser.c
DIR_PAGE_SRC = $(LIB_DIR)/dir_page.c
+LAUNCHER_DIR_PAGE_SRC = $(APPS_DIR)/launcher/launcher_dir_page.c
FILE_DIALOG_SRC = $(LIB_DIR)/file_dialog.c
CLIP_COPY_SRC = $(LIB_DIR)/clipboard_copy.c
CLIP_PASTE_SRC = $(LIB_DIR)/clipboard_paste.c
CLIP_COUNT_SRC = $(LIB_DIR)/clipboard_count.c
CLIP_ADMIN_SRC = $(LIB_DIR)/clipboard_admin.c
+CLIP_INSERT_SRC = $(LIB_DIR)/clipboard_insert.c
RESUME_STATE_CTX_SRC = $(LIB_DIR)/resume_state_ctx.c
RESUME_STATE_CORE_SRC = $(LIB_DIR)/resume_state_core.c
RESUME_STATE_SEGMENTS_SRC = $(LIB_DIR)/resume_state_segments.c
@@ -321,7 +351,8 @@ READYSHELL_RESIDENT_EASYFLASH_SRCS = \
$(REU_DMA_SRC) \
$(RESUME_STATE_SIMPLE_SRCS)
READYSHELL_RESIDENT_ASM_SRCS = \
- $(READYSHELL_PLATFORM_C64_DIR)/rs_runtime_c64.s
+ $(READYSHELL_PLATFORM_C64_DIR)/rs_runtime_c64.s \
+ $(TUI_READYOS_SRC)
READYSHELL_RESIDENT_C_OBJS = $(patsubst %.c,$(READYSHELL_OBJ_DIR)/resident/%.o,$(READYSHELL_RESIDENT_SRCS))
READYSHELL_RESIDENT_ASM_OBJS = $(patsubst %.s,$(READYSHELL_OBJ_DIR)/resident/%.o,$(READYSHELL_RESIDENT_ASM_SRCS))
READYSHELL_RESIDENT_OBJS = $(READYSHELL_RESIDENT_C_OBJS) $(READYSHELL_RESIDENT_ASM_OBJS)
@@ -354,26 +385,26 @@ TUI_BASE_MENU_INPUT_NAV_MISC = $(TUI_BASE) $(TUI_MENU_SRC) $(TUI_INPUT_SRC) $(TU
TUI_UCITEST = $(TUI_BASE_NAV) $(TUI_CONTROLS_SRC) $(TUI_SPLIT_SRC) $(TUI_OUTPUT_SRC)
LIB_LAUNCHER = $(TUI_BASE_MENU_MISC) $(TUI_HOTKEY_SRC) $(REU_DMA_SRC) $(REU_PHYS_SRC) $(REU_PHYS_PROBE_SRC) $(REU_CONTROL_BANK_SRC) $(REU_CONTROL_REGISTRY_SRC) $(RESUME_STATE_SEGMENT_SRCS)
-LIB_LAUNCHER_DISK = $(LIB_LAUNCHER) $(STORAGE_DEVICE_SRC) $(DIR_PAGE_SRC) $(FILE_DIALOG_SRC)
+LIB_LAUNCHER_DISK = $(LIB_LAUNCHER) $(STORAGE_DEVICE_SRC) $(LAUNCHER_DIR_PAGE_SRC) $(FILE_DIALOG_SRC)
LIB_REU_BASE = $(REU_INIT_SRC)
LIB_REU_DMA = $(REU_INIT_SRC) $(REU_ALLOC_SRC) $(REU_DMA_SRC)
LIB_REU_STATS = $(REU_INIT_SRC) $(REU_STATS_SRC)
LIB_REU_DMA_STATS = $(REU_INIT_SRC) $(REU_ALLOC_SRC) $(REU_DMA_SRC) $(REU_STATS_SRC)
-LIB_CLIP_COPY = $(CLIP_COPY_SRC)
+LIB_CLIP_COPY = $(CLIP_COPY_SRC) $(CLIP_INSERT_SRC) $(CLIP_COUNT_SRC)
LIB_CLIP_PASTE = $(CLIP_PASTE_SRC)
LIB_CLIP_COUNT = $(CLIP_COUNT_SRC)
LIB_CLIP_PASTE_COUNT = $(CLIP_PASTE_SRC) $(CLIP_COUNT_SRC)
-LIB_CLIP_COPY_PASTE_COUNT = $(CLIP_COPY_SRC) $(CLIP_PASTE_SRC) $(CLIP_COUNT_SRC)
+LIB_CLIP_COPY_PASTE_COUNT = $(CLIP_COPY_SRC) $(CLIP_INSERT_SRC) $(CLIP_PASTE_SRC) $(CLIP_COUNT_SRC)
LIB_EDITOR = $(TUI_BASE_MENU_INPUT_NAV_MISC) $(TUI_HOTKEY_SRC) $(LIB_REU_DMA) $(LIB_CLIP_COPY_PASTE_COUNT) $(RESUME_STATE_SEGMENT_SRCS) $(STORAGE_DEVICE_SRC) $(DIR_PAGE_SRC) $(FILE_DIALOG_SRC)
LIB_QUICKNOTES = $(TUI_BASE_MENU_INPUT_NAV_MISC) $(TUI_HOTKEY_SRC) $(LIB_REU_DMA_STATS) $(REU_OWNED_ALLOC_SRC) $(LIB_CLIP_COPY_PASTE_COUNT) $(RESUME_STATE_ALL_SRCS) $(STORAGE_DEVICE_SRC) $(DIR_PAGE_SRC) $(FILE_DIALOG_SRC)
LIB_CALCPLUS = $(TUI_BASE_NAV) $(TUI_HOTKEY_SRC) $(LIB_REU_DMA) $(LIB_CLIP_COPY_PASTE_COUNT) $(RESUME_STATE_SEGMENT_SRCS)
LIB_HEXVIEW = $(TUI_BASE_NAV_MISC) $(TUI_HOTKEY_SRC) $(LIB_REU_DMA) $(LIB_CLIP_COPY) $(RESUME_STATE_SIMPLE_SRCS)
-LIB_CLIPMGR = $(TUI_BASE_MENU_INPUT_NAV_MISC) $(TUI_HOTKEY_SRC) $(LIB_REU_DMA_STATS) $(LIB_CLIP_PASTE_COUNT) $(CLIP_ADMIN_SRC) $(RESUME_STATE_SIMPLE_SRCS) $(STORAGE_DEVICE_SRC) $(DIR_PAGE_SRC)
+LIB_CLIPMGR = $(TUI_BASE_MENU_INPUT_NAV_MISC) $(TUI_HOTKEY_SRC) $(LIB_REU_DMA_STATS) $(LIB_CLIP_PASTE_COUNT) $(CLIP_ADMIN_SRC) $(CLIP_INSERT_SRC) $(RESUME_STATE_SIMPLE_SRCS) $(STORAGE_DEVICE_SRC) $(DIR_PAGE_SRC)
LIB_REUVIEWER = $(TUI_BASE_NAV_MISC) $(TUI_HOTKEY_SRC) $(LIB_REU_DMA_STATS) $(REU_PHYS_SRC) $(REU_CONTROL_BANK_SRC) $(RESUME_STATE_SIMPLE_SRCS)
-LIB_SYSINFO = $(TUI_BASE_NAV_MISC) $(TUI_HOTKEY_SRC)
+LIB_SYSINFO = $(TUI_BASE_NAV_MISC) $(TUI_HOTKEY_LITE_SRC)
LIB_TASKLIST = $(TUI_BASE_MENU_INPUT_NAV_MISC) $(TUI_HOTKEY_SRC) $(LIB_REU_DMA) $(LIB_CLIP_COPY_PASTE_COUNT) $(RESUME_STATE_ALL_SRCS) $(STORAGE_DEVICE_SRC) $(DIR_PAGE_SRC)
LIB_SIMPLEFILES = $(TUI_BASE_MENU_INPUT_NAV_MISC) $(TUI_HOTKEY_SRC) $(REU_DMA_SRC) $(RESUME_STATE_SIMPLE_SRCS) $(STORAGE_DEVICE_SRC) $(FILE_BROWSER_SRC)
-LIB_SIMPLECELLS = $(TUI_BASE_MENU_INPUT_NAV_MISC) $(LIB_REU_DMA) $(RESUME_STATE_SEGMENT_SRCS) $(STORAGE_DEVICE_SRC) $(DIR_PAGE_SRC)
+LIB_SIMPLECELLS = $(TUI_BASE_MENU_INPUT_NAV_MISC) $(TUI_READYOS_SRC) $(LIB_REU_DMA) $(RESUME_STATE_SEGMENT_SRCS) $(STORAGE_DEVICE_SRC) $(DIR_PAGE_SRC)
LIB_GAME2048 = $(TUI_BASE_NAV) $(TUI_HOTKEY_SRC) $(REU_DMA_SRC) $(RESUME_STATE_SIMPLE_SRCS)
LIB_DEMINER = $(TUI_BASE_NAV) $(TUI_HOTKEY_SRC) $(REU_DMA_SRC) $(RESUME_STATE_SIMPLE_SRCS)
LIB_SIDETRIS = $(TUI_BASE_NAV) $(TUI_HOTKEY_SRC) $(REU_DMA_SRC) $(RESUME_STATE_SIMPLE_SRCS)
@@ -381,13 +412,13 @@ LIB_CAL26 = $(TUI_BASE_INPUT_NAV_MISC) $(TUI_HOTKEY_SRC) $(LIB_REU_DMA) $(LIB_CL
LIB_DIZZY = $(TUI_BASE_INPUT_NAV) $(TUI_HOTKEY_SRC) $(REU_DMA_SRC) $(RESUME_STATE_SEGMENT_SRCS)
LIB_README = $(TUI_BASE_NAV_MISC) $(TUI_HOTKEY_SRC) $(REU_DMA_SRC) $(RESUME_STATE_SIMPLE_SRCS)
LIB_READYSHELL = $(REU_DMA_SRC) $(RESUME_STATE_SIMPLE_SRCS)
-LIB_READYIRC = $(TUI_BASE_NAV_MISC) $(TUI_HOTKEY_SRC) $(LIB_REU_DMA) $(REU_OWNED_ALLOC_SRC) $(RESUME_STATE_SIMPLE_SRCS)
+LIB_READYIRC = $(TUI_BASE_INPUT_NAV_MISC) $(TUI_HOTKEY_SRC) $(LIB_REU_DMA) $(REU_OWNED_ALLOC_SRC) $(RESUME_STATE_SIMPLE_SRCS)
LIB_RIRC_RRNET = $(TUI_BASE_NAV_MISC) $(TUI_HOTKEY_SRC) $(LIB_REU_DMA) $(REU_OWNED_ALLOC_SRC) $(RESUME_STATE_SIMPLE_SRCS) $(IP65_TCP_LIB) $(IP65_C64_LIB)
-LIB_UCITEST = $(TUI_UCITEST) $(TUI_HOTKEY_SRC)
+LIB_UCITEST = $(TUI_UCITEST) $(TUI_HOTKEY_LITE_SRC)
EASYFLASH_PAYLOADS = $(LAUNCHER_EASYFLASH) $(READYSHELL_EASYFLASH) $(EDITOR) $(QUICKNOTES) $(CALCPLUS) $(HEXVIEW) $(CLIPMGR) $(REUVIEWER) $(SYSINFO) $(TASKLIST) $(SIMPLEFILES) $(SIMPLECELLS) $(GAME2048) $(DEMINER) $(SIDETRIS) $(CAL26) $(DIZZY) $(READYIRC) $(RIRC_RRNET) $(READYBASIC) $(UCITEST) $(READMEAPP) $(READYSHELL_OVL1_PRG) $(READYSHELL_OVL2_PRG) $(READYSHELL_OVL3_PRG) $(READYSHELL_OVL4_PRG) $(READYSHELL_OVL5_PRG) $(READYSHELL_OVL6_PRG) $(READYSHELL_OVL7_PRG) $(READYSHELL_OVL8_PRG) $(READYSHELL_OVL9_PRG)
# Primary binaries shared across profiles
-PROGRAMS = $(BOOT) $(PREBOOT) $(SETD71) $(SHOWCFG) $(TEST_REU) $(LAUNCHER) $(EDITOR) $(QUICKNOTES) $(CALCPLUS) $(HEXVIEW) $(CLIPMGR) $(REUVIEWER) $(SYSINFO) $(TASKLIST) $(SIMPLEFILES) $(SIMPLECELLS) $(GAME2048) $(DEMINER) $(SIDETRIS) $(CAL26) $(DIZZY) $(READYIRC) $(RIRC_RRNET) $(READYBASIC) $(READYBASIC_RBTEST1) $(READYBASIC_RBPROC1) $(READYBASIC_RBPROCERR) $(READYBASIC_MODULES) $(UCITEST) $(READMEAPP) $(READYSHELL)
+PROGRAMS = $(BOOT) $(PREBOOT) $(SETD71) $(SHOWCFG) $(TEST_REU) $(LAUNCHER) $(EDITOR) $(QUICKNOTES) $(CALCPLUS) $(HEXVIEW) $(CLIPMGR) $(REUVIEWER) $(SYSINFO) $(TASKLIST) $(SIMPLEFILES) $(SIMPLECELLS) $(GAME2048) $(DEMINER) $(SIDETRIS) $(CAL26) $(DIZZY) $(READYIRC) $(RIRC_RRNET) $(READYBASIC) $(READYBASIC_RBTEST1) $(READYBASIC_RBPROC1) $(READYBASIC_RBPROCERR) $(READYBASIC_GFX_DEMOS) $(READYBASIC_SOUND_DEMOS) $(READYBASIC_MODULES) $(UCITEST) $(READMEAPP) $(READYSHELL)
$(BIN_DIR):
@mkdir -p "$@"
@@ -484,8 +515,8 @@ $(TEST_REU): $(SRC_DIR)/test_reu.c
$(CC) $(CFLAGS) -o $@ $<
# Launcher app (loads at $1000)
-$(LAUNCHER): $(APPS_DIR)/launcher/launcher.c $(LIB_LAUNCHER_DISK) $(VERSION_HEADER)
- $(CC) $(LAUNCHER_CFLAGS) -m $(OBJ_DIR)/launcher.map -o $@ $(APPS_DIR)/launcher/launcher.c $(LIB_LAUNCHER_DISK)
+$(LAUNCHER): $(APPS_DIR)/launcher/launcher.c $(LAUNCHER_DMA_SRCS) $(LIB_LAUNCHER_DISK) $(VERSION_HEADER)
+ $(CC) $(LAUNCHER_CFLAGS) -m $(OBJ_DIR)/launcher.map -o $@ $(APPS_DIR)/launcher/launcher.c $(LAUNCHER_DMA_SRCS) $(LIB_LAUNCHER_DISK)
$(LAUNCHER_EASYFLASH): $(APPS_DIR)/launcher/launcher_easyflash.c $(LIB_LAUNCHER) $(VERSION_HEADER) $(EASYFLASH_LAUNCHER_HEADER)
$(CC) $(LAUNCHER_CFLAGS) $(EASYFLASH_LAUNCHER_CPPFLAGS) -m $(OBJ_DIR)/launcher_easyflash.map -o $@ $(APPS_DIR)/launcher/launcher_easyflash.c $(LIB_LAUNCHER)
@@ -664,6 +695,15 @@ readybasic-demo-vice: $(BUILD_SUPPORT_DIR)/run_readybasic_demo_suite.sh
readybasic-full-vice: $(BUILD_SUPPORT_DIR)/run_readybasic_full_suite_visual_verification.sh
$(BUILD_SUPPORT_DIR)/run_readybasic_full_suite_visual_verification.sh
+readybasic-hotkey-vice: $(BUILD_SUPPORT_DIR)/run_readybasic_hotkey_probe.sh
+ READYBASIC_HOTKEY_BOOT_MODE=launcher READYBASIC_HOTKEY_SCENARIO=launcher_cycle $(BUILD_SUPPORT_DIR)/run_readybasic_hotkey_probe.sh
+
+readybasic-keyboard-regression-vice: $(BUILD_SUPPORT_DIR)/run_readybasic_keyboard_regression_probe.sh
+ $(BUILD_SUPPORT_DIR)/run_readybasic_keyboard_regression_probe.sh
+
+readybasic-reuviewer-f2-chain-vice: $(BUILD_SUPPORT_DIR)/run_readybasic_reuviewer_f2_chain_probe.sh
+ $(BUILD_SUPPORT_DIR)/run_readybasic_reuviewer_f2_chain_probe.sh
+
readybasic-cross-app-resume-vice: $(BUILD_SUPPORT_DIR)/run_readybasic_cross_app_resume_probe.sh
$(BUILD_SUPPORT_DIR)/run_readybasic_cross_app_resume_probe.sh
@@ -676,6 +716,33 @@ readybasic-lifecycle-vice: $(BUILD_SUPPORT_DIR)/run_readybasic_lifecycle_probe.s
readybasic-plugin-command-vice: $(BUILD_SUPPORT_DIR)/run_readybasic_plugin_command_probe.sh
$(BUILD_SUPPORT_DIR)/run_readybasic_plugin_command_probe.sh
+readybasic-gfx-phase1-vice: $(BUILD_SUPPORT_DIR)/run_readybasic_gfx_phase1_probe.sh
+ $(BUILD_SUPPORT_DIR)/run_readybasic_gfx_phase1_probe.sh
+
+readybasic-sprite-steps-vice: $(BUILD_SUPPORT_DIR)/run_readybasic_sprite_steps_demo.sh
+ $(BUILD_SUPPORT_DIR)/run_readybasic_sprite_steps_demo.sh
+
+readybasic-gfx-phase2-vice: $(BUILD_SUPPORT_DIR)/run_readybasic_gfx_phase2_demo.sh
+ $(BUILD_SUPPORT_DIR)/run_readybasic_gfx_phase2_demo.sh
+
+readybasic-gfx-phase3-vice: $(BUILD_SUPPORT_DIR)/run_readybasic_gfx_phase3_demo.sh
+ $(BUILD_SUPPORT_DIR)/run_readybasic_gfx_phase3_demo.sh
+
+readybasic-gfx-mbitmap-vice: $(BUILD_SUPPORT_DIR)/run_readybasic_gfx_mbitmap_demo.sh
+ $(BUILD_SUPPORT_DIR)/run_readybasic_gfx_mbitmap_demo.sh
+
+readybasic-gfx-phase4-vice: $(BUILD_SUPPORT_DIR)/run_readybasic_gfx_phase4_demo.sh
+ $(BUILD_SUPPORT_DIR)/run_readybasic_gfx_phase4_demo.sh
+
+readybasic-gfx-phase5-vice: $(BUILD_SUPPORT_DIR)/run_readybasic_gfx_phase5_demo.sh
+ $(BUILD_SUPPORT_DIR)/run_readybasic_gfx_phase5_demo.sh
+
+readybasic-sound-phase1-vice: $(BUILD_SUPPORT_DIR)/run_readybasic_sound_phase1_demo.sh
+ $(BUILD_SUPPORT_DIR)/run_readybasic_sound_phase1_demo.sh
+
+readybasic-readyos-loaded-apps-vice: $(BUILD_SUPPORT_DIR)/run_readybasic_readyos_loaded_apps_suite.sh
+ $(BUILD_SUPPORT_DIR)/run_readybasic_readyos_loaded_apps_suite.sh
+
readybasic-module-overlay-vice: $(BUILD_SUPPORT_DIR)/run_readybasic_module_overlay_probe.sh
$(BUILD_SUPPORT_DIR)/run_readybasic_module_overlay_probe.sh
@@ -685,12 +752,24 @@ readybasic-program-vice: $(BUILD_SUPPORT_DIR)/run_readybasic_program_probe.sh
readybasic-rbtest1-vice: $(BUILD_SUPPORT_DIR)/run_readybasic_rbtest1_probe.sh
$(BUILD_SUPPORT_DIR)/run_readybasic_rbtest1_probe.sh
+readybasic-resume-min-vice: $(BUILD_SUPPORT_DIR)/run_readybasic_resume_min_probe.sh
+ $(BUILD_SUPPORT_DIR)/run_readybasic_resume_min_probe.sh
+
+readybasic-screen-reu-temp-vice: $(BUILD_SUPPORT_DIR)/run_readybasic_screen_reu_temp_probe.sh
+ $(BUILD_SUPPORT_DIR)/run_readybasic_screen_reu_temp_probe.sh
+
launcher-reu-state-vice: $(BUILD_SUPPORT_DIR)/run_launcher_reu_state_probe.sh
$(BUILD_SUPPORT_DIR)/run_launcher_reu_state_probe.sh
quicknotes-owned-reu-vice: $(BUILD_SUPPORT_DIR)/run_quicknotes_owned_reu_probe.sh
$(BUILD_SUPPORT_DIR)/run_quicknotes_owned_reu_probe.sh
+readyshell-cross-app-resume-vice: $(BUILD_SUPPORT_DIR)/run_readyshell_cross_app_resume_probe.sh
+ $(BUILD_SUPPORT_DIR)/run_readyshell_cross_app_resume_probe.sh
+
+readyshell-cross-app-resume-c64u: $(BUILD_SUPPORT_DIR)/run_readyshell_cross_app_resume_c64u.sh
+ $(BUILD_SUPPORT_DIR)/run_readyshell_cross_app_resume_c64u.sh
+
readybasic-second-entry-editor-vice: $(BUILD_SUPPORT_DIR)/run_readybasic_second_entry_editor_probe.sh
$(BUILD_SUPPORT_DIR)/run_readybasic_second_entry_editor_probe.sh
@@ -702,7 +781,7 @@ readybasic-vice-plans: $(READYBASIC_VICE_SCRIPTS)
READYBASIC_SKIP_BUILD=1 READYBASIC_GENERATE_PLAN_ONLY=1 "$$script"; \
done
-readybasic-vice-suites: readybasic-demo-vice readybasic-repeat-label-vice readybasic-lifecycle-vice readybasic-module-overlay-vice readybasic-plugin-command-vice readybasic-program-vice readybasic-rbtest1-vice readybasic-state-vice readybasic-large-vars-vice readybasic-cross-app-resume-vice readybasic-second-entry-editor-vice readybasic-full-vice
+readybasic-vice-suites: readybasic-demo-vice readybasic-repeat-label-vice readybasic-lifecycle-vice readybasic-module-overlay-vice readybasic-plugin-command-vice readybasic-program-vice readybasic-rbtest1-vice readybasic-resume-min-vice readybasic-screen-reu-temp-vice readybasic-state-vice readybasic-large-vars-vice readybasic-hotkey-vice readybasic-keyboard-regression-vice readybasic-reuviewer-f2-chain-vice readybasic-cross-app-resume-vice readybasic-second-entry-editor-vice readybasic-gfx-phase1-vice readybasic-sprite-steps-vice readybasic-gfx-phase2-vice readybasic-gfx-phase3-vice readybasic-gfx-mbitmap-vice readybasic-gfx-phase4-vice readybasic-gfx-phase5-vice readybasic-sound-phase1-vice readybasic-readyos-loaded-apps-vice readybasic-full-vice
readybasic-memory-report: $(READYBASIC) $(BUILD_SUPPORT_DIR)/readybasic_memory_report.py
$(PYTHON) $(BUILD_SUPPORT_DIR)/readybasic_memory_report.py --html-out docs/readybasic_memory_diagrams.html
@@ -720,6 +799,14 @@ $(READYBASIC_RBPROCERR): $(APPS_DIR)/readybasic/rbprocerr.bas
@mkdir -p "$(OBJ_DIR)"
$(PETCAT) -w2 -l 2ac1 -o $@ -- $<
+$(OBJ_DIR)/rbgfx%.prg: $(APPS_DIR)/readybasic/rbgfx%.bas
+ @mkdir -p "$(OBJ_DIR)"
+ $(PETCAT) -w2 -l 2ac1 -o $@ -- $<
+
+$(OBJ_DIR)/rbsnd%.prg: $(APPS_DIR)/readybasic/rbsnd%.bas
+ @mkdir -p "$(OBJ_DIR)"
+ $(PETCAT) -w2 -l 2ac1 -o $@ -- $<
+
$(READYBASIC_MODULES): $(BUILD_SUPPORT_DIR)/build_readybasic_disk_modules.py
@mkdir -p "$(READYBASIC_MODULE_DIR)"
$(PYTHON) $(BUILD_SUPPORT_DIR)/build_readybasic_disk_modules.py --out-dir "$(READYBASIC_MODULE_DIR)"
@@ -973,8 +1060,9 @@ easyflash-verify: easyflash
$(PYTHON) $(BUILD_SUPPORT_DIR)/vice_easyflash_smoke.py write-monitor --output "$(EASYFLASH_SMOKE_MON)" --launcher-map "$(OBJ_DIR)/launcher_easyflash.map" --boot-map "$(EASYFLASH_BOOT_MAP)" --include-preload
cp "$(EASYFLASH_OUTPUT_DIR)/readyos_easyflash.crt" "$(EASYFLASH_SMOKE_RUNTIME_CRT)"
rm -f "$(EASYFLASH_SMOKE_LOG)"
- script -q /dev/null x64sc -console -default +sound -warp -reu -reusize 16384 -cartcrt "$(EASYFLASH_SMOKE_RUNTIME_CRT)" -drive8type 1541 -devicebackend8 0 +busdevice8 -8 "$(EASYFLASH_OUTPUT_DIR)/readyos_data.d64" -moncommands "$(EASYFLASH_SMOKE_MON)" -monlog -monlogname "$(EASYFLASH_SMOKE_LOG)" -initbreak 0xe000 -limitcycles 120000000 || true
- $(PYTHON) $(BUILD_SUPPORT_DIR)/vice_easyflash_smoke.py verify-log --layout "$(EASYFLASH_LAYOUT_JSON)" --output-dir "$(EASYFLASH_OUTPUT_DIR)" --log "$(EASYFLASH_SMOKE_LOG)" --launcher-map "$(OBJ_DIR)/launcher_easyflash.map" --verify-preload
+ dd if=/dev/zero of="$(EASYFLASH_SMOKE_REU_IMAGE)" bs=1048576 count=16
+ script -q /dev/null x64sc -console -default +sound -warp -reu -reusize 16384 -reuimage "$(EASYFLASH_SMOKE_REU_IMAGE)" -reuimagerw -cartcrt "$(EASYFLASH_SMOKE_RUNTIME_CRT)" -drive8type 1541 -devicebackend8 0 +busdevice8 -8 "$(EASYFLASH_OUTPUT_DIR)/readyos_data.d64" -moncommands "$(EASYFLASH_SMOKE_MON)" -monlog -monlogname "$(EASYFLASH_SMOKE_LOG)" -initbreak 0xe000 -limitcycles 120000000 || true
+ $(PYTHON) $(BUILD_SUPPORT_DIR)/vice_easyflash_smoke.py verify-log --layout "$(EASYFLASH_LAYOUT_JSON)" --output-dir "$(EASYFLASH_OUTPUT_DIR)" --log "$(EASYFLASH_SMOKE_LOG)" --launcher-map "$(OBJ_DIR)/launcher_easyflash.map" --reu-image "$(EASYFLASH_SMOKE_REU_IMAGE)" --verify-preload
easyflash-report: easyflash
$(PYTHON) $(BUILD_SUPPORT_DIR)/readyos_easyflash.py report \
@@ -987,8 +1075,9 @@ easyflash-smoke: easyflash
$(PYTHON) $(BUILD_SUPPORT_DIR)/vice_easyflash_smoke.py write-monitor --output "$(EASYFLASH_SMOKE_MON)" --launcher-map "$(OBJ_DIR)/launcher_easyflash.map" --boot-map "$(EASYFLASH_BOOT_MAP)" --include-preload
cp "$(EASYFLASH_OUTPUT_DIR)/readyos_easyflash.crt" "$(EASYFLASH_SMOKE_RUNTIME_CRT)"
rm -f "$(EASYFLASH_SMOKE_LOG)"
- script -q /dev/null x64sc -console -default +sound -warp -reu -reusize 16384 -cartcrt "$(EASYFLASH_SMOKE_RUNTIME_CRT)" -drive8type 1541 -devicebackend8 0 +busdevice8 -8 "$(EASYFLASH_OUTPUT_DIR)/readyos_data.d64" -moncommands "$(EASYFLASH_SMOKE_MON)" -monlog -monlogname "$(EASYFLASH_SMOKE_LOG)" -initbreak 0xe000 -limitcycles 120000000 || true
- $(PYTHON) $(BUILD_SUPPORT_DIR)/vice_easyflash_smoke.py verify-log --layout "$(EASYFLASH_LAYOUT_JSON)" --output-dir "$(EASYFLASH_OUTPUT_DIR)" --log "$(EASYFLASH_SMOKE_LOG)" --launcher-map "$(OBJ_DIR)/launcher_easyflash.map" --verify-preload
+ dd if=/dev/zero of="$(EASYFLASH_SMOKE_REU_IMAGE)" bs=1048576 count=16
+ script -q /dev/null x64sc -console -default +sound -warp -reu -reusize 16384 -reuimage "$(EASYFLASH_SMOKE_REU_IMAGE)" -reuimagerw -cartcrt "$(EASYFLASH_SMOKE_RUNTIME_CRT)" -drive8type 1541 -devicebackend8 0 +busdevice8 -8 "$(EASYFLASH_OUTPUT_DIR)/readyos_data.d64" -moncommands "$(EASYFLASH_SMOKE_MON)" -monlog -monlogname "$(EASYFLASH_SMOKE_LOG)" -initbreak 0xe000 -limitcycles 120000000 || true
+ $(PYTHON) $(BUILD_SUPPORT_DIR)/vice_easyflash_smoke.py verify-log --layout "$(EASYFLASH_LAYOUT_JSON)" --output-dir "$(EASYFLASH_OUTPUT_DIR)" --log "$(EASYFLASH_SMOKE_LOG)" --launcher-map "$(OBJ_DIR)/launcher_easyflash.map" --reu-image "$(EASYFLASH_SMOKE_REU_IMAGE)" --verify-preload
easyflash-smoke-long: easyflash-smoke
@@ -1095,6 +1184,8 @@ verify: profile
python3 $(BUILD_SUPPORT_DIR)/verify_memory_map.py
python3 $(BUILD_SUPPORT_DIR)/verify_reu_control_bank.py
python3 $(BUILD_SUPPORT_DIR)/verify_dynamic_launcher.py
+ python3 $(BUILD_SUPPORT_DIR)/verify_documentation_contract.py
+ python3 $(BUILD_SUPPORT_DIR)/verify_shim_html_source.py
# Full rebuild + deep verification
fullcheck: clean verify
@@ -1225,6 +1316,8 @@ help:
@echo " readyshell-overlay-report - Generate ReadyShell overlay Markdown + HTML docs"
@echo " launcher-reu-state-vice - Run focused launcher unload/reload REU-state VICE probe"
@echo " quicknotes-owned-reu-vice - Run QuickNotes app-owned REU unload/viewer VICE probe"
+ @echo " readyshell-cross-app-resume-vice - Run ReadyShell cross-app resume VICE probe"
+ @echo " readyshell-cross-app-resume-c64u - Run ReadyShell cross-app resume probe on C64 Ultimate"
@echo " readybasic-vice-plans - Regenerate tracked ReadyBASIC VICE YAML plans"
@echo " readybasic-vice-suites - Run all repo-owned ReadyBASIC VICE suites"
@echo " readybasic-full-vice - Run the full ReadyBASIC VICE visual suite"
@@ -1285,5 +1378,5 @@ probe-rel:
launcher-verbose:
$(MAKE) LAUNCHER_CFG_VERBOSE=1 $(LAUNCHER)
-.PHONY: all clean verify verify-resume shim-verify fullcheck help run run-test seed-cal26 probe-rel launcher-verbose readybasic-plugin-static-check launcher-reu-state-vice quicknotes-owned-reu-vice readybasic-demo-vice readybasic-repeat-label-vice readybasic-full-vice readybasic-cross-app-resume-vice readybasic-large-vars-vice readybasic-lifecycle-vice readybasic-module-overlay-vice readybasic-plugin-command-vice readybasic-program-vice readybasic-rbtest1-vice readybasic-second-entry-editor-vice readybasic-state-vice readybasic-vice-plans readybasic-vice-suites readybasic-memory-report readyshell-host-tests readyshell-parse-smoke-host readyshell-vm-smoke-host readyshell-reu-tests-host editor-smoke-host tasklist-smoke-host programs prepare-version profile profiles release-all easyflash easyflash-verify easyflash-smoke easyflash-smoke-long easyflash-preload-verify easyflash-clean FORCE
+.PHONY: all clean verify verify-resume shim-verify fullcheck help run run-test seed-cal26 probe-rel launcher-verbose readybasic-plugin-static-check launcher-reu-state-vice quicknotes-owned-reu-vice readyshell-cross-app-resume-vice readyshell-cross-app-resume-c64u readybasic-demo-vice readybasic-repeat-label-vice readybasic-full-vice readybasic-hotkey-vice readybasic-keyboard-regression-vice readybasic-reuviewer-f2-chain-vice readybasic-cross-app-resume-vice readybasic-large-vars-vice readybasic-lifecycle-vice readybasic-module-overlay-vice readybasic-plugin-command-vice readybasic-gfx-phase1-vice readybasic-gfx-phase2-vice readybasic-gfx-phase3-vice readybasic-gfx-phase4-vice readybasic-gfx-phase5-vice readybasic-gfx-mbitmap-vice readybasic-sound-phase1-vice readybasic-sprite-steps-vice readybasic-readyos-loaded-apps-vice readybasic-program-vice readybasic-rbtest1-vice readybasic-second-entry-editor-vice readybasic-state-vice readybasic-vice-plans readybasic-vice-suites readybasic-memory-report readyshell-host-tests readyshell-parse-smoke-host readyshell-vm-smoke-host readyshell-reu-tests-host editor-smoke-host tasklist-smoke-host programs prepare-version profile profiles release-all easyflash easyflash-verify easyflash-smoke easyflash-smoke-long easyflash-preload-verify easyflash-clean FORCE
EASYFLASH_LAUNCHER_CPPFLAGS ?=
diff --git a/README.md b/README.md
index 0f74b4e..fac7192 100644
--- a/README.md
+++ b/README.md
@@ -5,13 +5,20 @@ Commodore 64 setup. Its long-term center of gravity is the new Commodore 64
Ultimate and related Ultimate-family hardware, but it is intended to support a
wide range of C64 setups that have a reasonably large REU. That includes VICE,
Ultimate-family hardware, and other practical REU-capable modern paths. PRECOG
-`0.2.4` is the current development line.
+`0.2.5` is the current development line.
-The current `0.2.4` development line is still comparatively generic rather
+The current `0.2.5` development line is still comparatively generic rather
than being explicitly tailored to the new C64 Ultimate. This cycle is expected
to push further in that Ultimate-first direction while still trying to stay
usable on other REU-capable C64 setups.
+The current tree also contains an opt-in C64 Ultimate DOS DMA launcher path.
+It loads disk PRGs directly into loader-assigned REU destinations when built
+with `LAUNCHER_DMA_LOAD=1`; normal release builds leave it disabled, and an
+enabled build falls back to the established disk loader whenever UCI, image
+mounting, file lookup, or transfer verification is unavailable. See
+[`docs/ultimate_dos_dma_loading.md`](docs/ultimate_dos_dma_loading.md).
+
## The Concept
What if a Commodore 64 could feel ready, not just nostalgic? ReadyOS treats
@@ -81,19 +88,19 @@ Boot note:
## Current Status
-- Base release: `0.2.4`
+- Base release: `0.2.5`
- Local builds use the existing rolling suffix flow for artifact filenames only
- Builds release media per profile
- Full-content profiles currently include about `20` launcher-visible entries
depending on media capacity; the catalog table below is the current app-token
union across profiles.
- App snapshots and app-owned resource banks are allocated on demand and
- recorded in logical REU bank `0`; ReadyOS no longer pre-reserves a fixed
- 24-bank app-slot gap.
+ recorded in the schema-v5 ReadyOS bank at physical `Skip`; ReadyOS does
+ not reserve a fixed app-slot gap or keep an allocation mirror in C64 RAM.
-## What's New In 0.2.4
+## What's New In 0.2.5
-- Development version bump from the `0.2.3` release-candidate line.
+- Development version bump from the `0.2.4` development line.
- New `precog-easyflash` cartridge SKU for VICE and Ultimate-family setups.
It boots from an EasyFlash `CRT`, keeps a companion `D64` on drive `8`, and
preloads the launcher, app snapshots, and ReadyShell overlays into the REU.
@@ -113,14 +120,20 @@ Boot note:
Ultimate UCI status, and drive status for devices `8` through `11`; on the
C64 Ultimate it shows a variety of Ultimate machine details, including
networking information and IP addresses.
-- The launcher and cartridge loaders now use logical REU bank `0` as the
- ReadyOS control bank for app snapshot lookup, resource-bank relationships,
+- The launcher and cartridge loaders use the physical `Skip` ReadyOS bank as
+ the source of truth for the launcher snapshot, explicit app-token mapping,
+ loaded/resumable status, clipboard metadata, hotkeys, resource relationships,
app catalog metadata, and REU Viewer ownership details. ReadyShell overlays,
ReadyShell state/scratch, and ReadyBASIC core/code banks are loader-assigned
resources rather than fixed physical banks.
+- Launcher return state is intentionally small: an `RSM1` UI record at
+ ReadyOS `$FC40` keeps selection/scroll/one-shot state, while the `LS` record
+ at `$B9D9` and app registry at `$BA00` reconstruct the app-bank, drive,
+ hotkey, resource, loaded-state, and size arrays. Those arrays are not kept as
+ a second authoritative copy in the launcher resume payload.
- Apps can opt into owner-recorded runtime REU allocation without growing the
primitive allocator or shim. QuickNotes note banks and the IRC scrollback
- banks now publish compact ownership records in logical REU bank `0`, so REU
+ banks now publish compact ownership records in the ReadyOS bank, so REU
Viewer can identify the owner and launcher unload can free those banks with
the app.
@@ -305,12 +318,15 @@ Notes:
- ReadyShell tutorial: [src/apps/readyshell/ReadyShelltutorial.md](src/apps/readyshell/ReadyShelltutorial.md)
- ReadyShell architecture: [docs/ReadyShellArchitecture.md](docs/ReadyShellArchitecture.md)
- ReadyShell overlay inventory: [docs/readyshell_overlay_inventory.md](docs/readyshell_overlay_inventory.md)
-- ReadyShell now ships eight overlays allowing language and command functionality that otherwise couldn't fit into the memory of a c64: `rsparser`, `rsvm`, `rsdrvilst`,
- `rsldv`, `rsstv`, `rsfops`, `rscat`, and `rscopy`.
+- ReadyShell now ships nine overlays allowing language and command
+ functionality that otherwise could not fit into C64 memory: `rsparser`,
+ `rsvm`, `rsdrvilst`, `rsldv`, `rsstv`, `rsfops`, `rscat`, `rscopy`, and
+ `rsedit`.
- ReadyShell overlays are loader-assigned resources. The profile
`rsovl+` line records which overlay PRGs are packed into each resource bank
- and at which bank-relative offset, while logical REU bank `0` records the
- runtime owner/resource relationship for REU Viewer, unload, and diagnostics.
+ and at which bank-relative offset, while the schema-v5 ReadyOS bank at
+ physical `Skip` records the runtime owner/resource relationship for REU
+ Viewer, unload, and diagnostics.
- Current ReadyShell command set: `PRT`, `MORE`, `TOP`, `SEL`, `GEN`, `TAP`,
`DRVI`, `LST`, `LDV`, `STV`, `CAT`, `PUT`, `ADD`, `DEL`, `REN`, and `COPY`.
- `LST` accepts wildcard patterns, optional drive selection, and optional
@@ -324,15 +340,40 @@ Notes:
- `showcfg.prg` is a BASIC inspector for the generated `apps.cfg` payload on
drive `8`.
+### ReadyBASIC examples and current guides
+
+ReadyBASIC now builds 32 graphics example PRGs (`rbgfx01_modes` through
+`rbgfx32_convex_poly`) and 6 sound examples (`rbsnd01_sid_basics` through
+`rbsnd06_three_voice`). They progress from mode setup and immediate drawing
+through REU surfaces, sprites/input, polygons, display lists, tilemaps,
+multicolor bitmap operations, and three-voice SID use. The Makefile lists the
+canonical filenames; the regular and EasyFlash demo/probe suites exercise the
+same generated programs.
+
+- [current ReadyBASIC design and measured memory](src/apps/readybasic/READYBASIC_CURRENT_DESIGN.md)
+- [graphics/event commands and demo coverage](src/apps/readybasic/READYBASIC_GRAPHICS_COMMAND_DESIGN.md)
+- [sound commands and examples](src/apps/readybasic/READYBASIC_SOUND_COMMAND_DESIGN.md)
+- [lifecycle and REU architecture](src/apps/readybasic/READYBASIC_LIFECYCLE_AND_REU_ARCHITECTURE.md)
+- [making module commands](src/apps/readybasic/READYBASIC_MAKING_COMMAND_GUIDE.md)
+
## Architecture Snapshot
Runtime memory layout:
-- app runtime window: `$1000-$C5FF`
-- REU metadata/system table: `$C600-$C7FF`
-- resident shim: `$C800-$C9FF`
+- app runtime window: `$1000-$C5FF` (`$B600` bytes)
+- resident shim: `$C600-$C9FF` (1 KB); `$C600-$C7FF` is reserved expansion
+ capacity and the public ABI remains at `$C800-$C9FF`
+- ReadyShell/ReadyBASIC high-RAM workspace: `$CA00-$CFFF` when owned by the
+ active app; it is outside the app snapshot and must be managed by that app
- hardware I/O region: `$D000-$DFFF`
+Spatially, the core RAM contract is:
+
+```text
+$1000 $C5FF $C600 $C9FF $CA00 $CFFF $D000
+|<--------------- active app snapshot: $B600 bytes -------------->|<-- 1 KB shim ------>|<- app high RAM ->|<-- I/O
+```
+
Runtime model:
- the active app owns `$1000-$C5FF`
@@ -343,30 +384,43 @@ Runtime model:
REU layout:
-- logical bank `0`: ReadyOS control/global bank, including the compact bank
- type mirror, 64-entry app registry, app/catalog metadata, resource records,
- copied dependency/source lines, and the shim token-to-physical-bank lookup
- page
-- launcher snapshot/resume bank at `Start+1`: loader-owned system resource
-- `Start+2` and above: available to dynamic allocation; no launcher overlay
- bank is reserved there
+- physical `Skip`: the ReadyOS bank; launcher snapshot at `$0000-$B5FF`,
+ followed by schema-v5 system state at `$B600-$FFFF`
+- physical `Skip+1` and above: dynamic allocation pool for app snapshots and resources
- app snapshots: allocated on demand by the launcher, then resolved by token
- through logical REU bank `0`
+ through the ReadyOS bank's explicit `$B740` mapping table
- clipboard payload banks: allocated from the dynamic pool
- app-owned runtime banks: allocated from the dynamic pool by apps that opt into
- the owned-allocation micromodule, recorded in bank `0`, and reclaimed by
+ the owned-allocation micromodule, recorded in the ReadyOS bank, and reclaimed by
launcher unload
- ReadyShell overlay banks: loader-assigned resources described by the profile
- overlay list and mirrored into bank `0` rich resource records
+ overlay list and published as ReadyOS-bank rich resource records
- ReadyShell state/scratch/value/CAT/diagnostic bank: one loader-assigned
resource bank with fixed relative subranges inside that bank
- ReadyBASIC core/code banks: loader-assigned resources, not fixed `$44/$45`
physical banks
- unavailable physical tail banks: detected by the launcher once at startup and
- marked as `REU_UNAVAIL` in the resident table plus bank `0` header, so REU
+ marked as `REU_UNAVAIL` in the ReadyOS-bank table/header, so REU
Viewer reports correct totals on smaller REU sizes
- remaining banks: dynamic allocation pool
+The shim's logical token is not a fixed physical app-bank number. Token `0`
+resolves directly to the ReadyOS bank at physical `Skip`; nonzero app tokens
+resolve through its `$B740` lookup page. Loaded/resumable status is authoritative
+at `$B840`, not in the retired `$C836-$C838` bitmap. This lets snapshots and
+resources move while preserving the 512-byte public shim ABI inside the full
+1 KB resident shim region.
+The current shim has 129 verifier-checked executable-padding bytes (largest
+contiguous run: 42 bytes) plus 11 ABI/data bytes that remain reserved rather
+than general feature space; the exact accounting is in the current shim
+architecture report.
+
+The ReadyOS bank also contains the active launcher catalog-shape settings at
+`$B9D9-$B9FF` and a 128-byte validated launcher runtime envelope at
+`$FC40-$FCBF`. The latter stores only compact UI state (and the bounded
+Ultimate DMA image path in DMA-enabled builds); the launcher restores its
+working registry arrays from the ReadyOS app records after every return.
+
Disk layout:
- media shape depends on the selected release profile
@@ -394,10 +448,16 @@ Main entry points:
print the known release profile ids
- `bash ./run.sh --build-all`
build every release profile and exit
+- `bash ./run.sh --profile precog-d81 --build-only`
+ build and package only the selected profile, then exit without starting VICE;
+ this is useful for hardware-test artifacts and custom `--config` builds
- `bash ./run.sh --force-artifacts-from-d71 --build-all`
promote non-excluded `SEQ` files and current `REL` files from the latest
built `precog-dual-d71` images into `cfg/authoritative/`, then rebuild all
profiles from that updated authoritative set
+- `LAUNCHER_DMA_LOAD=1 bash ./run.sh --profile precog-d81`
+ build the opt-in C64 Ultimate UCI/Ultimate DOS direct-to-REU launcher path;
+ disk fallback remains available
- `make seed-cal26`
seed CAL26 REL data into the latest built `precog-dual-d71` drive `8` image
- `bash ./run.sh --vice-fast`
@@ -480,6 +540,9 @@ plus the generated `apps.cfg`.
Public supporting docs in `docs/` currently include:
+- [documentation index and freshness policy](docs/DOCUMENTATION_INDEX.md)
+- [C64 Ultimate DOS DMA loading](docs/ultimate_dos_dma_loading.md)
+- [current 0.2.5 shim and ReadyOS-bank architecture](docs/ReadyOS_SHIM_ARCHITECTURE_0.2.5.md)
- `docs/clipboard_bundle_seq_format.md`
- `docs/quicknotes_seq_format.md`
- `docs/simplecells_seq_format.md`
@@ -488,7 +551,10 @@ Public supporting docs in `docs/` currently include:
Rendered documentation exports in `docs/` currently include:
-- [ReadyOS SHIM Architecture Report (HTML)](docs/ReadyOS%20SHIM%20Architecture%20Report%20%280.2%29.html)
+- [Documentation Index (HTML)](docs/DOCUMENTATION_INDEX.html)
+- [C64 Ultimate DOS DMA Loading (HTML)](docs/ultimate_dos_dma_loading.html)
+- [Current 0.2.5 SHIM Architecture Report (HTML)](docs/ReadyOS_SHIM_ARCHITECTURE_0.2.5.html)
+- [Preserved 0.2.4 SHIM Architecture Report (HTML)](docs/ReadyOS%20SHIM%20Architecture%20Report%20%280.2%29.html)
- [ReadyShell Overlay Inventory (HTML)](docs/readyshell_overlay_inventory.html)
- [ReadyShell Architecture (HTML)](docs/ReadyShellArchitecture.html)
diff --git a/ReadyOSREUPhase1Completed.html b/ReadyOSREUPhase1Completed.html
index a4cb868..6f614b3 100644
--- a/ReadyOSREUPhase1Completed.html
+++ b/ReadyOSREUPhase1Completed.html
@@ -1,3 +1,16 @@
+
+
+ Current ReadyOS contract (2026-08-02):
+ Physical Skip is the ReadyOS bank and Skip+1 is the first dynamic bank.
+ The launcher snapshot is ReadyOS $0000-$B5FF; schema v5 is $B600-$FFFF,
+ with token map $B740 and status $B840. C64 app RAM is
+ $1000-$C5FF ($B600), and the resident 1 KB shim owns
+ $C600-$C9FF with its public ABI at $C800.
+ Dated layouts and measurements below are retained as historical evidence.
+
+
+PRESERVED SNAPSHOT / DESIGN Preserved completed-phase record. Its full commented shim appendix is byte-verified current; other values describe the phase at the time and are not a live 0.2.5 memory contract.
+
ReadyOS
REU Enhancement Refactor - Phase 1 Completed
Phase 1 Completion Note
@@ -1088,300 +1101,290 @@
;-----------------------------------------------------------------------------
-; Shared ReadyOS shim image ($C800-$C9FF, 512 bytes)
-; This file is the canonical shim byte layout used by both the disk boot path
-; and the EasyFlash cartridge flavor. Keep it identical across all variants.
-;-----------------------------------------------------------------------------
-
-;-----------------------------------------------------------------------------
-; Page 1: $C800-$C8FF - Jump table, data, and helper routines
-;-----------------------------------------------------------------------------
-
-; $C800-$C817: Jump Table (24 bytes, 8 entries)
- jt_load_disk = $ C800 ; Load from disk, run
- jt_load_reu = $ C803 ; Fetch from REU, run
- jt_run_app = $ C806 ; Just run app
- jt_preload = $ C809 ; Preload to REU, return
- jt_return = $ C80C ; Return to launcher
- jt_switch = $ C80F ; Switch to another app
- jt_stash_cur = $ C812 ; Helper: stash current app
- jt_fetch_bank = $ C815 ; Helper: fetch from bank in A
-
- .byte $ 4C , $ 40 , $ C8 ; $C800: JMP load_disk ($C840)
- .byte $ 4C , $ 60 , $ C8 ; $C803: JMP load_reu ($C860)
- .byte $ 4C , $ 00 , $ 10 ; $C806: JMP $1000 (run app)
- .byte $ 4C , $ 80 , $ C8 ; $C809: JMP preload ($C880)
- .byte $ 4C , $ 00 , $ C9 ; $C80C: JMP return_to_launcher ($C900)
- .byte $ 4C , $ 40 , $ C9 ; $C80F: JMP switch_app ($C940)
- .byte $ 4C , $ C0, $ C8 ; $C812: JMP stash_current ($C8C0) - placeholder
- .byte $ 4C , $ F0, $ C8 ; $C815: JMP fetch_bank ($C8F0)
-
-; $C818: JMP log_byte ($C9E0)
- .byte $ 4C , $ E0, $ C9 ; $C818: JMP log_byte
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ; $C81B-$C81F: Padding
-
-; $C820-$C83F: Data Area (32 bytes)
-; $C820: target_bank - bank to load/switch to
-; $C821: filename_len
-; $C822-$C823: unused
-; $C824-$C82F: filename (12 bytes)
-; $C830: load_end_lo (KERNAL LOAD end addr low byte, saved by preload)
-; $C831: load_end_hi (KERNAL LOAD end addr high byte, saved by preload)
-; $C832-$C833: unused
-; $C834: current_bank - currently running app
-; $C835: last_saved
-; $C836: reu_bitmap_lo (banks 0-7)
-; $C837: reu_bitmap_hi (banks 8-15)
-; $C838: reu_bitmap_xhi (banks 16-23)
-; $C839: storage_drive - shim-global default storage drive for D8/D9 app dialogs
-; This persists across app switches and is shared by apps that use the
-; common file-dialog default-drive contract.
-; $C83A: log_index - debug byte ring head
-; $C83B: reu_bank_skip - physical 64K banks reserved before ReadyOS bank start
-; $C83C: launcher_flags - launcher-owned one-shot state flags
-; $C83D: reu_lookup_scratch - one-byte physical bank fetched from REU bank 0
-; $C83E-$C83F: reserved
-
- .byte $ 00 ; $C820: target_bank
- .byte $ 08 ; $C821: filename_len
- .byte $ 00 , $ 00 ; $C822-$C823: unused
- .byte "LAUNCHER " ; $C824-$C82F: filename (12 bytes)
- .byte $ 00 ,$ 00 ; $C830-$C831: load_end_lo, load_end_hi
- .byte $ 00 ,$ 00 ; $C832-$C833: unused
- .byte $ 00 ; $C834: current_bank
- .byte $ FF ; $C835: last_saved
- .byte $ 00 ; $C836: reu_bitmap_lo
- .byte $ 00 ; $C837: reu_bitmap_hi
- .byte $ 00 ; $C838: reu_bitmap_xhi
- .byte $ 08 ; $C839: storage_drive (default drive 8)
- .byte $ 00 ; $C83A: log_index (for debug buffer)
- .byte READYOS_REU_BANK_SKIP ; $C83B: reu_bank_skip (compiled into boot image)
- .byte $ 00 ; $C83C: launcher_flags
- .byte $ 00 ; $C83D: reu_lookup_scratch
- .byte $ 00 ,$ 00 ; $C83E-$C83F: reserved
-
-;-----------------------------------------------------------------------------
-; $C840: load_disk - Load app from disk and run (32 bytes)
-;-----------------------------------------------------------------------------
- .byte $ AD, $ 21 , $ C8 ; LDA $C821 (filename len)
- .byte $ A2, $ 24 ; LDX #$24
- .byte $ A0, $ C8 ; LDY #$C8 (filename at $C824)
- .byte $ 20 , $ BD, $ FF ; JSR $FFBD (SETNAM)
- .byte $ A9, $ 00 ; LDA #0
- .byte $ A2, $ 08 ; LDX #8
- .byte $ A0, $ 01 ; LDY #1
- .byte $ 20 , $ BA, $ FF ; JSR $FFBA (SETLFS)
- .byte $ A9, $ 00 ; LDA #0
- .byte $ 20 , $ D5, $ FF ; JSR $FFD5 (LOAD)
- .byte $ 4C , $ 00 , $ 10 ; JMP $1000
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ; Padding to $C860
-
-;-----------------------------------------------------------------------------
-; $C860: load_reu - Fetch app from REU and run (32 bytes)
-;-----------------------------------------------------------------------------
- .byte $ AD, $ 20 , $ C8 ; LDA $C820 (target bank)
- .byte $ 20 , $ F0, $ C8 ; JSR fetch_bank ($C8F0)
- .byte $ 4C , $ 00 , $ 10 ; JMP $1000
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00
-
-;-----------------------------------------------------------------------------
-; $C880: preload - Load to REU, return to launcher
-; Called via JSR $C809
-; DEBUG: writes markers to $C007-$C00C
-;-----------------------------------------------------------------------------
- .byte $ A9, $ AA ; LDA #$AA (170 = "preload entered")
- .byte $ 8D , $ 07 , $ C0 ; STA $C007
-
- .byte $ A9, $ 00 ; LDA #0 (bank 0)
- .byte $ 20 , $ E0, $ C8 ; JSR stash_to_bank ($C8E0)
-
- .byte $ A9, $ BB ; LDA #$BB (187 = "launcher stashed")
- .byte $ 8D , $ 08 , $ C0 ; STA $C008
-
- .byte $ AD, $ 21 , $ C8 ; LDA $C821 (len)
- .byte $ A2, $ 24 ; LDX #$24
- .byte $ A0, $ C8 ; LDY #$C8 (filename at $C824)
- .byte $ 20 , $ BD, $ FF ; JSR SETNAM
-
- .byte $ A9, $ 00 ; LDA #0
- .byte $ A2, $ 08 ; LDX #8
- .byte $ A0, $ 01 ; LDY #1
- .byte $ 20 , $ BA, $ FF ; JSR SETLFS
-
- .byte $ A9, $ CC ; LDA #$CC (204 = "about to LOAD")
- .byte $ 8D , $ 09 , $ C0 ; STA $C009
-
- .byte $ A9, $ 00 ; LDA #0
- .byte $ 20 , $ D5, $ FF ; JSR LOAD
-
- .byte $ 8E , $ 30 , $ C8 ; STX $C830 (end addr lo)
- .byte $ 8C , $ 31 , $ C8 ; STY $C831 (end addr hi)
-
- .byte $ AD, $ 20 , $ C8 ; LDA $C820 (target bank)
- .byte $ 20 , $ E0, $ C8 ; JSR stash_to_bank ($C8E0)
-
- .byte $ A9, $ EE ; LDA #$EE (238 = "app stashed")
- .byte $ 8D , $ 0B , $ C0 ; STA $C00B
-
- .byte $ AD, $ 20 , $ C8 ; LDA $C820 (target bank)
- .byte $ 20 , $ C0, $ C9 ; JSR set_bitmap ($C9C0)
-
- .byte $ A9, $ 00 ; LDA #0
- .byte $ 20 , $ F0, $ C8 ; JSR fetch_bank ($C8F0)
-
- .byte $ A9, $ FF ; LDA #$FF (255 = "launcher restored")
- .byte $ 8D , $ 0C , $ C0 ; STA $C00C
-
- .byte $ 60 ; RTS
-
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00
-
-;-----------------------------------------------------------------------------
-; $C8E0: stash_to_bank - Stash $1000-$C5FF to REU bank in A (16 bytes)
-;-----------------------------------------------------------------------------
- .byte $ 20 , $ 60 , $ C9 ; JSR reu_setup_logical ($C960)
- .byte $ A9, $ 90 ; LDA #$90 (STASH command)
- .byte $ 8D , $ 01 , $ DF ; STA $DF01 - execute transfer
- .byte $ 60 ; RTS
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00
-
-;-----------------------------------------------------------------------------
-; $C8F0: fetch_bank - Fetch from REU bank in A to $1000-$C5FF (16 bytes)
-;-----------------------------------------------------------------------------
- .byte $ 20 , $ 60 , $ C9 ; JSR reu_setup_logical ($C960)
- .byte $ A9, $ 91 ; LDA #$91 (FETCH command)
- .byte $ 8D , $ 01 , $ DF ; STA $DF01 - execute transfer
- .byte $ 60 ; RTS
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00
-
-;-----------------------------------------------------------------------------
-; Page 2: $C900-$C9FF - Main routines
-;-----------------------------------------------------------------------------
-
-;-----------------------------------------------------------------------------
-; $C900: return_to_launcher (64 bytes)
-;-----------------------------------------------------------------------------
- .byte $ AD, $ 34 , $ C8 ; LDA $C834 (current bank)
- .byte $ 20 , $ E0, $ C8 ; JSR stash_to_bank ($C8E0)
- .byte $ AD, $ 34 , $ C8 ; LDA $C834 (current bank)
- .byte $ 20 , $ C0, $ C9 ; JSR set_bitmap ($C9C0)
- .byte $ AD, $ 34 , $ C8 ; LDA $C834
- .byte $ 8D , $ 35 , $ C8 ; STA $C835
- .byte $ A9, $ 00 ; LDA #0
- .byte $ 20 , $ F0, $ C8 ; JSR fetch_bank ($C8F0)
- .byte $ A9, $ 00 ; LDA #0
- .byte $ 8D , $ 34 , $ C8 ; STA $C834
- .byte $ 4C , $ 00 , $ 10 ; JMP $1000
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00
- .byte $ 00
-
-;-----------------------------------------------------------------------------
-; $C940: switch_app (64 bytes)
-;-----------------------------------------------------------------------------
- .byte $ AD, $ 34 , $ C8 ; LDA $C834 (current bank)
- .byte $ 20 , $ E0, $ C8 ; JSR stash_to_bank ($C8E0)
- .byte $ AD, $ 34 , $ C8 ; LDA $C834 (current bank)
- .byte $ 20 , $ C0, $ C9 ; JSR set_bitmap ($C9C0)
- .byte $ AD, $ 20 , $ C8 ; LDA $C820 (target bank)
- .byte $ 20 , $ F0, $ C8 ; JSR fetch_bank ($C8F0)
- .byte $ AD, $ 20 , $ C8 ; LDA $C820
- .byte $ 8D , $ 34 , $ C8 ; STA $C834
- .byte $ 4C , $ 00 , $ 10 ; JMP $1000
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00
-
-;-----------------------------------------------------------------------------
-; $C960: reu_setup_logical - Resolve logical token via REU bank 0, then setup regs
-;-----------------------------------------------------------------------------
- .byte $ C9, $ 00 ; CMP #0 (logical launcher bank?)
- .byte $ D0, $ 09 ; BNE lookup_app_bank
- .byte $ AD, $ 3B , $ C8 ; LDA $C83B (reu_bank_skip)
- .byte $ 18 ; CLC
- .byte $ 69 , $ 01 ; ADC #$01 (launcher is Start+1)
- .byte $ 4C , $ A0, $ C9 ; JMP reu_setup ($C9A0)
- .byte $ AA ; lookup_app_bank: TAX (preserve logical token)
- .byte $ A9, $ 3D ; LDA #<$C83D
- .byte $ 8D , $ 02 , $ DF ; STA $DF02 (C64 addr lo)
- .byte $ A9, $ C8 ; LDA #>$C83D
- .byte $ 8D , $ 03 , $ DF ; STA $DF03 (C64 addr hi)
- .byte $ 8A ; TXA
- .byte $ 8D , $ 04 , $ DF ; STA $DF04 (REU offset lo = logical token)
- .byte $ A9, $ 2F ; LDA #$2F
- .byte $ 8D , $ 05 , $ DF ; STA $DF05 (REU offset hi = lookup page)
- .byte $ AD, $ 3B , $ C8 ; LDA $C83B (ReadyOS global physical bank)
- .byte $ 8D , $ 06 , $ DF ; STA $DF06
- .byte $ A9, $ 01 ; LDA #1
- .byte $ 8D , $ 07 , $ DF ; STA $DF07 (length lo)
- .byte $ A9, $ 00 ; LDA #0
- .byte $ 8D , $ 08 , $ DF ; STA $DF08 (length hi)
- .byte $ A9, $ 91 ; LDA #$91 (FETCH command)
- .byte $ 8D , $ 01 , $ DF ; STA $DF01 - fetch physical bank byte
- .byte $ AD, $ 3D , $ C8 ; LDA $C83D (resolved physical bank)
- .byte $ 4C , $ A0, $ C9 ; JMP reu_setup ($C9A0)
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ; Padding to $C9A0
-
-;-----------------------------------------------------------------------------
-; $C9A0: reu_setup - Set up REU registers for $B600 transfer at $1000
-;-----------------------------------------------------------------------------
- .byte $ 8D , $ 06 , $ DF ; STA $DF06 (bank)
- .byte $ A9, $ 00 ; LDA #$00
- .byte $ 8D , $ 02 , $ DF ; STA $DF02 (C64 addr lo = $00)
- .byte $ A9, $ 10 ; LDA #$10
- .byte $ 8D , $ 03 , $ DF ; STA $DF03 (C64 addr hi = $10, so $1000)
- .byte $ A9, $ 00 ; LDA #$00
- .byte $ 8D , $ 04 , $ DF ; STA $DF04 (REU addr lo)
- .byte $ 8D , $ 05 , $ DF ; STA $DF05 (REU addr hi)
- .byte $ 8D , $ 07 , $ DF ; STA $DF07 (len lo = $00)
- .byte $ A9, $ B6 ; LDA #$B6
- .byte $ 8D , $ 08 , $ DF ; STA $DF08 (len hi = $B6, so $B600 bytes)
- .byte $ 60 ; RTS
- .byte $ 00 ,$ 00
-
-;-----------------------------------------------------------------------------
-; $C9C0: set_bitmap - Set bit for bank in A in reu_bitmap ($C836-$C838)
-;-----------------------------------------------------------------------------
- .byte $ C9, $ 18 ; CMP #$18 (only banks 0-23 are tracked)
- .byte $ B0, $ 17 ; BCS done
- .byte $ AA ; TAX - preserve full bank
- .byte $ 29 , $ 07 ; AND #$07 - bit index within byte
- .byte $ A8 ; TAY - Y = bit index
- .byte $ 8A ; TXA - restore full bank
- .byte $ 4A ; LSR A
- .byte $ 4A ; LSR A
- .byte $ 4A ; LSR A
- .byte $ AA ; TAX - X = byte offset 0..2
- .byte $ A9, $ 01 ; LDA #$01
- .byte $ 88 ; DEY
- .byte $ 30 , $ 03 ; BMI store_bit
- .byte $ 0A ; ASL A
- .byte $ 10 , $ FA ; BPL shift_loop
- .byte $ 1D , $ 36 , $ C8 ; ORA $C836,X
- .byte $ 9D , $ 36 , $ C8 ; STA $C836,X
- .byte $ 60 ; RTS
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00
-
-;-----------------------------------------------------------------------------
-; $C9E0: log_byte - Write debug marker to buffer at $C980
-;-----------------------------------------------------------------------------
- .byte $ 48 ; PHA - save the byte to log
- .byte $ 8E , $ FC, $ 00 ; STX $00FC - save X to ZP temp
- .byte $ AE, $ 3A , $ C8 ; LDX $C83A - get log_index
- .byte $ 68 ; PLA - get byte back
- .byte $ 9D , $ 80 , $ C9 ; STA $C980,X - write to buffer
- .byte $ E8 ; INX - increment index
- .byte $ E0, $ 20 ; CPX #$20 - wrap at 32
- .byte $ D0, $ 02 ; BNE +2 (skip reset)
- .byte $ A2, $ 00 ; LDX #$00 - reset to 0
- .byte $ 8E , $ 3A , $ C8 ; STX $C83A - store new index
- .byte $ AE, $ FC, $ 00 ; LDX $00FC - restore X
- .byte $ 60 ; RTS
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00
+class="sourceCode asm">;-----------------------------------------------------------------------------
+; Shared ReadyOS shim image ($C600-$C9FF, 1024 bytes)
+; This file is the canonical shim byte layout used by both the disk boot path
+; and the EasyFlash cartridge flavor. Keep it identical across all variants.
+;-----------------------------------------------------------------------------
+
+;-----------------------------------------------------------------------------
+; Pages 1-2: $C600-$C7FF - reserved resident expansion space
+;-----------------------------------------------------------------------------
+; This space used to contain the C64-RAM REU allocation/metadata mirror. The
+; authoritative state now lives in the ReadyOS REU bank, but the RAM remains
+; resident shim-owned capacity rather than becoming app snapshot memory.
+.ifndef READYOS_SHIM_ABI_ONLY
+.res $0200, $00
+.endif
+
+;-----------------------------------------------------------------------------
+; Page 3: $C800-$C8FF - Jump table, data, and helper routines
+;-----------------------------------------------------------------------------
+
+; $C800-$C817: Jump Table (24 bytes, 8 entries)
+jt_load_disk = $C800 ; Load from disk, run
+jt_load_reu = $C803 ; Fetch from REU, run
+jt_run_app = $C806 ; Just run app
+jt_preload = $C809 ; Preload to REU, return
+jt_return = $C80C ; Return to launcher
+jt_switch = $C80F ; Switch to another app
+jt_reserved = $C812 ; Reserved compatibility slot (safe no-op)
+jt_fetch_bank = $C815 ; Helper: fetch from bank in A
+
+.byte $4C, $40, $C8 ; $C800: JMP load_disk ($C840)
+.byte $4C, $60, $C8 ; $C803: JMP load_reu ($C860)
+.byte $4C, $00, $10 ; $C806: JMP $1000 (run app)
+.byte $4C, $80, $C8 ; $C809: JMP preload ($C880)
+.byte $4C, $00, $C9 ; $C80C: JMP return_to_launcher ($C900)
+.byte $4C, $40, $C9 ; $C80F: JMP switch_app ($C940)
+.byte $4C, $FF, $C9 ; $C812: reserved helper -> safe RTS
+.byte $4C, $F0, $C8 ; $C815: JMP fetch_bank ($C8F0)
+
+; $C818: deprecated logger compatibility slot
+.byte $4C, $FF, $C9 ; $C818: deprecated logger -> safe RTS
+.byte $4C, $C0, $C9 ; $C81B: JMP mark_loaded (token in A)
+.byte $00,$00 ; $C81E-$C81F: reserved
+
+; $C820-$C83F: Data Area (32 bytes)
+; $C820: target_bank - bank to load/switch to
+; $C821: filename_len
+; $C822-$C823: launcher-side app-size scratch (not consumed by the shim)
+; $C824-$C82F: filename (12 bytes)
+; $C830: load_end_lo (KERNAL LOAD end addr low byte, saved by preload)
+; $C831: load_end_hi (KERNAL LOAD end addr high byte, saved by preload)
+; $C832-$C833: unused
+; $C834: current_bank - currently running app
+; $C835: last_saved
+; $C836-$C838: retired bitmap bytes (reserved; authoritative state is in REU)
+; $C839: storage_drive - shim-global default storage drive for D8/D9 app dialogs
+; This persists across app switches and is shared by apps that use the
+; common file-dialog default-drive contract.
+; $C83A: reserved (formerly log_index)
+; $C83B: readyos_bank - direct physical ReadyOS bank number (Skip)
+; $C83C: launcher_flags - launcher-owned one-shot state flags
+; $C83D: reu_lookup_scratch - one-byte ReadyOS-bank DMA scratch
+; $C83E: token_scratch; $C83F: reserved
+
+.byte $00 ; $C820: target_bank
+.byte $08 ; $C821: filename_len
+.byte $00, $00 ; $C822-$C823: launcher app-size scratch
+.byte "LAUNCHER " ; $C824-$C82F: filename (12 bytes)
+.byte $00,$00 ; $C830-$C831: load_end_lo, load_end_hi
+.byte $00,$00 ; $C832-$C833: unused
+.byte $00 ; $C834: current_bank
+.byte $FF ; $C835: last_saved
+.byte $00 ; $C836: reserved (retired bitmap byte)
+.byte $00 ; $C837: reserved (retired bitmap byte)
+.byte $00 ; $C838: reserved (retired bitmap byte)
+.byte $08 ; $C839: storage_drive (default drive 8)
+.byte $00 ; $C83A: reserved (retired debug-ring head)
+.byte READYOS_REU_BANK_SKIP ; $C83B: readyos_bank (physical Skip)
+.byte $00 ; $C83C: launcher_flags
+.byte $00 ; $C83D: reu_lookup_scratch
+.byte $00,$00 ; $C83E-$C83F: reserved
+
+;-----------------------------------------------------------------------------
+; $C840: load_disk - Load app from disk and run (32 bytes)
+;-----------------------------------------------------------------------------
+.byte $AD, $21, $C8 ; LDA $C821 (filename len)
+.byte $A2, $24 ; LDX #$24
+.byte $A0, $C8 ; LDY #$C8 (filename at $C824)
+.byte $20, $BD, $FF ; JSR $FFBD (SETNAM)
+.byte $A9, $00 ; LDA #0
+.byte $AE, $39, $C8 ; LDX $C839 (storage drive)
+.byte $A0, $01 ; LDY #1
+.byte $20, $BA, $FF ; JSR $FFBA (SETLFS)
+.byte $A9, $00 ; LDA #0
+.byte $20, $D5, $FF ; JSR $FFD5 (LOAD)
+.byte $4C, $00, $10 ; JMP $1000
+.byte $00,$00,$00,$00 ; Padding to $C860
+
+;-----------------------------------------------------------------------------
+; $C860: load_reu - Fetch app from REU and run (32 bytes)
+;-----------------------------------------------------------------------------
+.byte $AD, $20, $C8 ; LDA $C820 (target bank)
+.byte $20, $F0, $C8 ; JSR fetch_bank ($C8F0)
+.byte $4C, $00, $10 ; JMP $1000
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00
+
+;-----------------------------------------------------------------------------
+; $C880: preload - Load to REU, return to launcher
+; Called via JSR $C809
+;-----------------------------------------------------------------------------
+.byte $A9, $00 ; LDA #0 (launcher token -> ReadyOS bank)
+.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
+
+.byte $AD, $21, $C8 ; LDA $C821 (len)
+.byte $A2, $24 ; LDX #$24
+.byte $A0, $C8 ; LDY #$C8 (filename at $C824)
+.byte $20, $BD, $FF ; JSR SETNAM
+
+.byte $A9, $00 ; LDA #0
+.byte $AE, $39, $C8 ; LDX $C839 (storage drive)
+.byte $A0, $01 ; LDY #1
+.byte $20, $BA, $FF ; JSR SETLFS
+
+.byte $A9, $00 ; LDA #0
+.byte $20, $D5, $FF ; JSR LOAD
+
+.byte $8E, $30, $C8 ; STX $C830 (end addr lo)
+.byte $8C, $31, $C8 ; STY $C831 (end addr hi)
+
+.byte $AD, $20, $C8 ; LDA $C820 (target bank)
+.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
+
+.byte $AD, $20, $C8 ; LDA $C820 (target bank)
+.byte $20, $C0, $C9 ; JSR mark_loaded ($C9C0)
+
+.byte $A9, $00 ; LDA #0
+.byte $20, $F0, $C8 ; JSR fetch_bank ($C8F0)
+
+.byte $60 ; RTS
+
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00
+
+;-----------------------------------------------------------------------------
+; $C8E0: stash_to_bank - Stash $1000-$C5FF to REU bank in A (16 bytes)
+;-----------------------------------------------------------------------------
+.byte $20, $60, $C9 ; JSR reu_setup_logical ($C960)
+.byte $A9, $90 ; LDA #$90 (STASH command)
+.byte $8D, $01, $DF ; STA $DF01 - execute transfer
+.byte $60 ; RTS
+.byte $00,$00,$00,$00,$00,$00,$00
+
+;-----------------------------------------------------------------------------
+; $C8F0: fetch_bank - Fetch from REU bank in A to $1000-$C5FF (16 bytes)
+;-----------------------------------------------------------------------------
+.byte $20, $60, $C9 ; JSR reu_setup_logical ($C960)
+.byte $A9, $91 ; LDA #$91 (FETCH command)
+.byte $8D, $01, $DF ; STA $DF01 - execute transfer
+.byte $60 ; RTS
+.byte $00,$00,$00,$00,$00,$00,$00
+
+;-----------------------------------------------------------------------------
+; Page 4: $C900-$C9FF - Main routines
+;-----------------------------------------------------------------------------
+
+;-----------------------------------------------------------------------------
+; $C900: return_to_launcher (64 bytes)
+;-----------------------------------------------------------------------------
+.byte $AD, $34, $C8 ; LDA $C834 (current bank)
+.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
+.byte $AD, $34, $C8 ; LDA $C834 (current bank)
+.byte $20, $C0, $C9 ; JSR mark_loaded ($C9C0)
+.byte $AD, $34, $C8 ; LDA $C834
+.byte $8D, $35, $C8 ; STA $C835
+.byte $A9, $00 ; LDA #0
+.byte $20, $F0, $C8 ; JSR fetch_bank ($C8F0)
+.byte $A9, $00 ; LDA #0
+.byte $8D, $34, $C8 ; STA $C834
+.byte $4C, $00, $10 ; JMP $1000
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00
+
+;-----------------------------------------------------------------------------
+; $C940: switch_app (64 bytes)
+;-----------------------------------------------------------------------------
+.byte $AD, $34, $C8 ; LDA $C834 (current bank)
+.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
+.byte $AD, $34, $C8 ; LDA $C834 (current bank)
+.byte $20, $C0, $C9 ; JSR mark_loaded ($C9C0)
+.byte $AD, $20, $C8 ; LDA $C820 (target bank)
+.byte $20, $F0, $C8 ; JSR fetch_bank ($C8F0)
+.byte $AD, $20, $C8 ; LDA $C820
+.byte $8D, $34, $C8 ; STA $C834
+.byte $4C, $00, $10 ; JMP $1000
+.byte $00,$00,$00,$00,$00
+
+;-----------------------------------------------------------------------------
+; $C960: reu_setup_logical - Resolve token via the ReadyOS bank, then setup regs
+;-----------------------------------------------------------------------------
+.byte $C9, $00 ; CMP #0 (logical launcher bank?)
+.byte $D0, $06 ; BNE lookup_app_bank
+.byte $AD, $3B, $C8 ; LDA $C83B (ReadyOS bank contains launcher)
+.byte $4C, $A0, $C9 ; JMP reu_setup ($C9A0)
+.byte $AA ; lookup_app_bank: TAX (preserve logical token)
+.byte $A9, $3D ; LDA #<$C83D
+.byte $8D, $02, $DF ; STA $DF02 (C64 addr lo)
+.byte $A9, $C8 ; LDA #>$C83D
+.byte $8D, $03, $DF ; STA $DF03 (C64 addr hi)
+.byte $8A ; TXA
+.byte $18 ; CLC
+.byte $69, $40 ; ADC #<$B740 (mapping offset + token)
+.byte $8D, $04, $DF ; STA $DF04 (REU offset lo)
+.byte $A9, $B7 ; LDA #>$B740
+.byte $69, $00 ; ADC #0 (include low-byte carry)
+.byte $8D, $05, $DF ; STA $DF05 (REU offset hi)
+.byte $AD, $3B, $C8 ; LDA $C83B (ReadyOS global physical bank)
+.byte $8D, $06, $DF ; STA $DF06
+.byte $A9, $01 ; LDA #1
+.byte $8D, $07, $DF ; STA $DF07 (length lo)
+.byte $A9, $00 ; LDA #0
+.byte $8D, $08, $DF ; STA $DF08 (length hi)
+.byte $A9, $91 ; LDA #$91 (FETCH command)
+.byte $8D, $01, $DF ; STA $DF01 - fetch physical bank byte
+.byte $AD, $3D, $C8 ; LDA $C83D (resolved physical bank)
+.byte $4C, $A0, $C9 ; JMP reu_setup ($C9A0)
+.byte $00,$00 ; Padding to $C9A0
+
+;-----------------------------------------------------------------------------
+; $C9A0: reu_setup - Set up REU registers for $B600 transfer at $1000
+;-----------------------------------------------------------------------------
+.byte $8D, $06, $DF ; STA $DF06 (bank)
+.byte $A9, $00 ; LDA #$00
+.byte $8D, $02, $DF ; STA $DF02 (C64 addr lo = $00)
+.byte $A9, $10 ; LDA #$10
+.byte $8D, $03, $DF ; STA $DF03 (C64 addr hi = $10, so $1000)
+.byte $A9, $00 ; LDA #$00
+.byte $8D, $04, $DF ; STA $DF04 (REU addr lo)
+.byte $8D, $05, $DF ; STA $DF05 (REU addr hi)
+.byte $8D, $07, $DF ; STA $DF07 (len lo = $00)
+.byte $A9, $B6 ; LDA #$B6
+.byte $8D, $08, $DF ; STA $DF08 (len hi = $B6, so $B600 bytes)
+.byte $60 ; RTS
+.byte $00,$00
+
+;-----------------------------------------------------------------------------
+; $C9C0: mark_loaded - Commit token status after a successful snapshot stash
+; A = logical token. Status $07 means valid, loaded, and resumable.
+;-----------------------------------------------------------------------------
+.byte $8D, $3E, $C8 ; STA $C83E (preserve token)
+.byte $A9, $07 ; LDA #VALID|LOADED|RESUMABLE
+.byte $8D, $3D, $C8 ; STA $C83D
+.byte $A9, $3D ; C64 source = $C83D
+.byte $8D, $02, $DF
+.byte $A9, $C8
+.byte $8D, $03, $DF
+.byte $AD, $3E, $C8 ; token
+.byte $18 ; CLC
+.byte $69, $40 ; + <$B840 (token status table)
+.byte $8D, $04, $DF
+.byte $A9, $B8 ; >$B840
+.byte $69, $00 ; include low-byte carry
+.byte $8D, $05, $DF
+.byte $AD, $3B, $C8 ; ReadyOS physical bank
+.byte $8D, $06, $DF
+.byte $A9, $01 ; one byte
+.byte $8D, $07, $DF
+.byte $A9, $00
+.byte $8D, $08, $DF
+.byte $A9, $90 ; STASH C64 byte to ReadyOS bank
+.byte $8D, $01, $DF
+.byte $AD, $3E, $C8 ; preserve caller-visible token in A
+.byte $60 ; RTS
+.byte $00,$00,$00,$00 ; reserved through $C9FE
+.byte $60 ; $C9FF: compatibility no-op RTS
+
Implemented Logical Bank 0
Layout
The implemented v4 layout deliberately separates "hot, cheap to copy"
diff --git a/ReadyOSREUPhase1Completed.md b/ReadyOSREUPhase1Completed.md
index cddd7e6..e2cba5f 100644
--- a/ReadyOSREUPhase1Completed.md
+++ b/ReadyOSREUPhase1Completed.md
@@ -1,5 +1,21 @@
# ReadyOS REU Enhancement Refactor - Phase 1 Completed
+
+> **Current ReadyOS contract (2026-08-02):** Physical `Skip` is the ReadyOS
+> bank and `Skip+1` is the first dynamic bank. The launcher snapshot occupies
+> ReadyOS `$0000-$B5FF`; schema v5 occupies `$B600-$FFFF`, including the token
+> map at `$B740` and status at `$B840`. C64 app RAM is `$1000-$C5FF` (`$B600`),
+> and the resident 1 KB shim owns `$C600-$C9FF` with its public ABI at `$C800`.
+> Dated layouts and measurements below are retained as historical evidence.
+
+> Superseded architecture note (2026-08-01): this remains the Phase 1 evidence
+> record, but its logical-bank-0 control bank and `$C600-$C7FF` RAM mirror were
+> replaced by schema v5. The current design uses one combined ReadyOS bank at
+> physical `Skip+1`, keeps its launcher snapshot at `$0000-$B7FF`, stores all
+> mapping/status/registry data from `$B800` onward, and treats `$C600-$C7FF` as
+> app-private snapshot RAM. See `docs/ReadyOS_SHIM_ARCHITECTURE_0.2.5.md` and
+> `privatedocs/top_level_md/MEMORY_MAP.md` for the active contract.
+
## Phase 1 Completion Note
This document is the completed Phase 1 implementation record for the REU
@@ -676,13 +692,23 @@ contract while keeping the final image at `512` bytes.
```asm
;-----------------------------------------------------------------------------
-; Shared ReadyOS shim image ($C800-$C9FF, 512 bytes)
+; Shared ReadyOS shim image ($C600-$C9FF, 1024 bytes)
; This file is the canonical shim byte layout used by both the disk boot path
; and the EasyFlash cartridge flavor. Keep it identical across all variants.
;-----------------------------------------------------------------------------
;-----------------------------------------------------------------------------
-; Page 1: $C800-$C8FF - Jump table, data, and helper routines
+; Pages 1-2: $C600-$C7FF - reserved resident expansion space
+;-----------------------------------------------------------------------------
+; This space used to contain the C64-RAM REU allocation/metadata mirror. The
+; authoritative state now lives in the ReadyOS REU bank, but the RAM remains
+; resident shim-owned capacity rather than becoming app snapshot memory.
+.ifndef READYOS_SHIM_ABI_ONLY
+.res $0200, $00
+.endif
+
+;-----------------------------------------------------------------------------
+; Page 3: $C800-$C8FF - Jump table, data, and helper routines
;-----------------------------------------------------------------------------
; $C800-$C817: Jump Table (24 bytes, 8 entries)
@@ -692,7 +718,7 @@ jt_run_app = $C806 ; Just run app
jt_preload = $C809 ; Preload to REU, return
jt_return = $C80C ; Return to launcher
jt_switch = $C80F ; Switch to another app
-jt_stash_cur = $C812 ; Helper: stash current app
+jt_reserved = $C812 ; Reserved compatibility slot (safe no-op)
jt_fetch_bank = $C815 ; Helper: fetch from bank in A
.byte $4C, $40, $C8 ; $C800: JMP load_disk ($C840)
@@ -701,49 +727,48 @@ jt_fetch_bank = $C815 ; Helper: fetch from bank in A
.byte $4C, $80, $C8 ; $C809: JMP preload ($C880)
.byte $4C, $00, $C9 ; $C80C: JMP return_to_launcher ($C900)
.byte $4C, $40, $C9 ; $C80F: JMP switch_app ($C940)
-.byte $4C, $C0, $C8 ; $C812: JMP stash_current ($C8C0) - placeholder
+.byte $4C, $FF, $C9 ; $C812: reserved helper -> safe RTS
.byte $4C, $F0, $C8 ; $C815: JMP fetch_bank ($C8F0)
-; $C818: JMP log_byte ($C9E0)
-.byte $4C, $E0, $C9 ; $C818: JMP log_byte
-.byte $00,$00,$00,$00,$00 ; $C81B-$C81F: Padding
+; $C818: deprecated logger compatibility slot
+.byte $4C, $FF, $C9 ; $C818: deprecated logger -> safe RTS
+.byte $4C, $C0, $C9 ; $C81B: JMP mark_loaded (token in A)
+.byte $00,$00 ; $C81E-$C81F: reserved
; $C820-$C83F: Data Area (32 bytes)
; $C820: target_bank - bank to load/switch to
; $C821: filename_len
-; $C822-$C823: unused
+; $C822-$C823: launcher-side app-size scratch (not consumed by the shim)
; $C824-$C82F: filename (12 bytes)
; $C830: load_end_lo (KERNAL LOAD end addr low byte, saved by preload)
; $C831: load_end_hi (KERNAL LOAD end addr high byte, saved by preload)
; $C832-$C833: unused
; $C834: current_bank - currently running app
; $C835: last_saved
-; $C836: reu_bitmap_lo (banks 0-7)
-; $C837: reu_bitmap_hi (banks 8-15)
-; $C838: reu_bitmap_xhi (banks 16-23)
+; $C836-$C838: retired bitmap bytes (reserved; authoritative state is in REU)
; $C839: storage_drive - shim-global default storage drive for D8/D9 app dialogs
; This persists across app switches and is shared by apps that use the
; common file-dialog default-drive contract.
-; $C83A: log_index - debug byte ring head
-; $C83B: reu_bank_skip - physical 64K banks reserved before ReadyOS bank start
+; $C83A: reserved (formerly log_index)
+; $C83B: readyos_bank - direct physical ReadyOS bank number (Skip)
; $C83C: launcher_flags - launcher-owned one-shot state flags
-; $C83D: reu_lookup_scratch - one-byte physical bank fetched from REU bank 0
-; $C83E-$C83F: reserved
+; $C83D: reu_lookup_scratch - one-byte ReadyOS-bank DMA scratch
+; $C83E: token_scratch; $C83F: reserved
.byte $00 ; $C820: target_bank
.byte $08 ; $C821: filename_len
-.byte $00, $00 ; $C822-$C823: unused
+.byte $00, $00 ; $C822-$C823: launcher app-size scratch
.byte "LAUNCHER " ; $C824-$C82F: filename (12 bytes)
.byte $00,$00 ; $C830-$C831: load_end_lo, load_end_hi
.byte $00,$00 ; $C832-$C833: unused
.byte $00 ; $C834: current_bank
.byte $FF ; $C835: last_saved
-.byte $00 ; $C836: reu_bitmap_lo
-.byte $00 ; $C837: reu_bitmap_hi
-.byte $00 ; $C838: reu_bitmap_xhi
+.byte $00 ; $C836: reserved (retired bitmap byte)
+.byte $00 ; $C837: reserved (retired bitmap byte)
+.byte $00 ; $C838: reserved (retired bitmap byte)
.byte $08 ; $C839: storage_drive (default drive 8)
-.byte $00 ; $C83A: log_index (for debug buffer)
-.byte READYOS_REU_BANK_SKIP ; $C83B: reu_bank_skip (compiled into boot image)
+.byte $00 ; $C83A: reserved (retired debug-ring head)
+.byte READYOS_REU_BANK_SKIP ; $C83B: readyos_bank (physical Skip)
.byte $00 ; $C83C: launcher_flags
.byte $00 ; $C83D: reu_lookup_scratch
.byte $00,$00 ; $C83E-$C83F: reserved
@@ -756,13 +781,13 @@ jt_fetch_bank = $C815 ; Helper: fetch from bank in A
.byte $A0, $C8 ; LDY #$C8 (filename at $C824)
.byte $20, $BD, $FF ; JSR $FFBD (SETNAM)
.byte $A9, $00 ; LDA #0
-.byte $A2, $08 ; LDX #8
+.byte $AE, $39, $C8 ; LDX $C839 (storage drive)
.byte $A0, $01 ; LDY #1
.byte $20, $BA, $FF ; JSR $FFBA (SETLFS)
.byte $A9, $00 ; LDA #0
.byte $20, $D5, $FF ; JSR $FFD5 (LOAD)
.byte $4C, $00, $10 ; JMP $1000
-.byte $00,$00,$00,$00,$00 ; Padding to $C860
+.byte $00,$00,$00,$00 ; Padding to $C860
;-----------------------------------------------------------------------------
; $C860: load_reu - Fetch app from REU and run (32 bytes)
@@ -777,30 +802,20 @@ jt_fetch_bank = $C815 ; Helper: fetch from bank in A
;-----------------------------------------------------------------------------
; $C880: preload - Load to REU, return to launcher
; Called via JSR $C809
-; DEBUG: writes markers to $C007-$C00C
;-----------------------------------------------------------------------------
-.byte $A9, $AA ; LDA #$AA (170 = "preload entered")
-.byte $8D, $07, $C0 ; STA $C007
-
-.byte $A9, $00 ; LDA #0 (bank 0)
+.byte $A9, $00 ; LDA #0 (launcher token -> ReadyOS bank)
.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
-.byte $A9, $BB ; LDA #$BB (187 = "launcher stashed")
-.byte $8D, $08, $C0 ; STA $C008
-
.byte $AD, $21, $C8 ; LDA $C821 (len)
.byte $A2, $24 ; LDX #$24
.byte $A0, $C8 ; LDY #$C8 (filename at $C824)
.byte $20, $BD, $FF ; JSR SETNAM
.byte $A9, $00 ; LDA #0
-.byte $A2, $08 ; LDX #8
+.byte $AE, $39, $C8 ; LDX $C839 (storage drive)
.byte $A0, $01 ; LDY #1
.byte $20, $BA, $FF ; JSR SETLFS
-.byte $A9, $CC ; LDA #$CC (204 = "about to LOAD")
-.byte $8D, $09, $C0 ; STA $C009
-
.byte $A9, $00 ; LDA #0
.byte $20, $D5, $FF ; JSR LOAD
@@ -810,22 +825,20 @@ jt_fetch_bank = $C815 ; Helper: fetch from bank in A
.byte $AD, $20, $C8 ; LDA $C820 (target bank)
.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
-.byte $A9, $EE ; LDA #$EE (238 = "app stashed")
-.byte $8D, $0B, $C0 ; STA $C00B
-
.byte $AD, $20, $C8 ; LDA $C820 (target bank)
-.byte $20, $C0, $C9 ; JSR set_bitmap ($C9C0)
+.byte $20, $C0, $C9 ; JSR mark_loaded ($C9C0)
.byte $A9, $00 ; LDA #0
.byte $20, $F0, $C8 ; JSR fetch_bank ($C8F0)
-.byte $A9, $FF ; LDA #$FF (255 = "launcher restored")
-.byte $8D, $0C, $C0 ; STA $C00C
-
.byte $60 ; RTS
-.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00
;-----------------------------------------------------------------------------
; $C8E0: stash_to_bank - Stash $1000-$C5FF to REU bank in A (16 bytes)
@@ -846,7 +859,7 @@ jt_fetch_bank = $C815 ; Helper: fetch from bank in A
.byte $00,$00,$00,$00,$00,$00,$00
;-----------------------------------------------------------------------------
-; Page 2: $C900-$C9FF - Main routines
+; Page 4: $C900-$C9FF - Main routines
;-----------------------------------------------------------------------------
;-----------------------------------------------------------------------------
@@ -855,7 +868,7 @@ jt_fetch_bank = $C815 ; Helper: fetch from bank in A
.byte $AD, $34, $C8 ; LDA $C834 (current bank)
.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
.byte $AD, $34, $C8 ; LDA $C834 (current bank)
-.byte $20, $C0, $C9 ; JSR set_bitmap ($C9C0)
+.byte $20, $C0, $C9 ; JSR mark_loaded ($C9C0)
.byte $AD, $34, $C8 ; LDA $C834
.byte $8D, $35, $C8 ; STA $C835
.byte $A9, $00 ; LDA #0
@@ -875,7 +888,7 @@ jt_fetch_bank = $C815 ; Helper: fetch from bank in A
.byte $AD, $34, $C8 ; LDA $C834 (current bank)
.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
.byte $AD, $34, $C8 ; LDA $C834 (current bank)
-.byte $20, $C0, $C9 ; JSR set_bitmap ($C9C0)
+.byte $20, $C0, $C9 ; JSR mark_loaded ($C9C0)
.byte $AD, $20, $C8 ; LDA $C820 (target bank)
.byte $20, $F0, $C8 ; JSR fetch_bank ($C8F0)
.byte $AD, $20, $C8 ; LDA $C820
@@ -884,13 +897,11 @@ jt_fetch_bank = $C815 ; Helper: fetch from bank in A
.byte $00,$00,$00,$00,$00
;-----------------------------------------------------------------------------
-; $C960: reu_setup_logical - Resolve logical token via REU bank 0, then setup regs
+; $C960: reu_setup_logical - Resolve token via the ReadyOS bank, then setup regs
;-----------------------------------------------------------------------------
.byte $C9, $00 ; CMP #0 (logical launcher bank?)
-.byte $D0, $09 ; BNE lookup_app_bank
-.byte $AD, $3B, $C8 ; LDA $C83B (reu_bank_skip)
-.byte $18 ; CLC
-.byte $69, $01 ; ADC #$01 (launcher is Start+1)
+.byte $D0, $06 ; BNE lookup_app_bank
+.byte $AD, $3B, $C8 ; LDA $C83B (ReadyOS bank contains launcher)
.byte $4C, $A0, $C9 ; JMP reu_setup ($C9A0)
.byte $AA ; lookup_app_bank: TAX (preserve logical token)
.byte $A9, $3D ; LDA #<$C83D
@@ -898,9 +909,12 @@ jt_fetch_bank = $C815 ; Helper: fetch from bank in A
.byte $A9, $C8 ; LDA #>$C83D
.byte $8D, $03, $DF ; STA $DF03 (C64 addr hi)
.byte $8A ; TXA
-.byte $8D, $04, $DF ; STA $DF04 (REU offset lo = logical token)
-.byte $A9, $2F ; LDA #$2F
-.byte $8D, $05, $DF ; STA $DF05 (REU offset hi = lookup page)
+.byte $18 ; CLC
+.byte $69, $40 ; ADC #<$B740 (mapping offset + token)
+.byte $8D, $04, $DF ; STA $DF04 (REU offset lo)
+.byte $A9, $B7 ; LDA #>$B740
+.byte $69, $00 ; ADC #0 (include low-byte carry)
+.byte $8D, $05, $DF ; STA $DF05 (REU offset hi)
.byte $AD, $3B, $C8 ; LDA $C83B (ReadyOS global physical bank)
.byte $8D, $06, $DF ; STA $DF06
.byte $A9, $01 ; LDA #1
@@ -911,7 +925,7 @@ jt_fetch_bank = $C815 ; Helper: fetch from bank in A
.byte $8D, $01, $DF ; STA $DF01 - fetch physical bank byte
.byte $AD, $3D, $C8 ; LDA $C83D (resolved physical bank)
.byte $4C, $A0, $C9 ; JMP reu_setup ($C9A0)
-.byte $00,$00,$00,$00 ; Padding to $C9A0
+.byte $00,$00 ; Padding to $C9A0
;-----------------------------------------------------------------------------
; $C9A0: reu_setup - Set up REU registers for $B600 transfer at $1000
@@ -931,44 +945,35 @@ jt_fetch_bank = $C815 ; Helper: fetch from bank in A
.byte $00,$00
;-----------------------------------------------------------------------------
-; $C9C0: set_bitmap - Set bit for bank in A in reu_bitmap ($C836-$C838)
+; $C9C0: mark_loaded - Commit token status after a successful snapshot stash
+; A = logical token. Status $07 means valid, loaded, and resumable.
;-----------------------------------------------------------------------------
-.byte $C9, $18 ; CMP #$18 (only banks 0-23 are tracked)
-.byte $B0, $17 ; BCS done
-.byte $AA ; TAX - preserve full bank
-.byte $29, $07 ; AND #$07 - bit index within byte
-.byte $A8 ; TAY - Y = bit index
-.byte $8A ; TXA - restore full bank
-.byte $4A ; LSR A
-.byte $4A ; LSR A
-.byte $4A ; LSR A
-.byte $AA ; TAX - X = byte offset 0..2
-.byte $A9, $01 ; LDA #$01
-.byte $88 ; DEY
-.byte $30, $03 ; BMI store_bit
-.byte $0A ; ASL A
-.byte $10, $FA ; BPL shift_loop
-.byte $1D, $36, $C8 ; ORA $C836,X
-.byte $9D, $36, $C8 ; STA $C836,X
-.byte $60 ; RTS
-.byte $00,$00,$00,$00
-
-;-----------------------------------------------------------------------------
-; $C9E0: log_byte - Write debug marker to buffer at $C980
-;-----------------------------------------------------------------------------
-.byte $48 ; PHA - save the byte to log
-.byte $8E, $FC, $00 ; STX $00FC - save X to ZP temp
-.byte $AE, $3A, $C8 ; LDX $C83A - get log_index
-.byte $68 ; PLA - get byte back
-.byte $9D, $80, $C9 ; STA $C980,X - write to buffer
-.byte $E8 ; INX - increment index
-.byte $E0, $20 ; CPX #$20 - wrap at 32
-.byte $D0, $02 ; BNE +2 (skip reset)
-.byte $A2, $00 ; LDX #$00 - reset to 0
-.byte $8E, $3A, $C8 ; STX $C83A - store new index
-.byte $AE, $FC, $00 ; LDX $00FC - restore X
+.byte $8D, $3E, $C8 ; STA $C83E (preserve token)
+.byte $A9, $07 ; LDA #VALID|LOADED|RESUMABLE
+.byte $8D, $3D, $C8 ; STA $C83D
+.byte $A9, $3D ; C64 source = $C83D
+.byte $8D, $02, $DF
+.byte $A9, $C8
+.byte $8D, $03, $DF
+.byte $AD, $3E, $C8 ; token
+.byte $18 ; CLC
+.byte $69, $40 ; + <$B840 (token status table)
+.byte $8D, $04, $DF
+.byte $A9, $B8 ; >$B840
+.byte $69, $00 ; include low-byte carry
+.byte $8D, $05, $DF
+.byte $AD, $3B, $C8 ; ReadyOS physical bank
+.byte $8D, $06, $DF
+.byte $A9, $01 ; one byte
+.byte $8D, $07, $DF
+.byte $A9, $00
+.byte $8D, $08, $DF
+.byte $A9, $90 ; STASH C64 byte to ReadyOS bank
+.byte $8D, $01, $DF
+.byte $AD, $3E, $C8 ; preserve caller-visible token in A
.byte $60 ; RTS
-.byte $00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00 ; reserved through $C9FE
+.byte $60 ; $C9FF: compatibility no-op RTS
```
### Implemented Logical Bank 0 Layout
diff --git a/Releases/0.2.4/precog-kung-fu-flash-2-d81 2/README.md b/Releases/0.2.4/precog-kung-fu-flash-2-d81 2/README.md
new file mode 100644
index 0000000..9860dc1
--- /dev/null
+++ b/Releases/0.2.4/precog-kung-fu-flash-2-d81 2/README.md
@@ -0,0 +1,79 @@
+# precog (kung fu flash 2 d81)
+
+- Release Line: `0.2.4`
+- Artifact Build: `0.2.4`
+- Kind: `kung-fu-flash-2-d81`
+
+## Why This Variant Exists
+
+- Full-content single-D81 profile tuned for Kung Fu Flash 2 disk loading with a 1MB REU and no skipped REU banks.
+
+## Artifacts
+
+- Drive 8: `readyos-v0.2.4-kung-fu-flash-2-d81.d81`
+- Host-Side Boot PRG: `readyos-v0.2.4-kung-fu-flash-2-d81-preboot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.4-kung-fu-flash-2-d81-boot.prg`
+
+## Included Apps
+
+- Drive 8: `editor` - editor
+- Drive 8: `readyshell` - readyshell (beta)
+- Drive 8: `simplefiles` - simple files
+- Drive 8: `clipmgr` - clipboard
+- Drive 8: `readybasic` - ready basic (alpha)
+- Drive 8: `cal26` - calendar 26
+- Drive 8: `tasklist` - task list
+- Drive 8: `reuviewer` - reu viewer
+- Drive 8: `sysinfo` - system info
+- Drive 8: `quicknotes` - quicknotes
+- Drive 8: `calcplus` - calc plus
+- Drive 8: `hexview` - hex viewer
+- Drive 8: `simplecells` - simple cells (alpha)
+- Drive 8: `game2048` - 2048 game
+- Drive 8: `deminer` - deminer
+- Drive 8: `dizzy` - dizzy kanban
+- Drive 8: `readyirc` - readyirc
+- Drive 8: `ucitest` - uci tester
+- Drive 8: `rirc-rrnet` - readyirc rrnet
+- Drive 8: `readme` - read.me
+
+## VICE Setup
+
+- Enable REU with at least `1MB`; this SKU targets KFF2's 1MB REU mode.
+- The host-side boot PRGs are convenience autostart files. The disk copy of `PREBOOT` is still the normal disk-side bootstrap.
+- Configure drive 8 as `1581` and attach `readyos-v0.2.4-kung-fu-flash-2-d81.d81`.
+
+### VICE Command Example
+
+- Autostart target: `readyos-v0.2.4-kung-fu-flash-2-d81-preboot.prg`
+
+```sh
+x64sc -reu -reusize 1024 -drive8type 1581 -devicebackend8 0 +busdevice8 -8 readyos-v0.2.4-kung-fu-flash-2-d81.d81 -autostart readyos-v0.2.4-kung-fu-flash-2-d81-preboot.prg
+```
+
+## 1MB REU Budget
+
+- This SKU is intentionally limited to `1MB` REU, which is `16` physical `64KB` REU banks.
+- It uses `reu_bank_skip=0`, so ReadyOS can use all 16 physical banks instead of skipping the lower bank range used by the normal test profiles.
+- Fresh launcher state uses `2` banks by default: bank `0` for ReadyOS control/global metadata and bank `1` for the launcher snapshot. That leaves `14` banks for suspended apps and app resources.
+- Each suspended app normally costs `1` additional bank.
+- ReadyShell costs `5` banks when loaded: `1` app snapshot bank, `3` overlay cache banks, and `1` state/scratch bank. With only ReadyShell loaded, expect about `7/16` banks in use.
+- ReadyBasic costs `3` banks when loaded: `1` app snapshot bank plus `2` ReadyBasic core/code resource banks. With only ReadyBasic loaded, expect about `5/16` banks in use.
+- ReadyShell and ReadyBasic loaded at the same time can use about `10/16` banks before any other suspended apps are counted.
+- When REU Viewer or the launcher shows the 1MB REU getting close to full, unload suspended apps before launching more. Unloading frees their app snapshot and resource banks.
+- If all REU banks are full, launching another app may simply do nothing instead of showing an error. Unload one or more apps to make room, then launch the app again.
+
+## Boot
+
+- This profile uses the direct boot chain `PREBOOT -> BOOT`.
+- There is no `SETD71` stage for this variant.
+- Attach the single disk on drive `8`, then autostart `readyos-v0.2.4-kung-fu-flash-2-d81-preboot.prg` or run `LOAD "PREBOOT",8` then `RUN`.
+
+## C64 Ultimate
+
+- Copy the listed disk image files to the target storage.
+- Enable the REU with at least `1MB`; this SKU targets KFF2's 1MB REU mode.
+- The host-side boot PRGs are optional convenience files for emulator launching; the disk-side `PREBOOT` entry is the standard hardware boot path.
+- Attach the single disk image on drive `8`, then boot with `LOAD "PREBOOT",8` and `RUN`.
+- This variant boots directly from `PREBOOT` into `BOOT` and does not use `SETD71`.
+
diff --git a/Releases/0.2.4/precog-kung-fu-flash-2-d81 2/help.md b/Releases/0.2.4/precog-kung-fu-flash-2-d81 2/help.md
new file mode 100644
index 0000000..9860dc1
--- /dev/null
+++ b/Releases/0.2.4/precog-kung-fu-flash-2-d81 2/help.md
@@ -0,0 +1,79 @@
+# precog (kung fu flash 2 d81)
+
+- Release Line: `0.2.4`
+- Artifact Build: `0.2.4`
+- Kind: `kung-fu-flash-2-d81`
+
+## Why This Variant Exists
+
+- Full-content single-D81 profile tuned for Kung Fu Flash 2 disk loading with a 1MB REU and no skipped REU banks.
+
+## Artifacts
+
+- Drive 8: `readyos-v0.2.4-kung-fu-flash-2-d81.d81`
+- Host-Side Boot PRG: `readyos-v0.2.4-kung-fu-flash-2-d81-preboot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.4-kung-fu-flash-2-d81-boot.prg`
+
+## Included Apps
+
+- Drive 8: `editor` - editor
+- Drive 8: `readyshell` - readyshell (beta)
+- Drive 8: `simplefiles` - simple files
+- Drive 8: `clipmgr` - clipboard
+- Drive 8: `readybasic` - ready basic (alpha)
+- Drive 8: `cal26` - calendar 26
+- Drive 8: `tasklist` - task list
+- Drive 8: `reuviewer` - reu viewer
+- Drive 8: `sysinfo` - system info
+- Drive 8: `quicknotes` - quicknotes
+- Drive 8: `calcplus` - calc plus
+- Drive 8: `hexview` - hex viewer
+- Drive 8: `simplecells` - simple cells (alpha)
+- Drive 8: `game2048` - 2048 game
+- Drive 8: `deminer` - deminer
+- Drive 8: `dizzy` - dizzy kanban
+- Drive 8: `readyirc` - readyirc
+- Drive 8: `ucitest` - uci tester
+- Drive 8: `rirc-rrnet` - readyirc rrnet
+- Drive 8: `readme` - read.me
+
+## VICE Setup
+
+- Enable REU with at least `1MB`; this SKU targets KFF2's 1MB REU mode.
+- The host-side boot PRGs are convenience autostart files. The disk copy of `PREBOOT` is still the normal disk-side bootstrap.
+- Configure drive 8 as `1581` and attach `readyos-v0.2.4-kung-fu-flash-2-d81.d81`.
+
+### VICE Command Example
+
+- Autostart target: `readyos-v0.2.4-kung-fu-flash-2-d81-preboot.prg`
+
+```sh
+x64sc -reu -reusize 1024 -drive8type 1581 -devicebackend8 0 +busdevice8 -8 readyos-v0.2.4-kung-fu-flash-2-d81.d81 -autostart readyos-v0.2.4-kung-fu-flash-2-d81-preboot.prg
+```
+
+## 1MB REU Budget
+
+- This SKU is intentionally limited to `1MB` REU, which is `16` physical `64KB` REU banks.
+- It uses `reu_bank_skip=0`, so ReadyOS can use all 16 physical banks instead of skipping the lower bank range used by the normal test profiles.
+- Fresh launcher state uses `2` banks by default: bank `0` for ReadyOS control/global metadata and bank `1` for the launcher snapshot. That leaves `14` banks for suspended apps and app resources.
+- Each suspended app normally costs `1` additional bank.
+- ReadyShell costs `5` banks when loaded: `1` app snapshot bank, `3` overlay cache banks, and `1` state/scratch bank. With only ReadyShell loaded, expect about `7/16` banks in use.
+- ReadyBasic costs `3` banks when loaded: `1` app snapshot bank plus `2` ReadyBasic core/code resource banks. With only ReadyBasic loaded, expect about `5/16` banks in use.
+- ReadyShell and ReadyBasic loaded at the same time can use about `10/16` banks before any other suspended apps are counted.
+- When REU Viewer or the launcher shows the 1MB REU getting close to full, unload suspended apps before launching more. Unloading frees their app snapshot and resource banks.
+- If all REU banks are full, launching another app may simply do nothing instead of showing an error. Unload one or more apps to make room, then launch the app again.
+
+## Boot
+
+- This profile uses the direct boot chain `PREBOOT -> BOOT`.
+- There is no `SETD71` stage for this variant.
+- Attach the single disk on drive `8`, then autostart `readyos-v0.2.4-kung-fu-flash-2-d81-preboot.prg` or run `LOAD "PREBOOT",8` then `RUN`.
+
+## C64 Ultimate
+
+- Copy the listed disk image files to the target storage.
+- Enable the REU with at least `1MB`; this SKU targets KFF2's 1MB REU mode.
+- The host-side boot PRGs are optional convenience files for emulator launching; the disk-side `PREBOOT` entry is the standard hardware boot path.
+- Attach the single disk image on drive `8`, then boot with `LOAD "PREBOOT",8` and `RUN`.
+- This variant boots directly from `PREBOOT` into `BOOT` and does not use `SETD71`.
+
diff --git a/Releases/0.2.4/precog-kung-fu-flash-2-d81 2/helpme.md b/Releases/0.2.4/precog-kung-fu-flash-2-d81 2/helpme.md
new file mode 100644
index 0000000..9860dc1
--- /dev/null
+++ b/Releases/0.2.4/precog-kung-fu-flash-2-d81 2/helpme.md
@@ -0,0 +1,79 @@
+# precog (kung fu flash 2 d81)
+
+- Release Line: `0.2.4`
+- Artifact Build: `0.2.4`
+- Kind: `kung-fu-flash-2-d81`
+
+## Why This Variant Exists
+
+- Full-content single-D81 profile tuned for Kung Fu Flash 2 disk loading with a 1MB REU and no skipped REU banks.
+
+## Artifacts
+
+- Drive 8: `readyos-v0.2.4-kung-fu-flash-2-d81.d81`
+- Host-Side Boot PRG: `readyos-v0.2.4-kung-fu-flash-2-d81-preboot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.4-kung-fu-flash-2-d81-boot.prg`
+
+## Included Apps
+
+- Drive 8: `editor` - editor
+- Drive 8: `readyshell` - readyshell (beta)
+- Drive 8: `simplefiles` - simple files
+- Drive 8: `clipmgr` - clipboard
+- Drive 8: `readybasic` - ready basic (alpha)
+- Drive 8: `cal26` - calendar 26
+- Drive 8: `tasklist` - task list
+- Drive 8: `reuviewer` - reu viewer
+- Drive 8: `sysinfo` - system info
+- Drive 8: `quicknotes` - quicknotes
+- Drive 8: `calcplus` - calc plus
+- Drive 8: `hexview` - hex viewer
+- Drive 8: `simplecells` - simple cells (alpha)
+- Drive 8: `game2048` - 2048 game
+- Drive 8: `deminer` - deminer
+- Drive 8: `dizzy` - dizzy kanban
+- Drive 8: `readyirc` - readyirc
+- Drive 8: `ucitest` - uci tester
+- Drive 8: `rirc-rrnet` - readyirc rrnet
+- Drive 8: `readme` - read.me
+
+## VICE Setup
+
+- Enable REU with at least `1MB`; this SKU targets KFF2's 1MB REU mode.
+- The host-side boot PRGs are convenience autostart files. The disk copy of `PREBOOT` is still the normal disk-side bootstrap.
+- Configure drive 8 as `1581` and attach `readyos-v0.2.4-kung-fu-flash-2-d81.d81`.
+
+### VICE Command Example
+
+- Autostart target: `readyos-v0.2.4-kung-fu-flash-2-d81-preboot.prg`
+
+```sh
+x64sc -reu -reusize 1024 -drive8type 1581 -devicebackend8 0 +busdevice8 -8 readyos-v0.2.4-kung-fu-flash-2-d81.d81 -autostart readyos-v0.2.4-kung-fu-flash-2-d81-preboot.prg
+```
+
+## 1MB REU Budget
+
+- This SKU is intentionally limited to `1MB` REU, which is `16` physical `64KB` REU banks.
+- It uses `reu_bank_skip=0`, so ReadyOS can use all 16 physical banks instead of skipping the lower bank range used by the normal test profiles.
+- Fresh launcher state uses `2` banks by default: bank `0` for ReadyOS control/global metadata and bank `1` for the launcher snapshot. That leaves `14` banks for suspended apps and app resources.
+- Each suspended app normally costs `1` additional bank.
+- ReadyShell costs `5` banks when loaded: `1` app snapshot bank, `3` overlay cache banks, and `1` state/scratch bank. With only ReadyShell loaded, expect about `7/16` banks in use.
+- ReadyBasic costs `3` banks when loaded: `1` app snapshot bank plus `2` ReadyBasic core/code resource banks. With only ReadyBasic loaded, expect about `5/16` banks in use.
+- ReadyShell and ReadyBasic loaded at the same time can use about `10/16` banks before any other suspended apps are counted.
+- When REU Viewer or the launcher shows the 1MB REU getting close to full, unload suspended apps before launching more. Unloading frees their app snapshot and resource banks.
+- If all REU banks are full, launching another app may simply do nothing instead of showing an error. Unload one or more apps to make room, then launch the app again.
+
+## Boot
+
+- This profile uses the direct boot chain `PREBOOT -> BOOT`.
+- There is no `SETD71` stage for this variant.
+- Attach the single disk on drive `8`, then autostart `readyos-v0.2.4-kung-fu-flash-2-d81-preboot.prg` or run `LOAD "PREBOOT",8` then `RUN`.
+
+## C64 Ultimate
+
+- Copy the listed disk image files to the target storage.
+- Enable the REU with at least `1MB`; this SKU targets KFF2's 1MB REU mode.
+- The host-side boot PRGs are optional convenience files for emulator launching; the disk-side `PREBOOT` entry is the standard hardware boot path.
+- Attach the single disk image on drive `8`, then boot with `LOAD "PREBOOT",8` and `RUN`.
+- This variant boots directly from `PREBOOT` into `BOOT` and does not use `SETD71`.
+
diff --git a/Releases/0.2.4/precog-kung-fu-flash-2-d81 2/manifest.json b/Releases/0.2.4/precog-kung-fu-flash-2-d81 2/manifest.json
new file mode 100644
index 0000000..a7b0ff1
--- /dev/null
+++ b/Releases/0.2.4/precog-kung-fu-flash-2-d81 2/manifest.json
@@ -0,0 +1,158 @@
+{
+ "id": "precog-kung-fu-flash-2-d81",
+ "display_name": "precog (kung fu flash 2 d81)",
+ "kind": "kung-fu-flash-2-d81",
+ "variant_boot_name": "precog kung fu flash 2 d81",
+ "version_text": "0.2.4",
+ "reu_size_kb": 1024,
+ "catalog_source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/cfg/profiles/precog-kung-fu-flash-2-d81.ini",
+ "autostart_prg": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.4/precog-kung-fu-flash-2-d81/readyos-v0.2.4-kung-fu-flash-2-d81-preboot.prg",
+ "autostart_disk_prg": "preboot.prg",
+ "preboot_mode": "boot",
+ "disks": [
+ {
+ "index": 1,
+ "drive": 8,
+ "image_type": "d81",
+ "vice_drive_type": "1581",
+ "true_drive": false,
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.4/precog-kung-fu-flash-2-d81/readyos-v0.2.4-kung-fu-flash-2-d81.d81"
+ }
+ ],
+ "boot_prgs": [
+ {
+ "stem": "preboot",
+ "disk_name": "preboot",
+ "source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/preboot.prg",
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.4/precog-kung-fu-flash-2-d81/readyos-v0.2.4-kung-fu-flash-2-d81-preboot.prg"
+ },
+ {
+ "stem": "boot",
+ "disk_name": "boot",
+ "source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/boot.prg",
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.4/precog-kung-fu-flash-2-d81/readyos-v0.2.4-kung-fu-flash-2-d81-boot.prg"
+ }
+ ],
+ "apps": [
+ {
+ "drive": 8,
+ "prg": "editor",
+ "label": "editor",
+ "desc": "text editor with clipboard"
+ },
+ {
+ "drive": 8,
+ "prg": "readyshell",
+ "label": "readyshell (beta)",
+ "desc": "command shell poc scaffold"
+ },
+ {
+ "drive": 8,
+ "prg": "simplefiles",
+ "label": "simple files",
+ "desc": "dual pane file manager and seq viewer"
+ },
+ {
+ "drive": 8,
+ "prg": "clipmgr",
+ "label": "clipboard",
+ "desc": "manage clipboard items"
+ },
+ {
+ "drive": 8,
+ "prg": "readybasic",
+ "label": "ready basic (alpha)",
+ "desc": "scoped basic v2 bridge poc"
+ },
+ {
+ "drive": 8,
+ "prg": "cal26",
+ "label": "calendar 26",
+ "desc": "calendar for 2026 with appointments"
+ },
+ {
+ "drive": 8,
+ "prg": "tasklist",
+ "label": "task list",
+ "desc": "outliner with notes and search"
+ },
+ {
+ "drive": 8,
+ "prg": "reuviewer",
+ "label": "reu viewer",
+ "desc": "view reu memory usage"
+ },
+ {
+ "drive": 8,
+ "prg": "sysinfo",
+ "label": "system info",
+ "desc": "system, reu, and ultimate status"
+ },
+ {
+ "drive": 8,
+ "prg": "quicknotes",
+ "label": "quicknotes",
+ "desc": "reu-backed note editor"
+ },
+ {
+ "drive": 8,
+ "prg": "calcplus",
+ "label": "calc plus",
+ "desc": "keyboard-first expression calculator"
+ },
+ {
+ "drive": 8,
+ "prg": "hexview",
+ "label": "hex viewer",
+ "desc": "browse memory in hex format"
+ },
+ {
+ "drive": 8,
+ "prg": "simplecells",
+ "label": "simple cells (alpha)",
+ "desc": "spreadsheet with formulas and colors"
+ },
+ {
+ "drive": 8,
+ "prg": "game2048",
+ "label": "2048 game",
+ "desc": "2048 tile puzzle"
+ },
+ {
+ "drive": 8,
+ "prg": "deminer",
+ "label": "deminer",
+ "desc": "minesweeper-style puzzle"
+ },
+ {
+ "drive": 8,
+ "prg": "dizzy",
+ "label": "dizzy kanban",
+ "desc": "fizzy inspired kanban app"
+ },
+ {
+ "drive": 8,
+ "prg": "readyirc",
+ "label": "readyirc",
+ "desc": "ultimate tcp irc client"
+ },
+ {
+ "drive": 8,
+ "prg": "ucitest",
+ "label": "uci tester",
+ "desc": "ultimate command interface lab"
+ },
+ {
+ "drive": 8,
+ "prg": "rirc-rrnet",
+ "label": "readyirc rrnet",
+ "desc": "rr-net tcp irc client"
+ },
+ {
+ "drive": 8,
+ "prg": "readme",
+ "label": "read.me",
+ "desc": "readyos, ultimate buddy, precog poc os"
+ }
+ ]
+}
diff --git a/Releases/0.2.4/precog-kung-fu-flash-2-d81 2/readyos-v0.2.4-kung-fu-flash-2-d81-boot.prg b/Releases/0.2.4/precog-kung-fu-flash-2-d81 2/readyos-v0.2.4-kung-fu-flash-2-d81-boot.prg
new file mode 100644
index 0000000..a5f4eca
Binary files /dev/null and b/Releases/0.2.4/precog-kung-fu-flash-2-d81 2/readyos-v0.2.4-kung-fu-flash-2-d81-boot.prg differ
diff --git a/Releases/0.2.4/precog-kung-fu-flash-2-d81 2/readyos-v0.2.4-kung-fu-flash-2-d81-preboot.prg b/Releases/0.2.4/precog-kung-fu-flash-2-d81 2/readyos-v0.2.4-kung-fu-flash-2-d81-preboot.prg
new file mode 100644
index 0000000..67aec11
Binary files /dev/null and b/Releases/0.2.4/precog-kung-fu-flash-2-d81 2/readyos-v0.2.4-kung-fu-flash-2-d81-preboot.prg differ
diff --git a/Releases/0.2.4/precog-kung-fu-flash-2-d81 2/readyos-v0.2.4-kung-fu-flash-2-d81.d81 b/Releases/0.2.4/precog-kung-fu-flash-2-d81 2/readyos-v0.2.4-kung-fu-flash-2-d81.d81
new file mode 100644
index 0000000..4bdc0d4
Binary files /dev/null and b/Releases/0.2.4/precog-kung-fu-flash-2-d81 2/readyos-v0.2.4-kung-fu-flash-2-d81.d81 differ
diff --git a/Releases/0.2.4/readyos-v0.2.4-kung-fu-flash-2-d81.zip b/Releases/0.2.4/readyos-v0.2.4-kung-fu-flash-2-d81.zip
new file mode 100644
index 0000000..f6b46f2
Binary files /dev/null and b/Releases/0.2.4/readyos-v0.2.4-kung-fu-flash-2-d81.zip differ
diff --git a/Releases/0.2.5/README.md b/Releases/0.2.5/README.md
new file mode 100644
index 0000000..40783da
--- /dev/null
+++ b/Releases/0.2.5/README.md
@@ -0,0 +1,199 @@
+# ReadyOS 0.2.5 Release Guide
+
+ReadyOS PRECOG is an experimental REU-first environment for a modern Commodore
+64 setup. Its long-term center of gravity is the new Commodore 64 Ultimate and
+related Ultimate-family hardware, but it is intended to support a wide range of
+C64 setups that have a reasonably large REU. This release line is organized as
+multiple disk-image variants so the same ReadyOS runtime can fit different
+real-world C64 environments without pretending every machine, cartridge,
+loader, or emulator mounts the same media.
+
+- Public release line: `0.2.5`
+- Current artifact build in this tree: `0.2.5Y`
+- Main site: [readyos64.com](https://readyos64.com)
+- Wiki / working knowledge base: [readyos.notion.site](https://readyos.notion.site)
+- GitHub source and issues: [ReadyOS-C64/ReadyOs](https://github.com/ReadyOS-C64/ReadyOs)
+
+If this folder is distributed as a GitHub release or a packaged download, this
+README is the landing page for the whole release line. The profile folders next
+to it are the actual ReadyOS SKUs for different disk and drive constraints.
+
+The current public `0.2.5` release is still comparatively generic
+rather than being explicitly tailored to the new C64 Ultimate. The next release
+is expected to push further in that Ultimate-first direction while still trying
+to stay usable on other REU-capable C64 setups.
+
+The source tree may also contain an experimental C64 Ultimate DOS DMA launcher
+build. It is not implied by choosing a D81 SKU: normal public artifacts use the
+portable disk path unless explicitly built with `LAUNCHER_DMA_LOAD=1`, and the
+experimental path retains disk fallback.
+
+## What ReadyOS Is
+
+ReadyOS is not trying to be a generic desktop shell squeezed into a C64. It is
+an opinionated, keyboard-first environment built around the idea that a modern
+C64 workflow should feel immediate once the machine is up:
+
+- fast app switching instead of cold-starting every tool from BASIC
+- suspend and resume across apps instead of constantly reloading state
+- shared clipboard and common interaction patterns across tools
+- full-screen, terminal-style apps that favor repeatable keyboard workflows
+- REU-backed state so the machine can behave more like a ready workspace than a
+ single-program-at-a-time disk menu
+
+The current public release line is `0.2.5`. Full-content ReadyOS
+profiles currently expose `16` launcher-visible apps, with
+the exact app mix depending on the variant you choose.
+
+## Runtime And REU Contract
+
+- The active app snapshot is `$1000-$C5FF` (`$B600` bytes). The resident 1 KB
+ shim owns `$C600-$C9FF`; its public ABI remains at `$C800-$C9FF`.
+- Physical REU bank `Skip` is the **ReadyOS bank** and is never allocated to an
+ app/resource. Physical `Skip+1` is the first dynamic bank.
+- The ReadyOS bank contains the launcher snapshot at `$0000-$B5FF` and
+ schema-v5 mappings, status, clipboard, hotkeys, registry/catalog, audit, and
+ launcher runtime state at `$B600-$FFFF`.
+- Logical app tokens resolve through the explicit `$B740` table; they are not
+ physical bank numbers and must not be converted with arithmetic.
+- ReadyShell and ReadyBASIC resource banks are loader-assigned and recorded in
+ the ReadyOS bank. ReadyBASIC retains its custom ca65/ld65 compact-image shape.
+
+## Why There Are Multiple Variants
+
+The short answer is that C64 storage and loader realities are not uniform.
+
+ReadyOS wants to run on:
+
+- C64 Ultimate and Ultimate 64 setups
+- VICE on modern desktops
+- real C64 hardware with REU-capable cartridges or other REU-capable expansions
+- THEC64 Mini and Maxi style workflows
+- web C64 emulators and simplified loaders that may only mount a single `D64`
+
+Those environments differ in three important ways:
+
+1. Drive type support.
+ Some setups are happy with `1571` or `1581` style media, while others are
+ effectively limited to `1541` / `D64`.
+
+2. Number of simultaneously mounted images.
+ Some environments can keep two drives online all the time. Others can only
+ mount one disk image at once, which forces ReadyOS into smaller curated
+ subsets.
+
+3. REU path and convenience model.
+ ReadyOS is designed for an REU-capable path. VICE can emulate that cleanly,
+ Ultimate-family hardware can provide it directly, and some other modern
+ setups can approximate it well enough to be practical. But the storage SKU
+ still has to match the drive and media constraints of the environment.
+
+That is why this release line ships multiple folders instead of pretending one
+image is universally correct. The runtime philosophy is shared. The disk-image
+packaging changes to match the target.
+
+## Quick Recommendation By Environment
+
+- If you are on C64 Ultimate, Ultimate 64, or VICE and want the fullest,
+ easiest default: start with `precog-d81` or `precog-dual-d71`.
+- If your setup wants the main local verification target and is comfortable with
+ two mounted `1571` drives: use `precog-dual-d71`.
+- If your setup prefers one full-content image on a `1581` / `D81` path: use
+ `precog-d81`.
+- If you only have `1541`-class compatibility but can mount two disks: use
+ `precog-dual-d64`.
+- If you can only mount one `D64` at a time, especially in simpler emulators,
+ loaders, THEC64-style flows, or web environments: choose one of the solo
+ `D64` subsets based on the app group you care about.
+
+## Public Variant Matrix
+
+This release line currently has `9` public variants.
+
+| Folder | Media | Best Fit | Why It Exists | Boot |
+| --- | --- | --- | --- | --- |
+| `precog-dual-d71` | 2x `D71` on drives `8` and `9` | C64 Ultimate, Ultimate 64, or VICE setups that can keep two 1571-class drives mounted. | Default full-content profile for two 1571-class drives and the main local verification target. | `PREBOOT -> SETD71 -> BOOT` |
+| `precog-d81` | 1x `D81` on drive `8` | C64 Ultimate, VICE, or other 1581-capable setups that prefer one full-content image. | Full-content single-disk profile for 1581 and D81 setups where the whole current app catalog fits on one image. | `PREBOOT -> BOOT` |
+| `precog-kung-fu-flash-2-d81` | 1x `D81` on drive `8` | Kung Fu Flash 2 users who want one full-content D81 and the cartridge's 1MB REU mode instead of CRT cartridge mode. | Full-content single-D81 profile tuned for Kung Fu Flash 2 disk loading with a 1MB REU and no skipped REU banks. | `PREBOOT -> BOOT` |
+| `precog-dual-d64` | 2x `D64` on drives `8` and `9` | Real or emulated 1541-only setups that can mount two disks but not D71 or D81 media. | Reduced dual-disk profile for 1541-class environments that can mount two D64 images but not higher-capacity media. | `PREBOOT -> BOOT` |
+| `precog-solo-d64-a` | 1x `D64` on drive `8` | THEC64, web emulators, or simple loaders that can mount only one D64 at a time. | Single-D64 subset focused on editor, reference, and dizzy for one-disk-only environments. | `PREBOOT -> BOOT` |
+| `precog-solo-d64-b` | 1x `D64` on drive `8` | THEC64, web emulators, or simple loaders that can mount only one D64 at a time. | Single-D64 productivity subset centered on quicknotes, clipboard, calculator, and files. | `PREBOOT -> BOOT` |
+| `precog-solo-d64-c` | 1x `D64` on drive `8` | THEC64, web emulators, or simple loaders that can mount only one D64 at a time. | Single-D64 planning subset centered on tasklist, calendar, and REU viewer. | `PREBOOT -> BOOT` |
+| `precog-solo-d64-d` | 1x `D64` on drive `8` | THEC64, web emulators, or simple loaders that can mount only one D64 at a time. | Single-D64 experimental subset for simple cells, calculator, 2048, and deminer. | `PREBOOT -> BOOT` |
+| `precog-solo-d64-e` | 1x `D64` on drive `8` | THEC64, web emulators, or simple loaders that can mount only one D64 at a time. | Single-D64 shell-focused subset for readyshell and its overlay payloads in one-disk-only environments. | `PREBOOT -> BOOT` |
+
+## What The Release Root Contains
+
+The release line is centered on these public folders:
+
+- `precog-dual-d71/`
+- `precog-d81/`
+- `precog-kung-fu-flash-2-d81/`
+- `precog-dual-d64/`
+- `precog-solo-d64-a/`
+- `precog-solo-d64-b/`
+- `precog-solo-d64-c/`
+- `precog-solo-d64-d/`
+- `precog-solo-d64-e/`
+
+Depending on whether a local workflow built one profile or all profiles, a
+working tree may not contain every folder until the full multi-profile build has
+been run. The intended GitHub release layout is this shared root README plus the
+variant folders that carry the actual images, boot PRGs, `manifest.json`, and
+per-variant `help.md` / `helpme.md`.
+
+## How To Think About The Variants
+
+The variants are not random repacks. They are different answers to the same
+question: "What is the best ReadyOS shape for this storage environment?"
+
+- `precog-dual-d71` is the broadest "mainline" profile when two `1571`-class
+ drives are available. It remains the primary local verification target.
+- `precog-d81` is the cleanest single-image full-content option when `1581`
+ support is available.
+- `precog-dual-d64` exists because many C64-adjacent environments still top out
+ at `D64`, but can at least keep two images mounted.
+- The solo `D64` variants exist for the environments that cannot do more than
+ one `D64` at a time. Instead of forcing a bloated or broken one-disk build,
+ ReadyOS splits into intentional subsets.
+
+That last category matters more than it may seem. A web emulator that only
+mounts one `D64` is a very different target from VICE on a desktop with REU and
+multiple virtual drives. THEC64 Mini / Maxi style workflows can also be more
+pleasant with smaller, direct, single-image choices. A release that pretends all
+of those paths are identical would be harder to understand and harder to boot.
+
+## REU Expectation
+
+ReadyOS is still an REU-first environment. The disk-image variants solve storage
+shape, not the absence of an REU-capable path.
+
+Recommended baseline:
+
+- enable the REU
+- use at least `1MB`; use `8MB` or `16MB` where the environment supports it
+- treat VICE and Ultimate-family hardware as the smoothest targets today
+
+On real C64 hardware, the exact cartridge or expansion path can vary. The main
+question is not the brand of REU-capable device, but whether the setup can
+deliver the REU behavior the runtime expects and whether the chosen media SKU
+matches the drive constraints of that setup.
+
+## Debug Variants
+
+This release line also ships debug-trace variants for ReadyShell development: `precog-d81-rsdebug`, `precog-dual-d71-rsdebug`, `precog-solo-d64-e-rsdebug`. They are intended for debugging and instrumentation, not as the default end-user choice.
+
+If you are just trying to run ReadyOS, prefer the non-debug variants first.
+
+## Where To Go Next
+
+- Start with the variant folder that matches your environment.
+- Read that folder's `helpme.md` for exact boot and VICE setup details.
+- Use [readyos64.com](https://readyos64.com) as the public front door.
+- Use [readyos.notion.site](https://readyos.notion.site) for the more wiki-like working docs.
+- Use [GitHub](https://github.com/ReadyOS-C64/ReadyOs) for source, issues, and future packaged releases.
+
+ReadyOS `0.2.5` is still explicitly experimental, but the purpose
+of this release layout is simple: make it easier to pick the right image for the
+hardware or emulator in front of you, instead of assuming every C64 environment
+looks the same.
diff --git a/Releases/0.2.5/precog-d81-rsdebug/help.md b/Releases/0.2.5/precog-d81-rsdebug/help.md
new file mode 100644
index 0000000..7ea69b3
--- /dev/null
+++ b/Releases/0.2.5/precog-d81-rsdebug/help.md
@@ -0,0 +1,68 @@
+# precog (d81, readyshell debug trace)
+
+- Release Line: `0.2.5`
+- Artifact Build: `0.2.5Y`
+- Kind: `d81`
+
+## Why This Variant Exists
+
+- Full-content single-disk profile for 1581 and D81 setups where the whole current app catalog fits on one image.
+
+## Artifacts
+
+- Drive 8: `readyos-v0.2.5y-d81.d81`
+- Host-Side Boot PRG: `readyos-v0.2.5y-d81-preboot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.5y-d81-boot.prg`
+
+## Included Apps
+
+- Drive 8: `editor` - editor
+- Drive 8: `readyshell` - readyshell (beta)
+- Drive 8: `simplefiles` - simple files
+- Drive 8: `clipmgr` - clipboard
+- Drive 8: `readybasic` - ready basic (alpha)
+- Drive 8: `cal26` - calendar 26
+- Drive 8: `tasklist` - task list
+- Drive 8: `reuviewer` - reu viewer
+- Drive 8: `sysinfo` - system info
+- Drive 8: `quicknotes` - quicknotes
+- Drive 8: `calcplus` - calc plus
+- Drive 8: `hexview` - hex viewer
+- Drive 8: `simplecells` - simple cells (alpha)
+- Drive 8: `game2048` - 2048 game
+- Drive 8: `deminer` - deminer
+- Drive 8: `dizzy` - dizzy kanban
+- Drive 8: `readyirc` - readyirc
+- Drive 8: `ucitest` - uci tester
+- Drive 8: `rirc-rrnet` - readyirc rrnet
+- Drive 8: `readme` - read.me
+
+## VICE Setup
+
+- Enable REU with at least `1MB`; `8MB` or `16MB` is recommended where available.
+- The host-side boot PRGs are convenience autostart files. The disk copy of `PREBOOT` is still the normal disk-side bootstrap.
+- Configure drive 8 as `1581` with true drive enabled and attach `readyos-v0.2.5y-d81.d81`.
+
+### VICE Command Example
+
+- Autostart target: `readyos-v0.2.5y-d81-preboot.prg`
+
+```sh
+x64sc -reu -reusize 16384 -drive8type 1581 -drive8truedrive -devicebackend8 0 +busdevice8 -8 readyos-v0.2.5y-d81.d81 -autostart readyos-v0.2.5y-d81-preboot.prg
+```
+
+## Boot
+
+- This profile uses the direct boot chain `PREBOOT -> BOOT`.
+- There is no `SETD71` stage for this variant.
+- Attach the single disk on drive `8`, then autostart `readyos-v0.2.5y-d81-preboot.prg` or run `LOAD "PREBOOT",8` then `RUN`.
+
+## C64 Ultimate
+
+- Copy the listed disk image files to the target storage.
+- Enable the REU with at least `1MB`; use `8MB` or `16MB` where available.
+- The host-side boot PRGs are optional convenience files for emulator launching; the disk-side `PREBOOT` entry is the standard hardware boot path.
+- Choosing a disk SKU does not enable the experimental Ultimate DOS DMA launcher. Normal release artifacts use the portable disk loader; DMA requires an explicit `LAUNCHER_DMA_LOAD=1` source build and retains disk fallback.
+- Attach the single disk image on drive `8`, then boot with `LOAD "PREBOOT",8` and `RUN`.
+- This variant boots directly from `PREBOOT` into `BOOT` and does not use `SETD71`.
+
diff --git a/Releases/0.2.5/precog-d81-rsdebug/helpme.md b/Releases/0.2.5/precog-d81-rsdebug/helpme.md
new file mode 100644
index 0000000..7ea69b3
--- /dev/null
+++ b/Releases/0.2.5/precog-d81-rsdebug/helpme.md
@@ -0,0 +1,68 @@
+# precog (d81, readyshell debug trace)
+
+- Release Line: `0.2.5`
+- Artifact Build: `0.2.5Y`
+- Kind: `d81`
+
+## Why This Variant Exists
+
+- Full-content single-disk profile for 1581 and D81 setups where the whole current app catalog fits on one image.
+
+## Artifacts
+
+- Drive 8: `readyos-v0.2.5y-d81.d81`
+- Host-Side Boot PRG: `readyos-v0.2.5y-d81-preboot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.5y-d81-boot.prg`
+
+## Included Apps
+
+- Drive 8: `editor` - editor
+- Drive 8: `readyshell` - readyshell (beta)
+- Drive 8: `simplefiles` - simple files
+- Drive 8: `clipmgr` - clipboard
+- Drive 8: `readybasic` - ready basic (alpha)
+- Drive 8: `cal26` - calendar 26
+- Drive 8: `tasklist` - task list
+- Drive 8: `reuviewer` - reu viewer
+- Drive 8: `sysinfo` - system info
+- Drive 8: `quicknotes` - quicknotes
+- Drive 8: `calcplus` - calc plus
+- Drive 8: `hexview` - hex viewer
+- Drive 8: `simplecells` - simple cells (alpha)
+- Drive 8: `game2048` - 2048 game
+- Drive 8: `deminer` - deminer
+- Drive 8: `dizzy` - dizzy kanban
+- Drive 8: `readyirc` - readyirc
+- Drive 8: `ucitest` - uci tester
+- Drive 8: `rirc-rrnet` - readyirc rrnet
+- Drive 8: `readme` - read.me
+
+## VICE Setup
+
+- Enable REU with at least `1MB`; `8MB` or `16MB` is recommended where available.
+- The host-side boot PRGs are convenience autostart files. The disk copy of `PREBOOT` is still the normal disk-side bootstrap.
+- Configure drive 8 as `1581` with true drive enabled and attach `readyos-v0.2.5y-d81.d81`.
+
+### VICE Command Example
+
+- Autostart target: `readyos-v0.2.5y-d81-preboot.prg`
+
+```sh
+x64sc -reu -reusize 16384 -drive8type 1581 -drive8truedrive -devicebackend8 0 +busdevice8 -8 readyos-v0.2.5y-d81.d81 -autostart readyos-v0.2.5y-d81-preboot.prg
+```
+
+## Boot
+
+- This profile uses the direct boot chain `PREBOOT -> BOOT`.
+- There is no `SETD71` stage for this variant.
+- Attach the single disk on drive `8`, then autostart `readyos-v0.2.5y-d81-preboot.prg` or run `LOAD "PREBOOT",8` then `RUN`.
+
+## C64 Ultimate
+
+- Copy the listed disk image files to the target storage.
+- Enable the REU with at least `1MB`; use `8MB` or `16MB` where available.
+- The host-side boot PRGs are optional convenience files for emulator launching; the disk-side `PREBOOT` entry is the standard hardware boot path.
+- Choosing a disk SKU does not enable the experimental Ultimate DOS DMA launcher. Normal release artifacts use the portable disk loader; DMA requires an explicit `LAUNCHER_DMA_LOAD=1` source build and retains disk fallback.
+- Attach the single disk image on drive `8`, then boot with `LOAD "PREBOOT",8` and `RUN`.
+- This variant boots directly from `PREBOOT` into `BOOT` and does not use `SETD71`.
+
diff --git a/Releases/0.2.5/precog-d81-rsdebug/manifest.json b/Releases/0.2.5/precog-d81-rsdebug/manifest.json
new file mode 100644
index 0000000..f96a553
--- /dev/null
+++ b/Releases/0.2.5/precog-d81-rsdebug/manifest.json
@@ -0,0 +1,158 @@
+{
+ "id": "precog-d81-rsdebug",
+ "display_name": "precog (d81, readyshell debug trace)",
+ "kind": "d81",
+ "variant_boot_name": "precog d81",
+ "version_text": "0.2.5Y",
+ "reu_size_kb": 16384,
+ "catalog_source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/cfg/profiles/precog-d81.ini",
+ "autostart_prg": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-d81-rsdebug/readyos-v0.2.5y-d81-preboot.prg",
+ "autostart_disk_prg": "preboot.prg",
+ "preboot_mode": "boot",
+ "disks": [
+ {
+ "index": 1,
+ "drive": 8,
+ "image_type": "d81",
+ "vice_drive_type": "1581",
+ "true_drive": true,
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-d81-rsdebug/readyos-v0.2.5y-d81.d81"
+ }
+ ],
+ "boot_prgs": [
+ {
+ "stem": "preboot",
+ "disk_name": "preboot",
+ "source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/preboot.prg",
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-d81-rsdebug/readyos-v0.2.5y-d81-preboot.prg"
+ },
+ {
+ "stem": "boot",
+ "disk_name": "boot",
+ "source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/boot.prg",
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-d81-rsdebug/readyos-v0.2.5y-d81-boot.prg"
+ }
+ ],
+ "apps": [
+ {
+ "drive": 8,
+ "prg": "editor",
+ "label": "editor",
+ "desc": "text editor with clipboard"
+ },
+ {
+ "drive": 8,
+ "prg": "readyshell",
+ "label": "readyshell (beta)",
+ "desc": "command shell poc scaffold"
+ },
+ {
+ "drive": 8,
+ "prg": "simplefiles",
+ "label": "simple files",
+ "desc": "dual pane file manager and seq viewer"
+ },
+ {
+ "drive": 8,
+ "prg": "clipmgr",
+ "label": "clipboard",
+ "desc": "manage clipboard items"
+ },
+ {
+ "drive": 8,
+ "prg": "readybasic",
+ "label": "ready basic (alpha)",
+ "desc": "scoped basic v2 bridge poc"
+ },
+ {
+ "drive": 8,
+ "prg": "cal26",
+ "label": "calendar 26",
+ "desc": "calendar for 2026 with appointments"
+ },
+ {
+ "drive": 8,
+ "prg": "tasklist",
+ "label": "task list",
+ "desc": "outliner with notes and search"
+ },
+ {
+ "drive": 8,
+ "prg": "reuviewer",
+ "label": "reu viewer",
+ "desc": "view reu memory usage"
+ },
+ {
+ "drive": 8,
+ "prg": "sysinfo",
+ "label": "system info",
+ "desc": "system, reu, and ultimate status"
+ },
+ {
+ "drive": 8,
+ "prg": "quicknotes",
+ "label": "quicknotes",
+ "desc": "reu-backed note editor"
+ },
+ {
+ "drive": 8,
+ "prg": "calcplus",
+ "label": "calc plus",
+ "desc": "keyboard-first expression calculator"
+ },
+ {
+ "drive": 8,
+ "prg": "hexview",
+ "label": "hex viewer",
+ "desc": "browse memory in hex format"
+ },
+ {
+ "drive": 8,
+ "prg": "simplecells",
+ "label": "simple cells (alpha)",
+ "desc": "spreadsheet with formulas and colors"
+ },
+ {
+ "drive": 8,
+ "prg": "game2048",
+ "label": "2048 game",
+ "desc": "2048 tile puzzle"
+ },
+ {
+ "drive": 8,
+ "prg": "deminer",
+ "label": "deminer",
+ "desc": "minesweeper-style puzzle"
+ },
+ {
+ "drive": 8,
+ "prg": "dizzy",
+ "label": "dizzy kanban",
+ "desc": "fizzy inspired kanban app"
+ },
+ {
+ "drive": 8,
+ "prg": "readyirc",
+ "label": "readyirc",
+ "desc": "ultimate tcp irc client"
+ },
+ {
+ "drive": 8,
+ "prg": "ucitest",
+ "label": "uci tester",
+ "desc": "ultimate command interface lab"
+ },
+ {
+ "drive": 8,
+ "prg": "rirc-rrnet",
+ "label": "readyirc rrnet",
+ "desc": "rr-net tcp irc client"
+ },
+ {
+ "drive": 8,
+ "prg": "readme",
+ "label": "read.me",
+ "desc": "readyos, ultimate buddy, precog poc os"
+ }
+ ]
+}
diff --git a/Releases/0.2.5/precog-d81-rsdebug/readyos-v0.2.5i-d81-boot.prg b/Releases/0.2.5/precog-d81-rsdebug/readyos-v0.2.5i-d81-boot.prg
new file mode 100644
index 0000000..198a89e
Binary files /dev/null and b/Releases/0.2.5/precog-d81-rsdebug/readyos-v0.2.5i-d81-boot.prg differ
diff --git a/Releases/0.2.5/precog-d81-rsdebug/readyos-v0.2.5i-d81-preboot.prg b/Releases/0.2.5/precog-d81-rsdebug/readyos-v0.2.5i-d81-preboot.prg
new file mode 100644
index 0000000..67aec11
Binary files /dev/null and b/Releases/0.2.5/precog-d81-rsdebug/readyos-v0.2.5i-d81-preboot.prg differ
diff --git a/Releases/0.2.5/precog-d81-rsdebug/readyos-v0.2.5i-d81.d81 b/Releases/0.2.5/precog-d81-rsdebug/readyos-v0.2.5i-d81.d81
new file mode 100644
index 0000000..b4a64c9
Binary files /dev/null and b/Releases/0.2.5/precog-d81-rsdebug/readyos-v0.2.5i-d81.d81 differ
diff --git a/Releases/0.2.5/precog-d81-rsdebug/readyos-v0.2.5y-d81-boot.prg b/Releases/0.2.5/precog-d81-rsdebug/readyos-v0.2.5y-d81-boot.prg
new file mode 100644
index 0000000..5477a72
Binary files /dev/null and b/Releases/0.2.5/precog-d81-rsdebug/readyos-v0.2.5y-d81-boot.prg differ
diff --git a/Releases/0.2.5/precog-d81-rsdebug/readyos-v0.2.5y-d81-preboot.prg b/Releases/0.2.5/precog-d81-rsdebug/readyos-v0.2.5y-d81-preboot.prg
new file mode 100644
index 0000000..67aec11
Binary files /dev/null and b/Releases/0.2.5/precog-d81-rsdebug/readyos-v0.2.5y-d81-preboot.prg differ
diff --git a/Releases/0.2.5/precog-d81-rsdebug/readyos-v0.2.5y-d81.d81 b/Releases/0.2.5/precog-d81-rsdebug/readyos-v0.2.5y-d81.d81
new file mode 100644
index 0000000..843e3cd
Binary files /dev/null and b/Releases/0.2.5/precog-d81-rsdebug/readyos-v0.2.5y-d81.d81 differ
diff --git a/Releases/0.2.5/precog-d81/help.md b/Releases/0.2.5/precog-d81/help.md
new file mode 100644
index 0000000..f0b1a5c
--- /dev/null
+++ b/Releases/0.2.5/precog-d81/help.md
@@ -0,0 +1,68 @@
+# precog (d81)
+
+- Release Line: `0.2.5`
+- Artifact Build: `0.2.5Y`
+- Kind: `d81`
+
+## Why This Variant Exists
+
+- Full-content single-disk profile for 1581 and D81 setups where the whole current app catalog fits on one image.
+
+## Artifacts
+
+- Drive 8: `readyos-v0.2.5y-d81.d81`
+- Host-Side Boot PRG: `readyos-v0.2.5y-d81-preboot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.5y-d81-boot.prg`
+
+## Included Apps
+
+- Drive 8: `editor` - editor
+- Drive 8: `readyshell` - readyshell (beta)
+- Drive 8: `simplefiles` - simple files
+- Drive 8: `clipmgr` - clipboard
+- Drive 8: `readybasic` - ready basic (alpha)
+- Drive 8: `cal26` - calendar 26
+- Drive 8: `tasklist` - task list
+- Drive 8: `reuviewer` - reu viewer
+- Drive 8: `sysinfo` - system info
+- Drive 8: `quicknotes` - quicknotes
+- Drive 8: `calcplus` - calc plus
+- Drive 8: `hexview` - hex viewer
+- Drive 8: `simplecells` - simple cells (alpha)
+- Drive 8: `game2048` - 2048 game
+- Drive 8: `deminer` - deminer
+- Drive 8: `dizzy` - dizzy kanban
+- Drive 8: `readyirc` - readyirc
+- Drive 8: `ucitest` - uci tester
+- Drive 8: `rirc-rrnet` - readyirc rrnet
+- Drive 8: `readme` - read.me
+
+## VICE Setup
+
+- Enable REU with at least `1MB`; `8MB` or `16MB` is recommended where available.
+- The host-side boot PRGs are convenience autostart files. The disk copy of `PREBOOT` is still the normal disk-side bootstrap.
+- Configure drive 8 as `1581` with true drive enabled and attach `readyos-v0.2.5y-d81.d81`.
+
+### VICE Command Example
+
+- Autostart target: `readyos-v0.2.5y-d81-preboot.prg`
+
+```sh
+x64sc -reu -reusize 16384 -drive8type 1581 -drive8truedrive -devicebackend8 0 +busdevice8 -8 readyos-v0.2.5y-d81.d81 -autostart readyos-v0.2.5y-d81-preboot.prg
+```
+
+## Boot
+
+- This profile uses the direct boot chain `PREBOOT -> BOOT`.
+- There is no `SETD71` stage for this variant.
+- Attach the single disk on drive `8`, then autostart `readyos-v0.2.5y-d81-preboot.prg` or run `LOAD "PREBOOT",8` then `RUN`.
+
+## C64 Ultimate
+
+- Copy the listed disk image files to the target storage.
+- Enable the REU with at least `1MB`; use `8MB` or `16MB` where available.
+- The host-side boot PRGs are optional convenience files for emulator launching; the disk-side `PREBOOT` entry is the standard hardware boot path.
+- Choosing a disk SKU does not enable the experimental Ultimate DOS DMA launcher. Normal release artifacts use the portable disk loader; DMA requires an explicit `LAUNCHER_DMA_LOAD=1` source build and retains disk fallback.
+- Attach the single disk image on drive `8`, then boot with `LOAD "PREBOOT",8` and `RUN`.
+- This variant boots directly from `PREBOOT` into `BOOT` and does not use `SETD71`.
+
diff --git a/Releases/0.2.5/precog-d81/helpme.md b/Releases/0.2.5/precog-d81/helpme.md
new file mode 100644
index 0000000..f0b1a5c
--- /dev/null
+++ b/Releases/0.2.5/precog-d81/helpme.md
@@ -0,0 +1,68 @@
+# precog (d81)
+
+- Release Line: `0.2.5`
+- Artifact Build: `0.2.5Y`
+- Kind: `d81`
+
+## Why This Variant Exists
+
+- Full-content single-disk profile for 1581 and D81 setups where the whole current app catalog fits on one image.
+
+## Artifacts
+
+- Drive 8: `readyos-v0.2.5y-d81.d81`
+- Host-Side Boot PRG: `readyos-v0.2.5y-d81-preboot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.5y-d81-boot.prg`
+
+## Included Apps
+
+- Drive 8: `editor` - editor
+- Drive 8: `readyshell` - readyshell (beta)
+- Drive 8: `simplefiles` - simple files
+- Drive 8: `clipmgr` - clipboard
+- Drive 8: `readybasic` - ready basic (alpha)
+- Drive 8: `cal26` - calendar 26
+- Drive 8: `tasklist` - task list
+- Drive 8: `reuviewer` - reu viewer
+- Drive 8: `sysinfo` - system info
+- Drive 8: `quicknotes` - quicknotes
+- Drive 8: `calcplus` - calc plus
+- Drive 8: `hexview` - hex viewer
+- Drive 8: `simplecells` - simple cells (alpha)
+- Drive 8: `game2048` - 2048 game
+- Drive 8: `deminer` - deminer
+- Drive 8: `dizzy` - dizzy kanban
+- Drive 8: `readyirc` - readyirc
+- Drive 8: `ucitest` - uci tester
+- Drive 8: `rirc-rrnet` - readyirc rrnet
+- Drive 8: `readme` - read.me
+
+## VICE Setup
+
+- Enable REU with at least `1MB`; `8MB` or `16MB` is recommended where available.
+- The host-side boot PRGs are convenience autostart files. The disk copy of `PREBOOT` is still the normal disk-side bootstrap.
+- Configure drive 8 as `1581` with true drive enabled and attach `readyos-v0.2.5y-d81.d81`.
+
+### VICE Command Example
+
+- Autostart target: `readyos-v0.2.5y-d81-preboot.prg`
+
+```sh
+x64sc -reu -reusize 16384 -drive8type 1581 -drive8truedrive -devicebackend8 0 +busdevice8 -8 readyos-v0.2.5y-d81.d81 -autostart readyos-v0.2.5y-d81-preboot.prg
+```
+
+## Boot
+
+- This profile uses the direct boot chain `PREBOOT -> BOOT`.
+- There is no `SETD71` stage for this variant.
+- Attach the single disk on drive `8`, then autostart `readyos-v0.2.5y-d81-preboot.prg` or run `LOAD "PREBOOT",8` then `RUN`.
+
+## C64 Ultimate
+
+- Copy the listed disk image files to the target storage.
+- Enable the REU with at least `1MB`; use `8MB` or `16MB` where available.
+- The host-side boot PRGs are optional convenience files for emulator launching; the disk-side `PREBOOT` entry is the standard hardware boot path.
+- Choosing a disk SKU does not enable the experimental Ultimate DOS DMA launcher. Normal release artifacts use the portable disk loader; DMA requires an explicit `LAUNCHER_DMA_LOAD=1` source build and retains disk fallback.
+- Attach the single disk image on drive `8`, then boot with `LOAD "PREBOOT",8` and `RUN`.
+- This variant boots directly from `PREBOOT` into `BOOT` and does not use `SETD71`.
+
diff --git a/Releases/0.2.5/precog-d81/manifest.json b/Releases/0.2.5/precog-d81/manifest.json
new file mode 100644
index 0000000..d204d33
--- /dev/null
+++ b/Releases/0.2.5/precog-d81/manifest.json
@@ -0,0 +1,158 @@
+{
+ "id": "precog-d81",
+ "display_name": "precog (d81)",
+ "kind": "d81",
+ "variant_boot_name": "precog d81",
+ "version_text": "0.2.5Y",
+ "reu_size_kb": 16384,
+ "catalog_source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/cfg/profiles/precog-d81.ini",
+ "autostart_prg": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-d81/readyos-v0.2.5y-d81-preboot.prg",
+ "autostart_disk_prg": "preboot.prg",
+ "preboot_mode": "boot",
+ "disks": [
+ {
+ "index": 1,
+ "drive": 8,
+ "image_type": "d81",
+ "vice_drive_type": "1581",
+ "true_drive": true,
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-d81/readyos-v0.2.5y-d81.d81"
+ }
+ ],
+ "boot_prgs": [
+ {
+ "stem": "preboot",
+ "disk_name": "preboot",
+ "source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/preboot.prg",
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-d81/readyos-v0.2.5y-d81-preboot.prg"
+ },
+ {
+ "stem": "boot",
+ "disk_name": "boot",
+ "source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/boot.prg",
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-d81/readyos-v0.2.5y-d81-boot.prg"
+ }
+ ],
+ "apps": [
+ {
+ "drive": 8,
+ "prg": "editor",
+ "label": "editor",
+ "desc": "text editor with clipboard"
+ },
+ {
+ "drive": 8,
+ "prg": "readyshell",
+ "label": "readyshell (beta)",
+ "desc": "command shell poc scaffold"
+ },
+ {
+ "drive": 8,
+ "prg": "simplefiles",
+ "label": "simple files",
+ "desc": "dual pane file manager and seq viewer"
+ },
+ {
+ "drive": 8,
+ "prg": "clipmgr",
+ "label": "clipboard",
+ "desc": "manage clipboard items"
+ },
+ {
+ "drive": 8,
+ "prg": "readybasic",
+ "label": "ready basic (alpha)",
+ "desc": "scoped basic v2 bridge poc"
+ },
+ {
+ "drive": 8,
+ "prg": "cal26",
+ "label": "calendar 26",
+ "desc": "calendar for 2026 with appointments"
+ },
+ {
+ "drive": 8,
+ "prg": "tasklist",
+ "label": "task list",
+ "desc": "outliner with notes and search"
+ },
+ {
+ "drive": 8,
+ "prg": "reuviewer",
+ "label": "reu viewer",
+ "desc": "view reu memory usage"
+ },
+ {
+ "drive": 8,
+ "prg": "sysinfo",
+ "label": "system info",
+ "desc": "system, reu, and ultimate status"
+ },
+ {
+ "drive": 8,
+ "prg": "quicknotes",
+ "label": "quicknotes",
+ "desc": "reu-backed note editor"
+ },
+ {
+ "drive": 8,
+ "prg": "calcplus",
+ "label": "calc plus",
+ "desc": "keyboard-first expression calculator"
+ },
+ {
+ "drive": 8,
+ "prg": "hexview",
+ "label": "hex viewer",
+ "desc": "browse memory in hex format"
+ },
+ {
+ "drive": 8,
+ "prg": "simplecells",
+ "label": "simple cells (alpha)",
+ "desc": "spreadsheet with formulas and colors"
+ },
+ {
+ "drive": 8,
+ "prg": "game2048",
+ "label": "2048 game",
+ "desc": "2048 tile puzzle"
+ },
+ {
+ "drive": 8,
+ "prg": "deminer",
+ "label": "deminer",
+ "desc": "minesweeper-style puzzle"
+ },
+ {
+ "drive": 8,
+ "prg": "dizzy",
+ "label": "dizzy kanban",
+ "desc": "fizzy inspired kanban app"
+ },
+ {
+ "drive": 8,
+ "prg": "readyirc",
+ "label": "readyirc",
+ "desc": "ultimate tcp irc client"
+ },
+ {
+ "drive": 8,
+ "prg": "ucitest",
+ "label": "uci tester",
+ "desc": "ultimate command interface lab"
+ },
+ {
+ "drive": 8,
+ "prg": "rirc-rrnet",
+ "label": "readyirc rrnet",
+ "desc": "rr-net tcp irc client"
+ },
+ {
+ "drive": 8,
+ "prg": "readme",
+ "label": "read.me",
+ "desc": "readyos, ultimate buddy, precog poc os"
+ }
+ ]
+}
diff --git a/Releases/0.2.5/precog-d81/readyos-v0.2.5i-d81-boot.prg b/Releases/0.2.5/precog-d81/readyos-v0.2.5i-d81-boot.prg
new file mode 100644
index 0000000..198a89e
Binary files /dev/null and b/Releases/0.2.5/precog-d81/readyos-v0.2.5i-d81-boot.prg differ
diff --git a/Releases/0.2.5/precog-d81/readyos-v0.2.5i-d81-preboot.prg b/Releases/0.2.5/precog-d81/readyos-v0.2.5i-d81-preboot.prg
new file mode 100644
index 0000000..67aec11
Binary files /dev/null and b/Releases/0.2.5/precog-d81/readyos-v0.2.5i-d81-preboot.prg differ
diff --git a/Releases/0.2.5/precog-d81/readyos-v0.2.5i-d81.d81 b/Releases/0.2.5/precog-d81/readyos-v0.2.5i-d81.d81
new file mode 100644
index 0000000..c31adf7
Binary files /dev/null and b/Releases/0.2.5/precog-d81/readyos-v0.2.5i-d81.d81 differ
diff --git a/Releases/0.2.5/precog-d81/readyos-v0.2.5y-d81-boot.prg b/Releases/0.2.5/precog-d81/readyos-v0.2.5y-d81-boot.prg
new file mode 100644
index 0000000..5477a72
Binary files /dev/null and b/Releases/0.2.5/precog-d81/readyos-v0.2.5y-d81-boot.prg differ
diff --git a/Releases/0.2.5/precog-d81/readyos-v0.2.5y-d81-preboot.prg b/Releases/0.2.5/precog-d81/readyos-v0.2.5y-d81-preboot.prg
new file mode 100644
index 0000000..67aec11
Binary files /dev/null and b/Releases/0.2.5/precog-d81/readyos-v0.2.5y-d81-preboot.prg differ
diff --git a/Releases/0.2.5/precog-d81/readyos-v0.2.5y-d81.d81 b/Releases/0.2.5/precog-d81/readyos-v0.2.5y-d81.d81
new file mode 100644
index 0000000..844a3bf
Binary files /dev/null and b/Releases/0.2.5/precog-d81/readyos-v0.2.5y-d81.d81 differ
diff --git a/Releases/0.2.5/precog-dual-d64/help.md b/Releases/0.2.5/precog-dual-d64/help.md
new file mode 100644
index 0000000..6909ad9
--- /dev/null
+++ b/Releases/0.2.5/precog-dual-d64/help.md
@@ -0,0 +1,58 @@
+# precog (dual d64)
+
+- Release Line: `0.2.5`
+- Artifact Build: `0.2.5Y`
+- Kind: `dual-d64`
+
+## Why This Variant Exists
+
+- Reduced dual-disk profile for 1541-class environments that can mount two D64 images but not higher-capacity media.
+
+## Artifacts
+
+- Drive 8: `readyos-v0.2.5y-dual-d64_1.d64`
+- Drive 9: `readyos-v0.2.5y-dual-d64_2.d64`
+- Host-Side Boot PRG: `readyos-v0.2.5y-dual-d64-preboot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.5y-dual-d64-boot.prg`
+
+## Included Apps
+
+- Drive 9: `editor` - editor
+- Drive 8: `readyshell` - readyshell (beta)
+- Drive 9: `simplefiles` - simple files
+- Drive 9: `clipmgr` - clipboard
+- Drive 8: `cal26` - calendar 26
+- Drive 9: `tasklist` - task list
+- Drive 8: `quicknotes` - quicknotes
+- Drive 9: `calcplus` - calc plus
+
+## VICE Setup
+
+- Enable REU with at least `1MB`; `8MB` or `16MB` is recommended where available.
+- The host-side boot PRGs are convenience autostart files. The disk copy of `PREBOOT` is still the normal disk-side bootstrap.
+- Configure drive 8 as `1541` with true drive enabled and attach `readyos-v0.2.5y-dual-d64_1.d64`.
+- Configure drive 9 as `1541` with true drive enabled and attach `readyos-v0.2.5y-dual-d64_2.d64`.
+
+### VICE Command Example
+
+- Autostart target: `readyos-v0.2.5y-dual-d64-preboot.prg`
+
+```sh
+x64sc -reu -reusize 16384 -drive8type 1541 -drive8truedrive -devicebackend8 0 +busdevice8 -8 readyos-v0.2.5y-dual-d64_1.d64 -drive9type 1541 -drive9truedrive -devicebackend9 0 +busdevice9 -9 readyos-v0.2.5y-dual-d64_2.d64 -autostart readyos-v0.2.5y-dual-d64-preboot.prg
+```
+
+## Boot
+
+- This profile uses the direct boot chain `PREBOOT -> BOOT`.
+- There is no `SETD71` stage for this variant.
+- Attach all listed disks before boot, then autostart `readyos-v0.2.5y-dual-d64-preboot.prg` or run `LOAD "PREBOOT",8` then `RUN`.
+
+## C64 Ultimate
+
+- Copy the listed disk image files to the target storage.
+- Enable the REU with at least `1MB`; use `8MB` or `16MB` where available.
+- The host-side boot PRGs are optional convenience files for emulator launching; the disk-side `PREBOOT` entry is the standard hardware boot path.
+- Choosing a disk SKU does not enable the experimental Ultimate DOS DMA launcher. Normal release artifacts use the portable disk loader; DMA requires an explicit `LAUNCHER_DMA_LOAD=1` source build and retains disk fallback.
+- Attach all listed disk images to their matching drives before boot, then run `LOAD "PREBOOT",8` and `RUN`.
+- This variant boots directly from `PREBOOT` into `BOOT` and does not use `SETD71`.
+
diff --git a/Releases/0.2.5/precog-dual-d64/helpme.md b/Releases/0.2.5/precog-dual-d64/helpme.md
new file mode 100644
index 0000000..6909ad9
--- /dev/null
+++ b/Releases/0.2.5/precog-dual-d64/helpme.md
@@ -0,0 +1,58 @@
+# precog (dual d64)
+
+- Release Line: `0.2.5`
+- Artifact Build: `0.2.5Y`
+- Kind: `dual-d64`
+
+## Why This Variant Exists
+
+- Reduced dual-disk profile for 1541-class environments that can mount two D64 images but not higher-capacity media.
+
+## Artifacts
+
+- Drive 8: `readyos-v0.2.5y-dual-d64_1.d64`
+- Drive 9: `readyos-v0.2.5y-dual-d64_2.d64`
+- Host-Side Boot PRG: `readyos-v0.2.5y-dual-d64-preboot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.5y-dual-d64-boot.prg`
+
+## Included Apps
+
+- Drive 9: `editor` - editor
+- Drive 8: `readyshell` - readyshell (beta)
+- Drive 9: `simplefiles` - simple files
+- Drive 9: `clipmgr` - clipboard
+- Drive 8: `cal26` - calendar 26
+- Drive 9: `tasklist` - task list
+- Drive 8: `quicknotes` - quicknotes
+- Drive 9: `calcplus` - calc plus
+
+## VICE Setup
+
+- Enable REU with at least `1MB`; `8MB` or `16MB` is recommended where available.
+- The host-side boot PRGs are convenience autostart files. The disk copy of `PREBOOT` is still the normal disk-side bootstrap.
+- Configure drive 8 as `1541` with true drive enabled and attach `readyos-v0.2.5y-dual-d64_1.d64`.
+- Configure drive 9 as `1541` with true drive enabled and attach `readyos-v0.2.5y-dual-d64_2.d64`.
+
+### VICE Command Example
+
+- Autostart target: `readyos-v0.2.5y-dual-d64-preboot.prg`
+
+```sh
+x64sc -reu -reusize 16384 -drive8type 1541 -drive8truedrive -devicebackend8 0 +busdevice8 -8 readyos-v0.2.5y-dual-d64_1.d64 -drive9type 1541 -drive9truedrive -devicebackend9 0 +busdevice9 -9 readyos-v0.2.5y-dual-d64_2.d64 -autostart readyos-v0.2.5y-dual-d64-preboot.prg
+```
+
+## Boot
+
+- This profile uses the direct boot chain `PREBOOT -> BOOT`.
+- There is no `SETD71` stage for this variant.
+- Attach all listed disks before boot, then autostart `readyos-v0.2.5y-dual-d64-preboot.prg` or run `LOAD "PREBOOT",8` then `RUN`.
+
+## C64 Ultimate
+
+- Copy the listed disk image files to the target storage.
+- Enable the REU with at least `1MB`; use `8MB` or `16MB` where available.
+- The host-side boot PRGs are optional convenience files for emulator launching; the disk-side `PREBOOT` entry is the standard hardware boot path.
+- Choosing a disk SKU does not enable the experimental Ultimate DOS DMA launcher. Normal release artifacts use the portable disk loader; DMA requires an explicit `LAUNCHER_DMA_LOAD=1` source build and retains disk fallback.
+- Attach all listed disk images to their matching drives before boot, then run `LOAD "PREBOOT",8` and `RUN`.
+- This variant boots directly from `PREBOOT` into `BOOT` and does not use `SETD71`.
+
diff --git a/Releases/0.2.5/precog-dual-d64/manifest.json b/Releases/0.2.5/precog-dual-d64/manifest.json
new file mode 100644
index 0000000..2c5337d
--- /dev/null
+++ b/Releases/0.2.5/precog-dual-d64/manifest.json
@@ -0,0 +1,94 @@
+{
+ "id": "precog-dual-d64",
+ "display_name": "precog (dual d64)",
+ "kind": "dual-d64",
+ "variant_boot_name": "precog dual d64",
+ "version_text": "0.2.5Y",
+ "reu_size_kb": 16384,
+ "catalog_source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/cfg/profiles/precog-dual-d64.ini",
+ "autostart_prg": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-dual-d64/readyos-v0.2.5y-dual-d64-preboot.prg",
+ "autostart_disk_prg": "preboot.prg",
+ "preboot_mode": "boot",
+ "disks": [
+ {
+ "index": 1,
+ "drive": 8,
+ "image_type": "d64",
+ "vice_drive_type": "1541",
+ "true_drive": true,
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-dual-d64/readyos-v0.2.5y-dual-d64_1.d64"
+ },
+ {
+ "index": 2,
+ "drive": 9,
+ "image_type": "d64",
+ "vice_drive_type": "1541",
+ "true_drive": true,
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-dual-d64/readyos-v0.2.5y-dual-d64_2.d64"
+ }
+ ],
+ "boot_prgs": [
+ {
+ "stem": "preboot",
+ "disk_name": "preboot",
+ "source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/preboot.prg",
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-dual-d64/readyos-v0.2.5y-dual-d64-preboot.prg"
+ },
+ {
+ "stem": "boot",
+ "disk_name": "boot",
+ "source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/boot.prg",
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-dual-d64/readyos-v0.2.5y-dual-d64-boot.prg"
+ }
+ ],
+ "apps": [
+ {
+ "drive": 9,
+ "prg": "editor",
+ "label": "editor",
+ "desc": "text editor with clipboard"
+ },
+ {
+ "drive": 8,
+ "prg": "readyshell",
+ "label": "readyshell (beta)",
+ "desc": "command shell poc scaffold"
+ },
+ {
+ "drive": 9,
+ "prg": "simplefiles",
+ "label": "simple files",
+ "desc": "dual pane file manager and seq viewer"
+ },
+ {
+ "drive": 9,
+ "prg": "clipmgr",
+ "label": "clipboard",
+ "desc": "manage clipboard items"
+ },
+ {
+ "drive": 8,
+ "prg": "cal26",
+ "label": "calendar 26",
+ "desc": "calendar for 2026 with appointments"
+ },
+ {
+ "drive": 9,
+ "prg": "tasklist",
+ "label": "task list",
+ "desc": "outliner with notes and search"
+ },
+ {
+ "drive": 8,
+ "prg": "quicknotes",
+ "label": "quicknotes",
+ "desc": "reu-backed note editor"
+ },
+ {
+ "drive": 9,
+ "prg": "calcplus",
+ "label": "calc plus",
+ "desc": "keyboard-first expression calculator"
+ }
+ ]
+}
diff --git a/Releases/0.2.5/precog-dual-d64/readyos-v0.2.5i-dual-d64-boot.prg b/Releases/0.2.5/precog-dual-d64/readyos-v0.2.5i-dual-d64-boot.prg
new file mode 100644
index 0000000..8ed8dff
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d64/readyos-v0.2.5i-dual-d64-boot.prg differ
diff --git a/Releases/0.2.5/precog-dual-d64/readyos-v0.2.5i-dual-d64-preboot.prg b/Releases/0.2.5/precog-dual-d64/readyos-v0.2.5i-dual-d64-preboot.prg
new file mode 100644
index 0000000..67aec11
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d64/readyos-v0.2.5i-dual-d64-preboot.prg differ
diff --git a/Releases/0.2.5/precog-dual-d64/readyos-v0.2.5i-dual-d64_1.d64 b/Releases/0.2.5/precog-dual-d64/readyos-v0.2.5i-dual-d64_1.d64
new file mode 100644
index 0000000..3d1f005
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d64/readyos-v0.2.5i-dual-d64_1.d64 differ
diff --git a/Releases/0.2.5/precog-dual-d64/readyos-v0.2.5i-dual-d64_2.d64 b/Releases/0.2.5/precog-dual-d64/readyos-v0.2.5i-dual-d64_2.d64
new file mode 100644
index 0000000..dc0fced
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d64/readyos-v0.2.5i-dual-d64_2.d64 differ
diff --git a/Releases/0.2.5/precog-dual-d64/readyos-v0.2.5y-dual-d64-boot.prg b/Releases/0.2.5/precog-dual-d64/readyos-v0.2.5y-dual-d64-boot.prg
new file mode 100644
index 0000000..ca58320
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d64/readyos-v0.2.5y-dual-d64-boot.prg differ
diff --git a/Releases/0.2.5/precog-dual-d64/readyos-v0.2.5y-dual-d64-preboot.prg b/Releases/0.2.5/precog-dual-d64/readyos-v0.2.5y-dual-d64-preboot.prg
new file mode 100644
index 0000000..67aec11
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d64/readyos-v0.2.5y-dual-d64-preboot.prg differ
diff --git a/Releases/0.2.5/precog-dual-d64/readyos-v0.2.5y-dual-d64_1.d64 b/Releases/0.2.5/precog-dual-d64/readyos-v0.2.5y-dual-d64_1.d64
new file mode 100644
index 0000000..0f544ef
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d64/readyos-v0.2.5y-dual-d64_1.d64 differ
diff --git a/Releases/0.2.5/precog-dual-d64/readyos-v0.2.5y-dual-d64_2.d64 b/Releases/0.2.5/precog-dual-d64/readyos-v0.2.5y-dual-d64_2.d64
new file mode 100644
index 0000000..e194b1f
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d64/readyos-v0.2.5y-dual-d64_2.d64 differ
diff --git a/Releases/0.2.5/precog-dual-d71-rsdebug/help.md b/Releases/0.2.5/precog-dual-d71-rsdebug/help.md
new file mode 100644
index 0000000..38c037d
--- /dev/null
+++ b/Releases/0.2.5/precog-dual-d71-rsdebug/help.md
@@ -0,0 +1,69 @@
+# precog (dual d71, readyshell debug trace)
+
+- Release Line: `0.2.5`
+- Artifact Build: `0.2.5Y`
+- Kind: `dual-d71`
+
+## Why This Variant Exists
+
+- Default full-content profile for two 1571-class drives and the main local verification target.
+
+## Artifacts
+
+- Drive 8: `readyos-v0.2.5y-dual-d71_1.d71`
+- Drive 9: `readyos-v0.2.5y-dual-d71_2.d71`
+- Host-Side Boot PRG: `readyos-v0.2.5y-dual-d71-preboot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.5y-dual-d71-boot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.5y-dual-d71-setd71.prg`
+
+## Included Apps
+
+- Drive 9: `editor` - editor
+- Drive 8: `readyshell` - readyshell (beta)
+- Drive 9: `simplefiles` - simple files
+- Drive 9: `clipmgr` - clipboard
+- Drive 9: `readybasic` - ready basic (alpha)
+- Drive 8: `cal26` - calendar 26
+- Drive 9: `tasklist` - task list
+- Drive 9: `reuviewer` - reu viewer
+- Drive 9: `sysinfo` - system info
+- Drive 8: `quicknotes` - quicknotes
+- Drive 9: `calcplus` - calc plus
+- Drive 9: `hexview` - hex viewer
+- Drive 9: `simplecells` - simple cells (alpha)
+- Drive 9: `game2048` - 2048 game
+- Drive 8: `dizzy` - dizzy kanban
+- Drive 9: `readyirc` - readyirc
+- `readme` is intentionally omitted from the dual-D71 variants to preserve disk space for app growth.
+
+## VICE Setup
+
+- Enable REU with at least `1MB`; `8MB` or `16MB` is recommended where available.
+- The host-side boot PRGs are convenience autostart files. The disk copy of `PREBOOT` is still the normal disk-side bootstrap.
+- Configure drive 8 as `1571` with true drive enabled and attach `readyos-v0.2.5y-dual-d71_1.d71`.
+- Configure drive 9 as `1571` with true drive enabled and attach `readyos-v0.2.5y-dual-d71_2.d71`.
+
+### VICE Command Example
+
+- Autostart target: `readyos-v0.2.5y-dual-d71-preboot.prg`
+
+```sh
+x64sc -reu -reusize 16384 -drive8type 1571 -drive8truedrive -devicebackend8 0 +busdevice8 -8 readyos-v0.2.5y-dual-d71_1.d71 -drive9type 1571 -drive9truedrive -devicebackend9 0 +busdevice9 -9 readyos-v0.2.5y-dual-d71_2.d71 -autostart readyos-v0.2.5y-dual-d71-preboot.prg
+```
+
+## Boot
+
+- This profile uses the dual-stage boot chain `PREBOOT -> SETD71 -> BOOT`.
+- Both disks must already be attached before boot, and both drives must be configured as `1571`.
+- `SETD71` is part of this variant and reasserts the dual-1571 setup before loading `BOOT`.
+- In VICE, autostart `readyos-v0.2.5y-dual-d71-preboot.prg`, or manually run `LOAD "PREBOOT",8` then `RUN`.
+
+## C64 Ultimate
+
+- Copy the listed disk image files to the target storage.
+- Enable the REU with at least `1MB`; use `8MB` or `16MB` where available.
+- The host-side boot PRGs are optional convenience files for emulator launching; the disk-side `PREBOOT` entry is the standard hardware boot path.
+- Choosing a disk SKU does not enable the experimental Ultimate DOS DMA launcher. Normal release artifacts use the portable disk loader; DMA requires an explicit `LAUNCHER_DMA_LOAD=1` source build and retains disk fallback.
+- Attach both disk images before boot and use `1571`-compatible drive assignments for the two-disk set.
+- Boot with `LOAD "PREBOOT",8` then `RUN`; this variant then chains through `SETD71` before loading `BOOT`.
+
diff --git a/Releases/0.2.5/precog-dual-d71-rsdebug/helpme.md b/Releases/0.2.5/precog-dual-d71-rsdebug/helpme.md
new file mode 100644
index 0000000..38c037d
--- /dev/null
+++ b/Releases/0.2.5/precog-dual-d71-rsdebug/helpme.md
@@ -0,0 +1,69 @@
+# precog (dual d71, readyshell debug trace)
+
+- Release Line: `0.2.5`
+- Artifact Build: `0.2.5Y`
+- Kind: `dual-d71`
+
+## Why This Variant Exists
+
+- Default full-content profile for two 1571-class drives and the main local verification target.
+
+## Artifacts
+
+- Drive 8: `readyos-v0.2.5y-dual-d71_1.d71`
+- Drive 9: `readyos-v0.2.5y-dual-d71_2.d71`
+- Host-Side Boot PRG: `readyos-v0.2.5y-dual-d71-preboot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.5y-dual-d71-boot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.5y-dual-d71-setd71.prg`
+
+## Included Apps
+
+- Drive 9: `editor` - editor
+- Drive 8: `readyshell` - readyshell (beta)
+- Drive 9: `simplefiles` - simple files
+- Drive 9: `clipmgr` - clipboard
+- Drive 9: `readybasic` - ready basic (alpha)
+- Drive 8: `cal26` - calendar 26
+- Drive 9: `tasklist` - task list
+- Drive 9: `reuviewer` - reu viewer
+- Drive 9: `sysinfo` - system info
+- Drive 8: `quicknotes` - quicknotes
+- Drive 9: `calcplus` - calc plus
+- Drive 9: `hexview` - hex viewer
+- Drive 9: `simplecells` - simple cells (alpha)
+- Drive 9: `game2048` - 2048 game
+- Drive 8: `dizzy` - dizzy kanban
+- Drive 9: `readyirc` - readyirc
+- `readme` is intentionally omitted from the dual-D71 variants to preserve disk space for app growth.
+
+## VICE Setup
+
+- Enable REU with at least `1MB`; `8MB` or `16MB` is recommended where available.
+- The host-side boot PRGs are convenience autostart files. The disk copy of `PREBOOT` is still the normal disk-side bootstrap.
+- Configure drive 8 as `1571` with true drive enabled and attach `readyos-v0.2.5y-dual-d71_1.d71`.
+- Configure drive 9 as `1571` with true drive enabled and attach `readyos-v0.2.5y-dual-d71_2.d71`.
+
+### VICE Command Example
+
+- Autostart target: `readyos-v0.2.5y-dual-d71-preboot.prg`
+
+```sh
+x64sc -reu -reusize 16384 -drive8type 1571 -drive8truedrive -devicebackend8 0 +busdevice8 -8 readyos-v0.2.5y-dual-d71_1.d71 -drive9type 1571 -drive9truedrive -devicebackend9 0 +busdevice9 -9 readyos-v0.2.5y-dual-d71_2.d71 -autostart readyos-v0.2.5y-dual-d71-preboot.prg
+```
+
+## Boot
+
+- This profile uses the dual-stage boot chain `PREBOOT -> SETD71 -> BOOT`.
+- Both disks must already be attached before boot, and both drives must be configured as `1571`.
+- `SETD71` is part of this variant and reasserts the dual-1571 setup before loading `BOOT`.
+- In VICE, autostart `readyos-v0.2.5y-dual-d71-preboot.prg`, or manually run `LOAD "PREBOOT",8` then `RUN`.
+
+## C64 Ultimate
+
+- Copy the listed disk image files to the target storage.
+- Enable the REU with at least `1MB`; use `8MB` or `16MB` where available.
+- The host-side boot PRGs are optional convenience files for emulator launching; the disk-side `PREBOOT` entry is the standard hardware boot path.
+- Choosing a disk SKU does not enable the experimental Ultimate DOS DMA launcher. Normal release artifacts use the portable disk loader; DMA requires an explicit `LAUNCHER_DMA_LOAD=1` source build and retains disk fallback.
+- Attach both disk images before boot and use `1571`-compatible drive assignments for the two-disk set.
+- Boot with `LOAD "PREBOOT",8` then `RUN`; this variant then chains through `SETD71` before loading `BOOT`.
+
diff --git a/Releases/0.2.5/precog-dual-d71-rsdebug/manifest.json b/Releases/0.2.5/precog-dual-d71-rsdebug/manifest.json
new file mode 100644
index 0000000..86df447
--- /dev/null
+++ b/Releases/0.2.5/precog-dual-d71-rsdebug/manifest.json
@@ -0,0 +1,148 @@
+{
+ "id": "precog-dual-d71-rsdebug",
+ "display_name": "precog (dual d71, readyshell debug trace)",
+ "kind": "dual-d71",
+ "variant_boot_name": "precog dual d71",
+ "version_text": "0.2.5Y",
+ "reu_size_kb": 16384,
+ "catalog_source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/cfg/profiles/precog-dual-d71.ini",
+ "autostart_prg": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5y-dual-d71-preboot.prg",
+ "autostart_disk_prg": "preboot.prg",
+ "preboot_mode": "setd71",
+ "disks": [
+ {
+ "index": 1,
+ "drive": 8,
+ "image_type": "d71",
+ "vice_drive_type": "1571",
+ "true_drive": true,
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5y-dual-d71_1.d71"
+ },
+ {
+ "index": 2,
+ "drive": 9,
+ "image_type": "d71",
+ "vice_drive_type": "1571",
+ "true_drive": true,
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5y-dual-d71_2.d71"
+ }
+ ],
+ "boot_prgs": [
+ {
+ "stem": "preboot",
+ "disk_name": "preboot",
+ "source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/preboot.prg",
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5y-dual-d71-preboot.prg"
+ },
+ {
+ "stem": "boot",
+ "disk_name": "boot",
+ "source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/boot.prg",
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5y-dual-d71-boot.prg"
+ },
+ {
+ "stem": "setd71",
+ "disk_name": "setd71",
+ "source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/setd71.prg",
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5y-dual-d71-setd71.prg"
+ }
+ ],
+ "apps": [
+ {
+ "drive": 9,
+ "prg": "editor",
+ "label": "editor",
+ "desc": "text editor with clipboard"
+ },
+ {
+ "drive": 8,
+ "prg": "readyshell",
+ "label": "readyshell (beta)",
+ "desc": "command shell poc scaffold"
+ },
+ {
+ "drive": 9,
+ "prg": "simplefiles",
+ "label": "simple files",
+ "desc": "dual pane file manager and seq viewer"
+ },
+ {
+ "drive": 9,
+ "prg": "clipmgr",
+ "label": "clipboard",
+ "desc": "manage clipboard items"
+ },
+ {
+ "drive": 9,
+ "prg": "readybasic",
+ "label": "ready basic (alpha)",
+ "desc": "scoped basic v2 bridge poc"
+ },
+ {
+ "drive": 8,
+ "prg": "cal26",
+ "label": "calendar 26",
+ "desc": "calendar for 2026 with appointments"
+ },
+ {
+ "drive": 9,
+ "prg": "tasklist",
+ "label": "task list",
+ "desc": "outliner with notes and search"
+ },
+ {
+ "drive": 9,
+ "prg": "reuviewer",
+ "label": "reu viewer",
+ "desc": "view reu memory usage"
+ },
+ {
+ "drive": 9,
+ "prg": "sysinfo",
+ "label": "system info",
+ "desc": "system, reu, and ultimate status"
+ },
+ {
+ "drive": 8,
+ "prg": "quicknotes",
+ "label": "quicknotes",
+ "desc": "reu-backed note editor"
+ },
+ {
+ "drive": 9,
+ "prg": "calcplus",
+ "label": "calc plus",
+ "desc": "keyboard-first expression calculator"
+ },
+ {
+ "drive": 9,
+ "prg": "hexview",
+ "label": "hex viewer",
+ "desc": "browse memory in hex format"
+ },
+ {
+ "drive": 9,
+ "prg": "simplecells",
+ "label": "simple cells (alpha)",
+ "desc": "spreadsheet with formulas and colors"
+ },
+ {
+ "drive": 9,
+ "prg": "game2048",
+ "label": "2048 game",
+ "desc": "2048 tile puzzle"
+ },
+ {
+ "drive": 8,
+ "prg": "dizzy",
+ "label": "dizzy kanban",
+ "desc": "fizzy inspired kanban app"
+ },
+ {
+ "drive": 9,
+ "prg": "readyirc",
+ "label": "readyirc",
+ "desc": "ultimate tcp irc client"
+ }
+ ]
+}
diff --git a/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5i-dual-d71-boot.prg b/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5i-dual-d71-boot.prg
new file mode 100644
index 0000000..74d5fd2
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5i-dual-d71-boot.prg differ
diff --git a/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5i-dual-d71-preboot.prg b/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5i-dual-d71-preboot.prg
new file mode 100644
index 0000000..2567d06
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5i-dual-d71-preboot.prg differ
diff --git a/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5i-dual-d71-setd71.prg b/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5i-dual-d71-setd71.prg
new file mode 100644
index 0000000..6c04d19
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5i-dual-d71-setd71.prg differ
diff --git a/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5i-dual-d71_1.d71 b/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5i-dual-d71_1.d71
new file mode 100644
index 0000000..cb595c3
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5i-dual-d71_1.d71 differ
diff --git a/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5i-dual-d71_2.d71 b/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5i-dual-d71_2.d71
new file mode 100644
index 0000000..efc942b
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5i-dual-d71_2.d71 differ
diff --git a/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5y-dual-d71-boot.prg b/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5y-dual-d71-boot.prg
new file mode 100644
index 0000000..7031154
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5y-dual-d71-boot.prg differ
diff --git a/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5y-dual-d71-preboot.prg b/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5y-dual-d71-preboot.prg
new file mode 100644
index 0000000..2567d06
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5y-dual-d71-preboot.prg differ
diff --git a/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5y-dual-d71-setd71.prg b/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5y-dual-d71-setd71.prg
new file mode 100644
index 0000000..6c04d19
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5y-dual-d71-setd71.prg differ
diff --git a/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5y-dual-d71_1.d71 b/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5y-dual-d71_1.d71
new file mode 100644
index 0000000..68534ed
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5y-dual-d71_1.d71 differ
diff --git a/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5y-dual-d71_2.d71 b/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5y-dual-d71_2.d71
new file mode 100644
index 0000000..7fb834c
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d71-rsdebug/readyos-v0.2.5y-dual-d71_2.d71 differ
diff --git a/Releases/0.2.5/precog-dual-d71/help.md b/Releases/0.2.5/precog-dual-d71/help.md
new file mode 100644
index 0000000..91e1c02
--- /dev/null
+++ b/Releases/0.2.5/precog-dual-d71/help.md
@@ -0,0 +1,69 @@
+# precog (dual d71)
+
+- Release Line: `0.2.5`
+- Artifact Build: `0.2.5Y`
+- Kind: `dual-d71`
+
+## Why This Variant Exists
+
+- Default full-content profile for two 1571-class drives and the main local verification target.
+
+## Artifacts
+
+- Drive 8: `readyos-v0.2.5y-dual-d71_1.d71`
+- Drive 9: `readyos-v0.2.5y-dual-d71_2.d71`
+- Host-Side Boot PRG: `readyos-v0.2.5y-dual-d71-preboot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.5y-dual-d71-boot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.5y-dual-d71-setd71.prg`
+
+## Included Apps
+
+- Drive 9: `editor` - editor
+- Drive 8: `readyshell` - readyshell (beta)
+- Drive 9: `simplefiles` - simple files
+- Drive 9: `clipmgr` - clipboard
+- Drive 9: `readybasic` - ready basic (alpha)
+- Drive 8: `cal26` - calendar 26
+- Drive 9: `tasklist` - task list
+- Drive 9: `reuviewer` - reu viewer
+- Drive 9: `sysinfo` - system info
+- Drive 8: `quicknotes` - quicknotes
+- Drive 9: `calcplus` - calc plus
+- Drive 9: `hexview` - hex viewer
+- Drive 9: `simplecells` - simple cells (alpha)
+- Drive 9: `game2048` - 2048 game
+- Drive 8: `dizzy` - dizzy kanban
+- Drive 9: `readyirc` - readyirc
+- `readme` is intentionally omitted from the dual-D71 variants to preserve disk space for app growth.
+
+## VICE Setup
+
+- Enable REU with at least `1MB`; `8MB` or `16MB` is recommended where available.
+- The host-side boot PRGs are convenience autostart files. The disk copy of `PREBOOT` is still the normal disk-side bootstrap.
+- Configure drive 8 as `1571` with true drive enabled and attach `readyos-v0.2.5y-dual-d71_1.d71`.
+- Configure drive 9 as `1571` with true drive enabled and attach `readyos-v0.2.5y-dual-d71_2.d71`.
+
+### VICE Command Example
+
+- Autostart target: `readyos-v0.2.5y-dual-d71-preboot.prg`
+
+```sh
+x64sc -reu -reusize 16384 -drive8type 1571 -drive8truedrive -devicebackend8 0 +busdevice8 -8 readyos-v0.2.5y-dual-d71_1.d71 -drive9type 1571 -drive9truedrive -devicebackend9 0 +busdevice9 -9 readyos-v0.2.5y-dual-d71_2.d71 -autostart readyos-v0.2.5y-dual-d71-preboot.prg
+```
+
+## Boot
+
+- This profile uses the dual-stage boot chain `PREBOOT -> SETD71 -> BOOT`.
+- Both disks must already be attached before boot, and both drives must be configured as `1571`.
+- `SETD71` is part of this variant and reasserts the dual-1571 setup before loading `BOOT`.
+- In VICE, autostart `readyos-v0.2.5y-dual-d71-preboot.prg`, or manually run `LOAD "PREBOOT",8` then `RUN`.
+
+## C64 Ultimate
+
+- Copy the listed disk image files to the target storage.
+- Enable the REU with at least `1MB`; use `8MB` or `16MB` where available.
+- The host-side boot PRGs are optional convenience files for emulator launching; the disk-side `PREBOOT` entry is the standard hardware boot path.
+- Choosing a disk SKU does not enable the experimental Ultimate DOS DMA launcher. Normal release artifacts use the portable disk loader; DMA requires an explicit `LAUNCHER_DMA_LOAD=1` source build and retains disk fallback.
+- Attach both disk images before boot and use `1571`-compatible drive assignments for the two-disk set.
+- Boot with `LOAD "PREBOOT",8` then `RUN`; this variant then chains through `SETD71` before loading `BOOT`.
+
diff --git a/Releases/0.2.5/precog-dual-d71/helpme.md b/Releases/0.2.5/precog-dual-d71/helpme.md
new file mode 100644
index 0000000..91e1c02
--- /dev/null
+++ b/Releases/0.2.5/precog-dual-d71/helpme.md
@@ -0,0 +1,69 @@
+# precog (dual d71)
+
+- Release Line: `0.2.5`
+- Artifact Build: `0.2.5Y`
+- Kind: `dual-d71`
+
+## Why This Variant Exists
+
+- Default full-content profile for two 1571-class drives and the main local verification target.
+
+## Artifacts
+
+- Drive 8: `readyos-v0.2.5y-dual-d71_1.d71`
+- Drive 9: `readyos-v0.2.5y-dual-d71_2.d71`
+- Host-Side Boot PRG: `readyos-v0.2.5y-dual-d71-preboot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.5y-dual-d71-boot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.5y-dual-d71-setd71.prg`
+
+## Included Apps
+
+- Drive 9: `editor` - editor
+- Drive 8: `readyshell` - readyshell (beta)
+- Drive 9: `simplefiles` - simple files
+- Drive 9: `clipmgr` - clipboard
+- Drive 9: `readybasic` - ready basic (alpha)
+- Drive 8: `cal26` - calendar 26
+- Drive 9: `tasklist` - task list
+- Drive 9: `reuviewer` - reu viewer
+- Drive 9: `sysinfo` - system info
+- Drive 8: `quicknotes` - quicknotes
+- Drive 9: `calcplus` - calc plus
+- Drive 9: `hexview` - hex viewer
+- Drive 9: `simplecells` - simple cells (alpha)
+- Drive 9: `game2048` - 2048 game
+- Drive 8: `dizzy` - dizzy kanban
+- Drive 9: `readyirc` - readyirc
+- `readme` is intentionally omitted from the dual-D71 variants to preserve disk space for app growth.
+
+## VICE Setup
+
+- Enable REU with at least `1MB`; `8MB` or `16MB` is recommended where available.
+- The host-side boot PRGs are convenience autostart files. The disk copy of `PREBOOT` is still the normal disk-side bootstrap.
+- Configure drive 8 as `1571` with true drive enabled and attach `readyos-v0.2.5y-dual-d71_1.d71`.
+- Configure drive 9 as `1571` with true drive enabled and attach `readyos-v0.2.5y-dual-d71_2.d71`.
+
+### VICE Command Example
+
+- Autostart target: `readyos-v0.2.5y-dual-d71-preboot.prg`
+
+```sh
+x64sc -reu -reusize 16384 -drive8type 1571 -drive8truedrive -devicebackend8 0 +busdevice8 -8 readyos-v0.2.5y-dual-d71_1.d71 -drive9type 1571 -drive9truedrive -devicebackend9 0 +busdevice9 -9 readyos-v0.2.5y-dual-d71_2.d71 -autostart readyos-v0.2.5y-dual-d71-preboot.prg
+```
+
+## Boot
+
+- This profile uses the dual-stage boot chain `PREBOOT -> SETD71 -> BOOT`.
+- Both disks must already be attached before boot, and both drives must be configured as `1571`.
+- `SETD71` is part of this variant and reasserts the dual-1571 setup before loading `BOOT`.
+- In VICE, autostart `readyos-v0.2.5y-dual-d71-preboot.prg`, or manually run `LOAD "PREBOOT",8` then `RUN`.
+
+## C64 Ultimate
+
+- Copy the listed disk image files to the target storage.
+- Enable the REU with at least `1MB`; use `8MB` or `16MB` where available.
+- The host-side boot PRGs are optional convenience files for emulator launching; the disk-side `PREBOOT` entry is the standard hardware boot path.
+- Choosing a disk SKU does not enable the experimental Ultimate DOS DMA launcher. Normal release artifacts use the portable disk loader; DMA requires an explicit `LAUNCHER_DMA_LOAD=1` source build and retains disk fallback.
+- Attach both disk images before boot and use `1571`-compatible drive assignments for the two-disk set.
+- Boot with `LOAD "PREBOOT",8` then `RUN`; this variant then chains through `SETD71` before loading `BOOT`.
+
diff --git a/Releases/0.2.5/precog-dual-d71/manifest.json b/Releases/0.2.5/precog-dual-d71/manifest.json
new file mode 100644
index 0000000..d1c681e
--- /dev/null
+++ b/Releases/0.2.5/precog-dual-d71/manifest.json
@@ -0,0 +1,148 @@
+{
+ "id": "precog-dual-d71",
+ "display_name": "precog (dual d71)",
+ "kind": "dual-d71",
+ "variant_boot_name": "precog dual d71",
+ "version_text": "0.2.5Y",
+ "reu_size_kb": 16384,
+ "catalog_source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/cfg/profiles/precog-dual-d71.ini",
+ "autostart_prg": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5y-dual-d71-preboot.prg",
+ "autostart_disk_prg": "preboot.prg",
+ "preboot_mode": "setd71",
+ "disks": [
+ {
+ "index": 1,
+ "drive": 8,
+ "image_type": "d71",
+ "vice_drive_type": "1571",
+ "true_drive": true,
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5y-dual-d71_1.d71"
+ },
+ {
+ "index": 2,
+ "drive": 9,
+ "image_type": "d71",
+ "vice_drive_type": "1571",
+ "true_drive": true,
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5y-dual-d71_2.d71"
+ }
+ ],
+ "boot_prgs": [
+ {
+ "stem": "preboot",
+ "disk_name": "preboot",
+ "source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/preboot.prg",
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5y-dual-d71-preboot.prg"
+ },
+ {
+ "stem": "boot",
+ "disk_name": "boot",
+ "source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/boot.prg",
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5y-dual-d71-boot.prg"
+ },
+ {
+ "stem": "setd71",
+ "disk_name": "setd71",
+ "source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/setd71.prg",
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5y-dual-d71-setd71.prg"
+ }
+ ],
+ "apps": [
+ {
+ "drive": 9,
+ "prg": "editor",
+ "label": "editor",
+ "desc": "text editor with clipboard"
+ },
+ {
+ "drive": 8,
+ "prg": "readyshell",
+ "label": "readyshell (beta)",
+ "desc": "command shell poc scaffold"
+ },
+ {
+ "drive": 9,
+ "prg": "simplefiles",
+ "label": "simple files",
+ "desc": "dual pane file manager and seq viewer"
+ },
+ {
+ "drive": 9,
+ "prg": "clipmgr",
+ "label": "clipboard",
+ "desc": "manage clipboard items"
+ },
+ {
+ "drive": 9,
+ "prg": "readybasic",
+ "label": "ready basic (alpha)",
+ "desc": "scoped basic v2 bridge poc"
+ },
+ {
+ "drive": 8,
+ "prg": "cal26",
+ "label": "calendar 26",
+ "desc": "calendar for 2026 with appointments"
+ },
+ {
+ "drive": 9,
+ "prg": "tasklist",
+ "label": "task list",
+ "desc": "outliner with notes and search"
+ },
+ {
+ "drive": 9,
+ "prg": "reuviewer",
+ "label": "reu viewer",
+ "desc": "view reu memory usage"
+ },
+ {
+ "drive": 9,
+ "prg": "sysinfo",
+ "label": "system info",
+ "desc": "system, reu, and ultimate status"
+ },
+ {
+ "drive": 8,
+ "prg": "quicknotes",
+ "label": "quicknotes",
+ "desc": "reu-backed note editor"
+ },
+ {
+ "drive": 9,
+ "prg": "calcplus",
+ "label": "calc plus",
+ "desc": "keyboard-first expression calculator"
+ },
+ {
+ "drive": 9,
+ "prg": "hexview",
+ "label": "hex viewer",
+ "desc": "browse memory in hex format"
+ },
+ {
+ "drive": 9,
+ "prg": "simplecells",
+ "label": "simple cells (alpha)",
+ "desc": "spreadsheet with formulas and colors"
+ },
+ {
+ "drive": 9,
+ "prg": "game2048",
+ "label": "2048 game",
+ "desc": "2048 tile puzzle"
+ },
+ {
+ "drive": 8,
+ "prg": "dizzy",
+ "label": "dizzy kanban",
+ "desc": "fizzy inspired kanban app"
+ },
+ {
+ "drive": 9,
+ "prg": "readyirc",
+ "label": "readyirc",
+ "desc": "ultimate tcp irc client"
+ }
+ ]
+}
diff --git a/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5j-dual-d71-boot.prg b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5j-dual-d71-boot.prg
new file mode 100644
index 0000000..8f02db0
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5j-dual-d71-boot.prg differ
diff --git a/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5j-dual-d71-preboot.prg b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5j-dual-d71-preboot.prg
new file mode 100644
index 0000000..2567d06
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5j-dual-d71-preboot.prg differ
diff --git a/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5j-dual-d71-setd71.prg b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5j-dual-d71-setd71.prg
new file mode 100644
index 0000000..6c04d19
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5j-dual-d71-setd71.prg differ
diff --git a/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5j-dual-d71_1.d71 b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5j-dual-d71_1.d71
new file mode 100644
index 0000000..c49fd3d
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5j-dual-d71_1.d71 differ
diff --git a/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5j-dual-d71_2.d71 b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5j-dual-d71_2.d71
new file mode 100644
index 0000000..efc942b
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5j-dual-d71_2.d71 differ
diff --git a/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5k-dual-d71-boot.prg b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5k-dual-d71-boot.prg
new file mode 100644
index 0000000..06e2bd0
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5k-dual-d71-boot.prg differ
diff --git a/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5k-dual-d71-preboot.prg b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5k-dual-d71-preboot.prg
new file mode 100644
index 0000000..2567d06
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5k-dual-d71-preboot.prg differ
diff --git a/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5k-dual-d71-setd71.prg b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5k-dual-d71-setd71.prg
new file mode 100644
index 0000000..6c04d19
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5k-dual-d71-setd71.prg differ
diff --git a/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5k-dual-d71_1.d71 b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5k-dual-d71_1.d71
new file mode 100644
index 0000000..c999cee
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5k-dual-d71_1.d71 differ
diff --git a/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5k-dual-d71_2.d71 b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5k-dual-d71_2.d71
new file mode 100644
index 0000000..efc81b9
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5k-dual-d71_2.d71 differ
diff --git a/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5l-dual-d71_1.d71 b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5l-dual-d71_1.d71
new file mode 100644
index 0000000..2eb667b
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5l-dual-d71_1.d71 differ
diff --git a/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5l-dual-d71_2.d71 b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5l-dual-d71_2.d71
new file mode 100644
index 0000000..2cad64f
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5l-dual-d71_2.d71 differ
diff --git a/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5y-dual-d71-boot.prg b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5y-dual-d71-boot.prg
new file mode 100644
index 0000000..7031154
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5y-dual-d71-boot.prg differ
diff --git a/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5y-dual-d71-preboot.prg b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5y-dual-d71-preboot.prg
new file mode 100644
index 0000000..2567d06
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5y-dual-d71-preboot.prg differ
diff --git a/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5y-dual-d71-setd71.prg b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5y-dual-d71-setd71.prg
new file mode 100644
index 0000000..6c04d19
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5y-dual-d71-setd71.prg differ
diff --git a/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5y-dual-d71_1.d71 b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5y-dual-d71_1.d71
new file mode 100644
index 0000000..b57096b
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5y-dual-d71_1.d71 differ
diff --git a/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5y-dual-d71_2.d71 b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5y-dual-d71_2.d71
new file mode 100644
index 0000000..7fb834c
Binary files /dev/null and b/Releases/0.2.5/precog-dual-d71/readyos-v0.2.5y-dual-d71_2.d71 differ
diff --git a/Releases/0.2.5/precog-easyflash/help.md b/Releases/0.2.5/precog-easyflash/help.md
new file mode 100644
index 0000000..9ffce02
--- /dev/null
+++ b/Releases/0.2.5/precog-easyflash/help.md
@@ -0,0 +1,12 @@
+# readyos easyflash
+
+- attach `readyos_easyflash.crt` as an easyflash cartridge
+- mount `readyos_data.d64` on drive `8`
+- enable REU with at least `1MB`; `8MB` or `16MB` is recommended where available
+- if an app snapshot preloaded from the cartridge is unloaded from REU, ReadyOS cannot load it again from the cartridge until you restart ReadyOS
+
+## vice example
+
+```sh
+x64sc -reu -reusize 16384 -cartcrt readyos_easyflash.crt -drive8type 1541 -devicebackend8 0 +busdevice8 -8 readyos_data.d64
+```
diff --git a/Releases/0.2.5/precog-easyflash/helpme.md b/Releases/0.2.5/precog-easyflash/helpme.md
new file mode 100644
index 0000000..9ffce02
--- /dev/null
+++ b/Releases/0.2.5/precog-easyflash/helpme.md
@@ -0,0 +1,12 @@
+# readyos easyflash
+
+- attach `readyos_easyflash.crt` as an easyflash cartridge
+- mount `readyos_data.d64` on drive `8`
+- enable REU with at least `1MB`; `8MB` or `16MB` is recommended where available
+- if an app snapshot preloaded from the cartridge is unloaded from REU, ReadyOS cannot load it again from the cartridge until you restart ReadyOS
+
+## vice example
+
+```sh
+x64sc -reu -reusize 16384 -cartcrt readyos_easyflash.crt -drive8type 1541 -devicebackend8 0 +busdevice8 -8 readyos_data.d64
+```
diff --git a/Releases/0.2.5/precog-easyflash/layout.json b/Releases/0.2.5/precog-easyflash/layout.json
new file mode 100644
index 0000000..03f5dd1
--- /dev/null
+++ b/Releases/0.2.5/precog-easyflash/layout.json
@@ -0,0 +1,428 @@
+{
+ "reu_bank_skip": 32,
+ "launcher": {
+ "artifact": "bin/launcher_easyflash.prg",
+ "start_bank": 1,
+ "bank_span": 2,
+ "load_addr": 4096,
+ "payload_len": 26977,
+ "checksum16": 29934
+ },
+ "apps": [
+ {
+ "bank": 1,
+ "reu_bank": 33,
+ "prg": "editor",
+ "label": "editor",
+ "artifact": "bin/editor.prg",
+ "start_bank": 3,
+ "bank_span": 2,
+ "load_addr": 4096,
+ "payload_len": 24518,
+ "checksum16": 16078,
+ "default_slot": 1,
+ "resource_set": 0
+ },
+ {
+ "bank": 2,
+ "reu_bank": 34,
+ "prg": "readyshell",
+ "label": "readyshell (beta)",
+ "artifact": "bin/readyshell_easyflash.prg",
+ "start_bank": 5,
+ "bank_span": 2,
+ "load_addr": 4096,
+ "payload_len": 28037,
+ "checksum16": 2385,
+ "default_slot": 2,
+ "resource_set": 1
+ },
+ {
+ "bank": 3,
+ "reu_bank": 35,
+ "prg": "simplefiles",
+ "label": "simple files",
+ "artifact": "bin/simplefiles.prg",
+ "start_bank": 7,
+ "bank_span": 2,
+ "load_addr": 4096,
+ "payload_len": 29755,
+ "checksum16": 54942,
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 4,
+ "reu_bank": 36,
+ "prg": "clipmgr",
+ "label": "clipboard",
+ "artifact": "bin/clipmgr.prg",
+ "start_bank": 9,
+ "bank_span": 2,
+ "load_addr": 4096,
+ "payload_len": 30893,
+ "checksum16": 56578,
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 5,
+ "reu_bank": 37,
+ "prg": "readybasic",
+ "label": "ready basic (alpha)",
+ "artifact": "bin/readybasic.prg",
+ "start_bank": 11,
+ "bank_span": 2,
+ "load_addr": 4096,
+ "payload_len": 28672,
+ "checksum16": 41909,
+ "default_slot": 3,
+ "resource_set": 2
+ },
+ {
+ "bank": 6,
+ "reu_bank": 38,
+ "prg": "cal26",
+ "label": "calendar 26",
+ "artifact": "bin/cal26.prg",
+ "start_bank": 13,
+ "bank_span": 2,
+ "load_addr": 4096,
+ "payload_len": 32616,
+ "checksum16": 9689,
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 7,
+ "reu_bank": 39,
+ "prg": "tasklist",
+ "label": "task list",
+ "artifact": "bin/tasklist.prg",
+ "start_bank": 15,
+ "bank_span": 2,
+ "load_addr": 4096,
+ "payload_len": 31267,
+ "checksum16": 60758,
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 8,
+ "reu_bank": 40,
+ "prg": "reuviewer",
+ "label": "reu viewer",
+ "artifact": "bin/reuviewer.prg",
+ "start_bank": 17,
+ "bank_span": 1,
+ "load_addr": 4096,
+ "payload_len": 15151,
+ "checksum16": 35503,
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 9,
+ "reu_bank": 41,
+ "prg": "sysinfo",
+ "label": "system info",
+ "artifact": "bin/sysinfo.prg",
+ "start_bank": 18,
+ "bank_span": 1,
+ "load_addr": 4096,
+ "payload_len": 16231,
+ "checksum16": 55115,
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 10,
+ "reu_bank": 42,
+ "prg": "quicknotes",
+ "label": "quicknotes",
+ "artifact": "bin/quicknotes.prg",
+ "start_bank": 19,
+ "bank_span": 2,
+ "load_addr": 4096,
+ "payload_len": 31253,
+ "checksum16": 63323,
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 11,
+ "reu_bank": 43,
+ "prg": "calcplus",
+ "label": "calc plus",
+ "artifact": "bin/calcplus.prg",
+ "start_bank": 21,
+ "bank_span": 3,
+ "load_addr": 4096,
+ "payload_len": 37521,
+ "checksum16": 15975,
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 12,
+ "reu_bank": 44,
+ "prg": "hexview",
+ "label": "hex viewer",
+ "artifact": "bin/hexview.prg",
+ "start_bank": 24,
+ "bank_span": 1,
+ "load_addr": 4096,
+ "payload_len": 12839,
+ "checksum16": 26671,
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 13,
+ "reu_bank": 45,
+ "prg": "simplecells",
+ "label": "simple cells (alpha)",
+ "artifact": "bin/simplecells.prg",
+ "start_bank": 25,
+ "bank_span": 3,
+ "load_addr": 4096,
+ "payload_len": 34950,
+ "checksum16": 64587,
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 14,
+ "reu_bank": 46,
+ "prg": "game2048",
+ "label": "2048 game",
+ "artifact": "bin/game2048.prg",
+ "start_bank": 28,
+ "bank_span": 2,
+ "load_addr": 4096,
+ "payload_len": 16884,
+ "checksum16": 45595,
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 15,
+ "reu_bank": 47,
+ "prg": "sidetris",
+ "label": "sidetris",
+ "artifact": "bin/sidetris.prg",
+ "start_bank": 30,
+ "bank_span": 1,
+ "load_addr": 4096,
+ "payload_len": 15543,
+ "checksum16": 40474,
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 16,
+ "reu_bank": 48,
+ "prg": "deminer",
+ "label": "deminer",
+ "artifact": "bin/deminer.prg",
+ "start_bank": 31,
+ "bank_span": 2,
+ "load_addr": 4096,
+ "payload_len": 20224,
+ "checksum16": 19712,
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 17,
+ "reu_bank": 49,
+ "prg": "dizzy",
+ "label": "dizzy kanban",
+ "artifact": "bin/dizzy.prg",
+ "start_bank": 33,
+ "bank_span": 3,
+ "load_addr": 4096,
+ "payload_len": 38685,
+ "checksum16": 45022,
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 18,
+ "reu_bank": 50,
+ "prg": "readyirc",
+ "label": "readyirc",
+ "artifact": "bin/readyirc.prg",
+ "start_bank": 36,
+ "bank_span": 2,
+ "load_addr": 4096,
+ "payload_len": 21929,
+ "checksum16": 61089,
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 19,
+ "reu_bank": 51,
+ "prg": "ucitest",
+ "label": "uci tester",
+ "artifact": "bin/ucitest.prg",
+ "start_bank": 38,
+ "bank_span": 2,
+ "load_addr": 4096,
+ "payload_len": 22591,
+ "checksum16": 3348,
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 20,
+ "reu_bank": 52,
+ "prg": "rirc-rrnet",
+ "label": "readyirc rrnet",
+ "artifact": "bin/rirc-rrnet.prg",
+ "start_bank": 40,
+ "bank_span": 2,
+ "load_addr": 4096,
+ "payload_len": 21505,
+ "checksum16": 17195,
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 21,
+ "reu_bank": 53,
+ "prg": "readme",
+ "label": "read.me",
+ "artifact": "bin/readme.prg",
+ "start_bank": 42,
+ "bank_span": 2,
+ "load_addr": 4096,
+ "payload_len": 24151,
+ "checksum16": 12301,
+ "default_slot": 0,
+ "resource_set": 0
+ }
+ ],
+ "overlays": [
+ {
+ "name": "rsparser",
+ "artifact": "bin/rsparser.prg",
+ "start_bank": 44,
+ "bank_span": 1,
+ "load_addr": 36352,
+ "payload_len": 13005,
+ "checksum16": 24021,
+ "reu_bank": 54,
+ "reu_off": 0,
+ "valid_bit": 1
+ },
+ {
+ "name": "rsvm",
+ "artifact": "bin/rsvm.prg",
+ "start_bank": 45,
+ "bank_span": 1,
+ "load_addr": 36352,
+ "payload_len": 14028,
+ "checksum16": 19620,
+ "reu_bank": 54,
+ "reu_off": 14336,
+ "valid_bit": 2
+ },
+ {
+ "name": "rsdrvilst",
+ "artifact": "bin/rsdrvilst.prg",
+ "start_bank": 46,
+ "bank_span": 1,
+ "load_addr": 36352,
+ "payload_len": 11258,
+ "checksum16": 52473,
+ "reu_bank": 54,
+ "reu_off": 28672,
+ "valid_bit": 4
+ },
+ {
+ "name": "rsldv",
+ "artifact": "bin/rsldv.prg",
+ "start_bank": 47,
+ "bank_span": 1,
+ "load_addr": 36352,
+ "payload_len": 11894,
+ "checksum16": 62081,
+ "reu_bank": 55,
+ "reu_off": 0,
+ "valid_bit": 8
+ },
+ {
+ "name": "rsstv",
+ "artifact": "bin/rsstv.prg",
+ "start_bank": 48,
+ "bank_span": 1,
+ "load_addr": 36352,
+ "payload_len": 10249,
+ "checksum16": 23078,
+ "reu_bank": 54,
+ "reu_off": 43008,
+ "valid_bit": 16
+ },
+ {
+ "name": "rsfops",
+ "artifact": "bin/rsfops.prg",
+ "start_bank": 49,
+ "bank_span": 1,
+ "load_addr": 36352,
+ "payload_len": 14325,
+ "checksum16": 20202,
+ "reu_bank": 55,
+ "reu_off": 14336,
+ "valid_bit": 32
+ },
+ {
+ "name": "rscat",
+ "artifact": "bin/rscat.prg",
+ "start_bank": 50,
+ "bank_span": 1,
+ "load_addr": 36352,
+ "payload_len": 8081,
+ "checksum16": 28204,
+ "reu_bank": 55,
+ "reu_off": 28672,
+ "valid_bit": 64
+ },
+ {
+ "name": "rscopy",
+ "artifact": "bin/rscopy.prg",
+ "start_bank": 51,
+ "bank_span": 1,
+ "load_addr": 36352,
+ "payload_len": 6599,
+ "checksum16": 43284,
+ "reu_bank": 55,
+ "reu_off": 43008,
+ "valid_bit": 128
+ },
+ {
+ "name": "rsedit",
+ "artifact": "bin/rsedit.prg",
+ "start_bank": 52,
+ "bank_span": 1,
+ "load_addr": 36352,
+ "payload_len": 2002,
+ "checksum16": 13,
+ "reu_bank": 56,
+ "reu_off": 0,
+ "valid_bit": 256
+ }
+ ],
+ "readyshell_cache_banks": [
+ 54,
+ 55,
+ 56
+ ],
+ "readyshell_state_bank": 57,
+ "readybasic_banks": [
+ 58,
+ 59
+ ],
+ "last_used_bank": 52
+}
diff --git a/Releases/0.2.5/precog-easyflash/manifest.json b/Releases/0.2.5/precog-easyflash/manifest.json
new file mode 100644
index 0000000..ce634a6
--- /dev/null
+++ b/Releases/0.2.5/precog-easyflash/manifest.json
@@ -0,0 +1,301 @@
+{
+ "id": "precog-easyflash",
+ "display_name": "precog easyflash",
+ "kind": "easyflash",
+ "version_text": "0.2.5Y",
+ "catalog_source": "cfg/flavors/readyos_easyflash.ini",
+ "artifacts": {
+ "crt": "Releases/0.2.5/precog-easyflash/readyos_easyflash.crt",
+ "data_disk": "Releases/0.2.5/precog-easyflash/readyos_data.d64",
+ "raw_bin": "Releases/0.2.5/precog-easyflash/readyos_easyflash.bin",
+ "layout": "Releases/0.2.5/precog-easyflash/layout.json"
+ },
+ "apps": [
+ {
+ "bank": 1,
+ "prg": "editor",
+ "label": "editor",
+ "desc": "text editor with clipboard",
+ "default_slot": 1,
+ "resource_set": 0
+ },
+ {
+ "bank": 2,
+ "prg": "readyshell",
+ "label": "readyshell (beta)",
+ "desc": "command shell poc scaffold",
+ "default_slot": 2,
+ "resource_set": 1
+ },
+ {
+ "bank": 3,
+ "prg": "simplefiles",
+ "label": "simple files",
+ "desc": "dual pane file manager and seq viewer",
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 4,
+ "prg": "clipmgr",
+ "label": "clipboard",
+ "desc": "manage clipboard items",
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 5,
+ "prg": "readybasic",
+ "label": "ready basic (alpha)",
+ "desc": "scoped basic v2 bridge poc",
+ "default_slot": 3,
+ "resource_set": 2
+ },
+ {
+ "bank": 6,
+ "prg": "cal26",
+ "label": "calendar 26",
+ "desc": "calendar for 2026 with appointments",
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 7,
+ "prg": "tasklist",
+ "label": "task list",
+ "desc": "outliner with notes and search",
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 8,
+ "prg": "reuviewer",
+ "label": "reu viewer",
+ "desc": "view reu memory usage",
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 9,
+ "prg": "sysinfo",
+ "label": "system info",
+ "desc": "system, reu, and ultimate status",
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 10,
+ "prg": "quicknotes",
+ "label": "quicknotes",
+ "desc": "reu-backed note editor",
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 11,
+ "prg": "calcplus",
+ "label": "calc plus",
+ "desc": "keyboard-first expression calculator",
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 12,
+ "prg": "hexview",
+ "label": "hex viewer",
+ "desc": "browse memory in hex format",
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 13,
+ "prg": "simplecells",
+ "label": "simple cells (alpha)",
+ "desc": "spreadsheet with formulas and colors",
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 14,
+ "prg": "game2048",
+ "label": "2048 game",
+ "desc": "2048 tile puzzle",
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 15,
+ "prg": "sidetris",
+ "label": "sidetris",
+ "desc": "sideways tetris",
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 16,
+ "prg": "deminer",
+ "label": "deminer",
+ "desc": "minesweeper-style puzzle",
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 17,
+ "prg": "dizzy",
+ "label": "dizzy kanban",
+ "desc": "fizzy inspired kanban app",
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 18,
+ "prg": "readyirc",
+ "label": "readyirc",
+ "desc": "ultimate tcp irc client",
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 19,
+ "prg": "ucitest",
+ "label": "uci tester",
+ "desc": "ultimate command interface lab",
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 20,
+ "prg": "rirc-rrnet",
+ "label": "readyirc rrnet",
+ "desc": "rr-net tcp irc client",
+ "default_slot": 0,
+ "resource_set": 0
+ },
+ {
+ "bank": 21,
+ "prg": "readme",
+ "label": "read.me",
+ "desc": "readyos, ultimate buddy, precog poc os",
+ "default_slot": 0,
+ "resource_set": 0
+ }
+ ],
+ "launcher": {
+ "artifact": "bin/launcher_easyflash.prg",
+ "start_bank": 1,
+ "bank_span": 2,
+ "load_addr": 4096,
+ "payload_len": 26977,
+ "checksum16": 29934
+ },
+ "overlays": [
+ {
+ "name": "rsparser",
+ "artifact": "bin/rsparser.prg",
+ "start_bank": 44,
+ "bank_span": 1,
+ "load_addr": 36352,
+ "payload_len": 13005,
+ "checksum16": 24021,
+ "reu_bank": 54,
+ "reu_off": 0,
+ "valid_bit": 1
+ },
+ {
+ "name": "rsvm",
+ "artifact": "bin/rsvm.prg",
+ "start_bank": 45,
+ "bank_span": 1,
+ "load_addr": 36352,
+ "payload_len": 14028,
+ "checksum16": 19620,
+ "reu_bank": 54,
+ "reu_off": 14336,
+ "valid_bit": 2
+ },
+ {
+ "name": "rsdrvilst",
+ "artifact": "bin/rsdrvilst.prg",
+ "start_bank": 46,
+ "bank_span": 1,
+ "load_addr": 36352,
+ "payload_len": 11258,
+ "checksum16": 52473,
+ "reu_bank": 54,
+ "reu_off": 28672,
+ "valid_bit": 4
+ },
+ {
+ "name": "rsldv",
+ "artifact": "bin/rsldv.prg",
+ "start_bank": 47,
+ "bank_span": 1,
+ "load_addr": 36352,
+ "payload_len": 11894,
+ "checksum16": 62081,
+ "reu_bank": 55,
+ "reu_off": 0,
+ "valid_bit": 8
+ },
+ {
+ "name": "rsstv",
+ "artifact": "bin/rsstv.prg",
+ "start_bank": 48,
+ "bank_span": 1,
+ "load_addr": 36352,
+ "payload_len": 10249,
+ "checksum16": 23078,
+ "reu_bank": 54,
+ "reu_off": 43008,
+ "valid_bit": 16
+ },
+ {
+ "name": "rsfops",
+ "artifact": "bin/rsfops.prg",
+ "start_bank": 49,
+ "bank_span": 1,
+ "load_addr": 36352,
+ "payload_len": 14325,
+ "checksum16": 20202,
+ "reu_bank": 55,
+ "reu_off": 14336,
+ "valid_bit": 32
+ },
+ {
+ "name": "rscat",
+ "artifact": "bin/rscat.prg",
+ "start_bank": 50,
+ "bank_span": 1,
+ "load_addr": 36352,
+ "payload_len": 8081,
+ "checksum16": 28204,
+ "reu_bank": 55,
+ "reu_off": 28672,
+ "valid_bit": 64
+ },
+ {
+ "name": "rscopy",
+ "artifact": "bin/rscopy.prg",
+ "start_bank": 51,
+ "bank_span": 1,
+ "load_addr": 36352,
+ "payload_len": 6599,
+ "checksum16": 43284,
+ "reu_bank": 55,
+ "reu_off": 43008,
+ "valid_bit": 128
+ },
+ {
+ "name": "rsedit",
+ "artifact": "bin/rsedit.prg",
+ "start_bank": 52,
+ "bank_span": 1,
+ "load_addr": 36352,
+ "payload_len": 2002,
+ "checksum16": 13,
+ "reu_bank": 56,
+ "reu_off": 0,
+ "valid_bit": 256
+ }
+ ]
+}
diff --git a/agentworking/easyflash_focus_largevars/readyos_data.easyflash-vice.d64 b/Releases/0.2.5/precog-easyflash/readyos_data.d64
similarity index 100%
rename from agentworking/easyflash_focus_largevars/readyos_data.easyflash-vice.d64
rename to Releases/0.2.5/precog-easyflash/readyos_data.d64
diff --git a/Releases/0.2.5/precog-easyflash/readyos_easyflash.bin b/Releases/0.2.5/precog-easyflash/readyos_easyflash.bin
new file mode 100644
index 0000000..ab25a58
Binary files /dev/null and b/Releases/0.2.5/precog-easyflash/readyos_easyflash.bin differ
diff --git a/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt b/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt
new file mode 100644
index 0000000..2fd2b50
Binary files /dev/null and b/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt differ
diff --git a/Releases/0.2.5/precog-kung-fu-flash-2-d81/README.md b/Releases/0.2.5/precog-kung-fu-flash-2-d81/README.md
new file mode 100644
index 0000000..cac4f70
--- /dev/null
+++ b/Releases/0.2.5/precog-kung-fu-flash-2-d81/README.md
@@ -0,0 +1,80 @@
+# precog (kung fu flash 2 d81)
+
+- Release Line: `0.2.5`
+- Artifact Build: `0.2.5Y`
+- Kind: `kung-fu-flash-2-d81`
+
+## Why This Variant Exists
+
+- Full-content single-D81 profile tuned for Kung Fu Flash 2 disk loading with a 1MB REU and no skipped REU banks.
+
+## Artifacts
+
+- Drive 8: `readyos-v0.2.5y-kung-fu-flash-2-d81.d81`
+- Host-Side Boot PRG: `readyos-v0.2.5y-kung-fu-flash-2-d81-preboot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.5y-kung-fu-flash-2-d81-boot.prg`
+
+## Included Apps
+
+- Drive 8: `editor` - editor
+- Drive 8: `readyshell` - readyshell (beta)
+- Drive 8: `simplefiles` - simple files
+- Drive 8: `clipmgr` - clipboard
+- Drive 8: `readybasic` - ready basic (alpha)
+- Drive 8: `cal26` - calendar 26
+- Drive 8: `tasklist` - task list
+- Drive 8: `reuviewer` - reu viewer
+- Drive 8: `sysinfo` - system info
+- Drive 8: `quicknotes` - quicknotes
+- Drive 8: `calcplus` - calc plus
+- Drive 8: `hexview` - hex viewer
+- Drive 8: `simplecells` - simple cells (alpha)
+- Drive 8: `game2048` - 2048 game
+- Drive 8: `deminer` - deminer
+- Drive 8: `dizzy` - dizzy kanban
+- Drive 8: `readyirc` - readyirc
+- Drive 8: `ucitest` - uci tester
+- Drive 8: `rirc-rrnet` - readyirc rrnet
+- Drive 8: `readme` - read.me
+
+## VICE Setup
+
+- Enable REU with at least `1MB`; this SKU targets KFF2's 1MB REU mode.
+- The host-side boot PRGs are convenience autostart files. The disk copy of `PREBOOT` is still the normal disk-side bootstrap.
+- Configure drive 8 as `1581` and attach `readyos-v0.2.5y-kung-fu-flash-2-d81.d81`.
+
+### VICE Command Example
+
+- Autostart target: `readyos-v0.2.5y-kung-fu-flash-2-d81-preboot.prg`
+
+```sh
+x64sc -reu -reusize 1024 -drive8type 1581 -devicebackend8 0 +busdevice8 -8 readyos-v0.2.5y-kung-fu-flash-2-d81.d81 -autostart readyos-v0.2.5y-kung-fu-flash-2-d81-preboot.prg
+```
+
+## 1MB REU Budget
+
+- This SKU is intentionally limited to `1MB` REU, which is `16` physical `64KB` REU banks.
+- It uses `reu_bank_skip=0`, so ReadyOS can use all 16 physical banks instead of skipping the lower bank range used by the normal test profiles.
+- Fresh launcher state uses `1` bank by default: bank `0` is the combined ReadyOS bank, holding both the launcher snapshot and schema-v5 system state. That leaves `15` banks for suspended apps and app resources.
+- Each suspended app normally costs `1` additional bank.
+- ReadyShell costs `5` additional banks when loaded: `1` app snapshot bank, `3` overlay cache banks, and `1` state/scratch bank. With only ReadyShell loaded, expect about `6/16` banks in use including the ReadyOS bank.
+- ReadyBasic costs `3` additional banks when loaded: `1` app snapshot bank plus `2` ReadyBasic core/code resource banks. With only ReadyBasic loaded, expect about `4/16` banks in use including the ReadyOS bank.
+- ReadyShell and ReadyBasic loaded at the same time can use about `9/16` banks including the ReadyOS bank, before any other suspended apps are counted.
+- When REU Viewer or the launcher shows the 1MB REU getting close to full, unload suspended apps before launching more. Unloading frees their app snapshot and resource banks.
+- If all REU banks are full, launching another app may simply do nothing instead of showing an error. Unload one or more apps to make room, then launch the app again.
+
+## Boot
+
+- This profile uses the direct boot chain `PREBOOT -> BOOT`.
+- There is no `SETD71` stage for this variant.
+- Attach the single disk on drive `8`, then autostart `readyos-v0.2.5y-kung-fu-flash-2-d81-preboot.prg` or run `LOAD "PREBOOT",8` then `RUN`.
+
+## C64 Ultimate
+
+- Copy the listed disk image files to the target storage.
+- Enable the REU with at least `1MB`; this SKU targets KFF2's 1MB REU mode.
+- The host-side boot PRGs are optional convenience files for emulator launching; the disk-side `PREBOOT` entry is the standard hardware boot path.
+- Choosing a disk SKU does not enable the experimental Ultimate DOS DMA launcher. Normal release artifacts use the portable disk loader; DMA requires an explicit `LAUNCHER_DMA_LOAD=1` source build and retains disk fallback.
+- Attach the single disk image on drive `8`, then boot with `LOAD "PREBOOT",8` and `RUN`.
+- This variant boots directly from `PREBOOT` into `BOOT` and does not use `SETD71`.
+
diff --git a/Releases/0.2.5/precog-kung-fu-flash-2-d81/help.md b/Releases/0.2.5/precog-kung-fu-flash-2-d81/help.md
new file mode 100644
index 0000000..cac4f70
--- /dev/null
+++ b/Releases/0.2.5/precog-kung-fu-flash-2-d81/help.md
@@ -0,0 +1,80 @@
+# precog (kung fu flash 2 d81)
+
+- Release Line: `0.2.5`
+- Artifact Build: `0.2.5Y`
+- Kind: `kung-fu-flash-2-d81`
+
+## Why This Variant Exists
+
+- Full-content single-D81 profile tuned for Kung Fu Flash 2 disk loading with a 1MB REU and no skipped REU banks.
+
+## Artifacts
+
+- Drive 8: `readyos-v0.2.5y-kung-fu-flash-2-d81.d81`
+- Host-Side Boot PRG: `readyos-v0.2.5y-kung-fu-flash-2-d81-preboot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.5y-kung-fu-flash-2-d81-boot.prg`
+
+## Included Apps
+
+- Drive 8: `editor` - editor
+- Drive 8: `readyshell` - readyshell (beta)
+- Drive 8: `simplefiles` - simple files
+- Drive 8: `clipmgr` - clipboard
+- Drive 8: `readybasic` - ready basic (alpha)
+- Drive 8: `cal26` - calendar 26
+- Drive 8: `tasklist` - task list
+- Drive 8: `reuviewer` - reu viewer
+- Drive 8: `sysinfo` - system info
+- Drive 8: `quicknotes` - quicknotes
+- Drive 8: `calcplus` - calc plus
+- Drive 8: `hexview` - hex viewer
+- Drive 8: `simplecells` - simple cells (alpha)
+- Drive 8: `game2048` - 2048 game
+- Drive 8: `deminer` - deminer
+- Drive 8: `dizzy` - dizzy kanban
+- Drive 8: `readyirc` - readyirc
+- Drive 8: `ucitest` - uci tester
+- Drive 8: `rirc-rrnet` - readyirc rrnet
+- Drive 8: `readme` - read.me
+
+## VICE Setup
+
+- Enable REU with at least `1MB`; this SKU targets KFF2's 1MB REU mode.
+- The host-side boot PRGs are convenience autostart files. The disk copy of `PREBOOT` is still the normal disk-side bootstrap.
+- Configure drive 8 as `1581` and attach `readyos-v0.2.5y-kung-fu-flash-2-d81.d81`.
+
+### VICE Command Example
+
+- Autostart target: `readyos-v0.2.5y-kung-fu-flash-2-d81-preboot.prg`
+
+```sh
+x64sc -reu -reusize 1024 -drive8type 1581 -devicebackend8 0 +busdevice8 -8 readyos-v0.2.5y-kung-fu-flash-2-d81.d81 -autostart readyos-v0.2.5y-kung-fu-flash-2-d81-preboot.prg
+```
+
+## 1MB REU Budget
+
+- This SKU is intentionally limited to `1MB` REU, which is `16` physical `64KB` REU banks.
+- It uses `reu_bank_skip=0`, so ReadyOS can use all 16 physical banks instead of skipping the lower bank range used by the normal test profiles.
+- Fresh launcher state uses `1` bank by default: bank `0` is the combined ReadyOS bank, holding both the launcher snapshot and schema-v5 system state. That leaves `15` banks for suspended apps and app resources.
+- Each suspended app normally costs `1` additional bank.
+- ReadyShell costs `5` additional banks when loaded: `1` app snapshot bank, `3` overlay cache banks, and `1` state/scratch bank. With only ReadyShell loaded, expect about `6/16` banks in use including the ReadyOS bank.
+- ReadyBasic costs `3` additional banks when loaded: `1` app snapshot bank plus `2` ReadyBasic core/code resource banks. With only ReadyBasic loaded, expect about `4/16` banks in use including the ReadyOS bank.
+- ReadyShell and ReadyBasic loaded at the same time can use about `9/16` banks including the ReadyOS bank, before any other suspended apps are counted.
+- When REU Viewer or the launcher shows the 1MB REU getting close to full, unload suspended apps before launching more. Unloading frees their app snapshot and resource banks.
+- If all REU banks are full, launching another app may simply do nothing instead of showing an error. Unload one or more apps to make room, then launch the app again.
+
+## Boot
+
+- This profile uses the direct boot chain `PREBOOT -> BOOT`.
+- There is no `SETD71` stage for this variant.
+- Attach the single disk on drive `8`, then autostart `readyos-v0.2.5y-kung-fu-flash-2-d81-preboot.prg` or run `LOAD "PREBOOT",8` then `RUN`.
+
+## C64 Ultimate
+
+- Copy the listed disk image files to the target storage.
+- Enable the REU with at least `1MB`; this SKU targets KFF2's 1MB REU mode.
+- The host-side boot PRGs are optional convenience files for emulator launching; the disk-side `PREBOOT` entry is the standard hardware boot path.
+- Choosing a disk SKU does not enable the experimental Ultimate DOS DMA launcher. Normal release artifacts use the portable disk loader; DMA requires an explicit `LAUNCHER_DMA_LOAD=1` source build and retains disk fallback.
+- Attach the single disk image on drive `8`, then boot with `LOAD "PREBOOT",8` and `RUN`.
+- This variant boots directly from `PREBOOT` into `BOOT` and does not use `SETD71`.
+
diff --git a/Releases/0.2.5/precog-kung-fu-flash-2-d81/helpme.md b/Releases/0.2.5/precog-kung-fu-flash-2-d81/helpme.md
new file mode 100644
index 0000000..cac4f70
--- /dev/null
+++ b/Releases/0.2.5/precog-kung-fu-flash-2-d81/helpme.md
@@ -0,0 +1,80 @@
+# precog (kung fu flash 2 d81)
+
+- Release Line: `0.2.5`
+- Artifact Build: `0.2.5Y`
+- Kind: `kung-fu-flash-2-d81`
+
+## Why This Variant Exists
+
+- Full-content single-D81 profile tuned for Kung Fu Flash 2 disk loading with a 1MB REU and no skipped REU banks.
+
+## Artifacts
+
+- Drive 8: `readyos-v0.2.5y-kung-fu-flash-2-d81.d81`
+- Host-Side Boot PRG: `readyos-v0.2.5y-kung-fu-flash-2-d81-preboot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.5y-kung-fu-flash-2-d81-boot.prg`
+
+## Included Apps
+
+- Drive 8: `editor` - editor
+- Drive 8: `readyshell` - readyshell (beta)
+- Drive 8: `simplefiles` - simple files
+- Drive 8: `clipmgr` - clipboard
+- Drive 8: `readybasic` - ready basic (alpha)
+- Drive 8: `cal26` - calendar 26
+- Drive 8: `tasklist` - task list
+- Drive 8: `reuviewer` - reu viewer
+- Drive 8: `sysinfo` - system info
+- Drive 8: `quicknotes` - quicknotes
+- Drive 8: `calcplus` - calc plus
+- Drive 8: `hexview` - hex viewer
+- Drive 8: `simplecells` - simple cells (alpha)
+- Drive 8: `game2048` - 2048 game
+- Drive 8: `deminer` - deminer
+- Drive 8: `dizzy` - dizzy kanban
+- Drive 8: `readyirc` - readyirc
+- Drive 8: `ucitest` - uci tester
+- Drive 8: `rirc-rrnet` - readyirc rrnet
+- Drive 8: `readme` - read.me
+
+## VICE Setup
+
+- Enable REU with at least `1MB`; this SKU targets KFF2's 1MB REU mode.
+- The host-side boot PRGs are convenience autostart files. The disk copy of `PREBOOT` is still the normal disk-side bootstrap.
+- Configure drive 8 as `1581` and attach `readyos-v0.2.5y-kung-fu-flash-2-d81.d81`.
+
+### VICE Command Example
+
+- Autostart target: `readyos-v0.2.5y-kung-fu-flash-2-d81-preboot.prg`
+
+```sh
+x64sc -reu -reusize 1024 -drive8type 1581 -devicebackend8 0 +busdevice8 -8 readyos-v0.2.5y-kung-fu-flash-2-d81.d81 -autostart readyos-v0.2.5y-kung-fu-flash-2-d81-preboot.prg
+```
+
+## 1MB REU Budget
+
+- This SKU is intentionally limited to `1MB` REU, which is `16` physical `64KB` REU banks.
+- It uses `reu_bank_skip=0`, so ReadyOS can use all 16 physical banks instead of skipping the lower bank range used by the normal test profiles.
+- Fresh launcher state uses `1` bank by default: bank `0` is the combined ReadyOS bank, holding both the launcher snapshot and schema-v5 system state. That leaves `15` banks for suspended apps and app resources.
+- Each suspended app normally costs `1` additional bank.
+- ReadyShell costs `5` additional banks when loaded: `1` app snapshot bank, `3` overlay cache banks, and `1` state/scratch bank. With only ReadyShell loaded, expect about `6/16` banks in use including the ReadyOS bank.
+- ReadyBasic costs `3` additional banks when loaded: `1` app snapshot bank plus `2` ReadyBasic core/code resource banks. With only ReadyBasic loaded, expect about `4/16` banks in use including the ReadyOS bank.
+- ReadyShell and ReadyBasic loaded at the same time can use about `9/16` banks including the ReadyOS bank, before any other suspended apps are counted.
+- When REU Viewer or the launcher shows the 1MB REU getting close to full, unload suspended apps before launching more. Unloading frees their app snapshot and resource banks.
+- If all REU banks are full, launching another app may simply do nothing instead of showing an error. Unload one or more apps to make room, then launch the app again.
+
+## Boot
+
+- This profile uses the direct boot chain `PREBOOT -> BOOT`.
+- There is no `SETD71` stage for this variant.
+- Attach the single disk on drive `8`, then autostart `readyos-v0.2.5y-kung-fu-flash-2-d81-preboot.prg` or run `LOAD "PREBOOT",8` then `RUN`.
+
+## C64 Ultimate
+
+- Copy the listed disk image files to the target storage.
+- Enable the REU with at least `1MB`; this SKU targets KFF2's 1MB REU mode.
+- The host-side boot PRGs are optional convenience files for emulator launching; the disk-side `PREBOOT` entry is the standard hardware boot path.
+- Choosing a disk SKU does not enable the experimental Ultimate DOS DMA launcher. Normal release artifacts use the portable disk loader; DMA requires an explicit `LAUNCHER_DMA_LOAD=1` source build and retains disk fallback.
+- Attach the single disk image on drive `8`, then boot with `LOAD "PREBOOT",8` and `RUN`.
+- This variant boots directly from `PREBOOT` into `BOOT` and does not use `SETD71`.
+
diff --git a/Releases/0.2.5/precog-kung-fu-flash-2-d81/manifest.json b/Releases/0.2.5/precog-kung-fu-flash-2-d81/manifest.json
new file mode 100644
index 0000000..fcfcd19
--- /dev/null
+++ b/Releases/0.2.5/precog-kung-fu-flash-2-d81/manifest.json
@@ -0,0 +1,158 @@
+{
+ "id": "precog-kung-fu-flash-2-d81",
+ "display_name": "precog (kung fu flash 2 d81)",
+ "kind": "kung-fu-flash-2-d81",
+ "variant_boot_name": "precog kung fu flash 2 d81",
+ "version_text": "0.2.5Y",
+ "reu_size_kb": 1024,
+ "catalog_source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/cfg/profiles/precog-kung-fu-flash-2-d81.ini",
+ "autostart_prg": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-kung-fu-flash-2-d81/readyos-v0.2.5y-kung-fu-flash-2-d81-preboot.prg",
+ "autostart_disk_prg": "preboot.prg",
+ "preboot_mode": "boot",
+ "disks": [
+ {
+ "index": 1,
+ "drive": 8,
+ "image_type": "d81",
+ "vice_drive_type": "1581",
+ "true_drive": false,
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-kung-fu-flash-2-d81/readyos-v0.2.5y-kung-fu-flash-2-d81.d81"
+ }
+ ],
+ "boot_prgs": [
+ {
+ "stem": "preboot",
+ "disk_name": "preboot",
+ "source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/preboot.prg",
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-kung-fu-flash-2-d81/readyos-v0.2.5y-kung-fu-flash-2-d81-preboot.prg"
+ },
+ {
+ "stem": "boot",
+ "disk_name": "boot",
+ "source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/boot.prg",
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-kung-fu-flash-2-d81/readyos-v0.2.5y-kung-fu-flash-2-d81-boot.prg"
+ }
+ ],
+ "apps": [
+ {
+ "drive": 8,
+ "prg": "editor",
+ "label": "editor",
+ "desc": "text editor with clipboard"
+ },
+ {
+ "drive": 8,
+ "prg": "readyshell",
+ "label": "readyshell (beta)",
+ "desc": "command shell poc scaffold"
+ },
+ {
+ "drive": 8,
+ "prg": "simplefiles",
+ "label": "simple files",
+ "desc": "dual pane file manager and seq viewer"
+ },
+ {
+ "drive": 8,
+ "prg": "clipmgr",
+ "label": "clipboard",
+ "desc": "manage clipboard items"
+ },
+ {
+ "drive": 8,
+ "prg": "readybasic",
+ "label": "ready basic (alpha)",
+ "desc": "scoped basic v2 bridge poc"
+ },
+ {
+ "drive": 8,
+ "prg": "cal26",
+ "label": "calendar 26",
+ "desc": "calendar for 2026 with appointments"
+ },
+ {
+ "drive": 8,
+ "prg": "tasklist",
+ "label": "task list",
+ "desc": "outliner with notes and search"
+ },
+ {
+ "drive": 8,
+ "prg": "reuviewer",
+ "label": "reu viewer",
+ "desc": "view reu memory usage"
+ },
+ {
+ "drive": 8,
+ "prg": "sysinfo",
+ "label": "system info",
+ "desc": "system, reu, and ultimate status"
+ },
+ {
+ "drive": 8,
+ "prg": "quicknotes",
+ "label": "quicknotes",
+ "desc": "reu-backed note editor"
+ },
+ {
+ "drive": 8,
+ "prg": "calcplus",
+ "label": "calc plus",
+ "desc": "keyboard-first expression calculator"
+ },
+ {
+ "drive": 8,
+ "prg": "hexview",
+ "label": "hex viewer",
+ "desc": "browse memory in hex format"
+ },
+ {
+ "drive": 8,
+ "prg": "simplecells",
+ "label": "simple cells (alpha)",
+ "desc": "spreadsheet with formulas and colors"
+ },
+ {
+ "drive": 8,
+ "prg": "game2048",
+ "label": "2048 game",
+ "desc": "2048 tile puzzle"
+ },
+ {
+ "drive": 8,
+ "prg": "deminer",
+ "label": "deminer",
+ "desc": "minesweeper-style puzzle"
+ },
+ {
+ "drive": 8,
+ "prg": "dizzy",
+ "label": "dizzy kanban",
+ "desc": "fizzy inspired kanban app"
+ },
+ {
+ "drive": 8,
+ "prg": "readyirc",
+ "label": "readyirc",
+ "desc": "ultimate tcp irc client"
+ },
+ {
+ "drive": 8,
+ "prg": "ucitest",
+ "label": "uci tester",
+ "desc": "ultimate command interface lab"
+ },
+ {
+ "drive": 8,
+ "prg": "rirc-rrnet",
+ "label": "readyirc rrnet",
+ "desc": "rr-net tcp irc client"
+ },
+ {
+ "drive": 8,
+ "prg": "readme",
+ "label": "read.me",
+ "desc": "readyos, ultimate buddy, precog poc os"
+ }
+ ]
+}
diff --git a/Releases/0.2.5/precog-kung-fu-flash-2-d81/readyos-v0.2.5i-kung-fu-flash-2-d81-boot.prg b/Releases/0.2.5/precog-kung-fu-flash-2-d81/readyos-v0.2.5i-kung-fu-flash-2-d81-boot.prg
new file mode 100644
index 0000000..f0c1fcb
Binary files /dev/null and b/Releases/0.2.5/precog-kung-fu-flash-2-d81/readyos-v0.2.5i-kung-fu-flash-2-d81-boot.prg differ
diff --git a/Releases/0.2.5/precog-kung-fu-flash-2-d81/readyos-v0.2.5i-kung-fu-flash-2-d81-preboot.prg b/Releases/0.2.5/precog-kung-fu-flash-2-d81/readyos-v0.2.5i-kung-fu-flash-2-d81-preboot.prg
new file mode 100644
index 0000000..67aec11
Binary files /dev/null and b/Releases/0.2.5/precog-kung-fu-flash-2-d81/readyos-v0.2.5i-kung-fu-flash-2-d81-preboot.prg differ
diff --git a/Releases/0.2.5/precog-kung-fu-flash-2-d81/readyos-v0.2.5i-kung-fu-flash-2-d81.d81 b/Releases/0.2.5/precog-kung-fu-flash-2-d81/readyos-v0.2.5i-kung-fu-flash-2-d81.d81
new file mode 100644
index 0000000..b004d78
Binary files /dev/null and b/Releases/0.2.5/precog-kung-fu-flash-2-d81/readyos-v0.2.5i-kung-fu-flash-2-d81.d81 differ
diff --git a/Releases/0.2.5/precog-kung-fu-flash-2-d81/readyos-v0.2.5y-kung-fu-flash-2-d81-boot.prg b/Releases/0.2.5/precog-kung-fu-flash-2-d81/readyos-v0.2.5y-kung-fu-flash-2-d81-boot.prg
new file mode 100644
index 0000000..84163bd
Binary files /dev/null and b/Releases/0.2.5/precog-kung-fu-flash-2-d81/readyos-v0.2.5y-kung-fu-flash-2-d81-boot.prg differ
diff --git a/Releases/0.2.5/precog-kung-fu-flash-2-d81/readyos-v0.2.5y-kung-fu-flash-2-d81-preboot.prg b/Releases/0.2.5/precog-kung-fu-flash-2-d81/readyos-v0.2.5y-kung-fu-flash-2-d81-preboot.prg
new file mode 100644
index 0000000..67aec11
Binary files /dev/null and b/Releases/0.2.5/precog-kung-fu-flash-2-d81/readyos-v0.2.5y-kung-fu-flash-2-d81-preboot.prg differ
diff --git a/Releases/0.2.5/precog-kung-fu-flash-2-d81/readyos-v0.2.5y-kung-fu-flash-2-d81.d81 b/Releases/0.2.5/precog-kung-fu-flash-2-d81/readyos-v0.2.5y-kung-fu-flash-2-d81.d81
new file mode 100644
index 0000000..b8e38c3
Binary files /dev/null and b/Releases/0.2.5/precog-kung-fu-flash-2-d81/readyos-v0.2.5y-kung-fu-flash-2-d81.d81 differ
diff --git a/Releases/0.2.5/precog-solo-d64-a/help.md b/Releases/0.2.5/precog-solo-d64-a/help.md
new file mode 100644
index 0000000..35bdf8d
--- /dev/null
+++ b/Releases/0.2.5/precog-solo-d64-a/help.md
@@ -0,0 +1,52 @@
+# precog (solo d64 subset a)
+
+- Release Line: `0.2.5`
+- Artifact Build: `0.2.5Y`
+- Kind: `solo-d64-a`
+
+## Why This Variant Exists
+
+- Single-D64 subset focused on editor, reference, and dizzy for one-disk-only environments.
+
+## Artifacts
+
+- Drive 8: `readyos-v0.2.5y-solo-d64-a.d64`
+- Host-Side Boot PRG: `readyos-v0.2.5y-solo-d64-a-preboot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.5y-solo-d64-a-boot.prg`
+
+## Included Apps
+
+- Drive 8: `editor` - editor
+- Drive 8: `hexview` - hex viewer
+- Drive 8: `readme` - read.me
+- Drive 8: `dizzy` - dizzy kanban
+
+## VICE Setup
+
+- Enable REU with at least `1MB`; `8MB` or `16MB` is recommended where available.
+- The host-side boot PRGs are convenience autostart files. The disk copy of `PREBOOT` is still the normal disk-side bootstrap.
+- Configure drive 8 as `1541` with true drive enabled and attach `readyos-v0.2.5y-solo-d64-a.d64`.
+
+### VICE Command Example
+
+- Autostart target: `readyos-v0.2.5y-solo-d64-a-preboot.prg`
+
+```sh
+x64sc -reu -reusize 16384 -drive8type 1541 -drive8truedrive -devicebackend8 0 +busdevice8 -8 readyos-v0.2.5y-solo-d64-a.d64 -autostart readyos-v0.2.5y-solo-d64-a-preboot.prg
+```
+
+## Boot
+
+- This profile uses the direct boot chain `PREBOOT -> BOOT`.
+- There is no `SETD71` stage for this variant.
+- Attach the single disk on drive `8`, then autostart `readyos-v0.2.5y-solo-d64-a-preboot.prg` or run `LOAD "PREBOOT",8` then `RUN`.
+
+## C64 Ultimate
+
+- Copy the listed disk image files to the target storage.
+- Enable the REU with at least `1MB`; use `8MB` or `16MB` where available.
+- The host-side boot PRGs are optional convenience files for emulator launching; the disk-side `PREBOOT` entry is the standard hardware boot path.
+- Choosing a disk SKU does not enable the experimental Ultimate DOS DMA launcher. Normal release artifacts use the portable disk loader; DMA requires an explicit `LAUNCHER_DMA_LOAD=1` source build and retains disk fallback.
+- Attach the single disk image on drive `8`, then boot with `LOAD "PREBOOT",8` and `RUN`.
+- This variant boots directly from `PREBOOT` into `BOOT` and does not use `SETD71`.
+
diff --git a/Releases/0.2.5/precog-solo-d64-a/helpme.md b/Releases/0.2.5/precog-solo-d64-a/helpme.md
new file mode 100644
index 0000000..35bdf8d
--- /dev/null
+++ b/Releases/0.2.5/precog-solo-d64-a/helpme.md
@@ -0,0 +1,52 @@
+# precog (solo d64 subset a)
+
+- Release Line: `0.2.5`
+- Artifact Build: `0.2.5Y`
+- Kind: `solo-d64-a`
+
+## Why This Variant Exists
+
+- Single-D64 subset focused on editor, reference, and dizzy for one-disk-only environments.
+
+## Artifacts
+
+- Drive 8: `readyos-v0.2.5y-solo-d64-a.d64`
+- Host-Side Boot PRG: `readyos-v0.2.5y-solo-d64-a-preboot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.5y-solo-d64-a-boot.prg`
+
+## Included Apps
+
+- Drive 8: `editor` - editor
+- Drive 8: `hexview` - hex viewer
+- Drive 8: `readme` - read.me
+- Drive 8: `dizzy` - dizzy kanban
+
+## VICE Setup
+
+- Enable REU with at least `1MB`; `8MB` or `16MB` is recommended where available.
+- The host-side boot PRGs are convenience autostart files. The disk copy of `PREBOOT` is still the normal disk-side bootstrap.
+- Configure drive 8 as `1541` with true drive enabled and attach `readyos-v0.2.5y-solo-d64-a.d64`.
+
+### VICE Command Example
+
+- Autostart target: `readyos-v0.2.5y-solo-d64-a-preboot.prg`
+
+```sh
+x64sc -reu -reusize 16384 -drive8type 1541 -drive8truedrive -devicebackend8 0 +busdevice8 -8 readyos-v0.2.5y-solo-d64-a.d64 -autostart readyos-v0.2.5y-solo-d64-a-preboot.prg
+```
+
+## Boot
+
+- This profile uses the direct boot chain `PREBOOT -> BOOT`.
+- There is no `SETD71` stage for this variant.
+- Attach the single disk on drive `8`, then autostart `readyos-v0.2.5y-solo-d64-a-preboot.prg` or run `LOAD "PREBOOT",8` then `RUN`.
+
+## C64 Ultimate
+
+- Copy the listed disk image files to the target storage.
+- Enable the REU with at least `1MB`; use `8MB` or `16MB` where available.
+- The host-side boot PRGs are optional convenience files for emulator launching; the disk-side `PREBOOT` entry is the standard hardware boot path.
+- Choosing a disk SKU does not enable the experimental Ultimate DOS DMA launcher. Normal release artifacts use the portable disk loader; DMA requires an explicit `LAUNCHER_DMA_LOAD=1` source build and retains disk fallback.
+- Attach the single disk image on drive `8`, then boot with `LOAD "PREBOOT",8` and `RUN`.
+- This variant boots directly from `PREBOOT` into `BOOT` and does not use `SETD71`.
+
diff --git a/Releases/0.2.5/precog-solo-d64-a/manifest.json b/Releases/0.2.5/precog-solo-d64-a/manifest.json
new file mode 100644
index 0000000..acb0a7a
--- /dev/null
+++ b/Releases/0.2.5/precog-solo-d64-a/manifest.json
@@ -0,0 +1,62 @@
+{
+ "id": "precog-solo-d64-a",
+ "display_name": "precog (solo d64 subset a)",
+ "kind": "solo-d64-a",
+ "variant_boot_name": "precog solo d64 subset a",
+ "version_text": "0.2.5Y",
+ "reu_size_kb": 16384,
+ "catalog_source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/cfg/profiles/precog-solo-d64-a.ini",
+ "autostart_prg": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-solo-d64-a/readyos-v0.2.5y-solo-d64-a-preboot.prg",
+ "autostart_disk_prg": "preboot.prg",
+ "preboot_mode": "boot",
+ "disks": [
+ {
+ "index": 1,
+ "drive": 8,
+ "image_type": "d64",
+ "vice_drive_type": "1541",
+ "true_drive": true,
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-solo-d64-a/readyos-v0.2.5y-solo-d64-a.d64"
+ }
+ ],
+ "boot_prgs": [
+ {
+ "stem": "preboot",
+ "disk_name": "preboot",
+ "source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/preboot.prg",
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-solo-d64-a/readyos-v0.2.5y-solo-d64-a-preboot.prg"
+ },
+ {
+ "stem": "boot",
+ "disk_name": "boot",
+ "source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/boot.prg",
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-solo-d64-a/readyos-v0.2.5y-solo-d64-a-boot.prg"
+ }
+ ],
+ "apps": [
+ {
+ "drive": 8,
+ "prg": "editor",
+ "label": "editor",
+ "desc": "text editor with clipboard"
+ },
+ {
+ "drive": 8,
+ "prg": "hexview",
+ "label": "hex viewer",
+ "desc": "browse memory in hex format"
+ },
+ {
+ "drive": 8,
+ "prg": "readme",
+ "label": "read.me",
+ "desc": "readyos, ultimate buddy, precog poc os"
+ },
+ {
+ "drive": 8,
+ "prg": "dizzy",
+ "label": "dizzy kanban",
+ "desc": "fizzy inspired kanban app"
+ }
+ ]
+}
diff --git a/Releases/0.2.5/precog-solo-d64-a/readyos-v0.2.5i-solo-d64-a-boot.prg b/Releases/0.2.5/precog-solo-d64-a/readyos-v0.2.5i-solo-d64-a-boot.prg
new file mode 100644
index 0000000..c3e2a97
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-a/readyos-v0.2.5i-solo-d64-a-boot.prg differ
diff --git a/Releases/0.2.5/precog-solo-d64-a/readyos-v0.2.5i-solo-d64-a-preboot.prg b/Releases/0.2.5/precog-solo-d64-a/readyos-v0.2.5i-solo-d64-a-preboot.prg
new file mode 100644
index 0000000..67aec11
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-a/readyos-v0.2.5i-solo-d64-a-preboot.prg differ
diff --git a/Releases/0.2.5/precog-solo-d64-a/readyos-v0.2.5i-solo-d64-a.d64 b/Releases/0.2.5/precog-solo-d64-a/readyos-v0.2.5i-solo-d64-a.d64
new file mode 100644
index 0000000..d068426
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-a/readyos-v0.2.5i-solo-d64-a.d64 differ
diff --git a/Releases/0.2.5/precog-solo-d64-a/readyos-v0.2.5y-solo-d64-a-boot.prg b/Releases/0.2.5/precog-solo-d64-a/readyos-v0.2.5y-solo-d64-a-boot.prg
new file mode 100644
index 0000000..b1ef748
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-a/readyos-v0.2.5y-solo-d64-a-boot.prg differ
diff --git a/Releases/0.2.5/precog-solo-d64-a/readyos-v0.2.5y-solo-d64-a-preboot.prg b/Releases/0.2.5/precog-solo-d64-a/readyos-v0.2.5y-solo-d64-a-preboot.prg
new file mode 100644
index 0000000..67aec11
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-a/readyos-v0.2.5y-solo-d64-a-preboot.prg differ
diff --git a/Releases/0.2.5/precog-solo-d64-a/readyos-v0.2.5y-solo-d64-a.d64 b/Releases/0.2.5/precog-solo-d64-a/readyos-v0.2.5y-solo-d64-a.d64
new file mode 100644
index 0000000..ef21d03
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-a/readyos-v0.2.5y-solo-d64-a.d64 differ
diff --git a/Releases/0.2.5/precog-solo-d64-b/help.md b/Releases/0.2.5/precog-solo-d64-b/help.md
new file mode 100644
index 0000000..027c41b
--- /dev/null
+++ b/Releases/0.2.5/precog-solo-d64-b/help.md
@@ -0,0 +1,51 @@
+# precog (solo d64 subset b)
+
+- Release Line: `0.2.5`
+- Artifact Build: `0.2.5Y`
+- Kind: `solo-d64-b`
+
+## Why This Variant Exists
+
+- Single-D64 productivity subset centered on quicknotes, clipboard, calculator, and files.
+
+## Artifacts
+
+- Drive 8: `readyos-v0.2.5y-solo-d64-b.d64`
+- Host-Side Boot PRG: `readyos-v0.2.5y-solo-d64-b-preboot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.5y-solo-d64-b-boot.prg`
+
+## Included Apps
+
+- Drive 8: `simplefiles` - simple files
+- Drive 8: `clipmgr` - clipboard
+- Drive 8: `quicknotes` - quicknotes
+
+## VICE Setup
+
+- Enable REU with at least `1MB`; `8MB` or `16MB` is recommended where available.
+- The host-side boot PRGs are convenience autostart files. The disk copy of `PREBOOT` is still the normal disk-side bootstrap.
+- Configure drive 8 as `1541` with true drive enabled and attach `readyos-v0.2.5y-solo-d64-b.d64`.
+
+### VICE Command Example
+
+- Autostart target: `readyos-v0.2.5y-solo-d64-b-preboot.prg`
+
+```sh
+x64sc -reu -reusize 16384 -drive8type 1541 -drive8truedrive -devicebackend8 0 +busdevice8 -8 readyos-v0.2.5y-solo-d64-b.d64 -autostart readyos-v0.2.5y-solo-d64-b-preboot.prg
+```
+
+## Boot
+
+- This profile uses the direct boot chain `PREBOOT -> BOOT`.
+- There is no `SETD71` stage for this variant.
+- Attach the single disk on drive `8`, then autostart `readyos-v0.2.5y-solo-d64-b-preboot.prg` or run `LOAD "PREBOOT",8` then `RUN`.
+
+## C64 Ultimate
+
+- Copy the listed disk image files to the target storage.
+- Enable the REU with at least `1MB`; use `8MB` or `16MB` where available.
+- The host-side boot PRGs are optional convenience files for emulator launching; the disk-side `PREBOOT` entry is the standard hardware boot path.
+- Choosing a disk SKU does not enable the experimental Ultimate DOS DMA launcher. Normal release artifacts use the portable disk loader; DMA requires an explicit `LAUNCHER_DMA_LOAD=1` source build and retains disk fallback.
+- Attach the single disk image on drive `8`, then boot with `LOAD "PREBOOT",8` and `RUN`.
+- This variant boots directly from `PREBOOT` into `BOOT` and does not use `SETD71`.
+
diff --git a/Releases/0.2.5/precog-solo-d64-b/helpme.md b/Releases/0.2.5/precog-solo-d64-b/helpme.md
new file mode 100644
index 0000000..027c41b
--- /dev/null
+++ b/Releases/0.2.5/precog-solo-d64-b/helpme.md
@@ -0,0 +1,51 @@
+# precog (solo d64 subset b)
+
+- Release Line: `0.2.5`
+- Artifact Build: `0.2.5Y`
+- Kind: `solo-d64-b`
+
+## Why This Variant Exists
+
+- Single-D64 productivity subset centered on quicknotes, clipboard, calculator, and files.
+
+## Artifacts
+
+- Drive 8: `readyos-v0.2.5y-solo-d64-b.d64`
+- Host-Side Boot PRG: `readyos-v0.2.5y-solo-d64-b-preboot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.5y-solo-d64-b-boot.prg`
+
+## Included Apps
+
+- Drive 8: `simplefiles` - simple files
+- Drive 8: `clipmgr` - clipboard
+- Drive 8: `quicknotes` - quicknotes
+
+## VICE Setup
+
+- Enable REU with at least `1MB`; `8MB` or `16MB` is recommended where available.
+- The host-side boot PRGs are convenience autostart files. The disk copy of `PREBOOT` is still the normal disk-side bootstrap.
+- Configure drive 8 as `1541` with true drive enabled and attach `readyos-v0.2.5y-solo-d64-b.d64`.
+
+### VICE Command Example
+
+- Autostart target: `readyos-v0.2.5y-solo-d64-b-preboot.prg`
+
+```sh
+x64sc -reu -reusize 16384 -drive8type 1541 -drive8truedrive -devicebackend8 0 +busdevice8 -8 readyos-v0.2.5y-solo-d64-b.d64 -autostart readyos-v0.2.5y-solo-d64-b-preboot.prg
+```
+
+## Boot
+
+- This profile uses the direct boot chain `PREBOOT -> BOOT`.
+- There is no `SETD71` stage for this variant.
+- Attach the single disk on drive `8`, then autostart `readyos-v0.2.5y-solo-d64-b-preboot.prg` or run `LOAD "PREBOOT",8` then `RUN`.
+
+## C64 Ultimate
+
+- Copy the listed disk image files to the target storage.
+- Enable the REU with at least `1MB`; use `8MB` or `16MB` where available.
+- The host-side boot PRGs are optional convenience files for emulator launching; the disk-side `PREBOOT` entry is the standard hardware boot path.
+- Choosing a disk SKU does not enable the experimental Ultimate DOS DMA launcher. Normal release artifacts use the portable disk loader; DMA requires an explicit `LAUNCHER_DMA_LOAD=1` source build and retains disk fallback.
+- Attach the single disk image on drive `8`, then boot with `LOAD "PREBOOT",8` and `RUN`.
+- This variant boots directly from `PREBOOT` into `BOOT` and does not use `SETD71`.
+
diff --git a/Releases/0.2.5/precog-solo-d64-b/manifest.json b/Releases/0.2.5/precog-solo-d64-b/manifest.json
new file mode 100644
index 0000000..ad46c53
--- /dev/null
+++ b/Releases/0.2.5/precog-solo-d64-b/manifest.json
@@ -0,0 +1,56 @@
+{
+ "id": "precog-solo-d64-b",
+ "display_name": "precog (solo d64 subset b)",
+ "kind": "solo-d64-b",
+ "variant_boot_name": "precog solo d64 subset b",
+ "version_text": "0.2.5Y",
+ "reu_size_kb": 16384,
+ "catalog_source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/cfg/profiles/precog-solo-d64-b.ini",
+ "autostart_prg": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-solo-d64-b/readyos-v0.2.5y-solo-d64-b-preboot.prg",
+ "autostart_disk_prg": "preboot.prg",
+ "preboot_mode": "boot",
+ "disks": [
+ {
+ "index": 1,
+ "drive": 8,
+ "image_type": "d64",
+ "vice_drive_type": "1541",
+ "true_drive": true,
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-solo-d64-b/readyos-v0.2.5y-solo-d64-b.d64"
+ }
+ ],
+ "boot_prgs": [
+ {
+ "stem": "preboot",
+ "disk_name": "preboot",
+ "source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/preboot.prg",
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-solo-d64-b/readyos-v0.2.5y-solo-d64-b-preboot.prg"
+ },
+ {
+ "stem": "boot",
+ "disk_name": "boot",
+ "source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/boot.prg",
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-solo-d64-b/readyos-v0.2.5y-solo-d64-b-boot.prg"
+ }
+ ],
+ "apps": [
+ {
+ "drive": 8,
+ "prg": "simplefiles",
+ "label": "simple files",
+ "desc": "dual pane file manager and seq viewer"
+ },
+ {
+ "drive": 8,
+ "prg": "clipmgr",
+ "label": "clipboard",
+ "desc": "manage clipboard items"
+ },
+ {
+ "drive": 8,
+ "prg": "quicknotes",
+ "label": "quicknotes",
+ "desc": "reu-backed note editor"
+ }
+ ]
+}
diff --git a/Releases/0.2.5/precog-solo-d64-b/readyos-v0.2.5i-solo-d64-b-boot.prg b/Releases/0.2.5/precog-solo-d64-b/readyos-v0.2.5i-solo-d64-b-boot.prg
new file mode 100644
index 0000000..713e823
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-b/readyos-v0.2.5i-solo-d64-b-boot.prg differ
diff --git a/Releases/0.2.5/precog-solo-d64-b/readyos-v0.2.5i-solo-d64-b-preboot.prg b/Releases/0.2.5/precog-solo-d64-b/readyos-v0.2.5i-solo-d64-b-preboot.prg
new file mode 100644
index 0000000..67aec11
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-b/readyos-v0.2.5i-solo-d64-b-preboot.prg differ
diff --git a/Releases/0.2.5/precog-solo-d64-b/readyos-v0.2.5i-solo-d64-b.d64 b/Releases/0.2.5/precog-solo-d64-b/readyos-v0.2.5i-solo-d64-b.d64
new file mode 100644
index 0000000..c5599f0
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-b/readyos-v0.2.5i-solo-d64-b.d64 differ
diff --git a/Releases/0.2.5/precog-solo-d64-b/readyos-v0.2.5y-solo-d64-b-boot.prg b/Releases/0.2.5/precog-solo-d64-b/readyos-v0.2.5y-solo-d64-b-boot.prg
new file mode 100644
index 0000000..d77f97c
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-b/readyos-v0.2.5y-solo-d64-b-boot.prg differ
diff --git a/Releases/0.2.5/precog-solo-d64-b/readyos-v0.2.5y-solo-d64-b-preboot.prg b/Releases/0.2.5/precog-solo-d64-b/readyos-v0.2.5y-solo-d64-b-preboot.prg
new file mode 100644
index 0000000..67aec11
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-b/readyos-v0.2.5y-solo-d64-b-preboot.prg differ
diff --git a/Releases/0.2.5/precog-solo-d64-b/readyos-v0.2.5y-solo-d64-b.d64 b/Releases/0.2.5/precog-solo-d64-b/readyos-v0.2.5y-solo-d64-b.d64
new file mode 100644
index 0000000..7cc88dc
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-b/readyos-v0.2.5y-solo-d64-b.d64 differ
diff --git a/Releases/0.2.5/precog-solo-d64-c/help.md b/Releases/0.2.5/precog-solo-d64-c/help.md
new file mode 100644
index 0000000..1a5e509
--- /dev/null
+++ b/Releases/0.2.5/precog-solo-d64-c/help.md
@@ -0,0 +1,52 @@
+# precog (solo d64 subset c)
+
+- Release Line: `0.2.5`
+- Artifact Build: `0.2.5Y`
+- Kind: `solo-d64-c`
+
+## Why This Variant Exists
+
+- Single-D64 planning subset centered on tasklist, calendar, and REU viewer.
+
+## Artifacts
+
+- Drive 8: `readyos-v0.2.5y-solo-d64-c.d64`
+- Host-Side Boot PRG: `readyos-v0.2.5y-solo-d64-c-preboot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.5y-solo-d64-c-boot.prg`
+
+## Included Apps
+
+- Drive 8: `cal26` - calendar 26
+- Drive 8: `tasklist` - task list
+- Drive 8: `reuviewer` - reu viewer
+- Drive 8: `sysinfo` - system info
+
+## VICE Setup
+
+- Enable REU with at least `1MB`; `8MB` or `16MB` is recommended where available.
+- The host-side boot PRGs are convenience autostart files. The disk copy of `PREBOOT` is still the normal disk-side bootstrap.
+- Configure drive 8 as `1541` with true drive enabled and attach `readyos-v0.2.5y-solo-d64-c.d64`.
+
+### VICE Command Example
+
+- Autostart target: `readyos-v0.2.5y-solo-d64-c-preboot.prg`
+
+```sh
+x64sc -reu -reusize 16384 -drive8type 1541 -drive8truedrive -devicebackend8 0 +busdevice8 -8 readyos-v0.2.5y-solo-d64-c.d64 -autostart readyos-v0.2.5y-solo-d64-c-preboot.prg
+```
+
+## Boot
+
+- This profile uses the direct boot chain `PREBOOT -> BOOT`.
+- There is no `SETD71` stage for this variant.
+- Attach the single disk on drive `8`, then autostart `readyos-v0.2.5y-solo-d64-c-preboot.prg` or run `LOAD "PREBOOT",8` then `RUN`.
+
+## C64 Ultimate
+
+- Copy the listed disk image files to the target storage.
+- Enable the REU with at least `1MB`; use `8MB` or `16MB` where available.
+- The host-side boot PRGs are optional convenience files for emulator launching; the disk-side `PREBOOT` entry is the standard hardware boot path.
+- Choosing a disk SKU does not enable the experimental Ultimate DOS DMA launcher. Normal release artifacts use the portable disk loader; DMA requires an explicit `LAUNCHER_DMA_LOAD=1` source build and retains disk fallback.
+- Attach the single disk image on drive `8`, then boot with `LOAD "PREBOOT",8` and `RUN`.
+- This variant boots directly from `PREBOOT` into `BOOT` and does not use `SETD71`.
+
diff --git a/Releases/0.2.5/precog-solo-d64-c/helpme.md b/Releases/0.2.5/precog-solo-d64-c/helpme.md
new file mode 100644
index 0000000..1a5e509
--- /dev/null
+++ b/Releases/0.2.5/precog-solo-d64-c/helpme.md
@@ -0,0 +1,52 @@
+# precog (solo d64 subset c)
+
+- Release Line: `0.2.5`
+- Artifact Build: `0.2.5Y`
+- Kind: `solo-d64-c`
+
+## Why This Variant Exists
+
+- Single-D64 planning subset centered on tasklist, calendar, and REU viewer.
+
+## Artifacts
+
+- Drive 8: `readyos-v0.2.5y-solo-d64-c.d64`
+- Host-Side Boot PRG: `readyos-v0.2.5y-solo-d64-c-preboot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.5y-solo-d64-c-boot.prg`
+
+## Included Apps
+
+- Drive 8: `cal26` - calendar 26
+- Drive 8: `tasklist` - task list
+- Drive 8: `reuviewer` - reu viewer
+- Drive 8: `sysinfo` - system info
+
+## VICE Setup
+
+- Enable REU with at least `1MB`; `8MB` or `16MB` is recommended where available.
+- The host-side boot PRGs are convenience autostart files. The disk copy of `PREBOOT` is still the normal disk-side bootstrap.
+- Configure drive 8 as `1541` with true drive enabled and attach `readyos-v0.2.5y-solo-d64-c.d64`.
+
+### VICE Command Example
+
+- Autostart target: `readyos-v0.2.5y-solo-d64-c-preboot.prg`
+
+```sh
+x64sc -reu -reusize 16384 -drive8type 1541 -drive8truedrive -devicebackend8 0 +busdevice8 -8 readyos-v0.2.5y-solo-d64-c.d64 -autostart readyos-v0.2.5y-solo-d64-c-preboot.prg
+```
+
+## Boot
+
+- This profile uses the direct boot chain `PREBOOT -> BOOT`.
+- There is no `SETD71` stage for this variant.
+- Attach the single disk on drive `8`, then autostart `readyos-v0.2.5y-solo-d64-c-preboot.prg` or run `LOAD "PREBOOT",8` then `RUN`.
+
+## C64 Ultimate
+
+- Copy the listed disk image files to the target storage.
+- Enable the REU with at least `1MB`; use `8MB` or `16MB` where available.
+- The host-side boot PRGs are optional convenience files for emulator launching; the disk-side `PREBOOT` entry is the standard hardware boot path.
+- Choosing a disk SKU does not enable the experimental Ultimate DOS DMA launcher. Normal release artifacts use the portable disk loader; DMA requires an explicit `LAUNCHER_DMA_LOAD=1` source build and retains disk fallback.
+- Attach the single disk image on drive `8`, then boot with `LOAD "PREBOOT",8` and `RUN`.
+- This variant boots directly from `PREBOOT` into `BOOT` and does not use `SETD71`.
+
diff --git a/Releases/0.2.5/precog-solo-d64-c/manifest.json b/Releases/0.2.5/precog-solo-d64-c/manifest.json
new file mode 100644
index 0000000..6095a4b
--- /dev/null
+++ b/Releases/0.2.5/precog-solo-d64-c/manifest.json
@@ -0,0 +1,62 @@
+{
+ "id": "precog-solo-d64-c",
+ "display_name": "precog (solo d64 subset c)",
+ "kind": "solo-d64-c",
+ "variant_boot_name": "precog solo d64 subset c",
+ "version_text": "0.2.5Y",
+ "reu_size_kb": 16384,
+ "catalog_source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/cfg/profiles/precog-solo-d64-c.ini",
+ "autostart_prg": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-solo-d64-c/readyos-v0.2.5y-solo-d64-c-preboot.prg",
+ "autostart_disk_prg": "preboot.prg",
+ "preboot_mode": "boot",
+ "disks": [
+ {
+ "index": 1,
+ "drive": 8,
+ "image_type": "d64",
+ "vice_drive_type": "1541",
+ "true_drive": true,
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-solo-d64-c/readyos-v0.2.5y-solo-d64-c.d64"
+ }
+ ],
+ "boot_prgs": [
+ {
+ "stem": "preboot",
+ "disk_name": "preboot",
+ "source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/preboot.prg",
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-solo-d64-c/readyos-v0.2.5y-solo-d64-c-preboot.prg"
+ },
+ {
+ "stem": "boot",
+ "disk_name": "boot",
+ "source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/boot.prg",
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-solo-d64-c/readyos-v0.2.5y-solo-d64-c-boot.prg"
+ }
+ ],
+ "apps": [
+ {
+ "drive": 8,
+ "prg": "cal26",
+ "label": "calendar 26",
+ "desc": "calendar for 2026 with appointments"
+ },
+ {
+ "drive": 8,
+ "prg": "tasklist",
+ "label": "task list",
+ "desc": "outliner with notes and search"
+ },
+ {
+ "drive": 8,
+ "prg": "reuviewer",
+ "label": "reu viewer",
+ "desc": "view reu memory usage"
+ },
+ {
+ "drive": 8,
+ "prg": "sysinfo",
+ "label": "system info",
+ "desc": "system, reu, and ultimate status"
+ }
+ ]
+}
diff --git a/Releases/0.2.5/precog-solo-d64-c/readyos-v0.2.5i-solo-d64-c-boot.prg b/Releases/0.2.5/precog-solo-d64-c/readyos-v0.2.5i-solo-d64-c-boot.prg
new file mode 100644
index 0000000..6f9a6cb
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-c/readyos-v0.2.5i-solo-d64-c-boot.prg differ
diff --git a/Releases/0.2.5/precog-solo-d64-c/readyos-v0.2.5i-solo-d64-c-preboot.prg b/Releases/0.2.5/precog-solo-d64-c/readyos-v0.2.5i-solo-d64-c-preboot.prg
new file mode 100644
index 0000000..67aec11
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-c/readyos-v0.2.5i-solo-d64-c-preboot.prg differ
diff --git a/Releases/0.2.5/precog-solo-d64-c/readyos-v0.2.5i-solo-d64-c.d64 b/Releases/0.2.5/precog-solo-d64-c/readyos-v0.2.5i-solo-d64-c.d64
new file mode 100644
index 0000000..1b577e8
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-c/readyos-v0.2.5i-solo-d64-c.d64 differ
diff --git a/Releases/0.2.5/precog-solo-d64-c/readyos-v0.2.5y-solo-d64-c-boot.prg b/Releases/0.2.5/precog-solo-d64-c/readyos-v0.2.5y-solo-d64-c-boot.prg
new file mode 100644
index 0000000..a4bf45b
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-c/readyos-v0.2.5y-solo-d64-c-boot.prg differ
diff --git a/Releases/0.2.5/precog-solo-d64-c/readyos-v0.2.5y-solo-d64-c-preboot.prg b/Releases/0.2.5/precog-solo-d64-c/readyos-v0.2.5y-solo-d64-c-preboot.prg
new file mode 100644
index 0000000..67aec11
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-c/readyos-v0.2.5y-solo-d64-c-preboot.prg differ
diff --git a/Releases/0.2.5/precog-solo-d64-c/readyos-v0.2.5y-solo-d64-c.d64 b/Releases/0.2.5/precog-solo-d64-c/readyos-v0.2.5y-solo-d64-c.d64
new file mode 100644
index 0000000..032c3cc
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-c/readyos-v0.2.5y-solo-d64-c.d64 differ
diff --git a/Releases/0.2.5/precog-solo-d64-d/help.md b/Releases/0.2.5/precog-solo-d64-d/help.md
new file mode 100644
index 0000000..eaa956f
--- /dev/null
+++ b/Releases/0.2.5/precog-solo-d64-d/help.md
@@ -0,0 +1,52 @@
+# precog (solo d64 subset d)
+
+- Release Line: `0.2.5`
+- Artifact Build: `0.2.5Y`
+- Kind: `solo-d64-d`
+
+## Why This Variant Exists
+
+- Single-D64 experimental subset for simple cells, calculator, 2048, and deminer.
+
+## Artifacts
+
+- Drive 8: `readyos-v0.2.5y-solo-d64-d.d64`
+- Host-Side Boot PRG: `readyos-v0.2.5y-solo-d64-d-preboot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.5y-solo-d64-d-boot.prg`
+
+## Included Apps
+
+- Drive 8: `simplecells` - simple cells (alpha)
+- Drive 8: `calcplus` - calc plus
+- Drive 8: `game2048` - 2048 game
+- Drive 8: `deminer` - deminer
+
+## VICE Setup
+
+- Enable REU with at least `1MB`; `8MB` or `16MB` is recommended where available.
+- The host-side boot PRGs are convenience autostart files. The disk copy of `PREBOOT` is still the normal disk-side bootstrap.
+- Configure drive 8 as `1541` with true drive enabled and attach `readyos-v0.2.5y-solo-d64-d.d64`.
+
+### VICE Command Example
+
+- Autostart target: `readyos-v0.2.5y-solo-d64-d-preboot.prg`
+
+```sh
+x64sc -reu -reusize 16384 -drive8type 1541 -drive8truedrive -devicebackend8 0 +busdevice8 -8 readyos-v0.2.5y-solo-d64-d.d64 -autostart readyos-v0.2.5y-solo-d64-d-preboot.prg
+```
+
+## Boot
+
+- This profile uses the direct boot chain `PREBOOT -> BOOT`.
+- There is no `SETD71` stage for this variant.
+- Attach the single disk on drive `8`, then autostart `readyos-v0.2.5y-solo-d64-d-preboot.prg` or run `LOAD "PREBOOT",8` then `RUN`.
+
+## C64 Ultimate
+
+- Copy the listed disk image files to the target storage.
+- Enable the REU with at least `1MB`; use `8MB` or `16MB` where available.
+- The host-side boot PRGs are optional convenience files for emulator launching; the disk-side `PREBOOT` entry is the standard hardware boot path.
+- Choosing a disk SKU does not enable the experimental Ultimate DOS DMA launcher. Normal release artifacts use the portable disk loader; DMA requires an explicit `LAUNCHER_DMA_LOAD=1` source build and retains disk fallback.
+- Attach the single disk image on drive `8`, then boot with `LOAD "PREBOOT",8` and `RUN`.
+- This variant boots directly from `PREBOOT` into `BOOT` and does not use `SETD71`.
+
diff --git a/Releases/0.2.5/precog-solo-d64-d/helpme.md b/Releases/0.2.5/precog-solo-d64-d/helpme.md
new file mode 100644
index 0000000..eaa956f
--- /dev/null
+++ b/Releases/0.2.5/precog-solo-d64-d/helpme.md
@@ -0,0 +1,52 @@
+# precog (solo d64 subset d)
+
+- Release Line: `0.2.5`
+- Artifact Build: `0.2.5Y`
+- Kind: `solo-d64-d`
+
+## Why This Variant Exists
+
+- Single-D64 experimental subset for simple cells, calculator, 2048, and deminer.
+
+## Artifacts
+
+- Drive 8: `readyos-v0.2.5y-solo-d64-d.d64`
+- Host-Side Boot PRG: `readyos-v0.2.5y-solo-d64-d-preboot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.5y-solo-d64-d-boot.prg`
+
+## Included Apps
+
+- Drive 8: `simplecells` - simple cells (alpha)
+- Drive 8: `calcplus` - calc plus
+- Drive 8: `game2048` - 2048 game
+- Drive 8: `deminer` - deminer
+
+## VICE Setup
+
+- Enable REU with at least `1MB`; `8MB` or `16MB` is recommended where available.
+- The host-side boot PRGs are convenience autostart files. The disk copy of `PREBOOT` is still the normal disk-side bootstrap.
+- Configure drive 8 as `1541` with true drive enabled and attach `readyos-v0.2.5y-solo-d64-d.d64`.
+
+### VICE Command Example
+
+- Autostart target: `readyos-v0.2.5y-solo-d64-d-preboot.prg`
+
+```sh
+x64sc -reu -reusize 16384 -drive8type 1541 -drive8truedrive -devicebackend8 0 +busdevice8 -8 readyos-v0.2.5y-solo-d64-d.d64 -autostart readyos-v0.2.5y-solo-d64-d-preboot.prg
+```
+
+## Boot
+
+- This profile uses the direct boot chain `PREBOOT -> BOOT`.
+- There is no `SETD71` stage for this variant.
+- Attach the single disk on drive `8`, then autostart `readyos-v0.2.5y-solo-d64-d-preboot.prg` or run `LOAD "PREBOOT",8` then `RUN`.
+
+## C64 Ultimate
+
+- Copy the listed disk image files to the target storage.
+- Enable the REU with at least `1MB`; use `8MB` or `16MB` where available.
+- The host-side boot PRGs are optional convenience files for emulator launching; the disk-side `PREBOOT` entry is the standard hardware boot path.
+- Choosing a disk SKU does not enable the experimental Ultimate DOS DMA launcher. Normal release artifacts use the portable disk loader; DMA requires an explicit `LAUNCHER_DMA_LOAD=1` source build and retains disk fallback.
+- Attach the single disk image on drive `8`, then boot with `LOAD "PREBOOT",8` and `RUN`.
+- This variant boots directly from `PREBOOT` into `BOOT` and does not use `SETD71`.
+
diff --git a/Releases/0.2.5/precog-solo-d64-d/manifest.json b/Releases/0.2.5/precog-solo-d64-d/manifest.json
new file mode 100644
index 0000000..7095537
--- /dev/null
+++ b/Releases/0.2.5/precog-solo-d64-d/manifest.json
@@ -0,0 +1,62 @@
+{
+ "id": "precog-solo-d64-d",
+ "display_name": "precog (solo d64 subset d)",
+ "kind": "solo-d64-d",
+ "variant_boot_name": "precog solo d64 subset d",
+ "version_text": "0.2.5Y",
+ "reu_size_kb": 16384,
+ "catalog_source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/cfg/profiles/precog-solo-d64-d.ini",
+ "autostart_prg": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-solo-d64-d/readyos-v0.2.5y-solo-d64-d-preboot.prg",
+ "autostart_disk_prg": "preboot.prg",
+ "preboot_mode": "boot",
+ "disks": [
+ {
+ "index": 1,
+ "drive": 8,
+ "image_type": "d64",
+ "vice_drive_type": "1541",
+ "true_drive": true,
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-solo-d64-d/readyos-v0.2.5y-solo-d64-d.d64"
+ }
+ ],
+ "boot_prgs": [
+ {
+ "stem": "preboot",
+ "disk_name": "preboot",
+ "source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/preboot.prg",
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-solo-d64-d/readyos-v0.2.5y-solo-d64-d-preboot.prg"
+ },
+ {
+ "stem": "boot",
+ "disk_name": "boot",
+ "source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/boot.prg",
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-solo-d64-d/readyos-v0.2.5y-solo-d64-d-boot.prg"
+ }
+ ],
+ "apps": [
+ {
+ "drive": 8,
+ "prg": "simplecells",
+ "label": "simple cells (alpha)",
+ "desc": "spreadsheet with formulas and colors"
+ },
+ {
+ "drive": 8,
+ "prg": "calcplus",
+ "label": "calc plus",
+ "desc": "keyboard-first expression calculator"
+ },
+ {
+ "drive": 8,
+ "prg": "game2048",
+ "label": "2048 game",
+ "desc": "2048 tile puzzle"
+ },
+ {
+ "drive": 8,
+ "prg": "deminer",
+ "label": "deminer",
+ "desc": "minesweeper-style puzzle"
+ }
+ ]
+}
diff --git a/Releases/0.2.5/precog-solo-d64-d/readyos-v0.2.5i-solo-d64-d-boot.prg b/Releases/0.2.5/precog-solo-d64-d/readyos-v0.2.5i-solo-d64-d-boot.prg
new file mode 100644
index 0000000..ee515f3
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-d/readyos-v0.2.5i-solo-d64-d-boot.prg differ
diff --git a/Releases/0.2.5/precog-solo-d64-d/readyos-v0.2.5i-solo-d64-d-preboot.prg b/Releases/0.2.5/precog-solo-d64-d/readyos-v0.2.5i-solo-d64-d-preboot.prg
new file mode 100644
index 0000000..67aec11
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-d/readyos-v0.2.5i-solo-d64-d-preboot.prg differ
diff --git a/Releases/0.2.5/precog-solo-d64-d/readyos-v0.2.5i-solo-d64-d.d64 b/Releases/0.2.5/precog-solo-d64-d/readyos-v0.2.5i-solo-d64-d.d64
new file mode 100644
index 0000000..f2ec1c2
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-d/readyos-v0.2.5i-solo-d64-d.d64 differ
diff --git a/Releases/0.2.5/precog-solo-d64-d/readyos-v0.2.5y-solo-d64-d-boot.prg b/Releases/0.2.5/precog-solo-d64-d/readyos-v0.2.5y-solo-d64-d-boot.prg
new file mode 100644
index 0000000..481d338
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-d/readyos-v0.2.5y-solo-d64-d-boot.prg differ
diff --git a/Releases/0.2.5/precog-solo-d64-d/readyos-v0.2.5y-solo-d64-d-preboot.prg b/Releases/0.2.5/precog-solo-d64-d/readyos-v0.2.5y-solo-d64-d-preboot.prg
new file mode 100644
index 0000000..67aec11
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-d/readyos-v0.2.5y-solo-d64-d-preboot.prg differ
diff --git a/Releases/0.2.5/precog-solo-d64-d/readyos-v0.2.5y-solo-d64-d.d64 b/Releases/0.2.5/precog-solo-d64-d/readyos-v0.2.5y-solo-d64-d.d64
new file mode 100644
index 0000000..7c730db
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-d/readyos-v0.2.5y-solo-d64-d.d64 differ
diff --git a/Releases/0.2.5/precog-solo-d64-e-rsdebug/help.md b/Releases/0.2.5/precog-solo-d64-e-rsdebug/help.md
new file mode 100644
index 0000000..29f513d
--- /dev/null
+++ b/Releases/0.2.5/precog-solo-d64-e-rsdebug/help.md
@@ -0,0 +1,49 @@
+# precog (solo d64 subset e, readyshell debug trace)
+
+- Release Line: `0.2.5`
+- Artifact Build: `0.2.5Y`
+- Kind: `solo-d64-e`
+
+## Why This Variant Exists
+
+- Single-D64 shell-focused subset for readyshell and its overlay payloads in one-disk-only environments.
+
+## Artifacts
+
+- Drive 8: `readyos-v0.2.5y-solo-d64-e.d64`
+- Host-Side Boot PRG: `readyos-v0.2.5y-solo-d64-e-preboot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.5y-solo-d64-e-boot.prg`
+
+## Included Apps
+
+- Drive 8: `readyshell` - readyshell (beta)
+
+## VICE Setup
+
+- Enable REU with at least `1MB`; `8MB` or `16MB` is recommended where available.
+- The host-side boot PRGs are convenience autostart files. The disk copy of `PREBOOT` is still the normal disk-side bootstrap.
+- Configure drive 8 as `1541` with true drive enabled and attach `readyos-v0.2.5y-solo-d64-e.d64`.
+
+### VICE Command Example
+
+- Autostart target: `readyos-v0.2.5y-solo-d64-e-preboot.prg`
+
+```sh
+x64sc -reu -reusize 16384 -drive8type 1541 -drive8truedrive -devicebackend8 0 +busdevice8 -8 readyos-v0.2.5y-solo-d64-e.d64 -autostart readyos-v0.2.5y-solo-d64-e-preboot.prg
+```
+
+## Boot
+
+- This profile uses the direct boot chain `PREBOOT -> BOOT`.
+- There is no `SETD71` stage for this variant.
+- Attach the single disk on drive `8`, then autostart `readyos-v0.2.5y-solo-d64-e-preboot.prg` or run `LOAD "PREBOOT",8` then `RUN`.
+
+## C64 Ultimate
+
+- Copy the listed disk image files to the target storage.
+- Enable the REU with at least `1MB`; use `8MB` or `16MB` where available.
+- The host-side boot PRGs are optional convenience files for emulator launching; the disk-side `PREBOOT` entry is the standard hardware boot path.
+- Choosing a disk SKU does not enable the experimental Ultimate DOS DMA launcher. Normal release artifacts use the portable disk loader; DMA requires an explicit `LAUNCHER_DMA_LOAD=1` source build and retains disk fallback.
+- Attach the single disk image on drive `8`, then boot with `LOAD "PREBOOT",8` and `RUN`.
+- This variant boots directly from `PREBOOT` into `BOOT` and does not use `SETD71`.
+
diff --git a/Releases/0.2.5/precog-solo-d64-e-rsdebug/helpme.md b/Releases/0.2.5/precog-solo-d64-e-rsdebug/helpme.md
new file mode 100644
index 0000000..29f513d
--- /dev/null
+++ b/Releases/0.2.5/precog-solo-d64-e-rsdebug/helpme.md
@@ -0,0 +1,49 @@
+# precog (solo d64 subset e, readyshell debug trace)
+
+- Release Line: `0.2.5`
+- Artifact Build: `0.2.5Y`
+- Kind: `solo-d64-e`
+
+## Why This Variant Exists
+
+- Single-D64 shell-focused subset for readyshell and its overlay payloads in one-disk-only environments.
+
+## Artifacts
+
+- Drive 8: `readyos-v0.2.5y-solo-d64-e.d64`
+- Host-Side Boot PRG: `readyos-v0.2.5y-solo-d64-e-preboot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.5y-solo-d64-e-boot.prg`
+
+## Included Apps
+
+- Drive 8: `readyshell` - readyshell (beta)
+
+## VICE Setup
+
+- Enable REU with at least `1MB`; `8MB` or `16MB` is recommended where available.
+- The host-side boot PRGs are convenience autostart files. The disk copy of `PREBOOT` is still the normal disk-side bootstrap.
+- Configure drive 8 as `1541` with true drive enabled and attach `readyos-v0.2.5y-solo-d64-e.d64`.
+
+### VICE Command Example
+
+- Autostart target: `readyos-v0.2.5y-solo-d64-e-preboot.prg`
+
+```sh
+x64sc -reu -reusize 16384 -drive8type 1541 -drive8truedrive -devicebackend8 0 +busdevice8 -8 readyos-v0.2.5y-solo-d64-e.d64 -autostart readyos-v0.2.5y-solo-d64-e-preboot.prg
+```
+
+## Boot
+
+- This profile uses the direct boot chain `PREBOOT -> BOOT`.
+- There is no `SETD71` stage for this variant.
+- Attach the single disk on drive `8`, then autostart `readyos-v0.2.5y-solo-d64-e-preboot.prg` or run `LOAD "PREBOOT",8` then `RUN`.
+
+## C64 Ultimate
+
+- Copy the listed disk image files to the target storage.
+- Enable the REU with at least `1MB`; use `8MB` or `16MB` where available.
+- The host-side boot PRGs are optional convenience files for emulator launching; the disk-side `PREBOOT` entry is the standard hardware boot path.
+- Choosing a disk SKU does not enable the experimental Ultimate DOS DMA launcher. Normal release artifacts use the portable disk loader; DMA requires an explicit `LAUNCHER_DMA_LOAD=1` source build and retains disk fallback.
+- Attach the single disk image on drive `8`, then boot with `LOAD "PREBOOT",8` and `RUN`.
+- This variant boots directly from `PREBOOT` into `BOOT` and does not use `SETD71`.
+
diff --git a/Releases/0.2.5/precog-solo-d64-e-rsdebug/manifest.json b/Releases/0.2.5/precog-solo-d64-e-rsdebug/manifest.json
new file mode 100644
index 0000000..7655496
--- /dev/null
+++ b/Releases/0.2.5/precog-solo-d64-e-rsdebug/manifest.json
@@ -0,0 +1,44 @@
+{
+ "id": "precog-solo-d64-e-rsdebug",
+ "display_name": "precog (solo d64 subset e, readyshell debug trace)",
+ "kind": "solo-d64-e",
+ "variant_boot_name": "precog solo d64 subset e",
+ "version_text": "0.2.5Y",
+ "reu_size_kb": 16384,
+ "catalog_source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/cfg/profiles/precog-solo-d64-e.ini",
+ "autostart_prg": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-solo-d64-e-rsdebug/readyos-v0.2.5y-solo-d64-e-preboot.prg",
+ "autostart_disk_prg": "preboot.prg",
+ "preboot_mode": "boot",
+ "disks": [
+ {
+ "index": 1,
+ "drive": 8,
+ "image_type": "d64",
+ "vice_drive_type": "1541",
+ "true_drive": true,
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-solo-d64-e-rsdebug/readyos-v0.2.5y-solo-d64-e.d64"
+ }
+ ],
+ "boot_prgs": [
+ {
+ "stem": "preboot",
+ "disk_name": "preboot",
+ "source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/preboot.prg",
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-solo-d64-e-rsdebug/readyos-v0.2.5y-solo-d64-e-preboot.prg"
+ },
+ {
+ "stem": "boot",
+ "disk_name": "boot",
+ "source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/boot.prg",
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-solo-d64-e-rsdebug/readyos-v0.2.5y-solo-d64-e-boot.prg"
+ }
+ ],
+ "apps": [
+ {
+ "drive": 8,
+ "prg": "readyshell",
+ "label": "readyshell (beta)",
+ "desc": "overlay-backed shell command test"
+ }
+ ]
+}
diff --git a/Releases/0.2.5/precog-solo-d64-e-rsdebug/readyos-v0.2.5i-solo-d64-e-boot.prg b/Releases/0.2.5/precog-solo-d64-e-rsdebug/readyos-v0.2.5i-solo-d64-e-boot.prg
new file mode 100644
index 0000000..859e9ca
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-e-rsdebug/readyos-v0.2.5i-solo-d64-e-boot.prg differ
diff --git a/Releases/0.2.5/precog-solo-d64-e-rsdebug/readyos-v0.2.5i-solo-d64-e-preboot.prg b/Releases/0.2.5/precog-solo-d64-e-rsdebug/readyos-v0.2.5i-solo-d64-e-preboot.prg
new file mode 100644
index 0000000..67aec11
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-e-rsdebug/readyos-v0.2.5i-solo-d64-e-preboot.prg differ
diff --git a/Releases/0.2.5/precog-solo-d64-e-rsdebug/readyos-v0.2.5i-solo-d64-e.d64 b/Releases/0.2.5/precog-solo-d64-e-rsdebug/readyos-v0.2.5i-solo-d64-e.d64
new file mode 100644
index 0000000..45314e2
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-e-rsdebug/readyos-v0.2.5i-solo-d64-e.d64 differ
diff --git a/Releases/0.2.5/precog-solo-d64-e-rsdebug/readyos-v0.2.5y-solo-d64-e-boot.prg b/Releases/0.2.5/precog-solo-d64-e-rsdebug/readyos-v0.2.5y-solo-d64-e-boot.prg
new file mode 100644
index 0000000..d9ed31b
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-e-rsdebug/readyos-v0.2.5y-solo-d64-e-boot.prg differ
diff --git a/Releases/0.2.5/precog-solo-d64-e-rsdebug/readyos-v0.2.5y-solo-d64-e-preboot.prg b/Releases/0.2.5/precog-solo-d64-e-rsdebug/readyos-v0.2.5y-solo-d64-e-preboot.prg
new file mode 100644
index 0000000..67aec11
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-e-rsdebug/readyos-v0.2.5y-solo-d64-e-preboot.prg differ
diff --git a/Releases/0.2.5/precog-solo-d64-e-rsdebug/readyos-v0.2.5y-solo-d64-e.d64 b/Releases/0.2.5/precog-solo-d64-e-rsdebug/readyos-v0.2.5y-solo-d64-e.d64
new file mode 100644
index 0000000..22975ec
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-e-rsdebug/readyos-v0.2.5y-solo-d64-e.d64 differ
diff --git a/Releases/0.2.5/precog-solo-d64-e/help.md b/Releases/0.2.5/precog-solo-d64-e/help.md
new file mode 100644
index 0000000..9d3521c
--- /dev/null
+++ b/Releases/0.2.5/precog-solo-d64-e/help.md
@@ -0,0 +1,49 @@
+# precog (solo d64 subset e)
+
+- Release Line: `0.2.5`
+- Artifact Build: `0.2.5Y`
+- Kind: `solo-d64-e`
+
+## Why This Variant Exists
+
+- Single-D64 shell-focused subset for readyshell and its overlay payloads in one-disk-only environments.
+
+## Artifacts
+
+- Drive 8: `readyos-v0.2.5y-solo-d64-e.d64`
+- Host-Side Boot PRG: `readyos-v0.2.5y-solo-d64-e-preboot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.5y-solo-d64-e-boot.prg`
+
+## Included Apps
+
+- Drive 8: `readyshell` - readyshell (beta)
+
+## VICE Setup
+
+- Enable REU with at least `1MB`; `8MB` or `16MB` is recommended where available.
+- The host-side boot PRGs are convenience autostart files. The disk copy of `PREBOOT` is still the normal disk-side bootstrap.
+- Configure drive 8 as `1541` with true drive enabled and attach `readyos-v0.2.5y-solo-d64-e.d64`.
+
+### VICE Command Example
+
+- Autostart target: `readyos-v0.2.5y-solo-d64-e-preboot.prg`
+
+```sh
+x64sc -reu -reusize 16384 -drive8type 1541 -drive8truedrive -devicebackend8 0 +busdevice8 -8 readyos-v0.2.5y-solo-d64-e.d64 -autostart readyos-v0.2.5y-solo-d64-e-preboot.prg
+```
+
+## Boot
+
+- This profile uses the direct boot chain `PREBOOT -> BOOT`.
+- There is no `SETD71` stage for this variant.
+- Attach the single disk on drive `8`, then autostart `readyos-v0.2.5y-solo-d64-e-preboot.prg` or run `LOAD "PREBOOT",8` then `RUN`.
+
+## C64 Ultimate
+
+- Copy the listed disk image files to the target storage.
+- Enable the REU with at least `1MB`; use `8MB` or `16MB` where available.
+- The host-side boot PRGs are optional convenience files for emulator launching; the disk-side `PREBOOT` entry is the standard hardware boot path.
+- Choosing a disk SKU does not enable the experimental Ultimate DOS DMA launcher. Normal release artifacts use the portable disk loader; DMA requires an explicit `LAUNCHER_DMA_LOAD=1` source build and retains disk fallback.
+- Attach the single disk image on drive `8`, then boot with `LOAD "PREBOOT",8` and `RUN`.
+- This variant boots directly from `PREBOOT` into `BOOT` and does not use `SETD71`.
+
diff --git a/Releases/0.2.5/precog-solo-d64-e/helpme.md b/Releases/0.2.5/precog-solo-d64-e/helpme.md
new file mode 100644
index 0000000..9d3521c
--- /dev/null
+++ b/Releases/0.2.5/precog-solo-d64-e/helpme.md
@@ -0,0 +1,49 @@
+# precog (solo d64 subset e)
+
+- Release Line: `0.2.5`
+- Artifact Build: `0.2.5Y`
+- Kind: `solo-d64-e`
+
+## Why This Variant Exists
+
+- Single-D64 shell-focused subset for readyshell and its overlay payloads in one-disk-only environments.
+
+## Artifacts
+
+- Drive 8: `readyos-v0.2.5y-solo-d64-e.d64`
+- Host-Side Boot PRG: `readyos-v0.2.5y-solo-d64-e-preboot.prg`
+- Host-Side Boot PRG: `readyos-v0.2.5y-solo-d64-e-boot.prg`
+
+## Included Apps
+
+- Drive 8: `readyshell` - readyshell (beta)
+
+## VICE Setup
+
+- Enable REU with at least `1MB`; `8MB` or `16MB` is recommended where available.
+- The host-side boot PRGs are convenience autostart files. The disk copy of `PREBOOT` is still the normal disk-side bootstrap.
+- Configure drive 8 as `1541` with true drive enabled and attach `readyos-v0.2.5y-solo-d64-e.d64`.
+
+### VICE Command Example
+
+- Autostart target: `readyos-v0.2.5y-solo-d64-e-preboot.prg`
+
+```sh
+x64sc -reu -reusize 16384 -drive8type 1541 -drive8truedrive -devicebackend8 0 +busdevice8 -8 readyos-v0.2.5y-solo-d64-e.d64 -autostart readyos-v0.2.5y-solo-d64-e-preboot.prg
+```
+
+## Boot
+
+- This profile uses the direct boot chain `PREBOOT -> BOOT`.
+- There is no `SETD71` stage for this variant.
+- Attach the single disk on drive `8`, then autostart `readyos-v0.2.5y-solo-d64-e-preboot.prg` or run `LOAD "PREBOOT",8` then `RUN`.
+
+## C64 Ultimate
+
+- Copy the listed disk image files to the target storage.
+- Enable the REU with at least `1MB`; use `8MB` or `16MB` where available.
+- The host-side boot PRGs are optional convenience files for emulator launching; the disk-side `PREBOOT` entry is the standard hardware boot path.
+- Choosing a disk SKU does not enable the experimental Ultimate DOS DMA launcher. Normal release artifacts use the portable disk loader; DMA requires an explicit `LAUNCHER_DMA_LOAD=1` source build and retains disk fallback.
+- Attach the single disk image on drive `8`, then boot with `LOAD "PREBOOT",8` and `RUN`.
+- This variant boots directly from `PREBOOT` into `BOOT` and does not use `SETD71`.
+
diff --git a/Releases/0.2.5/precog-solo-d64-e/manifest.json b/Releases/0.2.5/precog-solo-d64-e/manifest.json
new file mode 100644
index 0000000..ab11b83
--- /dev/null
+++ b/Releases/0.2.5/precog-solo-d64-e/manifest.json
@@ -0,0 +1,44 @@
+{
+ "id": "precog-solo-d64-e",
+ "display_name": "precog (solo d64 subset e)",
+ "kind": "solo-d64-e",
+ "variant_boot_name": "precog solo d64 subset e",
+ "version_text": "0.2.5Y",
+ "reu_size_kb": 16384,
+ "catalog_source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/cfg/profiles/precog-solo-d64-e.ini",
+ "autostart_prg": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-solo-d64-e/readyos-v0.2.5y-solo-d64-e-preboot.prg",
+ "autostart_disk_prg": "preboot.prg",
+ "preboot_mode": "boot",
+ "disks": [
+ {
+ "index": 1,
+ "drive": 8,
+ "image_type": "d64",
+ "vice_drive_type": "1541",
+ "true_drive": true,
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-solo-d64-e/readyos-v0.2.5y-solo-d64-e.d64"
+ }
+ ],
+ "boot_prgs": [
+ {
+ "stem": "preboot",
+ "disk_name": "preboot",
+ "source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/preboot.prg",
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-solo-d64-e/readyos-v0.2.5y-solo-d64-e-preboot.prg"
+ },
+ {
+ "stem": "boot",
+ "disk_name": "boot",
+ "source": "/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/boot.prg",
+ "path": "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-solo-d64-e/readyos-v0.2.5y-solo-d64-e-boot.prg"
+ }
+ ],
+ "apps": [
+ {
+ "drive": 8,
+ "prg": "readyshell",
+ "label": "readyshell (beta)",
+ "desc": "overlay-backed shell command test"
+ }
+ ]
+}
diff --git a/Releases/0.2.5/precog-solo-d64-e/readyos-v0.2.5i-solo-d64-e-boot.prg b/Releases/0.2.5/precog-solo-d64-e/readyos-v0.2.5i-solo-d64-e-boot.prg
new file mode 100644
index 0000000..859e9ca
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-e/readyos-v0.2.5i-solo-d64-e-boot.prg differ
diff --git a/Releases/0.2.5/precog-solo-d64-e/readyos-v0.2.5i-solo-d64-e-preboot.prg b/Releases/0.2.5/precog-solo-d64-e/readyos-v0.2.5i-solo-d64-e-preboot.prg
new file mode 100644
index 0000000..67aec11
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-e/readyos-v0.2.5i-solo-d64-e-preboot.prg differ
diff --git a/Releases/0.2.5/precog-solo-d64-e/readyos-v0.2.5i-solo-d64-e.d64 b/Releases/0.2.5/precog-solo-d64-e/readyos-v0.2.5i-solo-d64-e.d64
new file mode 100644
index 0000000..81489ed
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-e/readyos-v0.2.5i-solo-d64-e.d64 differ
diff --git a/Releases/0.2.5/precog-solo-d64-e/readyos-v0.2.5y-solo-d64-e-boot.prg b/Releases/0.2.5/precog-solo-d64-e/readyos-v0.2.5y-solo-d64-e-boot.prg
new file mode 100644
index 0000000..d9ed31b
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-e/readyos-v0.2.5y-solo-d64-e-boot.prg differ
diff --git a/Releases/0.2.5/precog-solo-d64-e/readyos-v0.2.5y-solo-d64-e-preboot.prg b/Releases/0.2.5/precog-solo-d64-e/readyos-v0.2.5y-solo-d64-e-preboot.prg
new file mode 100644
index 0000000..67aec11
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-e/readyos-v0.2.5y-solo-d64-e-preboot.prg differ
diff --git a/Releases/0.2.5/precog-solo-d64-e/readyos-v0.2.5y-solo-d64-e.d64 b/Releases/0.2.5/precog-solo-d64-e/readyos-v0.2.5y-solo-d64-e.d64
new file mode 100644
index 0000000..46024d0
Binary files /dev/null and b/Releases/0.2.5/precog-solo-d64-e/readyos-v0.2.5y-solo-d64-e.d64 differ
diff --git a/Releases/thec64-vice-d81/README.md b/Releases/thec64-vice-d81/README.md
index a323ac2..dc3cfdd 100644
--- a/Releases/thec64-vice-d81/README.md
+++ b/Releases/thec64-vice-d81/README.md
@@ -16,3 +16,7 @@ available. This experimental staging copy deliberately requests C64, PAL, and
- `RM` = 16 MB REU
The CJM repeats the same baseline with `X:64,pal,reu16384`, adds explicit joystick mappings so THEC64 controllers remain active, and leaves accurate disk mode off because THEC64 documents `accuratedisk` as applying to `d64`/`g64`.
+
+This staging copy uses the normal disk loader. The C64 Ultimate DOS DMA path is
+hardware-specific, opt-in at source-build time, and is not available on
+THEC64/VICE.
diff --git a/Releases/thec64-vice-easyflash/README.md b/Releases/thec64-vice-easyflash/README.md
index 75fb0b9..fd155fc 100644
--- a/Releases/thec64-vice-easyflash/README.md
+++ b/Releases/thec64-vice-easyflash/README.md
@@ -19,3 +19,7 @@ available. This experimental staging copy deliberately requests C64, PAL, and
The CJM repeats the same baseline with `X:64,pal,reu16384` and adds explicit joystick mappings so THEC64 controllers remain active. `readyos_data.d64` is included beside the cartridge for runtime app data access; the CJM cannot auto-mount it.
If an app snapshot preloaded from the cartridge is unloaded from REU, ReadyOS cannot load it again from the cartridge until you restart ReadyOS.
+
+EasyFlash uses cartridge-to-RAM-to-REU cold preload and never links the regular
+launcher's experimental Ultimate DOS DMA module. THEC64/VICE also does not
+provide the required C64 Ultimate UCI service.
diff --git a/ULTIMATEDOS_DMA_LOADING_LESSONS_LEARNT.md b/ULTIMATEDOS_DMA_LOADING_LESSONS_LEARNT.md
new file mode 100644
index 0000000..984ec38
--- /dev/null
+++ b/ULTIMATEDOS_DMA_LOADING_LESSONS_LEARNT.md
@@ -0,0 +1,1287 @@
+# Ultimate DOS DMA Loading Lessons Learnt
+
+This note records what was learned from the standalone C64 Ultimate DMA probe
+and the launcher-local DMA experiments. It is specifically about Ultimate DOS
+UCI technique; the launcher integration remains gated behind
+`LAUNCHER_DMA_LOAD=1`.
+
+> **Schema-v5 update (2026-08-02):** current main-app DMA destinations and
+> shim transfers cover `$1000-$C5FF` (`$B600`). Older `$C7FF/$B800` values in
+> dated hardware experiments below are retained only where they describe the
+> artifact tested at that time.
+
+## Current Proven Shape
+
+- Use Ultimate DOS UCI calls for the actual DMA load path.
+- Treat SoftIEC as a capability to detect/report, not as the loading transport.
+- Put the probe program and payload files inside a mounted disk image.
+- Mount the image as drive 8/A with the correct drive type (`d64` as 1541,
+ `d81` as 1581).
+- Load from the mounted image context, not from `/USB0/...` or `/USB1/...`
+ paths in the final loading path.
+- Use lowercase PETSCII directory names for probe payload files.
+- Keep ReadyOS-side launcher filenames and C64U paths as lowercase PETSCII.
+ BASIC/DOS may display those bytes as uppercase; do not normalize them to
+ shifted-uppercase PETSCII.
+- The DOS target expects ASCII file and directory bytes. For the lower-PETSCII
+ ReadyOS names used here, preserving the raw bytes sends the equivalent
+ uppercase ASCII spellings (`USB1`, `READYOS.D81`, `EDITOR`) that the C64U
+ storage view and disk entries resolve. Do not force ASCII lowercase.
+- Use fresh image names during automation to avoid stale mounted-image state.
+- Prime the launcher DMA UI state from the configured image path at launcher
+ startup. Do not show a lazy `DMA:??` state that depends on whichever action
+ happens to ask about DMA first.
+- The launcher startup check is intentionally path/config-only. A hardware run
+ that probed the UCI command-interface ID during launcher init cleared the
+ screen and never reached the first launcher draw. The actual load path still
+ probes UCI before using Ultimate DOS; startup must not touch UCI.
+
+The official Ultimate UCI documentation matters for the boundary here:
+
+- Ultimate DOS target `$01/$02` has its own current-directory and open-file
+ state. `DOS_CMD_LOAD_REU` (`$21`) reads from the currently opened Ultimate
+ DOS file; it does not name an IEC drive.
+- `DOS_CMD_COPY_UI_PATH` (`$15`) is documented as deprecated since firmware 3.0,
+ so it cannot be treated as a production bridge from "whatever is mounted as
+ drive 8" to the Ultimate DOS current directory.
+- Control `CTRL_CMD_LOAD_REU` (`$04 $08`) loads an REU image file from storage
+ into the Ultimate's REU memory. It is not an arbitrary per-file, per-offset
+ app/resource DMA loader.
+- Control `CTRL_CMD_GET_DRVINFO` (`$04 $29`) returns drive count plus
+ type/bus/power triples. It does not expose the mounted image path that the
+ launcher would need to synthesize an absolute Ultimate DOS path.
+- The hyperspeed KERNAL reference implementation
+ (`roms/c64rom/kernal/uci.s` in GideonZ/1541ultimate) is the protocol model:
+ write the target/command bytes and payload bytes to `CMD_IF_COMMAND`, push
+ the command through `CMD_IF_CONTROL`, wait for data/status state, then ack or
+ abort explicitly. The launcher micromodule follows that raw command-interface
+ pattern rather than using KERNAL or SoftIEC for the DMA transfer.
+
+The fresh D81 artifact is:
+
+```text
+build/uci_dma_probe/uci_dma_probe.d81
+sha256 f3f84122a7380635b9d30d6367893ddcab32d707b662a513b956e9fa3824be05
+```
+
+Its verified directory entries are:
+
+```text
+"probe" prg
+"udma1" prg
+"udma2" prg
+"udma3" prg
+```
+
+## Working Probe Flow
+
+The probe does this:
+
+1. Detects UCI by probing the Ultimate command interface base addresses.
+2. Reads and reports the SoftIEC bus byte.
+3. Uses Ultimate DOS commands to access files from the mounted image.
+4. Opens each payload file.
+5. Reads/verifies the PRG load address header.
+6. Seeks past the two-byte PRG header.
+7. Uses Ultimate DOS `LOAD_REU` (`$21`) to DMA payload bytes into REU.
+8. Fetches REU data back into RAM and verifies the expected byte patterns.
+9. Writes compact result bytes and screen debug output for automation capture.
+
+The current D81 C64U REST run reported:
+
+```text
+SUM USB:01 P:42 C:51 F1:55 F2:55 F3:55
+PROBE DONE
+```
+
+`F1/F2/F3 = $55` proves that the batched Ultimate DOS `LOAD_REU` flow works
+after Ultimate DOS has changed into the D81 filesystem. `P = $42` proves that a
+plain filename stat before that directory change did not resolve as a valid
+file stat, even though the same D81 was mounted as IEC drive 8/A. `C = $51`
+proves that `COPY_UI_PATH` did not return a usable success status in this
+REST-mounted D81 case, so it is not a proven pathless bridge.
+
+The C64U REST automation that proved reliable uses this discipline:
+
+- Upload the disk image by FTP.
+- Reset to BASIC before mounting.
+- Set Drive A type to match the image type.
+- Mount the image explicitly with `type=d64` or `type=d81`.
+- Reset to BASIC again after the mount.
+- Type BASIC input one byte at a time.
+- Wait for the keyboard buffer to drain between typed bytes.
+- Wait for the probe screen to show `PROBE DONE`.
+- Capture screen RAM and result buffers through REST.
+- Analyze result bytes plus RAM/REU snapshots.
+
+The VICE/dotnet sanity path is intentionally narrower:
+
+- Build the D81 and mount it as drive 8 under VICE.
+- Do not rely on `-autostart` deriving a useful filename from
+ `uci_dma_probe.prg`; that tried `LOAD"UCI.DMA.PROBE",8,1`, while the disk
+ file is named `probe`.
+- Type `LOAD"PROBE",8,1` and `RUN` through the dotnet input sequence.
+- Expect `UCI NOT FOUND` and validate the `$3000` result block as version
+ `$41`, no-UCI mode.
+- Use this only as a regression/smoke check. It cannot prove C64U Ultimate DOS
+ DMA because stock VICE does not expose the C64U UCI device.
+
+## Why Earlier Attempts Failed Or Misled Us
+
+### SoftIEC Was The Wrong Loading Path
+
+SoftIEC detection can be true on the C64U, but using SoftIEC as the load path
+was not the thing we were trying to prove. The requested path is Ultimate DOS
+DMA from files inside the mounted disk image.
+
+SoftIEC is useful as a presence/capability indicator. It should not be the
+launcher/app DMA transport unless a separate design explicitly chooses that.
+
+### D81 Needed Correct Drive-Type Handling
+
+The D81 case is more sensitive to the mounted drive type. The automation now
+sets Drive A to 1581 for D81 and mounts with `type=d81`. Relying on a generic
+mount state or a stale emulator/config assumption caused confusing failures.
+
+### Reset Timing Mattered
+
+The C64U state after mount was not always clean. The reliable automation resets
+before the mount and again after the mount before typing `LOAD"PROBE",8`.
+
+Without that, the machine could sit at BASIC, half-load, or show stale boot
+screens that looked like code failure but were really automation/state failure.
+
+### Keyboard Injection Was Too Coarse
+
+Bulk-writing the C64 keyboard buffer was unreliable on the C64U. The probe
+automation switched to one byte at a time and waits for `$C6` to drain after
+each byte.
+
+This made BASIC commands reproducible.
+
+### REST Memory Polling Can Disturb KERNAL Loads
+
+The ReadyOS C64U automation originally polled screen/RAM every second while the
+booter was still inside KERNAL `LOAD "launcher",8`. That reproduced a stable
+stuck `LOADING LAUNCHER...` screen. RAM captured during the stuck state matched
+`launcher.prg` only through C64 address `$3C08`, and a second sample did not
+advance.
+
+After adding a quiet wait before the first REST memory capture, the same normal
+`LAUNCHER_DMA_LOAD=0` D81 booted to the launcher and launched Editor. So do not
+classify a boot-screen hang from automation unless the automation avoided REST
+memory reads during active disk I/O.
+
+### Stale Image Names Hid The Real Result
+
+Reusing the same remote filename and mount state made it too easy to test an
+old D64/D81 image while thinking a new one was mounted. The probe automation
+uses distinct image names for D64 and D81 (`UCI40.D64`, `UCI41.D81`) and
+rebuilds/uploads before testing.
+
+### Case Was Easy To Misread
+
+C64 BASIC displays uppercase for text that may actually be lowercase PETSCII.
+The disk builder verifies the raw directory bytes for lowercase PETSCII names,
+not just what the screen or `c1541` display appears to say.
+
+This also applies to the launcher-side C64U image path. The launcher must
+preserve lowercase PETSCII path bytes such as `/usb1/readyos.d81` while parsing
+ReadyOS config/catalog data and while emitting the current DOS-target command
+bytes. Those byte values are valid ASCII uppercase spellings for the C64U path
+and disk entries. Converting the ReadyOS strings to shifted-uppercase PETSCII or
+ASCII lowercase is not equivalent.
+
+### Launcher Experiments Drifted From The Probe
+
+The standalone probe used the known-good Ultimate DOS sequence. A later launcher
+experiment drifted from that sequence and also introduced startup/boot noise,
+making the result hard to interpret. Launcher integration should stay directly
+aligned with the proven probe sequence, with any deviation verified on hardware.
+
+## Rules For Launcher Integration
+
+- Start from the working D81 probe sequence, not from a new interpretation.
+- Keep all launcher changes behind a small, obvious feature boundary until
+ hardware proof exists.
+- Treat the config path as the startup UI gate (`DMA:YES`/`DMA:NO`). The first
+ actual app/resource load probes UCI, performs the Ultimate DOS transaction,
+ and changes the status to `DMA:ON` only after a successful DMA load.
+- Persist the `DMA:ON` display bit through the launcher resume payload. The
+ mounted-image-ready bit stays process-local and is re-established by the next
+ Ultimate DOS load, because apps may leave the DOS target in a different
+ state.
+- When DMA is positively available, do not silently fall back to KERNAL/chunked
+ loading after an Ultimate DOS load failure. Falling back is still correct when
+ UCI is unavailable, but on C64U hardware a DMA failure must stay visible so we
+ do not confuse a slow disk preload with a working DMA preload.
+- Do not insert helper routines into the middle of the proven UCI transaction
+ code. One hardware build hung on the first cold DMA load at stage `250.3834`
+ after a helper was inserted before the DOS identify path. Moving helper code
+ to the end of the code segment restored the original transaction layout and
+ keeps future diffs easier to audit.
+- Any settle/quiesce helper should run only after a transaction path has
+ returned. It should synchronize the command interface and wait for idle; it
+ is not a startup probe and it should not touch the mount/path state.
+- Do not mark an app as loaded unless the Ultimate DOS command status and REU
+ verification path prove the data landed.
+- Keep the shim, boot, and app binaries out of scope.
+- First prove one standalone app payload, then ReadyShell overlay/resource
+ payloads, then ReadyBASIC/ReadyShell launch behavior.
+
+### Main App Snapshot Size Rule
+
+The Ultimate DOS `LOAD_REU` byte count and the ReadyOS shim restore byte count
+are different pieces of state:
+
+- `LOAD_REU` should use the exact PRG payload length reported by Ultimate DOS
+ `FILE_INFO` minus the two-byte PRG load header, after seeking to payload
+ offset 2. Loading a fixed window length from a shorter file is not a safe
+ EOF strategy.
+- For normal DMA-loaded app PRGs, the launcher records the exact payload size
+ for the shim REU launch, matching the pre-existing launcher/shim behavior.
+- A tested ReadyShell hypothesis tried clearing the full target snapshot window
+ and then asking the shim to restore the full `$B600` ReadyOS app window. On
+ C64U hardware, that moved the failure earlier: the DMA preload still reported
+ `DMA:ON`, but launching ReadyShell dropped to BASIC `READY.` instead of
+ drawing the shell UI.
+
+Current intentional guardrail:
+
+- Ultimate DOS DMA remains enabled for normal main app PRGs.
+- ReadyShell main PRG DMA is enabled when the experimental launcher is built
+ with `LAUNCHER_DMA_LOAD=1`; the top-level build gate still defaults off for
+ normal builds.
+- ReadyShell overlay/resource PRG DMA is also enabled under
+ `LAUNCHER_DMA_LOAD=1`, with KERNAL/chunked fallback if the Ultimate DOS call
+ fails.
+- This must stay covered by C64U hardware UI automation. VICE can prove normal
+ launcher behavior, but not the Ultimate DOS timing and mounted-image path.
+
+## Temporary Launcher Config Bridge
+
+The experimental launcher now has a deliberately temporary config key:
+
+```text
+[launcher]
+c64u_image_path=/usb1/readyos.d81
+```
+
+This is read from the normal `apps.cfg` path and cached inside the launcher.
+When `LAUNCHER_DMA_LOAD=1`, the launcher passes that string to the
+launcher-local Ultimate DOS micromodule before each DMA load. The current split
+for `/usb1/readyos.d81` is:
+
+1. `CHANGE_DIR /`
+2. `CHANGE_DIR /USB1`
+3. `MOUNT8 readyos.d81`
+4. `CHANGE_DIR readyos.d81`
+5. `OPEN` plain filenames such as `editor`, `readybasic`, `rsparser`, and
+ `rbcore`
+6. `READ` the two-byte PRG header and validate the expected load address
+7. `SEEK` to payload offset 2
+8. `LOAD_REU` the known destination window/slot length
+
+All names sent to the Ultimate DOS target in those commands must be ASCII
+bytes. The launcher currently preserves the ReadyOS lowercase PETSCII byte
+values because, for these names, they are also the uppercase ASCII spellings the
+C64U resolves.
+
+For the current hardware experiment, the DMA-enabled launcher also seeds the
+same path as its experimental default before reading `apps.cfg`. The config key
+should still be the intended control point, but the default avoids blocking the
+DMA transport test on a config-parse/cache issue.
+
+This is not the final desired design. It exists to verify the rest of the
+launcher DMA loader against real hardware while the pathless "currently mounted
+drive 8/A image" bridge remains unproven. The test image uploaded by automation
+must use the same C64U-side name as the config value, currently
+`/usb1/readyos.d81`. The known-good probe used short image names and paths
+without a trailing slash, so the launcher test should match that spelling.
+
+One important mount nuance remains: `MOUNT8` may transport successfully while
+returning no status bytes. The standalone probe did not require a status packet
+immediately after mount; it treated the following `CHANGE_DIR` into the mounted
+image as the validation step. The launcher micromodule follows that discipline
+and does not fail the mount solely because the status buffer is empty.
+
+## Launcher Size / Memory Impact
+
+Measured on the experimental branch after rebuilding only `bin/launcher.prg`:
+
+```text
+default launcher:
+ PRG bytes 38902
+ CODE $1033..$A1E7
+ RODATA $A1E8..$A77F
+ DATA $A780..$A7B1
+ ONCE $A7CE..$A7F3
+ BSS $A7F4..$B185
+
+LAUNCHER_DMA_LOAD=1 fixed-window build:
+ PRG bytes 42171
+ CODE $1033..$AE78
+ RODATA $AE79..$B444
+ DATA $B445..$B476
+ ONCE $B493..$B4B8
+ BSS $B4B9..$C023
+```
+
+The default build was rebuilt after this measurement and confirmed to have no
+`launcher_uci_dma` symbols in `obj/launcher.map`.
+
+## Launcher Integration Follow-Up
+
+The launcher integration remains experimental and disabled by default.
+
+What changed the interpretation:
+
+- The working probe was not a proof that plain Ultimate DOS filenames resolve
+ through IEC drive 8/A's mounted image. Ultimate DOS has its own current
+ directory state.
+- The revised probe made this explicit after forcing Ultimate DOS to `/` so
+ sticky state from prior runs could not mask the result: pre-CD `STAT "udma1"`
+ returned `P:42`, `COPY_UI_PATH` then returned `C:51`, while the later
+ CD-into-image batch load still returned `F1:55 F2:55 F3:55`.
+- REST mounting a D81 as drive A made IEC/KERNAL access see the image, but did
+ not make launcher-side Ultimate DOS `OPEN`/`STAT` reliably resolve `editor`
+ from that mounted IEC context.
+- Adding Ultimate DOS `COPY_UI_PATH` before `STAT`/`OPEN` did not make the
+ REST-mounted launcher case work. The probe now records this as `C:51`. It may
+ still be useful when a human has navigated/mounted through the Ultimate UI,
+ but that is not proven.
+- The successful launcher shape uses the explicit config bridge:
+ `CD /`, `CD usb1`, `MOUNT8 readyos.d81`, `CD readyos.d81`, then plain
+ filenames.
+- After those failures, normal builds were changed so `LAUNCHER_DMA_LOAD`
+ defaults to `0`. The UCI assembly module links only when explicitly building
+ with `LAUNCHER_DMA_LOAD=1`.
+
+Current safe conclusion:
+
+- Do not ship or publish the launcher UCI DMA path without hardware proof for
+ the app/resource set being enabled.
+- A pathless, production-safe Ultimate DOS load from "whatever disk image is
+ mounted as drive 8" is not proven.
+- The currently documented UCI commands do not expose a mounted-drive-to-DOS-path
+ bridge. The only proven DMA path is after Ultimate DOS itself has changed into
+ the disk-image filesystem.
+- If the final design must avoid absolute `/USB0` or `/USB1` paths and must not
+ use SoftIEC, the missing piece is a proven Ultimate DOS mechanism that binds
+ its filesystem context to the currently mounted IEC image.
+- Until that exists, the normal shim/KERNAL loader path is the safe launcher
+ behavior.
+
+## C64U Launcher Automation Notes
+
+The C64U REST automation can prove useful states, but failures must be
+classified from the captured screen:
+
+- A long `LOADING LAUNCHER...` screen with changing animation is not
+ necessarily a lockup. On a known-safe `LAUNCHER_DMA_LOAD=0` D81, the launcher
+ appeared after a brief blank transition.
+- A final BASIC `READY.` screen after `LOAD"BOOT",8` means the booter did not
+ actually run in that attempt. Treat this as mount/input/run sequencing noise,
+ not launcher init evidence.
+- For app-launch checks, wait for app-specific text such as `EDITOR:`. Matching
+ the launcher menu row `8 EDITOR` is a false positive.
+
+## Historical Launcher No-STAT / Fixed-Window Experiment
+
+The launcher integration exposed a C64U-side hazard that the standalone probe
+did not originally make obvious: after `CD`/`MOUNT`/`CD image`, issuing Ultimate
+DOS `FILE_STAT` for `editor` consistently stopped at the launcher's debug marker
+`55` and the C64U REST endpoint stopped responding.
+
+The launcher checkpoint tested in this section therefore avoided `FILE_STAT`
+entirely:
+
+- open the file by Ultimate DOS name
+- read and validate the two-byte PRG load address
+- seek back to payload offset 2
+- zero the destination REU window/slot first
+- issue Ultimate DOS `LOAD_REU` for the known destination window/slot length
+
+At that checkpoint, main app snapshots used the then-current `$1000-$C7FF`
+window (`$B800`). The later, hardware-proven implementation below superseded
+this experiment: it uses open-handle `FILE_INFO`, validates the PRG header, and
+loads the exact payload length into a pre-zeroed destination. The current
+schema-v5 app-window ceiling is `$1000-$C5FF` (`$B600`).
+
+Current measured launcher map impact, forced rebuilds:
+
+```text
+default launcher:
+ CODE $1033..$A1E7 size $91B5
+ RODATA $A1E8..$A77F size $0598
+ DATA $A780..$A7B1 size $0032
+ ONCE $A7CE..$A7F3 size $0026
+ BSS $A7F4..$B185 size $0992
+
+LAUNCHER_DMA_LOAD=1 fixed-window build:
+ PRG bytes 42171
+ CODE $1033..$AE78 size $9E46
+ RODATA $AE79..$B444 size $05CC
+ DATA $B445..$B476 size $0032
+ ONCE $B493..$B4B8 size $0026
+ BSS $B4B9..$C023 size $0B6B
+```
+
+## 2026-06-27 Launcher Hardware Result
+
+The launcher DMA path was proven on a C64U for the regular D81 profile when
+the D81 path is supplied in launcher config as `c64u_image_path=/usb1/readyos.d81`
+and the launcher is built with `LAUNCHER_DMA_LOAD=1`.
+
+The working Ultimate DOS sequence is:
+
+```text
+DOS target only, not SoftIEC
+CD /
+CD USB1
+MOUNT8 READYOS.D81
+CD READYOS.D81
+OPEN plain file name
+READ 2-byte PRG load address
+SEEK payload offset 2
+LOAD_REU fixed destination length
+```
+
+The important correction was to mirror the working probe: after `CD /`, change
+Ultimate DOS into `USB1`, then mount and enter the image by its short image name.
+Mounting with an absolute path and then trying `CD READYOS.D81` was not enough
+on the tested C64U; it returned `21,UNKNOWN`.
+
+This result was from the earlier fixed-window checkpoint: the launcher cleared
+the target and loaded its then-current `$B800` app window. The current loader
+supersedes that detail by using open-handle `FILE_INFO` and loading the exact
+payload length, bounded by the schema-v5 `$B600` app window. ReadyShell
+resources likewise use measured payload lengths, with the documented narrow
+rounding workaround for edge-of-slot overlays.
+
+Hardware evidence from C64U REST automation:
+
+- Final rebuilt artifact `readyos-v0.2.5u-d81.d81`, Editor: load dialog showed
+ `OK - 45 KB`, launcher showed `DMA:ON`, and Editor opened.
+- `readyos-v0.2.5d-d81.d81`, Editor: load dialog showed `OK - 45 KB`, launcher
+ showed `DMA:ON`, and Editor opened.
+- `readyos-v0.2.5z-d81.d81`, ReadyShell: load dialog showed `OK - 45 KB`,
+ launcher showed `DMA:ON`, and ReadyShell reached `READYOS READYSHELL` /
+ `LOADING DONE`.
+- `readyos-v0.2.5d-d81.d81`, ReadyBASIC: load dialog showed `OK - 45 KB`,
+ launcher showed `DMA:ON`, and ReadyBASIC reached its `READY.` prompt.
+
+One C64U quirk remains in the launcher implementation: the successful hardware
+shape keeps volatile stage/status writes during the UCI transaction. They are
+cleared from the normal success dialog before `OK - 45 KB` is drawn, but if DMA
+fails they intentionally remain as short diagnostic breadcrumbs on the load
+dialog. Removing those writes made the same logical path fall back to the
+KERNAL loader on hardware.
+
+### UCI Timing / Code-Shape Sensitivity
+
+This is the most surprising lesson from the Launcher integration. The UCI
+loader is not merely "logically correct"; on the tested C64U it is sensitive to
+the exact pacing/code shape around the Ultimate DOS transaction.
+
+External research context:
+
+- The official UCI documentation describes UCI as a small state machine exposed
+ through `$DF1C-$DF1F`. Commands may only be pushed while the interface is
+ idle. After the Ultimate prepares a response, the C64-side code must read any
+ data/status bytes it needs and then write `DATA_ACC` to release the response
+ and return the state machine to idle or busy for the next block.
+- The upstream `roms/c64rom/kernal/uci.s` code is conservative even though it
+ targets the SoftIEC/KERNAL path rather than Ultimate DOS. Before each command
+ setup it aborts any pending command, pushes the new command, waits while the
+ interface is busy, acknowledges data with `DATA_ACC`, and waits for the
+ accept bit to clear before continuing.
+- The official Ultimate64 firmware notes for `3.14d` dated 2026-03-01 include
+ "Fixes race condition in UCI" under general bugfixes. Treat plain `3.14.0`
+ / Commodore `1.0.0` separately from `3.14d`; the Commodore `1.1.0` changelog
+ says earlier `3.14.0` is the initial `1.0.0` firmware, but does not call out
+ that UCI race fix by name.
+- Public C64U/Ultimate documentation also distinguishes Software IEC from UCI.
+ Software IEC is the serial-bus virtual drive path. The launcher DMA path must
+ remain on the Ultimate DOS UCI target, where `LOAD_REU` reads from the
+ currently opened Ultimate DOS file into REU.
+
+Observed hardware evidence:
+
+- With stage/status stores to screen RAM (`$052C-$0533`) in place, the launcher
+ DMA path works on C64U.
+- Removing those stores made the same logical path fall back to the normal
+ KERNAL loader. The load dialog showed `OK - 24 KB`, the launcher showed
+ `DMA:NO`, and no Ultimate DOS REU load was used.
+- Replacing the stores with private BSS breadcrumbs did not restore the working
+ behavior.
+- Restoring the screen stores restored DMA. The success dialog is now cleared
+ wide enough that the user sees clean `OK - 45 KB`; on failure the diagnostic
+ bytes remain visible.
+
+Interpretation:
+
+- Treat this as **C64U UCI transaction pacing/code-shape sensitivity**, not as a
+ fully understood protocol rule.
+- The current best guess is that the extra absolute stores provide enough
+ spacing and/or preserve enough code-generation shape between command setup,
+ UCI status polling, response draining, path changes, open/read/seek, and
+ `LOAD_REU` for the C64U firmware/FPGA state machine to remain happy.
+- It may also relate to where the writes go. Private BSS writes were not an
+ equivalent substitute, so this is not proven to be "any delay will do".
+- It is also possible that the C compiler/assembler layout and register usage
+ around the C/asm boundary is part of the sensitivity. The screen writes are
+ volatile absolute stores, so they constrain generated code more strongly than
+ ordinary local/state writes.
+- The screen writes are not part of the payload path. The payload path is:
+ Ultimate DOS file -> `LOAD_REU` -> REU. The screen writes are small volatile
+ breadcrumbs around command setup/status capture and may be changing timing,
+ bus visibility, code layout, or C/asm boundary behavior enough to avoid a UCI
+ race on the tested firmware.
+
+Rules for future changes:
+
+- Do not remove or relocate the `$052C-$0533` stage/status writes unless the
+ replacement is retested on real C64U hardware.
+- If the visible diagnostics become undesirable, prefer clearing the affected
+ row after success, as the current code does, rather than removing the stores.
+- If we want a cleaner design, build a dedicated UCI pacing primitive and prove
+ it on hardware with Editor, ReadyShell, and ReadyBASIC before replacing the
+ screen breadcrumbs.
+- A cleaner pacing primitive should copy the upstream discipline rather than
+ merely burning cycles: on entry, clear errors/abort stale transactions; before
+ each command, drain data/status queues and require stable idle; after each
+ response, write `DATA_ACC`, wait for `DATA_ACC` to clear, then require stable
+ idle before the next command.
+- Do not use the destination slot size as the `LOAD_REU` length unless the file
+ is known to be exactly that size. ReadyShell overlays are short PRGs packed
+ into fixed `$3800` REU slots; the normal KERNAL/resource path reads until EOF
+ and leaves the pre-zeroed tail alone. The DMA path must query Ultimate DOS
+ `FILE_INFO`, subtract the two-byte PRG header, then `SEEK 2` and `LOAD_REU`
+ exactly that payload length.
+- A launcher experiment with named `FILE_STAT` failed on C64U firmware 3.14 in
+ the mounted-D81 path with stage `6`, `ERR_STAT`, debug `84`, before the main
+ ReadyShell PRG opened. Do not switch the launcher sizing path from
+ open-handle `FILE_INFO` back to named `FILE_STAT` without reproving it on
+ hardware.
+- ReadyShell has edge-of-slot overlays such as `rsfops`, whose real PRG payload
+ fits in `$3800` but is close enough that rounded/allocated-size answers can
+ trip the size guard. Preserve reported size bytes in diagnostics before
+ closing the Ultimate DOS handle; `CLOSE` can overwrite the status/debug bytes.
+- On the C64U D81 run, `rsfops` failed at stage `7` with `ERR_SIZE` and
+ reported size bytes `$8E,$38` (`$388E`). That matches 57 D81 blocks times
+ 254 bytes, not the actual host PRG size. The launcher therefore allows an
+ overlay-only clipped transfer when the target is the ReadyShell overlay slot
+ (`load address $8E00`, slot `$3800`) and the reported size is within the
+ next 512-byte rounding window. Main app PRGs still require exact reported
+ sizes.
+- Do not trust restored `app_resource_loaded` state when a main app is freshly
+ preloaded. A C64U reboot can preserve launcher bank-0 state while the REU
+ cache banks contain stale contents from a previous experiment/session. The
+ failure signature was ReadyShell drawing its header and `LOADING DONE`, then
+ hanging before the `>` prompt because overlay 9 (`rsedit`) metadata pointed at
+ a stale app snapshot bank. The launcher fix is to invalidate resource preload
+ state on every fresh main-app load, reload the resources, and reassert all
+ ReadyShell cache/state bank allocation types before restoring metadata.
+- Do not blindly reuse restored `app_rs_bank*` values. On C64U cross-app runs,
+ Editor and ReadyBASIC could load correctly, ReadyShell could reach its prompt,
+ and then an overlay command such as `LST "RSHELP"` could drop to BASIC if the
+ restored ReadyShell resource bank slots conflicted with banks now marked for
+ another app/resource type. Before reusing restored resource-bank slots, compare
+ them against the allocation table, discard conflicting or duplicate slots, and
+ allocate fresh banks before reloading overlays/modules.
+- ReadyShell currently clears its high-RAM runtime area at startup, which can
+ clear the launcher's `$CFF2` cached state-bank pointer before ReadyShell asks
+ for the REU state bank. In that case ReadyShell scans the allocation table for
+ the first `REU_RS_SCRATCH` bank. The launcher therefore must prune stale
+ ReadyShell cache/scratch allocation-table marks so only the current
+ ReadyShell cache banks and state/scratch bank are advertised before launch.
+- Keep the REU allocation table authoritative for loaded app snapshots as well
+ as resource banks. The DMA preload path updates the shim bitmap directly; it
+ must also mark the loaded app's physical REU bank as `REU_APP_STATE`, and the
+ launcher should reassert all currently loaded snapshot banks before allocating
+ resource banks. Otherwise ReadyShell overlay banks can be allocated over a
+ loaded app snapshot; later returning from that app can overwrite an overlay
+ bank and make commands such as `LST "RSHELP"` fail even though the ReadyShell
+ prompt and lighter commands still work.
+- On this experiment branch, Enter on an unloaded app should go through the
+ launcher preload path first, then launch from REU. That keeps DMA-capable app
+ loads, KERNAL fallback loads, and resource preparation on the same launcher
+ code path as F3/load-all instead of using the older direct disk-launch path.
+- Do not poll screen/RAM through the REST API while the C64 side is in the
+ boot/UCI-critical section. Earlier automation did this and produced stuck
+ boot screens that looked like launcher crashes but were really
+ automation/state interference.
+- Record the exact firmware version when testing. Behavior on `3.14.0`,
+ `3.14d`, Commodore `1.0.0`, and Commodore `1.1.0` may differ in precisely the
+ area this loader stresses.
+- VICE cannot prove this aspect. The failure mode only showed up on hardware.
+
+Final measured launcher map impact after the verified build:
+
+```text
+LAUNCHER_DMA_LOAD=1 verified build:
+ PRG bytes 43521
+ CODE $1033..$B3B1
+ RODATA $B3B2..$B98A
+ DATA $B98B..$B9BC
+ INIT $B9BD..$B9D8
+ ONCE $B9D9..$B9FE
+ BSS $B9FF..$C56E
+```
+
+Verification:
+
+- `python3 build_support/verify_memory_map.py` passed.
+- `python3 build_support/verify_launcher_dma_gate.py` passed.
+- C64U D81 artifact `readyos-v0.2.5q-d81.d81` was deployed as
+ `USB1/automation/vice_tasks_dotnet/readyos-readyshell-c64u-q.d81`; the FTP
+ listing was checked so no older experiment D81 from this series remained.
+- F3/load-selected ReadyShell path passed:
+ `READYOS_READYSHELL_OVERLAY_SMOKE_PASS`. The captured loading screen showed
+ `OK - 27 KB`, then ReadyShell passed `VER`, `LST "RSHELP"`,
+ `CAT "RSHELP" ! TOP 1`, and another `VER`.
+- Enter on unloaded ReadyShell path passed:
+ `READYOS_READYSHELL_ENTER_SMOKE_PASS`. The five-second early capture showed
+ `LOADING TO REU` with the ReadyShell selection and a UCI stage marker, then
+ ReadyShell passed the same overlay command smoke.
+
+## Launcher Startup/Resume Lessons
+
+- The launcher may reuse its cached catalog/resume payload instead of rereading
+ `apps.cfg` on every entry. Any config value that changes DMA behavior must be
+ part of that resume payload, or the cached path can silently fall back to the
+ compiled default. This specifically bit `c64u_image_path`: after a cached
+ launcher resume, first Enter/F1 paths could try the wrong image path and then
+ fall back to KERNAL disk I/O.
+- Bump the launcher resume schema whenever the resume payload layout changes.
+ That forces old hardware REU cache state to be discarded and makes the next
+ launcher run reread `apps.cfg` before it saves a new payload.
+- DMA status should be initialized during launcher startup without touching the
+ UCI registers. A real startup UCI detect can run too early in the
+ boot-to-launcher lifecycle and hang before the first menu draw. `DMA:YES`
+ therefore means a C64U image path is configured and the launcher will attempt
+ DMA; `DMA:ON` means at least one Ultimate DOS DMA transfer has succeeded in
+ the current launcher session; `DMA:NO` means no path is configured or a later
+ no-UCI/path/mount/image error disabled the DMA path.
+- A failed per-file transfer should not automatically disable DMA globally.
+ Only no-UCI/path/mount/image errors should flip global status to unavailable.
+ Size/header/open/read errors should fall back for that file while allowing
+ later files to attempt DMA.
+- Repeatedly remounting the same configured D81 for every app and overlay is
+ risky on the tested C64U. After one successful Ultimate DOS DMA load, the
+ launcher keeps a volatile in-session "image is mounted" flag and subsequent
+ DMA transfers open the next file from the current image directory instead of
+ issuing another root/CD/mount/CD-image sequence. The flag is not saved in the
+ resume payload and is cleared on startup and on no-UCI/path/mount/image
+ failures, so a retry can fall back to the full mount path when the mounted
+ image is genuinely suspect. File-level failures keep the mounted-image state:
+ ReadyShell can legitimately fall back to KERNAL for an overlay/resource while
+ Ultimate DOS is still positioned inside the D81, and forcing the next app back
+ through the full mount path reproduced the `330.3834` C64U stall.
+
+## 2026-07-07 Acceptance Verification
+
+This acceptance pass used fresh C64U runs with `READYOS_CLEAR_REU=1` before
+each reboot. C64U REST/FTP orchestration was launched from a Terminal-owned
+background bash, not from the foreground Codex shell.
+
+Hardware evidence:
+
+- Valid configured path, current-source DMA build:
+ `/tmp/readyos_c64u_accept_valid_y_20260707_001219`.
+ D81 `readyos-v0.2.5y-d81.d81` contained
+ `C64U_IMAGE_PATH=/USB1/READYOS-V0.2.5Y-D81.D81`.
+ Result: `READYOS_EDITOR_DIRECT_DMA_RETURN_PASS`, rc `0`; launcher returned
+ with Editor marked loaded and `DMA:ON`. Captured screens contained `DMA:ON`
+ four times.
+- Empty configured path, current-source DMA-capable build:
+ `/tmp/readyos_c64u_accept_empty_z_quietboot_20260707_002532`.
+ D81 `readyos-v0.2.5z-d81.d81` contained `C64U_IMAGE_PATH=`.
+ Result: `READYOS_EDITOR_DIRECT_DMA_RETURN_PASS`, rc `0`; launcher showed
+ `DMA:NO`, Editor loaded by the normal disk path, and the launcher returned
+ still showing `DMA:NO`. Captured screens contained no `DMA:ON`.
+- Short invalid configured path, current-source DMA-capable build:
+ `/tmp/readyos_c64u_accept_bad_b_quietboot_20260707_003405`.
+ D81 `readyos-v0.2.5b-d81.d81` contained
+ `C64U_IMAGE_PATH=/USB1/MISS.D81`.
+ Result: `READYOS_EDITOR_DIRECT_DMA_RETURN_PASS`, rc `0`; Editor opened and
+ returned to the launcher, `editor-direct matched EDITOR: ... saw_dma=0`, and
+ captured screens contained no `DMA:ON` or `DMA LOADING`.
+
+Automation lesson:
+
+- For non-DMA/fallback paths, give the C64U a long quiet window before the
+ first launcher screen poll and before app-ready polling. A current empty-path
+ D81 booted in VICE immediately, but on hardware the same image could sit on a
+ blank/boot-loading state when REST polled screen RAM too early. The passing
+ hardware fallback runs used `READYOS_BOOT_INITIAL_WAIT_S=220` and
+ `READYOS_QUIET_AFTER_APP_ENTER_S=95`.
+- The quiet waits are test-harness discipline, not ReadyOS product behavior.
+ They avoid REST/memory reads while the C64 side may be inside KERNAL disk I/O.
+- A long bad path is a separate config-parser failure mode. A 47-character
+ `C64U_IMAGE_PATH=...` line produced `CFG ERROR`/`ERR:2`; use a short invalid
+ path such as `/usb1/miss.d81` when testing missing-image fallback.
+
+Focused VICE regressions after these launcher/harness changes:
+
+- Regular D81 ReadyShell cross-app/overlay probe passed:
+ `logs/vice_auto_20260707_004150`, `"Status": "success"`.
+- EasyFlash ReadyShell-only converted probe passed:
+ `logs/vice_auto_20260707_004251`, `"Status": "success"`.
+- Empty-path D81 startup sanity in VICE passed:
+ `logs/vice_auto_20260707_002512`, `"Status": "success"`, asserting launcher
+ `DMA:NO`.
+
+## 2026-06-27 Launcher DMA Verification
+
+- Current tested branch build: `readyos-v0.2.5z-d81.d81`.
+ Local and FTP-downloaded `USB1/readyos-v0.2.5z-d81.d81` both hashed to
+ `42fd4f6e148aa5cab95972199324174acb807e219ff102c71b0eb444dab87c54`
+ before the hardware editor-direct run and again after the dotnet C64U suite.
+- `apps.cfg` for this run deliberately used
+ `c64u_image_path=/usb1/readyos-v0.2.5z-d81.d81` and
+ `load_all_to_reu=0`, so the booter did not auto-preload everything. The
+ human/user-world rule remains: the D81 can be mounted normally by the user,
+ while launcher DMA only needs a configured C64U storage path when it must
+ remount/recover the image itself.
+- The C64U path handling now sends Ultimate DOS storage path bytes in uppercase
+ for `CD`/`MOUNT` only, and leaves D81 file names for `OPEN` untouched. That
+ preserves the PETSCII/lowercase app/resource filename discipline inside the
+ mounted image while satisfying C64U storage-path matching for `/USB1`.
+- The working mount recovery shape is `CD /`, then try `CD
` exactly as
+ configured, and if that status fails and the configured directory starts with
+ `/`, retry once without the leading slash. This fixed the previous
+ `ERR_PATH`/status `84` failure for `/usb1/...`.
+- Do not add temporary top-left screen markers to launcher startup. They helped
+ diagnose draw progress, but they are not part of the working loader and can
+ look like the classic C64 blinking-cursor failure symptom. The remaining
+ `$052C-$0533` writes are the proven UCI pacing/status breadcrumbs inside the
+ loading screen area and are cleared on successful DMA.
+
+Measured launcher map for the verified `0.2.5Z` build:
+
+```text
+LAUNCHER_DMA_LOAD=1 verified build:
+ SHA256 bin/launcher.prg 50e00ec57be0f2905ae25a003c2bcc58c539110fe22d630031a49ccb8ebd7ceb
+ CODE $1033..$B380
+ RODATA $B381..$B957
+ DATA $B958..$B989
+ INIT $B98A..$B9A5
+ ONCE $B9A6..$B9CB
+ BSS $B9CC..$C3F6
+```
+
+Verification on C64U:
+
+- Static gates passed: `python3 build_support/verify_memory_map.py` and
+ `python3 build_support/verify_launcher_dma_gate.py`.
+- Shell/REST editor-direct smoke passed with
+ `READYOS_EDITOR_DIRECT_PASS`. It booted the fresh D81 from `USB1`, reached
+ the launcher with `DMA:YES`, pressed Enter on Editor, showed the REU loading
+ progress, and landed in Editor.
+- Dotnet C64U cross-app suite passed with `"Status": "success"` using
+ `/tmp/readyos_c64u_readyshell_dotnet_z3_20260627_131943` and trace
+ `logs/ultimate_auto_20260627_131952/trace.md`. It verified launcher
+ `DMA:YES`, direct Editor load returning to launcher as `DMA:ON`, ReadyBASIC
+ load returning as `DMA:ON`, and ReadyShell reaching its prompt after
+ ReadyBASIC.
+- The same dotnet suite exercised ReadyShell overlays with `VER`,
+ `LST "RSHELP"`, another `VER`, and `CAT "RSHELP" . TOP 1`; the decoded
+ capture showed `NAME:RSHELP,BLOCKS:5,TYPE:SEQ` and `VERSION 0.2`, so the
+ previous ReadyShell overlay preload hang was not reproduced in this build.
+
+## 2026-06-29 Launcher-Shape UCI Timing Probe
+
+- The timing probe must use the launcher loader shape, not the older standalone
+ named `FILE_STAT` probe. The working shape is still: detect UCI, identify,
+ drive-info, optional root/CD/mount/CD-image, open filename inside the mounted
+ image, `FILE_INFO` on the open handle, read the two-byte PRG load header,
+ seek to payload offset 2, `LOAD_REU`, close.
+- For per-stage timing, the probe now generates an instrumented copy of
+ `src/apps/launcher/launcher_uci_dma.s` at build time. The product launcher
+ source is not modified. The instrumented wrappers preserve the underlying
+ carry result with `php`/`plp`, so the launcher loader control flow remains
+ equivalent while accumulating stage timings in the probe result block.
+- Use the low/mid jiffy bytes (`$A2/$A1`) for timing. Reading `$A0/$A1`
+ produced coarse `$0100`-tick steps and made stage timings look falsely
+ quantized.
+- C64U run `USB1/UTV201111.D81` completed 29/29 launcher-style DMA loads:
+ `DONE:01`, `FAIL:00`, `SUCCESS:1D`, `loaded_kb=611`, `total_ms=83167`.
+- Stage timing for the 29 loads, including the first-load mount path and
+ subsequent mounted-image opens:
+
+```text
+load_reu 11.883s 14.3%
+open 10.733s 12.9%
+file_info 10.583s 12.7%
+identify 9.717s 11.7%
+read_header 9.683s 11.6%
+drvinfo 9.667s 11.6%
+close 9.650s 11.6%
+seek_payload 9.650s 11.6%
+mount 0.533s 0.6%
+cd_image 0.367s 0.4%
+cd_dir 0.350s 0.4%
+cd_root 0.333s 0.4%
+detect 0.000s 0.0%
+```
+
+- Interpretation: fixed per-file UCI command overhead dominates. The actual
+ `LOAD_REU` transfer was only about 14% of measured loader time for this
+ workload. The currently expensive per-file steps are open, file-info,
+ read-header, seek, close, and the repeated identify/drive-info calls. The
+ one-time path/mount/CD work is tiny after the launcher keeps the image
+ mounted for the session.
+
+## 2026-06-29 Fast-Raw Timing Variant
+
+- A second probe variant tested the aggressive hot path: after the image is
+ mounted, skip repeated detect/identify/drive-info and skip per-file
+ `FILE_INFO`, PRG header read, and seek. Each file uses the known PRG file
+ length from the build side, then does `OPEN`, one `LOAD_REU` from file offset
+ 0, and `CLOSE`. This deliberately loads the two-byte PRG address header into
+ REU too; it is a timing experiment, not a valid launcher contract yet.
+- C64U run `USB1/UTF201821.D81` completed 29/29 fast-raw DMA loads:
+ `DONE:01`, `FAIL:00`, `SUCCESS:1D`, `loaded_kb=607`, `total_ms=33300`.
+- Fast-raw stage timing for the 29 loads:
+
+```text
+load_reu 11.483s 34.5%
+open 10.233s 30.7%
+close 9.367s 28.1%
+mount 0.517s 1.6%
+cd_image 0.367s 1.1%
+cd_dir 0.350s 1.1%
+drvinfo 0.333s 1.0%
+cd_root 0.317s 1.0%
+identify 0.317s 1.0%
+detect 0.000s 0.0%
+file_info 0.000s 0.0%
+read_header 0.000s 0.0%
+seek_payload 0.000s 0.0%
+```
+
+- Interpretation: `LOAD_REU` is not a standalone filename-based operation in
+ the command shape we are using; the file still has to be selected/opened
+ first. So the practical minimal per-file hot path is `OPEN + LOAD_REU +
+ CLOSE`, not just `LOAD_REU`. This cut total measured load time from 83.167s
+ to 33.300s for the same 29-item workload, about a 2.5x improvement, before
+ any future contract change to handle the two-byte PRG header correctly.
+
+## 2026-07-04 Launcher UI And C64U Verification
+
+- Current deployed manual-test artifact: `USB1/readyos-v0.2.5e-d81.d81`.
+ The release-side config for this build uses
+ `c64u_image_path=/usb1/readyos-v0.2.5e-d81.d81`, so the launcher and the
+ automation are testing the same fresh-named D81 rather than a reused
+ `readyos.d81` mount.
+- The C64U automation deletes the same remote filename before upload, uploads
+ by FTP, verifies the FTP listing, sets Drive A to 1581, clears all 256 REU
+ banks with a tiny REST-run PRG, resets before mount, mounts the D81 as drive
+ A with `type=d81`, resets again, and only then starts ReadyOS.
+- The boot path used by the shell harness is not an autoload configuration
+ path. After the hard reset it reaches BASIC and types `LOAD"BOOT",8` then
+ `RUN`; app loading is triggered later by launcher UI actions.
+- Do not poll REST screen/RAM during the active booter/launcher disk load. The
+ harness waits through the boot window first, then captures screens. During
+ app DMA loads it is safe to capture screen RAM because the C64 side is showing
+ the launcher loading UI.
+- The visible UCI breadcrumb was reduced to one stage digit on the bottom
+ loading line. The working UI form is now:
+ `DMA LOADING 1/1 - 9` for simple apps and
+ `DMA LOADING 6/10 - 1` style progress for ReadyShell main plus overlays.
+ The old second debug digit in the middle of the screen was removed.
+- The bottom loading line explicitly says `DMA LOADING` or `DISK LOADING`.
+ A hardware regression run should search for `DISK LOADING` in captured
+ screens/logs when DMA is expected; none appeared in the verified `0.2.5E`
+ runs below.
+
+Measured launcher map for the verified `0.2.5E` build:
+
+```text
+LAUNCHER_DMA_LOAD=1 verified build:
+ CODE $1033..$B482 size $A450
+ RODATA $B483..$BA6F
+ DATA $BA70..$BAA1
+ INIT $BAA2..$BABD
+ ONCE $BABE..$BAE3
+ BSS $BAE4..$C514 size $0A31
+```
+
+Verification on C64U, all from Terminal-owned/background shells:
+
+- Static checks passed:
+ `python3 build_support/verify_launcher_dma_gate.py`,
+ `python3 build_support/verify_memory_map.py`,
+ `python3 build_support/verify_resume_contract.py`,
+ and `bash -n build_support/run_readyos_boot_c64u_rest.sh`.
+- Enter on Editor passed:
+ `READYOS_EDITOR_DIRECT_DMA_RETURN_PASS`. Captures showed
+ `DMA LOADING 1/1 - 2`, then `- 7`, then `- 9`, Editor opened, STOP
+ returned to the launcher, and the launcher showed `DMA:ON`.
+- F3/load-selected Editor passed:
+ `READYOS_EDITOR_LOAD_SELECTED_PASS`. The load-selected screen showed
+ `DMA LOADING 1/1 - 9`, then `PRESS ANY KEY`; the launcher returned with
+ `DMA:ON`, and Enter opened Editor from REU.
+- Load-all plus ReadyShell overlays passed:
+ `READYOS_LOADALL_READYSHELL_OVERLAY_PASS`. Captures showed ReadyShell
+ overlay progress such as `DMA LOADING 6/10`, `7/10`, `8/10`, `9/10`, and
+ `10/10`, then later simple apps as `1/1`. ReadyShell reached
+ `READYOS READYSHELL` / `LOADING DONE` and passed `VER`, `LST "RSHELP"`,
+ `CAT "RSHELP" . TOP 1`, and another `VER`.
+- Browse/app-manifest load passed:
+ `READYOS_MANIFEST_SIDETRIS_PASS`. The manifest browser selected Sidetris,
+ the load screen showed `DMA LOADING 1/1 - 9`, the launcher returned with
+ `DMA:ON`, and Sidetris launched.
+- ReadyBASIC F3/load-selected passed:
+ `READYOS_READYBASIC_LOAD_SELECTED_PASS`. The load-selected screen showed
+ `DMA LOADING 1/1 - 9`, the launcher returned with `DMA:ON`, and
+ ReadyBASIC reached its `READY.` prompt.
+
+Current automation caveat:
+
+- The harness can briefly look like it is still at BASIC after `LOAD"BOOT",8`
+ because it intentionally sleeps through the boot window before capturing the
+ launcher. Do not classify that as a launcher crash unless the later
+ `launcher_wait` capture fails and the final screen/memory dump also show no
+ ReadyOS progress.
+
+## 2026-07-05 DMA Must Not Fall Through To Disk
+
+The C64U manual test exposed a launcher integration bug that the earlier UI
+checks were too weak to catch. The launcher showed `DMA:YES`, then a selected
+app showed `DMA LOADING`, but after the Ultimate DOS attempt returned failure
+the same load fell through to the normal disk/KERNAL loader. To a human this
+looked like:
+
+- Editor: `DMA LOADING`, then slow `DISK LOADING` for the same app.
+- ReadyShell: each `1/10`, `2/10`, etc. overlay could show a DMA stage and
+ then load the same file through disk, making the overlay preload extremely
+ slow and ambiguous.
+
+Correct launcher behavior:
+
+- If DMA is not available at all, the normal disk/chunked loader remains the
+ right fallback. This keeps regular VICE and non-Ultimate hardware working.
+- If the launcher actually attempts an Ultimate DOS DMA load for the current
+ app/resource, a failure must be a failure for that item. Do not continue into
+ the disk path for the same item, and do not let `load all to REU` retry that
+ same item through disk.
+- ReadyShell resources must follow the same rule as the main app PRG. A failed
+ DMA attempt for an overlay must not silently fall through to the chunked disk
+ resource loader.
+- The UI distinction matters: `DMA:YES` means configured/available, `DMA:ON`
+ means at least one successful DMA transfer has completed, `DMA LOADING` means
+ the current transfer is using the Ultimate DOS path, and `DISK LOADING` means
+ the normal disk loader is active.
+
+Implementation lesson:
+
+- Keep one small launcher-local flag for "the current load attempted DMA".
+ Clear it when starting `load_app_to_reu()`, set it immediately before calling
+ the Ultimate DOS loader for either the main PRG or a resource PRG, and use it
+ to suppress load-all's historical retry path after a DMA-attempted failure.
+ This cost one BSS byte and kept the behavior contained inside the launcher.
+- Do not mark an app/resource as loaded unless the DMA path completed and the
+ expected REU/control metadata was updated. Showing a DMA progress digit is
+ not proof that the app is usable.
+
+Automation lesson:
+
+- A quiet sleep followed by "did the app eventually load?" is not enough for
+ this feature. It can pass while hiding the exact bug we care about.
+- Hardware tests must capture the loading screen repeatedly and treat
+ `DISK LOADING` as a failure whenever DMA is expected. They should also retain
+ the screen text that caused the failure.
+- The useful C64U checks are now:
+ - Load all to REU plus ReadyShell overlay smoke.
+ - Enter on a single-file app such as Editor.
+ - F3/load-selected or equivalent background load for ReadyShell overlays.
+ - Browse/app-manifest load, then launch the selected app.
+- A post-run grep across captured screens is a good sanity check: successful
+ DMA runs should have many `DMA LOADING` sightings and zero `DISK LOADING`
+ sightings.
+
+Verified C64U regression evidence for the corrected launcher:
+
+```text
+READYOS_LOADALL_READYSHELL_OVERLAY_PASS
+READYOS_EDITOR_DIRECT_DMA_RETURN_PASS
+READYOS_READYSHELL_OVERLAY_SMOKE_PASS
+READYOS_MANIFEST_SIDETRIS_PASS
+```
+
+The captured hardware artifacts for that run contained 267 `DMA LOADING`
+matches and 0 `DISK LOADING` matches across the load-all, Enter, F3/load-
+selected, and manifest-load paths.
+
+Fresh DMA launcher map after the fix:
+
+```text
+LAUNCHER_DMA_LOAD=1 verified build:
+ CODE $1033..$B49E size $A46C
+ RODATA $B49F..$BA8B
+ DATA $BA8C..$BABD
+ ONCE $BADA..$BAFF
+ BSS $BB00..$C531 size $0A32
+```
+
+## 2026-07-06 DMA Launcher Headroom Cliff
+
+The hardware blank-screen regression after the boot animation was not a boot,
+preboot, or shim failure. The launcher had loaded and begun initialization, but
+the DMA-enabled build had become too tight at the top of app RAM. It could
+reach screen-clear/draw work and then fall over before the launcher menu became
+visible.
+
+The important lesson is that the linker map's apparent end address is not the
+whole safety story on C64/cc65. The launcher also needs real runtime stack
+headroom below the ReadyOS app ceiling. A small assembler guard added during
+the progress-display cleanup was enough to expose the cliff, but the underlying
+problem was the DMA launcher's total footprint.
+
+Corrective approach:
+
+- Keep the Ultimate DOS stage-write code in the C64U-proven shape unless a new
+ hardware test proves a replacement. The visible write to `$07AE` is ugly, but
+ it has timing/transaction value on the real Ultimate hardware path.
+- For `LAUNCHER_DMA_LOAD=1`, reduce the launcher catalog capacity from 64 app
+ slots to 32 app slots. The current D81 catalog has 20 apps, so this preserves
+ the SKU's practical behavior while freeing enough BSS for stable stack space.
+- Leave non-DMA launcher builds at 64 app slots.
+- Do not touch boot, preboot, shim, or app binaries for this class of fix; the
+ instability was in the launcher's own initialization/runtime footprint.
+
+Verified headroom build:
+
+```text
+0.2.5X LAUNCHER_DMA_LOAD=1:
+ CODE $1033..$B4B7 size $A485
+ RODATA $B4B8..$BAD6 size $061F
+ DATA $BAD7..$BB08 size $0032
+ ONCE $BB25..$BB4A size $0026
+ BSS $BB4B..$C3DA size $0890
+ margin to $C590: 437 bytes
+ margin to $C600: 549 bytes
+```
+
+C64U verification for this corrected build:
+
+```text
+/USB1/READYOS.D81 = readyos-v0.2.5x-d81.d81
+READYOS_EDITOR_DIRECT_DMA_RETURN_PASS
+READYOS_BOOT_PASS
+```
+
+The packaged `apps.cfg` for the deployed D81 had:
+
+```text
+LOAD_ALL_TO_REU=0
+RUNAPPFIRST=
+C64U_IMAGE_PATH=/USB1/READYOS.D81
+```
+
+Bad-path note:
+
+- A deliberately wrong `C64U_IMAGE_PATH` correctly produced `DMA:NO` and the
+ visible notice `UDOS MOUNT FAILED; DMA OFF`.
+- That same bad-path test then hung after beginning the normal disk fallback
+ for Editor (`DISK LOADING 1/1 -`). Treat this as a separate follow-up before
+ claiming the UCI-failure fallback is fully robust.
+
+## 2026-07-06 DMA Open Failure Fallback
+
+The C64U hardware can report a usable UCI/DMA path during launcher startup and
+still fail the later per-file Ultimate DOS open. In the reproduced Editor case,
+the launcher reached the app menu with `DMA:YES`, but the direct DMA load failed
+at the `OPEN "editor"` stage with Ultimate DOS status `84,NO FILE`. The same D81
+was mounted as drive 8 and the regular disk loader could load the app, so this
+must be treated as an Ultimate DOS context/open failure rather than proof that
+the image or app catalog is missing.
+
+The robust launcher behavior is therefore:
+
+- Probe UCI and the configured image path at startup, so the UI can still show
+ whether the DMA path appears available.
+- Attempt DMA first when enabled and configured.
+- If the actual file open fails (`launcher_uci_dma_last_error == $02`, with the
+ debug status bytes showing the Ultimate DOS error), disable the current DMA
+ attempt and fall through to the normal disk/shim loader.
+- Do not surface this as `APP LOAD FAILED` unless the normal disk fallback also
+ fails.
+
+The first hardware-confirmed fallback build was `0.2.5T`:
+
+```text
+/USB1/READYOS.D81 = readyos-v0.2.5t-d81.d81
+READYOS_EDITOR_DIRECT_DMA_RETURN_PASS
+Observed sequence: DMA LOADING 1/1 - 5, then DISK LOADING 1/1 -, then Editor.
+```
+
+This does not solve the root cause of the intermittent `84,NO FILE` response
+from Ultimate DOS, but it restores the user-facing happy path: selecting an app
+loads it instead of bouncing back to the launcher with `APP LOAD FAILED`.
+
+Automation note:
+
+- `build_support/run_readyos_boot_c64u_rest.sh` now accepts
+ `C64U_MACHINE_REBOOT=1`. With that set, the harness uses
+ `PUT /v1/machine:reboot` instead of only `machine:reset` before the run. This
+ gives cleaner C64U hardware state for reproducing DMA/open behavior, while the
+ default remains the older reset path.
+
+## 2026-07-06 Reverted UCI-Failure Fallback
+
+The later hardware repro showed the `DMA open failed -> normal KERNAL disk
+fallback` path was not actually robust. After an Ultimate DOS open failure with
+status `84`, the launcher could enter the shim/KERNAL load markers and then hang
+at `DISK LOADING 1/1 -`. That means the failed UCI transaction can leave enough
+device/channel state behind that immediately falling into the normal disk path
+is unsafe on the C64U.
+
+Corrected rule:
+
+- Keep the verified DMA load path from the `7107bef` hardware run intact.
+- Do not alter `_launcher_uci_dma_load_prg` for UI niceties.
+- Do not fall through to KERNAL disk loading after a real UCI file-open error
+ unless a future probe proves the cleanup sequence is safe on hardware.
+- The only safe UX improvement at this stage is a startup mount probe: if UCI is
+ present but the configured `c64u_image_path` cannot be mounted, disable DMA and
+ display `UDOS MOUNT FAILED; DMA OFF` before the user tries to load an app.
+- Even after a successful startup mount probe, leave
+ `launcher_dma_image_ready=0` so the real app/resource load still follows the
+ verified mount-and-load path rather than a new "already mounted" shortcut.
+
+Memory note for the restored launcher in the current tree:
+
+- The old 64-slot catalog shape now overflows the DMA-enabled launcher BSS.
+ Keep `APP_SLOT_CAPACITY=32` when `LAUNCHER_DMA_LOAD=1`; this is a memory
+ containment change, not a DMA transaction change.
+
+## 2026-07-06 Verified Restore: Versioned Path Matters
+
+The current branch was restored to a passing C64U Editor DMA smoke only after
+matching all of these constraints:
+
+- Restore `src/apps/launcher/launcher_uci_dma.s` to the exact UCI load path from
+ the verified `7107bef` build. The later shared mount/probe helper looked
+ equivalent, but the hardware still failed at stage `55` with Ultimate DOS
+ status `84,NO FILE`.
+- Do not let startup probing set `launcher_dma_image_ready=1`; skipping the
+ load-side mount/open sequence is not the verified path.
+- Keep the volatile screen stage writes in both C and assembler. They are part
+ of the hardware-proven transaction shape, not disposable debug UI.
+- Copy the DMA filename into launcher-owned RAM before calling the UCI loader.
+ The catalog text buffer is shared and may later contain app descriptions.
+- The configured `c64u_image_path` must exactly match the actual file placed on
+ the C64U USB drive. The passing run used:
+
+```text
+/USB1/readyos-v0.2.5g-d81.d81
+C64U_IMAGE_PATH=/usb1/readyos-v0.2.5g-d81.d81
+READYOS_EDITOR_DIRECT_DMA_RETURN_PASS
+```
+
+The generic `/usb1/readyos.d81` path repeatedly failed the restored current
+branch at the UCI open stage. Treat the config/deployed-name match as a required
+precondition for DMA until a smaller probe proves otherwise.
+
+Bad-path status:
+
+- The earlier negative startup mount probe is not currently safe to keep in the
+ launcher. It changed enough UCI/load state to break the good path.
+- Reintroduce bad-path UI only after a standalone probe proves the sequence can
+ detect a missing image without altering the subsequent real app load path.
+
+## 2026-07-06 Hardware Restore Follow-up: Do Not Replace Mounted Images
+
+The fresh positive C64U smoke for `0.2.5K` passed with:
+
+```text
+/USB1/readyos-v0.2.5k-d81.d81
+C64U_IMAGE_PATH=/usb1/readyos-v0.2.5k-d81.d81
+READYOS_EDITOR_DIRECT_DMA_RETURN_PASS
+```
+
+After that, a safe-looking negative build with an empty `c64u_image_path` did
+not prove safe on hardware. It booted past BASIC `LOAD"BOOT",8`/`RUN` into a
+blank ReadyOS-colored screen and never reached the launcher. Treat the empty
+path negative as failed/unproven until it has its own smaller C64U probe or a
+launcher-side diagnosis. Do not use it as evidence that the good path is safe.
+
+The important artifact-handling lesson came next. Rebuilding another `0.2.5K`
+and letting the REST runner delete/re-upload `/USB1/readyos-v0.2.5k-d81.d81`
+while that filename had recently been mounted produced the same blank boot
+screen. Captured launcher/code memory matched the previous passing run, which
+can simply be stale C64 RAM after reboot; screen state is the authority here.
+
+Using a new versioned remote filename avoided the problem:
+
+```text
+/USB1/readyos-v0.2.5m-d81.d81
+C64U_IMAGE_PATH=/usb1/readyos-v0.2.5m-d81.d81
+READYOS_EDITOR_DIRECT_DMA_RETURN_PASS
+```
+
+Operational rule for C64U hardware automation:
+
+- Clear REU with the standalone automation program before boot.
+- Hard reboot and remount the image after REU clear.
+- Do not delete/re-upload the same D81 path if it may still be mounted or cached
+ by the C64U drive emulation.
+- Prefer a fresh versioned D81 filename for each hardware proof, or explicitly
+ unmount/eject the previous image by a known-good C64U API/menu path before
+ replacing it.
+- Keep the `c64u_image_path` inside `apps.cfg` matched exactly to the remote
+ filename being mounted.
+
+## 2026-07-06 Restore Verification: Positive Path vs Empty-Path Negative
+
+After reverting the fragile fallback/UI work, the restored launcher path was
+proved again on fresh C64U filenames:
+
+```text
+/USB1/readyos-v0.2.5n-d81.d81
+C64U_IMAGE_PATH=/usb1/readyos-v0.2.5n-d81.d81
+READYOS_EDITOR_DIRECT_DMA_RETURN_PASS
+
+/USB1/readyos-v0.2.5p-d81.d81
+C64U_IMAGE_PATH=/usb1/readyos-v0.2.5p-d81.d81
+READYOS_EDITOR_DIRECT_DMA_RETURN_PASS
+```
+
+Both runs used the standalone automation REU clear before reboot/mount/boot.
+`READYOS_CLEAR_REU=1` is a harness environment variable, not an `apps.cfg`
+setting and not a ReadyOS runtime feature.
+
+The launcher screen for the passing hardware build showed `DMA:YES` before the
+first app load, then `DMA:ON` after Editor returned to the launcher with the
+loaded marker. This is the current hardware proof of the restored DMA path.
+
+The empty `C64U_IMAGE_PATH=` negative remains nuanced:
+
+- The exact `0.2.5O` D81 with `C64U_IMAGE_PATH=` booted in VICE, displayed
+ `DMA:NO`, loaded Editor through the normal disk path, returned to the
+ launcher, then loaded ReadyShell through the normal disk/resource path and
+ reached the ReadyShell prompt.
+- The same empty-path style still blanked on C64U after `LOAD"BOOT",8` and
+ `RUN`. That reproduces the hardware-side blank symptom, but VICE proves the
+ launcher parser/startup path itself is not generally broken by the empty
+ value.
+
+Do not use the C64U empty-path failure to justify changing the proven DMA
+transaction. Treat it as a separate hardware/mount/runner investigation unless
+it can be reduced to a launcher-only repro.
+
+Focused regression evidence from this restore:
+
+- C64U positive DMA Editor direct-load/return:
+ `/tmp/readyos_c64u_positive_p_20260706_220449`
+- VICE no-DMA disk Editor plus ReadyShell:
+ `/Users/karlprosserpp/dev/c64projects/readyosprecog/logs/vice_auto_20260706_220237`
+- VICE current `0.2.5P` no-UCI/no-DMA Editor plus ReadyShell, with
+ `$00CC == $01` proving the KERNAL cursor blink is disabled on the launcher:
+ `/Users/karlprosserpp/dev/c64projects/readyosprecog/logs/vice_auto_20260706_221238`
+- EasyFlash ReadyShell cross-app suite:
+ `/Users/karlprosserpp/dev/c64projects/readyosprecog/logs/vice_auto_20260706_220333`
diff --git a/agentworking/easyflash_focus_largevars/readybasic_large_vars_probe.easyflash.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_focus_largevars/readybasic_large_vars_probe.easyflash.yaml
similarity index 100%
rename from agentworking/easyflash_focus_largevars/readybasic_large_vars_probe.easyflash.yaml
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_focus_largevars/readybasic_large_vars_probe.easyflash.yaml
diff --git a/agentworking/easyflash_focus_largevars/readybasic_large_vars_probe.regular.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_focus_largevars/readybasic_large_vars_probe.regular.yaml
similarity index 100%
rename from agentworking/easyflash_focus_largevars/readybasic_large_vars_probe.regular.yaml
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_focus_largevars/readybasic_large_vars_probe.regular.yaml
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_focus_largevars/readyos_data.easyflash-vice.d64 b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_focus_largevars/readyos_data.easyflash-vice.d64
new file mode 100644
index 0000000..61aa86d
Binary files /dev/null and b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_focus_largevars/readyos_data.easyflash-vice.d64 differ
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_cross_app_resume_probe.easyflash.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_cross_app_resume_probe.easyflash.yaml
new file mode 100644
index 0000000..a5cf7e8
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_cross_app_resume_probe.easyflash.yaml
@@ -0,0 +1,1173 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_cross_app_resume_probe_easyflash
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 240
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
+ autostart_enabled: false
+ disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
+ drive8_enabled: true
+ drive8_type: 1541
+ drive9_enabled: false
+ true_drive: true
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: easyflash_wait_launcher
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ pre_delay_s: 4
+ poll_s: 0.5
+ wait_timeout_s: 420
+ capture_label: easyflash_readybasic_launcher
+ - id: easyflash_start_readybasic
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 180
+ capture_label: readybasic_prompt
+ - id: build_program_lines
+ type: input.sequence
+ params:
+ keys: [78,69,87,13,49,48,32,80,82,73,78,84,32,34,79,78,69,34,13,50,48,32,80,82,73,78,84,32,34,84,87,79,34,13,51,48,32,80,82,73,78,84,32,34,84,72,82,69,69,34,13,52,48,32,80,82,73,78,84,32,34,70,79,85,82,34,13,53,48,32,80,82,73,78,84,32,34,70,73,86,69,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: clear_variables_after_program_entry
+ type: input.sequence
+ params:
+ keys: [67,76,82,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.5
+ - id: seed_large_direct_vars
+ type: input.sequence
+ params:
+ keys: [65,36,61,34,65,76,80,72,65,34,13,66,36,61,34,66,82,65,86,79,34,13,71,36,61,34,67,72,65,82,76,73,69,34,13,68,36,61,34,68,69,76,84,65,34,13,68,73,77,32,69,40,50,48,48,41,13,69,40,49,57,57,41,61,49,50,51,52,13,80,82,73,78,84,32,65,36,13,80,82,73,78,84,32,66,36,13,80,82,73,78,84,32,71,36,13,80,82,73,78,84,32,68,36,13,80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: assert_setup_alpha
+ type: assert.screen
+ params:
+ contains: "ALPHA"
+ - id: assert_setup_bravo
+ type: assert.screen
+ params:
+ contains: "BRAVO"
+ - id: assert_setup_charlie
+ type: assert.screen
+ params:
+ contains: "CHARLIE"
+ - id: assert_setup_delta
+ type: assert.screen
+ params:
+ contains: "DELTA"
+ - id: assert_setup_array
+ type: assert.screen
+ params:
+ contains: "1234"
+ - id: exit_readybasic_1
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_exit_1
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ # The cross-app leg deliberately uses Editor as the deterministic
+ # "other app" so this probe tests ReadyBASIC suspend/resume only.
+ - id: move_from_readybasic_to_editor_1
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_1
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: ctrl_b_to_launcher_from_editor_1
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_1
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_from_editor_to_readybasic_1
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_resume_1
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_resume_1
+ - id: list_after_cross_app_1
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_after_cross_app_1
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: print_a_after_cross_app_1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_a_after_cross_app_1
+ type: assert.screen
+ params:
+ contains: "ALPHA"
+ - id: print_b_after_cross_app_1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_b_after_cross_app_1
+ type: assert.screen
+ params:
+ contains: "BRAVO"
+ - id: print_g_after_cross_app_1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,71,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_g_after_cross_app_1
+ type: assert.screen
+ params:
+ contains: "CHARLIE"
+ - id: print_d_after_cross_app_1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_d_after_cross_app_1
+ type: assert.screen
+ params:
+ contains: "DELTA"
+ - id: print_e_after_cross_app_1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_e_after_cross_app_1
+ type: assert.screen
+ params:
+ contains: "1234"
+ - id: exit_readybasic_2
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_exit_2
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ # The cross-app leg deliberately uses Editor as the deterministic
+ # "other app" so this probe tests ReadyBASIC suspend/resume only.
+ - id: move_from_readybasic_to_editor_2
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_2
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: ctrl_b_to_launcher_from_editor_2
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_2
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_from_editor_to_readybasic_2
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_resume_2
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_resume_2
+ - id: list_after_cross_app_2
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_after_cross_app_2
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: print_a_after_cross_app_2
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_a_after_cross_app_2
+ type: assert.screen
+ params:
+ contains: "ALPHA"
+ - id: print_b_after_cross_app_2
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_b_after_cross_app_2
+ type: assert.screen
+ params:
+ contains: "BRAVO"
+ - id: print_g_after_cross_app_2
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,71,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_g_after_cross_app_2
+ type: assert.screen
+ params:
+ contains: "CHARLIE"
+ - id: print_d_after_cross_app_2
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_d_after_cross_app_2
+ type: assert.screen
+ params:
+ contains: "DELTA"
+ - id: print_e_after_cross_app_2
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_e_after_cross_app_2
+ type: assert.screen
+ params:
+ contains: "1234"
+ - id: exit_readybasic_3
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_exit_3
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ # The cross-app leg deliberately uses Editor as the deterministic
+ # "other app" so this probe tests ReadyBASIC suspend/resume only.
+ - id: move_from_readybasic_to_editor_3
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_3
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: ctrl_b_to_launcher_from_editor_3
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_3
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_from_editor_to_readybasic_3
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_resume_3
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_resume_3
+ - id: list_after_cross_app_3
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_after_cross_app_3
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: print_a_after_cross_app_3
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_a_after_cross_app_3
+ type: assert.screen
+ params:
+ contains: "ALPHA"
+ - id: print_b_after_cross_app_3
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_b_after_cross_app_3
+ type: assert.screen
+ params:
+ contains: "BRAVO"
+ - id: print_g_after_cross_app_3
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,71,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_g_after_cross_app_3
+ type: assert.screen
+ params:
+ contains: "CHARLIE"
+ - id: print_d_after_cross_app_3
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_d_after_cross_app_3
+ type: assert.screen
+ params:
+ contains: "DELTA"
+ - id: print_e_after_cross_app_3
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_e_after_cross_app_3
+ type: assert.screen
+ params:
+ contains: "1234"
+ - id: exit_readybasic_4
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_exit_4
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ # The cross-app leg deliberately uses Editor as the deterministic
+ # "other app" so this probe tests ReadyBASIC suspend/resume only.
+ - id: move_from_readybasic_to_editor_4
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_4
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: ctrl_b_to_launcher_from_editor_4
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_4
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_from_editor_to_readybasic_4
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_resume_4
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_resume_4
+ - id: list_after_cross_app_4
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_after_cross_app_4
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: print_a_after_cross_app_4
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_a_after_cross_app_4
+ type: assert.screen
+ params:
+ contains: "ALPHA"
+ - id: print_b_after_cross_app_4
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_b_after_cross_app_4
+ type: assert.screen
+ params:
+ contains: "BRAVO"
+ - id: print_g_after_cross_app_4
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,71,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_g_after_cross_app_4
+ type: assert.screen
+ params:
+ contains: "CHARLIE"
+ - id: print_d_after_cross_app_4
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_d_after_cross_app_4
+ type: assert.screen
+ params:
+ contains: "DELTA"
+ - id: print_e_after_cross_app_4
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_e_after_cross_app_4
+ type: assert.screen
+ params:
+ contains: "1234"
+ - id: exit_readybasic_5
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_exit_5
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ # The cross-app leg deliberately uses Editor as the deterministic
+ # "other app" so this probe tests ReadyBASIC suspend/resume only.
+ - id: move_from_readybasic_to_editor_5
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_5
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: ctrl_b_to_launcher_from_editor_5
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_5
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_from_editor_to_readybasic_5
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_resume_5
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_resume_5
+ - id: list_after_cross_app_5
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_after_cross_app_5
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: print_a_after_cross_app_5
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_a_after_cross_app_5
+ type: assert.screen
+ params:
+ contains: "ALPHA"
+ - id: print_b_after_cross_app_5
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_b_after_cross_app_5
+ type: assert.screen
+ params:
+ contains: "BRAVO"
+ - id: print_g_after_cross_app_5
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,71,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_g_after_cross_app_5
+ type: assert.screen
+ params:
+ contains: "CHARLIE"
+ - id: print_d_after_cross_app_5
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_d_after_cross_app_5
+ type: assert.screen
+ params:
+ contains: "DELTA"
+ - id: print_e_after_cross_app_5
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_e_after_cross_app_5
+ type: assert.screen
+ params:
+ contains: "1234"
+ - id: exit_readybasic_6
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_exit_6
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ # The cross-app leg deliberately uses Editor as the deterministic
+ # "other app" so this probe tests ReadyBASIC suspend/resume only.
+ - id: move_from_readybasic_to_editor_6
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_6
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: ctrl_b_to_launcher_from_editor_6
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_6
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_from_editor_to_readybasic_6
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_resume_6
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_resume_6
+ - id: list_after_cross_app_6
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_after_cross_app_6
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: print_a_after_cross_app_6
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_a_after_cross_app_6
+ type: assert.screen
+ params:
+ contains: "ALPHA"
+ - id: print_b_after_cross_app_6
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_b_after_cross_app_6
+ type: assert.screen
+ params:
+ contains: "BRAVO"
+ - id: print_g_after_cross_app_6
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,71,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_g_after_cross_app_6
+ type: assert.screen
+ params:
+ contains: "CHARLIE"
+ - id: print_d_after_cross_app_6
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_d_after_cross_app_6
+ type: assert.screen
+ params:
+ contains: "DELTA"
+ - id: print_e_after_cross_app_6
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_e_after_cross_app_6
+ type: assert.screen
+ params:
+ contains: "1234"
+ - id: exit_readybasic_7
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_exit_7
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ # The cross-app leg deliberately uses Editor as the deterministic
+ # "other app" so this probe tests ReadyBASIC suspend/resume only.
+ - id: move_from_readybasic_to_editor_7
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_7
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: ctrl_b_to_launcher_from_editor_7
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_7
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_from_editor_to_readybasic_7
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_resume_7
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_resume_7
+ - id: list_after_cross_app_7
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_after_cross_app_7
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: print_a_after_cross_app_7
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_a_after_cross_app_7
+ type: assert.screen
+ params:
+ contains: "ALPHA"
+ - id: print_b_after_cross_app_7
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_b_after_cross_app_7
+ type: assert.screen
+ params:
+ contains: "BRAVO"
+ - id: print_g_after_cross_app_7
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,71,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_g_after_cross_app_7
+ type: assert.screen
+ params:
+ contains: "CHARLIE"
+ - id: print_d_after_cross_app_7
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_d_after_cross_app_7
+ type: assert.screen
+ params:
+ contains: "DELTA"
+ - id: print_e_after_cross_app_7
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_e_after_cross_app_7
+ type: assert.screen
+ params:
+ contains: "1234"
+ - id: exit_readybasic_8
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_exit_8
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ # The cross-app leg deliberately uses Editor as the deterministic
+ # "other app" so this probe tests ReadyBASIC suspend/resume only.
+ - id: move_from_readybasic_to_editor_8
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_8
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: ctrl_b_to_launcher_from_editor_8
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_8
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_from_editor_to_readybasic_8
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_resume_8
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_resume_8
+ - id: list_after_cross_app_8
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_after_cross_app_8
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: print_a_after_cross_app_8
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_a_after_cross_app_8
+ type: assert.screen
+ params:
+ contains: "ALPHA"
+ - id: print_b_after_cross_app_8
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_b_after_cross_app_8
+ type: assert.screen
+ params:
+ contains: "BRAVO"
+ - id: print_g_after_cross_app_8
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,71,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_g_after_cross_app_8
+ type: assert.screen
+ params:
+ contains: "CHARLIE"
+ - id: print_d_after_cross_app_8
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_d_after_cross_app_8
+ type: assert.screen
+ params:
+ contains: "DELTA"
+ - id: print_e_after_cross_app_8
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_e_after_cross_app_8
+ type: assert.screen
+ params:
+ contains: "1234"
+ - id: exit_readybasic_9
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_exit_9
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ # The cross-app leg deliberately uses Editor as the deterministic
+ # "other app" so this probe tests ReadyBASIC suspend/resume only.
+ - id: move_from_readybasic_to_editor_9
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_9
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: ctrl_b_to_launcher_from_editor_9
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_9
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_from_editor_to_readybasic_9
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_resume_9
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_resume_9
+ - id: list_after_cross_app_9
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_after_cross_app_9
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: print_a_after_cross_app_9
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_a_after_cross_app_9
+ type: assert.screen
+ params:
+ contains: "ALPHA"
+ - id: print_b_after_cross_app_9
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_b_after_cross_app_9
+ type: assert.screen
+ params:
+ contains: "BRAVO"
+ - id: print_g_after_cross_app_9
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,71,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_g_after_cross_app_9
+ type: assert.screen
+ params:
+ contains: "CHARLIE"
+ - id: print_d_after_cross_app_9
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_d_after_cross_app_9
+ type: assert.screen
+ params:
+ contains: "DELTA"
+ - id: print_e_after_cross_app_9
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_e_after_cross_app_9
+ type: assert.screen
+ params:
+ contains: "1234"
+ - id: exit_readybasic_10
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_exit_10
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ # The cross-app leg deliberately uses Editor as the deterministic
+ # "other app" so this probe tests ReadyBASIC suspend/resume only.
+ - id: move_from_readybasic_to_editor_10
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_10
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: ctrl_b_to_launcher_from_editor_10
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_10
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_from_editor_to_readybasic_10
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_resume_10
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_resume_10
+ - id: list_after_cross_app_10
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_after_cross_app_10
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: print_a_after_cross_app_10
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_a_after_cross_app_10
+ type: assert.screen
+ params:
+ contains: "ALPHA"
+ - id: print_b_after_cross_app_10
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_b_after_cross_app_10
+ type: assert.screen
+ params:
+ contains: "BRAVO"
+ - id: print_g_after_cross_app_10
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,71,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_g_after_cross_app_10
+ type: assert.screen
+ params:
+ contains: "CHARLIE"
+ - id: print_d_after_cross_app_10
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_d_after_cross_app_10
+ type: assert.screen
+ params:
+ contains: "DELTA"
+ - id: print_e_after_cross_app_10
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_e_after_cross_app_10
+ type: assert.screen
+ params:
+ contains: "1234"
+ - id: dump_final_state
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_text_and_vars_1200, start: 0x1200, end: 0x1700 }
+ - { label: string_heap_9400, start: 0x9400, end: 0x9600 }
+ - { label: runtime_state_9600, start: 0x9600, end: 0x9A00 }
+ - { label: bridge_c000, start: 0xC000, end: 0xC5FF }
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_cross_app_resume_probe.regular.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_cross_app_resume_probe.regular.yaml
new file mode 100644
index 0000000..fbe9e7a
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_cross_app_resume_probe.regular.yaml
@@ -0,0 +1,1158 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_cross_app_resume_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 240
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 180
+ capture_label: readybasic_prompt
+ - id: build_program_lines
+ type: input.sequence
+ params:
+ keys: [78,69,87,13,49,48,32,80,82,73,78,84,32,34,79,78,69,34,13,50,48,32,80,82,73,78,84,32,34,84,87,79,34,13,51,48,32,80,82,73,78,84,32,34,84,72,82,69,69,34,13,52,48,32,80,82,73,78,84,32,34,70,79,85,82,34,13,53,48,32,80,82,73,78,84,32,34,70,73,86,69,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: clear_variables_after_program_entry
+ type: input.sequence
+ params:
+ keys: [67,76,82,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.5
+ - id: seed_large_direct_vars
+ type: input.sequence
+ params:
+ keys: [65,36,61,34,65,76,80,72,65,34,13,66,36,61,34,66,82,65,86,79,34,13,71,36,61,34,67,72,65,82,76,73,69,34,13,68,36,61,34,68,69,76,84,65,34,13,68,73,77,32,69,40,50,48,48,41,13,69,40,49,57,57,41,61,49,50,51,52,13,80,82,73,78,84,32,65,36,13,80,82,73,78,84,32,66,36,13,80,82,73,78,84,32,71,36,13,80,82,73,78,84,32,68,36,13,80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: assert_setup_alpha
+ type: assert.screen
+ params:
+ contains: "ALPHA"
+ - id: assert_setup_bravo
+ type: assert.screen
+ params:
+ contains: "BRAVO"
+ - id: assert_setup_charlie
+ type: assert.screen
+ params:
+ contains: "CHARLIE"
+ - id: assert_setup_delta
+ type: assert.screen
+ params:
+ contains: "DELTA"
+ - id: assert_setup_array
+ type: assert.screen
+ params:
+ contains: "1234"
+ - id: exit_readybasic_1
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_exit_1
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ # The cross-app leg deliberately uses Editor as the deterministic
+ # "other app" so this probe tests ReadyBASIC suspend/resume only.
+ - id: move_from_readybasic_to_editor_1
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_1
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: ctrl_b_to_launcher_from_editor_1
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_1
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_from_editor_to_readybasic_1
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_resume_1
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_resume_1
+ - id: list_after_cross_app_1
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_after_cross_app_1
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: print_a_after_cross_app_1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_a_after_cross_app_1
+ type: assert.screen
+ params:
+ contains: "ALPHA"
+ - id: print_b_after_cross_app_1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_b_after_cross_app_1
+ type: assert.screen
+ params:
+ contains: "BRAVO"
+ - id: print_g_after_cross_app_1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,71,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_g_after_cross_app_1
+ type: assert.screen
+ params:
+ contains: "CHARLIE"
+ - id: print_d_after_cross_app_1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_d_after_cross_app_1
+ type: assert.screen
+ params:
+ contains: "DELTA"
+ - id: print_e_after_cross_app_1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_e_after_cross_app_1
+ type: assert.screen
+ params:
+ contains: "1234"
+ - id: exit_readybasic_2
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_exit_2
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ # The cross-app leg deliberately uses Editor as the deterministic
+ # "other app" so this probe tests ReadyBASIC suspend/resume only.
+ - id: move_from_readybasic_to_editor_2
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_2
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: ctrl_b_to_launcher_from_editor_2
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_2
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_from_editor_to_readybasic_2
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_resume_2
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_resume_2
+ - id: list_after_cross_app_2
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_after_cross_app_2
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: print_a_after_cross_app_2
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_a_after_cross_app_2
+ type: assert.screen
+ params:
+ contains: "ALPHA"
+ - id: print_b_after_cross_app_2
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_b_after_cross_app_2
+ type: assert.screen
+ params:
+ contains: "BRAVO"
+ - id: print_g_after_cross_app_2
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,71,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_g_after_cross_app_2
+ type: assert.screen
+ params:
+ contains: "CHARLIE"
+ - id: print_d_after_cross_app_2
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_d_after_cross_app_2
+ type: assert.screen
+ params:
+ contains: "DELTA"
+ - id: print_e_after_cross_app_2
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_e_after_cross_app_2
+ type: assert.screen
+ params:
+ contains: "1234"
+ - id: exit_readybasic_3
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_exit_3
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ # The cross-app leg deliberately uses Editor as the deterministic
+ # "other app" so this probe tests ReadyBASIC suspend/resume only.
+ - id: move_from_readybasic_to_editor_3
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_3
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: ctrl_b_to_launcher_from_editor_3
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_3
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_from_editor_to_readybasic_3
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_resume_3
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_resume_3
+ - id: list_after_cross_app_3
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_after_cross_app_3
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: print_a_after_cross_app_3
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_a_after_cross_app_3
+ type: assert.screen
+ params:
+ contains: "ALPHA"
+ - id: print_b_after_cross_app_3
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_b_after_cross_app_3
+ type: assert.screen
+ params:
+ contains: "BRAVO"
+ - id: print_g_after_cross_app_3
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,71,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_g_after_cross_app_3
+ type: assert.screen
+ params:
+ contains: "CHARLIE"
+ - id: print_d_after_cross_app_3
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_d_after_cross_app_3
+ type: assert.screen
+ params:
+ contains: "DELTA"
+ - id: print_e_after_cross_app_3
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_e_after_cross_app_3
+ type: assert.screen
+ params:
+ contains: "1234"
+ - id: exit_readybasic_4
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_exit_4
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ # The cross-app leg deliberately uses Editor as the deterministic
+ # "other app" so this probe tests ReadyBASIC suspend/resume only.
+ - id: move_from_readybasic_to_editor_4
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_4
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: ctrl_b_to_launcher_from_editor_4
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_4
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_from_editor_to_readybasic_4
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_resume_4
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_resume_4
+ - id: list_after_cross_app_4
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_after_cross_app_4
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: print_a_after_cross_app_4
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_a_after_cross_app_4
+ type: assert.screen
+ params:
+ contains: "ALPHA"
+ - id: print_b_after_cross_app_4
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_b_after_cross_app_4
+ type: assert.screen
+ params:
+ contains: "BRAVO"
+ - id: print_g_after_cross_app_4
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,71,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_g_after_cross_app_4
+ type: assert.screen
+ params:
+ contains: "CHARLIE"
+ - id: print_d_after_cross_app_4
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_d_after_cross_app_4
+ type: assert.screen
+ params:
+ contains: "DELTA"
+ - id: print_e_after_cross_app_4
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_e_after_cross_app_4
+ type: assert.screen
+ params:
+ contains: "1234"
+ - id: exit_readybasic_5
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_exit_5
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ # The cross-app leg deliberately uses Editor as the deterministic
+ # "other app" so this probe tests ReadyBASIC suspend/resume only.
+ - id: move_from_readybasic_to_editor_5
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_5
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: ctrl_b_to_launcher_from_editor_5
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_5
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_from_editor_to_readybasic_5
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_resume_5
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_resume_5
+ - id: list_after_cross_app_5
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_after_cross_app_5
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: print_a_after_cross_app_5
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_a_after_cross_app_5
+ type: assert.screen
+ params:
+ contains: "ALPHA"
+ - id: print_b_after_cross_app_5
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_b_after_cross_app_5
+ type: assert.screen
+ params:
+ contains: "BRAVO"
+ - id: print_g_after_cross_app_5
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,71,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_g_after_cross_app_5
+ type: assert.screen
+ params:
+ contains: "CHARLIE"
+ - id: print_d_after_cross_app_5
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_d_after_cross_app_5
+ type: assert.screen
+ params:
+ contains: "DELTA"
+ - id: print_e_after_cross_app_5
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_e_after_cross_app_5
+ type: assert.screen
+ params:
+ contains: "1234"
+ - id: exit_readybasic_6
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_exit_6
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ # The cross-app leg deliberately uses Editor as the deterministic
+ # "other app" so this probe tests ReadyBASIC suspend/resume only.
+ - id: move_from_readybasic_to_editor_6
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_6
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: ctrl_b_to_launcher_from_editor_6
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_6
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_from_editor_to_readybasic_6
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_resume_6
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_resume_6
+ - id: list_after_cross_app_6
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_after_cross_app_6
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: print_a_after_cross_app_6
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_a_after_cross_app_6
+ type: assert.screen
+ params:
+ contains: "ALPHA"
+ - id: print_b_after_cross_app_6
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_b_after_cross_app_6
+ type: assert.screen
+ params:
+ contains: "BRAVO"
+ - id: print_g_after_cross_app_6
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,71,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_g_after_cross_app_6
+ type: assert.screen
+ params:
+ contains: "CHARLIE"
+ - id: print_d_after_cross_app_6
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_d_after_cross_app_6
+ type: assert.screen
+ params:
+ contains: "DELTA"
+ - id: print_e_after_cross_app_6
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_e_after_cross_app_6
+ type: assert.screen
+ params:
+ contains: "1234"
+ - id: exit_readybasic_7
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_exit_7
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ # The cross-app leg deliberately uses Editor as the deterministic
+ # "other app" so this probe tests ReadyBASIC suspend/resume only.
+ - id: move_from_readybasic_to_editor_7
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_7
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: ctrl_b_to_launcher_from_editor_7
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_7
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_from_editor_to_readybasic_7
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_resume_7
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_resume_7
+ - id: list_after_cross_app_7
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_after_cross_app_7
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: print_a_after_cross_app_7
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_a_after_cross_app_7
+ type: assert.screen
+ params:
+ contains: "ALPHA"
+ - id: print_b_after_cross_app_7
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_b_after_cross_app_7
+ type: assert.screen
+ params:
+ contains: "BRAVO"
+ - id: print_g_after_cross_app_7
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,71,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_g_after_cross_app_7
+ type: assert.screen
+ params:
+ contains: "CHARLIE"
+ - id: print_d_after_cross_app_7
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_d_after_cross_app_7
+ type: assert.screen
+ params:
+ contains: "DELTA"
+ - id: print_e_after_cross_app_7
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_e_after_cross_app_7
+ type: assert.screen
+ params:
+ contains: "1234"
+ - id: exit_readybasic_8
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_exit_8
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ # The cross-app leg deliberately uses Editor as the deterministic
+ # "other app" so this probe tests ReadyBASIC suspend/resume only.
+ - id: move_from_readybasic_to_editor_8
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_8
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: ctrl_b_to_launcher_from_editor_8
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_8
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_from_editor_to_readybasic_8
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_resume_8
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_resume_8
+ - id: list_after_cross_app_8
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_after_cross_app_8
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: print_a_after_cross_app_8
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_a_after_cross_app_8
+ type: assert.screen
+ params:
+ contains: "ALPHA"
+ - id: print_b_after_cross_app_8
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_b_after_cross_app_8
+ type: assert.screen
+ params:
+ contains: "BRAVO"
+ - id: print_g_after_cross_app_8
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,71,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_g_after_cross_app_8
+ type: assert.screen
+ params:
+ contains: "CHARLIE"
+ - id: print_d_after_cross_app_8
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_d_after_cross_app_8
+ type: assert.screen
+ params:
+ contains: "DELTA"
+ - id: print_e_after_cross_app_8
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_e_after_cross_app_8
+ type: assert.screen
+ params:
+ contains: "1234"
+ - id: exit_readybasic_9
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_exit_9
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ # The cross-app leg deliberately uses Editor as the deterministic
+ # "other app" so this probe tests ReadyBASIC suspend/resume only.
+ - id: move_from_readybasic_to_editor_9
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_9
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: ctrl_b_to_launcher_from_editor_9
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_9
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_from_editor_to_readybasic_9
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_resume_9
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_resume_9
+ - id: list_after_cross_app_9
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_after_cross_app_9
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: print_a_after_cross_app_9
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_a_after_cross_app_9
+ type: assert.screen
+ params:
+ contains: "ALPHA"
+ - id: print_b_after_cross_app_9
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_b_after_cross_app_9
+ type: assert.screen
+ params:
+ contains: "BRAVO"
+ - id: print_g_after_cross_app_9
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,71,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_g_after_cross_app_9
+ type: assert.screen
+ params:
+ contains: "CHARLIE"
+ - id: print_d_after_cross_app_9
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_d_after_cross_app_9
+ type: assert.screen
+ params:
+ contains: "DELTA"
+ - id: print_e_after_cross_app_9
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_e_after_cross_app_9
+ type: assert.screen
+ params:
+ contains: "1234"
+ - id: exit_readybasic_10
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_exit_10
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ # The cross-app leg deliberately uses Editor as the deterministic
+ # "other app" so this probe tests ReadyBASIC suspend/resume only.
+ - id: move_from_readybasic_to_editor_10
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_10
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: ctrl_b_to_launcher_from_editor_10
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_10
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_from_editor_to_readybasic_10
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_resume_10
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_resume_10
+ - id: list_after_cross_app_10
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_after_cross_app_10
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: print_a_after_cross_app_10
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_a_after_cross_app_10
+ type: assert.screen
+ params:
+ contains: "ALPHA"
+ - id: print_b_after_cross_app_10
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_b_after_cross_app_10
+ type: assert.screen
+ params:
+ contains: "BRAVO"
+ - id: print_g_after_cross_app_10
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,71,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_g_after_cross_app_10
+ type: assert.screen
+ params:
+ contains: "CHARLIE"
+ - id: print_d_after_cross_app_10
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_d_after_cross_app_10
+ type: assert.screen
+ params:
+ contains: "DELTA"
+ - id: print_e_after_cross_app_10
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: assert_e_after_cross_app_10
+ type: assert.screen
+ params:
+ contains: "1234"
+ - id: dump_final_state
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_text_and_vars_1200, start: 0x1200, end: 0x1700 }
+ - { label: string_heap_9400, start: 0x9400, end: 0x9600 }
+ - { label: runtime_state_9600, start: 0x9600, end: 0x9A00 }
+ - { label: bridge_c000, start: 0xC000, end: 0xC5FF }
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_demo_suite.easyflash.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_demo_suite.easyflash.yaml
new file mode 100644
index 0000000..b03998c
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_demo_suite.easyflash.yaml
@@ -0,0 +1,452 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_demo_suite_easyflash
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 240
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
+ autostart_enabled: false
+ disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
+ drive8_enabled: true
+ drive8_type: 1541
+ drive9_enabled: false
+ true_drive: true
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: easyflash_wait_launcher
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ pre_delay_s: 4
+ poll_s: 0.5
+ wait_timeout_s: 420
+ capture_label: easyflash_readybasic_launcher
+ - id: easyflash_start_readybasic
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "FREE:"
+ wait_timeout_s: 180
+ capture_label: demo_readybasic_prompt
+ - id: warp_off_for_visible_demo
+ type: warp.set
+ params:
+ enabled: false
+ capture_after: false
+ - id: demo_01_intro
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,49,58,32,82,69,65,68,89,66,65,83,73,67,32,66,65,83,73,67,83,34,13,80,82,73,78,84,32,34,70,82,69,69,77,69,77,44,32,86,65,82,73,65,66,76,69,83,44,32,65,78,68,32,65,32,80,82,79,71,82,65,77,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_01_setup
+ type: input.sequence
+ params:
+ keys: [70,82,69,69,77,69,77,40,41,13,78,69,87,13,65,37,61,52,50,13,49,48,32,66,37,61,90,65,68,68,49,54,40,52,50,44,56,41,13,50,48,32,80,82,73,78,84,32,34,80,82,79,71,82,65,77,32,83,85,77,34,59,66,37,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_01_list
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_01_basics
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,82,85,78,32,80,82,73,78,84,83,32,80,82,79,71,82,65,77,32,83,85,77,32,53,48,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13,82,85,78,13,65,37,61,52,50,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: assert_demo_01_program_sum
+ type: assert.screen
+ params:
+ contains: "PROGRAM SUM 50"
+ - id: demo_02_intro
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,50,58,32,83,85,83,80,69,78,68,32,65,78,68,32,82,69,83,84,79,82,69,34,13,80,82,73,78,84,32,34,69,88,73,84,32,84,79,32,82,69,65,68,89,79,83,44,32,86,73,83,73,84,32,69,68,73,84,79,82,44,32,82,69,84,85,82,78,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_02_exit_to_launcher
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: capture_after_demo_02_exit
+ type: screen.capture
+ params:
+ label: after_demo_02_exit
+ - id: wait_launcher_after_demo_02_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_readybasic_to_editor_demo
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.05
+ post_delay_s: 3.5
+ - id: wait_editor_demo
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: type_editor_demo_sentence
+ type: input.sequence
+ params:
+ keys: [82,69,65,68,89,66,65,83,73,67,32,68,69,77,79,32,86,73,83,73,84,69,68,32,69,68,73,84,79,82,32,65,78,68,32,82,69,84,85,82,78,69,68,46,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: ctrl_b_editor_demo
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.05
+ post_delay_s: 3.5
+ - id: wait_launcher_after_editor_demo
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_editor_to_readybasic_demo
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.05
+ post_delay_s: 3.5
+ - id: wait_readybasic_after_editor_demo
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 60
+ - id: demo_03_resume_liveness
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,82,69,83,85,77,69,32,76,73,86,69,34,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: assert_demo_03_resume_liveness
+ type: assert.screen
+ params:
+ contains: "RESUME LIVE"
+ - id: demo_03_resume_intro_clear
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,66,65,67,75,32,73,78,32,82,69,65,68,89,66,65,83,73,67,34,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_03_resume_intro_detail
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,86,65,82,73,65,66,76,69,83,32,65,78,68,32,80,82,79,71,82,65,77,32,84,69,88,84,32,83,72,79,85,76,68,32,82,69,77,65,73,78,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_03_resume_var_proof
+ type: input.sequence
+ params:
+ keys: [70,82,69,69,77,69,77,40,41,13,80,82,73,78,84,32,34,65,32,83,84,73,76,76,34,59,65,37,13,80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,65,32,73,83,32,52,50,32,65,78,68,32,82,85,78,32,83,84,73,76,76,32,87,79,82,75,83,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: capture_demo_03_resume_var_proof
+ type: screen.capture
+ params:
+ label: demo_03_resume_var_proof
+ - id: assert_demo_03_var_restored
+ type: assert.screen
+ params:
+ contains: "A STILL 42"
+ - id: demo_03_resume_run_proof
+ type: input.sequence
+ params:
+ keys: [82,85,78,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: assert_demo_03_program_restored
+ type: assert.screen
+ params:
+ contains: "PROGRAM SUM 50"
+ - id: demo_04_intro
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,51,58,32,65,83,83,69,77,66,76,69,82,32,67,79,77,77,65,78,68,83,34,13,80,82,73,78,84,32,34,67,79,77,77,65,78,68,83,32,82,69,84,85,82,78,32,86,65,76,85,69,83,32,65,83,32,69,88,80,82,69,83,83,73,79,78,83,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_04_assembler_setup
+ type: input.sequence
+ params:
+ keys: [78,37,61,90,65,68,68,49,54,40,55,44,56,41,13,84,36,61,85,80,80,69,82,40,34,114,101,97,100,121,34,41,13,76,36,61,76,79,87,69,82,40,34,76,79,85,68,34,41,13,72,37,61,90,72,73,68,68,69,78,82,65,77,40,34,65,66,34,41,13,80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,49,53,44,32,82,69,65,68,89,44,32,76,79,87,69,82,44,32,49,51,49,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_04_zadd_print
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,90,65,68,68,34,59,78,37,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_04_upper_print
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,85,80,80,69,82,32,34,59,84,36,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_04_lower_print
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,76,79,87,65,83,67,34,59,65,83,67,40,76,36,41,59,65,83,67,40,77,73,68,36,40,76,36,44,50,44,49,41,41,59,65,83,67,40,77,73,68,36,40,76,36,44,51,44,49,41,41,59,65,83,67,40,77,73,68,36,40,76,36,44,52,44,49,41,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_04_hidden_print
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,72,73,68,68,69,78,34,59,72,37,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: assert_demo_04_zadd
+ type: assert.screen
+ params:
+ contains: "ZADD 15"
+ - id: assert_demo_04_upper
+ type: assert.screen
+ params:
+ contains: "UPPER READY"
+ - id: assert_demo_04_hidden
+ type: assert.screen
+ params:
+ contains: "HIDDEN 131"
+ - id: demo_05_intro
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,52,58,32,80,82,79,67,32,79,78,76,89,34,13,80,82,73,78,84,32,34,80,82,79,67,32,84,65,75,69,83,32,80,65,82,65,77,69,84,69,82,83,32,65,78,68,32,68,79,69,83,32,87,79,82,75,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_05_program
+ type: input.sequence
+ params:
+ keys: [78,69,87,13,49,48,32,69,88,69,67,32,83,72,79,87,40,34,82,69,65,68,89,34,41,13,50,48,32,69,78,68,13,49,48,48,32,80,82,79,67,32,83,72,79,87,40,83,36,41,13,49,49,48,32,32,80,82,73,78,84,32,34,80,82,79,67,32,34,59,83,36,13,49,50,48,32,69,78,68,80,13,76,73,83,84,32,49,48,48,45,49,50,48,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_05_proc_func
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,80,82,79,67,32,82,69,65,68,89,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13,82,85,78,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: assert_demo_05_proc
+ type: assert.screen
+ params:
+ contains: "PROC READY"
+ - id: demo_05b_intro
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,53,58,32,73,78,84,69,71,69,82,32,70,85,78,67,34,13,80,82,73,78,84,32,34,70,85,78,67,32,82,69,84,85,82,78,83,32,84,72,82,79,85,71,72,32,82,69,84,32,65,83,32,65,78,32,69,88,80,82,69,83,83,73,79,78,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_05b_program
+ type: input.sequence
+ params:
+ keys: [78,69,87,13,49,48,32,65,37,61,65,68,68,73,40,52,44,53,41,13,50,48,32,80,82,73,78,84,32,34,65,68,68,73,34,59,65,37,13,51,48,32,69,78,68,13,49,48,48,32,70,85,78,67,32,65,68,68,73,40,88,37,44,89,37,41,13,49,49,48,32,32,82,69,84,32,88,37,43,89,37,13,49,50,48,32,69,78,68,80,13,76,73,83,84,32,49,48,48,45,49,50,48,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_05b_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,65,68,68,73,32,57,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13,82,85,78,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: assert_demo_05_addi
+ type: assert.screen
+ params:
+ contains: "ADDI 9"
+ - id: demo_05c_intro
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,54,58,32,83,84,82,73,78,71,32,65,78,68,32,70,76,79,65,84,32,70,85,78,67,83,34,13,80,82,73,78,84,32,34,82,69,84,32,75,69,69,80,83,32,83,84,82,73,78,71,32,65,78,68,32,80,76,65,73,78,32,78,85,77,69,82,73,67,32,84,89,80,69,83,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_05c_program
+ type: input.sequence
+ params:
+ keys: [78,69,87,13,49,48,32,84,36,61,72,69,76,76,79,40,34,75,65,82,76,34,41,13,50,48,32,80,82,73,78,84,32,84,36,13,51,48,32,70,61,83,67,65,76,69,40,50,46,53,41,13,52,48,32,80,82,73,78,84,32,34,83,67,65,76,69,34,59,70,13,53,48,32,69,78,68,13,49,48,48,32,70,85,78,67,32,72,69,76,76,79,40,78,36,41,13,49,49,48,32,32,82,69,84,32,34,72,73,32,34,43,78,36,13,49,50,48,32,69,78,68,80,13,49,51,48,32,70,85,78,67,32,83,67,65,76,69,40,88,41,13,49,52,48,32,32,82,69,84,32,88,42,49,46,53,13,49,53,48,32,69,78,68,80,13,76,73,83,84,32,49,48,48,45,49,53,48,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_05c_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,72,73,32,75,65,82,76,32,65,78,68,32,83,67,65,76,69,32,51,46,55,53,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13,82,85,78,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: assert_demo_05_hello
+ type: assert.screen
+ params:
+ contains: "HI KARL"
+ - id: assert_demo_05_scale
+ type: assert.screen
+ params:
+ contains: "SCALE 3.75"
+ - id: demo_06_intro
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,55,58,32,80,65,82,65,77,69,84,69,82,32,71,82,79,85,80,83,34,13,80,82,73,78,84,32,34,65,82,82,65,89,83,44,32,73,78,84,69,71,69,82,32,82,69,84,85,82,78,83,44,32,65,78,68,32,70,76,79,65,84,83,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_06_parameter_groups
+ type: input.sequence
+ params:
+ keys: [68,73,77,32,65,37,40,51,41,58,65,37,40,48,41,61,49,58,65,37,40,49,41,61,50,58,65,37,40,50,41,61,51,13,83,37,61,90,83,85,77,78,85,77,65,82,82,65,89,40,65,37,40,48,41,44,51,41,13,68,73,77,32,82,37,40,52,41,58,90,82,65,78,71,69,78,85,77,65,82,82,65,89,40,55,44,52,44,82,37,40,48,41,41,13,70,61,70,65,68,68,40,49,46,50,44,50,46,51,41,13,80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,83,85,77,32,54,44,32,82,65,78,71,69,32,55,46,46,49,48,44,32,70,65,68,68,32,51,46,53,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13,80,82,73,78,84,32,34,83,85,77,34,59,83,37,13,80,82,73,78,84,32,34,82,65,78,71,69,34,59,82,37,40,48,41,59,82,37,40,51,41,13,80,82,73,78,84,32,34,70,65,68,68,34,59,70,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: assert_demo_06_sum
+ type: assert.screen
+ params:
+ contains: "SUM 6"
+ - id: assert_demo_06_range
+ type: assert.screen
+ params:
+ contains: "RANGE 7 10"
+ - id: assert_demo_06_fadd
+ type: assert.screen
+ params:
+ contains: "FADD 3.5"
+ - id: demo_07_intro
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,56,58,32,82,69,85,32,66,85,70,70,69,82,32,67,79,77,77,65,78,68,83,34,13,80,82,73,78,84,32,34,66,85,70,78,69,87,32,82,69,84,85,82,78,83,59,32,70,73,76,76,32,65,78,68,32,70,82,69,69,32,68,79,32,87,79,82,75,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_07_reu
+ type: input.sequence
+ params:
+ keys: [72,37,61,66,85,70,78,69,87,40,54,52,41,13,66,85,70,70,73,76,76,40,72,37,44,49,55,48,41,13,80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,72,65,78,68,76,69,32,49,44,32,84,72,69,78,32,70,82,69,69,68,32,49,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13,80,82,73,78,84,32,34,72,65,78,68,76,69,34,59,72,37,13,66,85,70,70,82,69,69,40,72,37,41,13,80,82,73,78,84,32,34,70,82,69,69,68,34,59,72,37,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: assert_demo_07_handle
+ type: assert.screen
+ params:
+ contains: "HANDLE 1"
+ - id: assert_demo_07_freed
+ type: assert.screen
+ params:
+ contains: "FREED 1"
+ - id: demo_08_intro
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,57,58,32,83,67,82,69,69,78,32,84,72,82,79,85,71,72,32,82,69,85,34,13,80,82,73,78,84,32,34,83,67,82,67,65,80,32,83,65,86,69,83,59,32,83,67,82,80,85,84,32,82,69,83,84,79,82,69,83,32,83,67,82,69,69,78,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_08_screen_reu_a
+ type: input.sequence
+ params:
+ keys: [78,69,87,13,49,48,32,68,73,77,32,72,37,40,52,41,13,50,48,32,70,79,82,32,83,61,49,32,84,79,32,52,13,51,48,32,80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,82,69,85,32,83,67,82,69,69,78,34,59,83,13,52,48,32,80,82,73,78,84,32,67,72,82,36,40,53,41,59,34,77,65,82,75,34,59,83,59,34,32,84,69,88,84,32,65,78,68,32,67,79,76,79,82,34,13,53,48,32,70,79,82,32,73,61,48,32,84,79,32,51,57,13,54,48,32,80,79,75,69,49,48,50,52,43,56,48,43,73,44,54,52,43,83,13,55,48,32,80,79,75,69,53,53,50,57,54,43,56,48,43,73,44,83,43,49,13,56,48,32,78,69,88,84,32,73,13,57,48,32,72,37,40,83,41,61,83,67,82,67,65,80,40,41,13,49,48,48,32,78,69,88,84,32,83,13,49,49,48,32,80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,82,69,85,32,70,76,73,80,66,79,79,75,34,13,49,50,48,32,80,82,73,78,84,32,67,72,82,36,40,53,41,59,34,69,88,80,69,67,84,58,32,70,79,85,82,32,82,69,83,84,79,82,69,68,32,83,67,82,69,69,78,83,34,13,49,51,48,32,70,79,82,32,83,61,49,32,84,79,32,52,13,49,52,48,32,83,67,82,80,85,84,40,72,37,40,83,41,41,13,49,53,48,32,80,82,73,78,84,32,67,72,82,36,40,49,57,41,59,34,82,69,83,84,79,82,69,68,34,59,83,59,34,47,52,34,13,49,54,48,32,90,80,65,85,83,69,40,51,48,41,13,49,55,48,32,78,69,88,84,32,83,13,49,56,48,32,80,82,73,78,84,32,67,72,82,36,40,49,57,41,59,34,82,69,83,84,79,82,69,68,32,52,32,82,69,85,32,83,67,82,69,69,78,83,34,13,49,57,48,32,69,78,68,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_08_screen_reu_b
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,70,79,85,82,32,68,73,70,70,69,82,69,78,84,32,83,67,82,69,69,78,83,32,70,76,73,80,32,66,65,67,75,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13,82,85,78,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: wait_demo_08_reu_flipbook
+ type: screen.wait_contains
+ params:
+ text: "RESTORED 4 REU SCREENS"
+ wait_timeout_s: 90
+ - id: assert_demo_08_reu_flipbook
+ type: assert.screen
+ params:
+ contains: "RESTORED 4 REU SCREENS"
+ - id: demo_09_intro
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,49,48,58,32,67,79,78,84,82,79,76,76,69,68,32,69,82,82,79,82,34,13,80,82,73,78,84,32,34,90,70,65,73,76,32,83,72,79,87,83,32,82,69,65,68,89,66,65,83,73,67,32,69,82,82,79,82,32,67,76,69,65,78,85,80,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_09_zfail
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,82,66,32,69,82,82,79,82,32,55,32,65,78,68,32,88,37,32,66,69,67,79,77,69,83,32,90,69,82,79,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13,88,37,61,57,57,13,90,70,65,73,76,40,55,44,88,37,41,13,80,82,73,78,84,32,34,65,70,84,69,82,32,70,65,73,76,34,59,88,37,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: assert_demo_09_rb_error
+ type: assert.screen
+ params:
+ contains: "RB ERROR 7"
+ - id: assert_demo_09_fail_clear
+ type: assert.screen
+ params:
+ contains: "AFTER FAIL 0"
+ - id: demo_10_intro
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,49,49,58,32,78,69,83,84,69,68,32,69,88,80,82,69,83,83,73,79,78,83,34,13,80,82,73,78,84,32,34,67,79,77,77,65,78,68,83,32,65,78,68,32,70,85,78,67,83,32,70,69,69,68,32,79,84,72,69,82,32,69,88,80,82,69,83,83,73,79,78,83,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_10_program
+ type: input.sequence
+ params:
+ keys: [78,69,87,13,49,48,32,70,85,78,67,32,65,68,68,73,40,88,37,44,89,37,41,13,50,48,32,32,82,69,84,32,88,37,43,89,37,13,51,48,32,69,78,68,80,13,52,48,32,70,85,78,67,32,71,82,69,69,84,40,78,36,41,13,53,48,32,32,82,69,84,32,34,72,73,32,34,43,78,36,13,54,48,32,69,78,68,80,13,55,48,32,80,82,73,78,84,32,34,65,66,83,34,59,65,66,83,40,90,65,68,68,49,54,40,49,44,54,41,45,49,48,41,13,56,48,32,80,82,73,78,84,32,34,76,69,70,84,32,34,59,76,69,70,84,36,40,85,80,80,69,82,40,34,114,101,97,100,121,34,41,44,50,41,13,57,48,32,80,82,73,78,84,32,34,78,69,83,84,34,59,90,65,68,68,49,54,40,49,44,90,65,68,68,49,54,40,50,44,51,41,41,13,49,48,48,32,80,82,73,78,84,32,34,70,65,66,83,34,59,65,66,83,40,70,65,68,68,40,49,46,50,44,50,46,51,41,45,51,41,13,49,49,48,32,80,82,73,78,84,32,34,70,76,69,70,84,32,34,59,76,69,70,84,36,40,71,82,69,69,84,40,34,82,69,65,68,89,34,41,43,34,33,34,44,51,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_10_expressions
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,65,66,83,32,51,44,32,76,69,70,84,32,82,69,44,32,78,69,83,84,32,54,44,32,70,76,69,70,84,32,72,73,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13,82,85,78,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: assert_demo_10_abs
+ type: assert.screen
+ params:
+ contains: "ABS 3"
+ - id: assert_demo_10_left
+ type: assert.screen
+ params:
+ contains: "LEFT RE"
+ - id: assert_demo_10_nest
+ type: assert.screen
+ params:
+ contains: "NEST 6"
+ - id: assert_demo_10_fleft
+ type: assert.screen
+ params:
+ contains: "FLEFT HI"
+ - id: demo_done
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,67,79,77,80,76,69,84,69,34,13,80,82,73,78,84,32,34,67,79,77,77,65,78,68,83,44,32,80,82,79,67,47,70,85,78,67,44,32,82,69,85,44,32,69,82,82,79,82,83,32,80,65,83,83,69,68,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13,80,82,73,78,84,32,34,82,69,65,68,89,66,65,83,73,67,32,68,69,77,79,32,67,79,77,80,76,69,84,69,34,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: assert_demo_done
+ type: assert.screen
+ params:
+ contains: "READYBASIC DEMO COMPLETE"
+ - id: regs_final
+ type: monitor.command
+ params:
+ command: "r"
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_demo_suite.regular.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_demo_suite.regular.yaml
new file mode 100644
index 0000000..91618fe
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_demo_suite.regular.yaml
@@ -0,0 +1,437 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_demo_suite
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 240
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: false
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "FREE:"
+ wait_timeout_s: 180
+ capture_label: demo_readybasic_prompt
+ - id: warp_off_for_visible_demo
+ type: warp.set
+ params:
+ enabled: false
+ capture_after: false
+ - id: demo_01_intro
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,49,58,32,82,69,65,68,89,66,65,83,73,67,32,66,65,83,73,67,83,34,13,80,82,73,78,84,32,34,70,82,69,69,77,69,77,44,32,86,65,82,73,65,66,76,69,83,44,32,65,78,68,32,65,32,80,82,79,71,82,65,77,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_01_setup
+ type: input.sequence
+ params:
+ keys: [70,82,69,69,77,69,77,40,41,13,78,69,87,13,65,37,61,52,50,13,49,48,32,66,37,61,90,65,68,68,49,54,40,52,50,44,56,41,13,50,48,32,80,82,73,78,84,32,34,80,82,79,71,82,65,77,32,83,85,77,34,59,66,37,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_01_list
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_01_basics
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,82,85,78,32,80,82,73,78,84,83,32,80,82,79,71,82,65,77,32,83,85,77,32,53,48,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13,82,85,78,13,65,37,61,52,50,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: assert_demo_01_program_sum
+ type: assert.screen
+ params:
+ contains: "PROGRAM SUM 50"
+ - id: demo_02_intro
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,50,58,32,83,85,83,80,69,78,68,32,65,78,68,32,82,69,83,84,79,82,69,34,13,80,82,73,78,84,32,34,69,88,73,84,32,84,79,32,82,69,65,68,89,79,83,44,32,86,73,83,73,84,32,69,68,73,84,79,82,44,32,82,69,84,85,82,78,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_02_exit_to_launcher
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: capture_after_demo_02_exit
+ type: screen.capture
+ params:
+ label: after_demo_02_exit
+ - id: wait_launcher_after_demo_02_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_readybasic_to_editor_demo
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.05
+ post_delay_s: 3.5
+ - id: wait_editor_demo
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: type_editor_demo_sentence
+ type: input.sequence
+ params:
+ keys: [82,69,65,68,89,66,65,83,73,67,32,68,69,77,79,32,86,73,83,73,84,69,68,32,69,68,73,84,79,82,32,65,78,68,32,82,69,84,85,82,78,69,68,46,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: ctrl_b_editor_demo
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.05
+ post_delay_s: 3.5
+ - id: wait_launcher_after_editor_demo
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_editor_to_readybasic_demo
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.05
+ post_delay_s: 3.5
+ - id: wait_readybasic_after_editor_demo
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 60
+ - id: demo_03_resume_liveness
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,82,69,83,85,77,69,32,76,73,86,69,34,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: assert_demo_03_resume_liveness
+ type: assert.screen
+ params:
+ contains: "RESUME LIVE"
+ - id: demo_03_resume_intro_clear
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,66,65,67,75,32,73,78,32,82,69,65,68,89,66,65,83,73,67,34,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_03_resume_intro_detail
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,86,65,82,73,65,66,76,69,83,32,65,78,68,32,80,82,79,71,82,65,77,32,84,69,88,84,32,83,72,79,85,76,68,32,82,69,77,65,73,78,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_03_resume_var_proof
+ type: input.sequence
+ params:
+ keys: [70,82,69,69,77,69,77,40,41,13,80,82,73,78,84,32,34,65,32,83,84,73,76,76,34,59,65,37,13,80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,65,32,73,83,32,52,50,32,65,78,68,32,82,85,78,32,83,84,73,76,76,32,87,79,82,75,83,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: capture_demo_03_resume_var_proof
+ type: screen.capture
+ params:
+ label: demo_03_resume_var_proof
+ - id: assert_demo_03_var_restored
+ type: assert.screen
+ params:
+ contains: "A STILL 42"
+ - id: demo_03_resume_run_proof
+ type: input.sequence
+ params:
+ keys: [82,85,78,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: assert_demo_03_program_restored
+ type: assert.screen
+ params:
+ contains: "PROGRAM SUM 50"
+ - id: demo_04_intro
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,51,58,32,65,83,83,69,77,66,76,69,82,32,67,79,77,77,65,78,68,83,34,13,80,82,73,78,84,32,34,67,79,77,77,65,78,68,83,32,82,69,84,85,82,78,32,86,65,76,85,69,83,32,65,83,32,69,88,80,82,69,83,83,73,79,78,83,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_04_assembler_setup
+ type: input.sequence
+ params:
+ keys: [78,37,61,90,65,68,68,49,54,40,55,44,56,41,13,84,36,61,85,80,80,69,82,40,34,114,101,97,100,121,34,41,13,76,36,61,76,79,87,69,82,40,34,76,79,85,68,34,41,13,72,37,61,90,72,73,68,68,69,78,82,65,77,40,34,65,66,34,41,13,80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,49,53,44,32,82,69,65,68,89,44,32,76,79,87,69,82,44,32,49,51,49,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_04_zadd_print
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,90,65,68,68,34,59,78,37,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_04_upper_print
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,85,80,80,69,82,32,34,59,84,36,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_04_lower_print
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,76,79,87,65,83,67,34,59,65,83,67,40,76,36,41,59,65,83,67,40,77,73,68,36,40,76,36,44,50,44,49,41,41,59,65,83,67,40,77,73,68,36,40,76,36,44,51,44,49,41,41,59,65,83,67,40,77,73,68,36,40,76,36,44,52,44,49,41,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_04_hidden_print
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,72,73,68,68,69,78,34,59,72,37,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: assert_demo_04_zadd
+ type: assert.screen
+ params:
+ contains: "ZADD 15"
+ - id: assert_demo_04_upper
+ type: assert.screen
+ params:
+ contains: "UPPER READY"
+ - id: assert_demo_04_hidden
+ type: assert.screen
+ params:
+ contains: "HIDDEN 131"
+ - id: demo_05_intro
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,52,58,32,80,82,79,67,32,79,78,76,89,34,13,80,82,73,78,84,32,34,80,82,79,67,32,84,65,75,69,83,32,80,65,82,65,77,69,84,69,82,83,32,65,78,68,32,68,79,69,83,32,87,79,82,75,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_05_program
+ type: input.sequence
+ params:
+ keys: [78,69,87,13,49,48,32,69,88,69,67,32,83,72,79,87,40,34,82,69,65,68,89,34,41,13,50,48,32,69,78,68,13,49,48,48,32,80,82,79,67,32,83,72,79,87,40,83,36,41,13,49,49,48,32,32,80,82,73,78,84,32,34,80,82,79,67,32,34,59,83,36,13,49,50,48,32,69,78,68,80,13,76,73,83,84,32,49,48,48,45,49,50,48,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_05_proc_func
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,80,82,79,67,32,82,69,65,68,89,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13,82,85,78,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: assert_demo_05_proc
+ type: assert.screen
+ params:
+ contains: "PROC READY"
+ - id: demo_05b_intro
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,53,58,32,73,78,84,69,71,69,82,32,70,85,78,67,34,13,80,82,73,78,84,32,34,70,85,78,67,32,82,69,84,85,82,78,83,32,84,72,82,79,85,71,72,32,82,69,84,32,65,83,32,65,78,32,69,88,80,82,69,83,83,73,79,78,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_05b_program
+ type: input.sequence
+ params:
+ keys: [78,69,87,13,49,48,32,65,37,61,65,68,68,73,40,52,44,53,41,13,50,48,32,80,82,73,78,84,32,34,65,68,68,73,34,59,65,37,13,51,48,32,69,78,68,13,49,48,48,32,70,85,78,67,32,65,68,68,73,40,88,37,44,89,37,41,13,49,49,48,32,32,82,69,84,32,88,37,43,89,37,13,49,50,48,32,69,78,68,80,13,76,73,83,84,32,49,48,48,45,49,50,48,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_05b_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,65,68,68,73,32,57,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13,82,85,78,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: assert_demo_05_addi
+ type: assert.screen
+ params:
+ contains: "ADDI 9"
+ - id: demo_05c_intro
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,54,58,32,83,84,82,73,78,71,32,65,78,68,32,70,76,79,65,84,32,70,85,78,67,83,34,13,80,82,73,78,84,32,34,82,69,84,32,75,69,69,80,83,32,83,84,82,73,78,71,32,65,78,68,32,80,76,65,73,78,32,78,85,77,69,82,73,67,32,84,89,80,69,83,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_05c_program
+ type: input.sequence
+ params:
+ keys: [78,69,87,13,49,48,32,84,36,61,72,69,76,76,79,40,34,75,65,82,76,34,41,13,50,48,32,80,82,73,78,84,32,84,36,13,51,48,32,70,61,83,67,65,76,69,40,50,46,53,41,13,52,48,32,80,82,73,78,84,32,34,83,67,65,76,69,34,59,70,13,53,48,32,69,78,68,13,49,48,48,32,70,85,78,67,32,72,69,76,76,79,40,78,36,41,13,49,49,48,32,32,82,69,84,32,34,72,73,32,34,43,78,36,13,49,50,48,32,69,78,68,80,13,49,51,48,32,70,85,78,67,32,83,67,65,76,69,40,88,41,13,49,52,48,32,32,82,69,84,32,88,42,49,46,53,13,49,53,48,32,69,78,68,80,13,76,73,83,84,32,49,48,48,45,49,53,48,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_05c_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,72,73,32,75,65,82,76,32,65,78,68,32,83,67,65,76,69,32,51,46,55,53,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13,82,85,78,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: assert_demo_05_hello
+ type: assert.screen
+ params:
+ contains: "HI KARL"
+ - id: assert_demo_05_scale
+ type: assert.screen
+ params:
+ contains: "SCALE 3.75"
+ - id: demo_06_intro
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,55,58,32,80,65,82,65,77,69,84,69,82,32,71,82,79,85,80,83,34,13,80,82,73,78,84,32,34,65,82,82,65,89,83,44,32,73,78,84,69,71,69,82,32,82,69,84,85,82,78,83,44,32,65,78,68,32,70,76,79,65,84,83,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_06_parameter_groups
+ type: input.sequence
+ params:
+ keys: [68,73,77,32,65,37,40,51,41,58,65,37,40,48,41,61,49,58,65,37,40,49,41,61,50,58,65,37,40,50,41,61,51,13,83,37,61,90,83,85,77,78,85,77,65,82,82,65,89,40,65,37,40,48,41,44,51,41,13,68,73,77,32,82,37,40,52,41,58,90,82,65,78,71,69,78,85,77,65,82,82,65,89,40,55,44,52,44,82,37,40,48,41,41,13,70,61,70,65,68,68,40,49,46,50,44,50,46,51,41,13,80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,83,85,77,32,54,44,32,82,65,78,71,69,32,55,46,46,49,48,44,32,70,65,68,68,32,51,46,53,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13,80,82,73,78,84,32,34,83,85,77,34,59,83,37,13,80,82,73,78,84,32,34,82,65,78,71,69,34,59,82,37,40,48,41,59,82,37,40,51,41,13,80,82,73,78,84,32,34,70,65,68,68,34,59,70,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: assert_demo_06_sum
+ type: assert.screen
+ params:
+ contains: "SUM 6"
+ - id: assert_demo_06_range
+ type: assert.screen
+ params:
+ contains: "RANGE 7 10"
+ - id: assert_demo_06_fadd
+ type: assert.screen
+ params:
+ contains: "FADD 3.5"
+ - id: demo_07_intro
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,56,58,32,82,69,85,32,66,85,70,70,69,82,32,67,79,77,77,65,78,68,83,34,13,80,82,73,78,84,32,34,66,85,70,78,69,87,32,82,69,84,85,82,78,83,59,32,70,73,76,76,32,65,78,68,32,70,82,69,69,32,68,79,32,87,79,82,75,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_07_reu
+ type: input.sequence
+ params:
+ keys: [72,37,61,66,85,70,78,69,87,40,54,52,41,13,66,85,70,70,73,76,76,40,72,37,44,49,55,48,41,13,80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,72,65,78,68,76,69,32,49,44,32,84,72,69,78,32,70,82,69,69,68,32,49,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13,80,82,73,78,84,32,34,72,65,78,68,76,69,34,59,72,37,13,66,85,70,70,82,69,69,40,72,37,41,13,80,82,73,78,84,32,34,70,82,69,69,68,34,59,72,37,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: assert_demo_07_handle
+ type: assert.screen
+ params:
+ contains: "HANDLE 1"
+ - id: assert_demo_07_freed
+ type: assert.screen
+ params:
+ contains: "FREED 1"
+ - id: demo_08_intro
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,57,58,32,83,67,82,69,69,78,32,84,72,82,79,85,71,72,32,82,69,85,34,13,80,82,73,78,84,32,34,83,67,82,67,65,80,32,83,65,86,69,83,59,32,83,67,82,80,85,84,32,82,69,83,84,79,82,69,83,32,83,67,82,69,69,78,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_08_screen_reu_a
+ type: input.sequence
+ params:
+ keys: [78,69,87,13,49,48,32,68,73,77,32,72,37,40,52,41,13,50,48,32,70,79,82,32,83,61,49,32,84,79,32,52,13,51,48,32,80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,82,69,85,32,83,67,82,69,69,78,34,59,83,13,52,48,32,80,82,73,78,84,32,67,72,82,36,40,53,41,59,34,77,65,82,75,34,59,83,59,34,32,84,69,88,84,32,65,78,68,32,67,79,76,79,82,34,13,53,48,32,70,79,82,32,73,61,48,32,84,79,32,51,57,13,54,48,32,80,79,75,69,49,48,50,52,43,56,48,43,73,44,54,52,43,83,13,55,48,32,80,79,75,69,53,53,50,57,54,43,56,48,43,73,44,83,43,49,13,56,48,32,78,69,88,84,32,73,13,57,48,32,72,37,40,83,41,61,83,67,82,67,65,80,40,41,13,49,48,48,32,78,69,88,84,32,83,13,49,49,48,32,80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,82,69,85,32,70,76,73,80,66,79,79,75,34,13,49,50,48,32,80,82,73,78,84,32,67,72,82,36,40,53,41,59,34,69,88,80,69,67,84,58,32,70,79,85,82,32,82,69,83,84,79,82,69,68,32,83,67,82,69,69,78,83,34,13,49,51,48,32,70,79,82,32,83,61,49,32,84,79,32,52,13,49,52,48,32,83,67,82,80,85,84,40,72,37,40,83,41,41,13,49,53,48,32,80,82,73,78,84,32,67,72,82,36,40,49,57,41,59,34,82,69,83,84,79,82,69,68,34,59,83,59,34,47,52,34,13,49,54,48,32,90,80,65,85,83,69,40,51,48,41,13,49,55,48,32,78,69,88,84,32,83,13,49,56,48,32,80,82,73,78,84,32,67,72,82,36,40,49,57,41,59,34,82,69,83,84,79,82,69,68,32,52,32,82,69,85,32,83,67,82,69,69,78,83,34,13,49,57,48,32,69,78,68,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_08_screen_reu_b
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,70,79,85,82,32,68,73,70,70,69,82,69,78,84,32,83,67,82,69,69,78,83,32,70,76,73,80,32,66,65,67,75,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13,82,85,78,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: wait_demo_08_reu_flipbook
+ type: screen.wait_contains
+ params:
+ text: "RESTORED 4 REU SCREENS"
+ wait_timeout_s: 90
+ - id: assert_demo_08_reu_flipbook
+ type: assert.screen
+ params:
+ contains: "RESTORED 4 REU SCREENS"
+ - id: demo_09_intro
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,49,48,58,32,67,79,78,84,82,79,76,76,69,68,32,69,82,82,79,82,34,13,80,82,73,78,84,32,34,90,70,65,73,76,32,83,72,79,87,83,32,82,69,65,68,89,66,65,83,73,67,32,69,82,82,79,82,32,67,76,69,65,78,85,80,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_09_zfail
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,82,66,32,69,82,82,79,82,32,55,32,65,78,68,32,88,37,32,66,69,67,79,77,69,83,32,90,69,82,79,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13,88,37,61,57,57,13,90,70,65,73,76,40,55,44,88,37,41,13,80,82,73,78,84,32,34,65,70,84,69,82,32,70,65,73,76,34,59,88,37,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: assert_demo_09_rb_error
+ type: assert.screen
+ params:
+ contains: "RB ERROR 7"
+ - id: assert_demo_09_fail_clear
+ type: assert.screen
+ params:
+ contains: "AFTER FAIL 0"
+ - id: demo_10_intro
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,49,49,58,32,78,69,83,84,69,68,32,69,88,80,82,69,83,83,73,79,78,83,34,13,80,82,73,78,84,32,34,67,79,77,77,65,78,68,83,32,65,78,68,32,70,85,78,67,83,32,70,69,69,68,32,79,84,72,69,82,32,69,88,80,82,69,83,83,73,79,78,83,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_10_program
+ type: input.sequence
+ params:
+ keys: [78,69,87,13,49,48,32,70,85,78,67,32,65,68,68,73,40,88,37,44,89,37,41,13,50,48,32,32,82,69,84,32,88,37,43,89,37,13,51,48,32,69,78,68,80,13,52,48,32,70,85,78,67,32,71,82,69,69,84,40,78,36,41,13,53,48,32,32,82,69,84,32,34,72,73,32,34,43,78,36,13,54,48,32,69,78,68,80,13,55,48,32,80,82,73,78,84,32,34,65,66,83,34,59,65,66,83,40,90,65,68,68,49,54,40,49,44,54,41,45,49,48,41,13,56,48,32,80,82,73,78,84,32,34,76,69,70,84,32,34,59,76,69,70,84,36,40,85,80,80,69,82,40,34,114,101,97,100,121,34,41,44,50,41,13,57,48,32,80,82,73,78,84,32,34,78,69,83,84,34,59,90,65,68,68,49,54,40,49,44,90,65,68,68,49,54,40,50,44,51,41,41,13,49,48,48,32,80,82,73,78,84,32,34,70,65,66,83,34,59,65,66,83,40,70,65,68,68,40,49,46,50,44,50,46,51,41,45,51,41,13,49,49,48,32,80,82,73,78,84,32,34,70,76,69,70,84,32,34,59,76,69,70,84,36,40,71,82,69,69,84,40,34,82,69,65,68,89,34,41,43,34,33,34,44,51,41,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_10_expressions
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,65,66,83,32,51,44,32,76,69,70,84,32,82,69,44,32,78,69,83,84,32,54,44,32,70,76,69,70,84,32,72,73,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13,82,85,78,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: assert_demo_10_abs
+ type: assert.screen
+ params:
+ contains: "ABS 3"
+ - id: assert_demo_10_left
+ type: assert.screen
+ params:
+ contains: "LEFT RE"
+ - id: assert_demo_10_nest
+ type: assert.screen
+ params:
+ contains: "NEST 6"
+ - id: assert_demo_10_fleft
+ type: assert.screen
+ params:
+ contains: "FLEFT HI"
+ - id: demo_done
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,67,79,77,80,76,69,84,69,34,13,80,82,73,78,84,32,34,67,79,77,77,65,78,68,83,44,32,80,82,79,67,47,70,85,78,67,44,32,82,69,85,44,32,69,82,82,79,82,83,32,80,65,83,83,69,68,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13,80,82,73,78,84,32,34,82,69,65,68,89,66,65,83,73,67,32,68,69,77,79,32,67,79,77,80,76,69,84,69,34,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: assert_demo_done
+ type: assert.screen
+ params:
+ contains: "READYBASIC DEMO COMPLETE"
+ - id: regs_final
+ type: monitor.command
+ params:
+ command: "r"
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_full_suite_visual_verification.easyflash.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_full_suite_visual_verification.easyflash.yaml
new file mode 100644
index 0000000..5a93288
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_full_suite_visual_verification.easyflash.yaml
@@ -0,0 +1,992 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_full_suite_visual_verification_easyflash
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 1
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 120
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
+ autostart_enabled: false
+ disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
+ drive8_enabled: true
+ drive8_type: 1541
+ drive9_enabled: false
+ true_drive: true
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: easyflash_wait_launcher
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ pre_delay_s: 4
+ poll_s: 0.5
+ wait_timeout_s: 420
+ capture_label: easyflash_readybasic_launcher
+ - id: easyflash_start_readybasic
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 180
+ capture_label: readybasic_full_suite_visual_prompt
+ - id: dump_initial_plugin_state
+ type: dump.memory_ranges
+ params:
+ ranges: &plugin_ranges
+ - { label: entry_1000, start: 0x1000, end: 0x1120 }
+ - { label: resident_1200, start: 0x1200, end: 0x1BFF }
+ - { label: low_overlay_1c00, start: 0x1C00, end: 0x23FF }
+ - { label: shared_frames_2400, start: 0x2400, end: 0x27FF }
+ - { label: hidden_shadow_9a00, start: 0x9A00, end: 0x9FFF }
+ - { label: hidden_visible_a000, start: 0xA000, end: 0xA5FF }
+ - { label: hidden_overlay_a800, start: 0xA800, end: 0xA8FF }
+ - { label: bridge_c000, start: 0xC000, end: 0xC5FF }
+ - { label: reu_alloc_table_c600, start: 0xC600, end: 0xC6FF }
+
+ - id: direct_ping
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,90,69,67,72,79,32,72,69,65,76,84,72,32,76,79,87,32,79,86,76,32,83,84,65,84,69,77,69,78,84,32,83,84,79,82,69,83,32,80,37,61,49,32,83,67,82,69,69,78,32,68,45,90,69,67,72,79,13,90,69,67,72,79,49,40,80,37,41,13,80,82,73,78,84,32,34,68,45,90,69,67,72,79,34,59,80,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_ping
+ type: assert.screen
+ params:
+ contains: "D-ZECHO 1"
+ - id: dump_direct_ping
+ type: dump.memory_ranges
+ params:
+ ranges: *plugin_ranges
+
+ - id: direct_add16
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,65,68,68,32,78,85,77,32,80,65,82,65,77,83,32,82,69,84,85,82,78,32,65,37,61,49,53,32,83,67,82,69,69,78,32,68,45,65,68,68,13,65,37,61,90,65,68,68,49,54,40,53,44,49,48,41,13,80,82,73,78,84,32,34,68,45,65,68,68,34,59,65,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_add16
+ type: assert.screen
+ params:
+ contains: "D-ADD 15"
+
+ - id: direct_module_slots
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,83,76,79,84,83,32,66,85,73,76,84,73,78,32,77,79,68,85,76,69,32,83,76,79,84,32,80,82,79,79,70,83,13,80,82,73,78,84,32,34,68,45,83,48,34,59,90,83,76,79,84,48,40,41,13,80,82,73,78,84,32,34,68,45,83,49,34,59,90,83,76,79,84,49,40,41,13,80,82,73,78,84,32,34,68,45,83,50,34,59,90,83,76,79,84,50,40,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_module_slot0
+ type: assert.screen
+ params:
+ contains: "D-S0 30"
+ - id: assert_direct_module_slot1
+ type: assert.screen
+ params:
+ contains: "D-S1 31"
+ - id: assert_direct_module_slot2
+ type: assert.screen
+ params:
+ contains: "D-S2 32"
+
+ - id: direct_module_span_overlay_copy
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,77,79,68,32,83,80,65,78,32,79,86,69,82,76,65,89,32,67,79,80,89,32,80,82,79,79,70,83,13,80,82,73,78,84,32,34,68,45,82,83,84,34,59,90,67,80,89,82,83,84,40,41,13,80,82,73,78,84,32,34,68,45,83,80,65,78,34,59,90,83,80,65,78,40,41,13,80,82,73,78,84,32,34,68,45,79,86,76,34,59,90,79,86,76,49,40,41,59,34,47,34,59,90,79,86,76,50,40,41,13,80,82,73,78,84,32,34,68,45,82,83,84,34,59,90,67,80,89,82,83,84,40,41,13,65,61,90,83,76,79,84,49,40,41,13,66,61,90,83,76,79,84,49,40,41,13,80,82,73,78,84,32,34,68,45,67,79,80,89,34,59,90,67,79,80,89,40,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_module_span
+ type: assert.screen
+ params:
+ contains: "D-SPAN 40"
+ - id: assert_direct_module_overlay
+ type: assert.screen
+ params:
+ contains: "D-OVL 51 / 52"
+ - id: assert_direct_module_copy_skip
+ type: assert.screen
+ params:
+ contains: "D-COPY 2"
+
+ - id: direct_disk_module_load12
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,68,73,83,75,77,79,68,85,76,69,32,76,79,65,68,32,80,82,79,79,70,83,13,80,82,73,78,84,32,34,68,45,76,68,49,34,59,90,77,79,68,76,68,40,34,82,66,77,46,83,65,77,80,76,69,49,34,41,13,80,82,73,78,84,32,34,68,45,68,77,49,34,59,90,68,77,49,40,41,13,80,82,73,78,84,32,34,68,45,76,68,50,34,59,90,77,79,68,76,68,40,34,82,66,77,46,83,65,77,80,76,69,50,34,41,13,80,82,73,78,84,32,34,68,45,68,77,50,34,59,90,68,77,50,83,40,41,13,80,82,73,78,84,32,34,68,45,68,79,86,34,59,90,68,79,86,49,40,41,59,34,47,34,59,90,68,79,86,50,40,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_disk_module_load1
+ type: assert.screen
+ params:
+ contains: "D-LD1 1"
+ - id: assert_direct_disk_module_cmd1
+ type: assert.screen
+ params:
+ contains: "D-DM1 61"
+ - id: assert_direct_disk_module_load2
+ type: assert.screen
+ params:
+ contains: "D-LD2 3"
+ - id: assert_direct_disk_module_span
+ type: assert.screen
+ params:
+ contains: "D-DM2 74"
+ - id: assert_direct_disk_module_overlay
+ type: assert.screen
+ params:
+ contains: "D-DOV 72 / 73"
+
+ - id: direct_disk_module_load3
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,68,73,83,75,77,79,68,85,76,69,32,82,66,77,51,32,80,82,79,79,70,83,13,80,82,73,78,84,32,34,68,45,76,68,51,34,59,90,77,79,68,76,68,40,34,82,66,77,46,83,65,77,80,76,69,51,34,41,13,80,82,73,78,84,32,34,68,45,77,51,34,59,90,83,65,65,40,41,59,34,47,34,59,90,85,69,66,40,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_disk_module_load3
+ type: assert.screen
+ params:
+ contains: "D-LD3 30"
+ - id: assert_direct_disk_module_rbm3
+ type: assert.screen
+ params:
+ contains: "D-M3 4 / 113"
+
+ - id: direct_strup_variable
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,83,84,82,32,86,65,82,32,83,84,82,73,78,71,32,82,69,84,85,82,78,32,84,36,61,65,66,67,32,83,67,82,69,69,78,32,68,45,83,84,82,13,83,36,61,34,97,98,99,34,13,84,36,61,85,80,80,69,82,40,83,36,41,13,80,82,73,78,84,32,34,68,45,83,84,82,34,59,84,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_strup_variable
+ type: assert.screen
+ params:
+ contains: "D-STRABC"
+
+ - id: direct_strup_literal
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,76,73,84,32,81,85,79,84,69,68,32,83,84,82,73,78,71,32,82,69,84,85,82,78,32,85,36,61,68,69,70,32,83,67,82,69,69,78,32,68,45,76,73,84,13,85,36,61,85,80,80,69,82,40,34,100,101,102,34,41,13,80,82,73,78,84,32,34,68,45,76,73,84,34,59,85,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_strup_literal
+ type: assert.screen
+ params:
+ contains: "D-LITDEF"
+
+ - id: direct_lower_variable
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,76,79,87,69,82,32,86,65,82,32,83,84,82,73,78,71,32,82,69,84,85,82,78,32,76,36,61,97,98,99,32,83,67,82,69,69,78,32,68,45,76,79,87,13,83,36,61,34,65,66,67,34,13,76,36,61,76,79,87,69,82,40,83,36,41,13,80,82,73,78,84,32,34,68,45,76,79,87,65,83,67,34,59,65,83,67,40,76,36,41,59,65,83,67,40,77,73,68,36,40,76,36,44,50,44,49,41,41,59,65,83,67,40,77,73,68,36,40,76,36,44,51,44,49,41,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_lower_variable
+ type: assert.screen
+ params:
+ contains: "D-LOWASC 97 98 99"
+
+ - id: direct_lower_literal
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,76,79,87,69,82,32,76,73,84,69,82,65,76,32,83,84,82,73,78,71,32,82,69,84,85,82,78,32,76,36,61,103,104,105,32,83,67,82,69,69,78,32,68,45,76,76,79,87,13,76,36,61,76,79,87,69,82,40,34,71,72,73,34,41,13,80,82,73,78,84,32,34,68,45,76,76,79,87,65,83,67,34,59,65,83,67,40,76,36,41,59,65,83,67,40,77,73,68,36,40,76,36,44,50,44,49,41,41,59,65,83,67,40,77,73,68,36,40,76,36,44,51,44,49,41,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_lower_literal
+ type: assert.screen
+ params:
+ contains: "D-LLOWASC 103 104 105"
+
+ - id: direct_hcrc_hidden
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,90,72,73,68,68,69,78,82,65,77,32,72,73,68,68,69,78,32,65,48,48,48,32,87,79,82,75,69,82,32,82,69,84,85,82,78,32,72,37,61,49,51,49,32,83,67,82,69,69,78,32,68,45,90,72,73,68,68,69,78,82,65,77,13,72,37,61,90,72,73,68,68,69,78,82,65,77,40,34,65,66,34,41,13,80,82,73,78,84,32,34,68,45,90,72,73,68,68,69,78,82,65,77,34,59,72,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_hcrc_hidden
+ type: assert.screen
+ params:
+ contains: "D-ZHIDDENRAM 131"
+ - id: dump_direct_hidden_worker
+ type: dump.memory_ranges
+ params:
+ ranges: *plugin_ranges
+
+ - id: direct_sumai
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,83,85,77,32,73,78,84,32,65,82,82,65,89,32,80,84,82,32,67,79,85,78,84,32,82,69,84,85,82,78,32,83,37,61,54,32,83,67,82,69,69,78,32,68,45,83,85,77,13,68,73,77,32,65,37,40,51,41,13,65,37,40,48,41,61,49,58,65,37,40,49,41,61,50,58,65,37,40,50,41,61,51,13,83,37,61,90,83,85,77,78,85,77,65,82,82,65,89,40,65,37,40,48,41,44,51,41,13,80,82,73,78,84,32,34,68,45,83,85,77,34,59,83,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_sumai
+ type: assert.screen
+ params:
+ contains: "D-SUM 6"
+
+ - id: direct_rangeai
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,82,65,78,71,69,32,82,69,83,85,76,84,32,70,82,65,77,69,32,84,79,32,73,78,84,32,65,82,82,65,89,32,83,67,82,69,69,78,32,68,45,82,65,78,71,69,13,68,73,77,32,82,37,40,52,41,13,90,82,65,78,71,69,78,85,77,65,82,82,65,89,40,55,44,52,44,82,37,40,48,41,41,13,80,82,73,78,84,32,34,68,45,82,65,78,71,69,34,59,82,37,40,48,41,59,82,37,40,51,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_rangeai
+ type: assert.screen
+ params:
+ contains: "D-RANGE 7 10"
+
+ - id: direct_bufnew
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,66,85,70,78,69,87,32,82,69,85,32,72,65,78,68,76,69,32,84,65,66,76,69,32,82,69,84,85,82,78,32,72,37,61,49,32,83,67,82,69,69,78,32,68,45,66,85,70,13,72,37,61,66,85,70,78,69,87,40,51,48,48,41,13,80,82,73,78,84,32,34,68,45,66,85,70,34,59,72,37,59,34,58,69,78,68,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_bufnew
+ type: assert.screen
+ params:
+ contains: "D-BUF 1 :END"
+ - id: dump_direct_bufnew
+ type: dump.memory_ranges
+ params:
+ ranges: *plugin_ranges
+
+ - id: direct_buffill
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,66,85,70,70,73,76,76,32,82,69,85,32,72,65,78,68,76,69,32,72,37,32,66,89,84,69,32,49,55,48,32,83,67,82,69,69,78,32,68,45,70,73,76,76,13,66,85,70,70,73,76,76,40,72,37,44,49,55,48,41,13,80,82,73,78,84,32,34,68,45,70,73,76,76,32,79,75,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_buffill
+ type: assert.screen
+ params:
+ contains: "D-FILL OK"
+ - id: assert_direct_buffill_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: direct_buffree
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,66,85,70,70,82,69,69,32,82,69,76,69,65,83,69,32,82,69,85,32,72,65,78,68,76,69,32,72,37,32,83,67,82,69,69,78,32,68,45,70,82,69,69,13,66,85,70,70,82,69,69,40,72,37,41,13,80,82,73,78,84,32,34,68,45,70,82,69,69,32,79,75,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_buffree
+ type: assert.screen
+ params:
+ contains: "D-FREE OK"
+ - id: assert_direct_buffree_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: direct_scrcap_scrput_slot128
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,83,67,82,67,65,80,32,84,69,88,84,32,67,79,76,79,82,32,72,65,78,68,76,69,32,82,69,84,85,82,78,32,65,78,68,32,83,76,79,84,49,50,56,32,83,67,82,80,85,84,13,80,82,73,78,84,32,34,68,45,83,67,82,77,65,82,75,34,13,83,37,61,83,67,82,67,65,80,40,41,13,80,82,73,78,84,32,34,68,45,67,72,65,78,71,69,68,34,13,83,67,82,80,85,84,40,83,37,41,13,80,82,73,78,84,32,34,68,45,83,67,82,80,85,84,34,59,83,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_scrcap_restored_text
+ type: assert.screen
+ params:
+ contains: "D-SCRMARK"
+ - id: assert_direct_scrput_slot128
+ type: assert.screen
+ params:
+ contains: "D-SCRPUT 1"
+ - id: direct_buffill_rejects_screen_handle
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,66,85,70,70,73,76,76,32,77,85,83,84,32,82,69,74,69,67,84,32,83,67,82,69,69,78,32,72,65,78,68,76,69,32,84,89,80,69,13,66,85,70,70,73,76,76,40,83,37,44,49,55,48,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_buffill_rejects_screen_handle
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 40"
+ - id: direct_buffree_screen_handle
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,66,85,70,70,82,69,69,32,82,69,76,69,65,83,69,83,32,83,67,82,69,69,78,32,72,65,78,68,76,69,32,84,89,80,69,13,66,85,70,70,82,69,69,40,83,37,41,13,80,82,73,78,84,32,34,68,45,83,67,82,70,82,69,69,34,59,83,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_buffree_screen_handle
+ type: assert.screen
+ params:
+ contains: "D-SCRFREE 1"
+ - id: assert_direct_buffree_screen_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+ - id: direct_scrput_rejects_buffer_handle
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,83,67,82,80,85,84,32,77,85,83,84,32,82,69,74,69,67,84,32,66,85,70,70,69,82,32,72,65,78,68,76,69,32,84,89,80,69,13,66,37,61,66,85,70,78,69,87,40,51,48,48,41,13,83,67,82,80,85,84,40,66,37,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_scrput_rejects_buffer_handle
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 40"
+ - id: direct_free_buffer_after_type_error
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,70,82,69,69,40,66,37,41,13,80,82,73,78,84,32,34,68,45,66,85,70,82,69,69,34,59,66,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_free_buffer_after_type_error
+ type: assert.screen
+ params:
+ contains: "D-BUFREE 1"
+ - id: assert_direct_free_buffer_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: direct_handle_128_edge
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,72,37,61,66,85,70,78,69,87,40,49,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,68,45,72,77,65,88,34,59,72,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 5.0
+ - id: assert_direct_handle_128_edge
+ type: assert.screen
+ params:
+ contains: "D-HMAX 128"
+ - id: assert_direct_handle_128_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+ - id: direct_handle_129_rejected
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,69,37,61,66,85,70,78,69,87,40,49,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_handle_129_rejected
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 33"
+ - id: direct_free_128_handles
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,66,85,70,70,82,69,69,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,68,45,72,70,82,69,69,68,34,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 5.0
+ - id: assert_direct_free_128_handles
+ type: assert.screen
+ params:
+ contains: "D-HFREED"
+ - id: assert_direct_free_128_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+ - id: direct_48k_heap_edge
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,77,37,61,66,85,70,78,69,87,40,52,57,49,53,50,41,13,80,82,73,78,84,32,34,68,45,77,65,88,66,85,70,34,59,77,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_48k_heap_edge
+ type: assert.screen
+ params:
+ contains: "D-MAXBUF 1"
+ - id: direct_48k_heap_full
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,69,37,61,66,85,70,78,69,87,40,49,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_48k_heap_full
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 34"
+ - id: direct_free_48k_heap
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,70,82,69,69,40,77,37,41,13,80,82,73,78,84,32,34,68,45,77,65,88,70,82,69,69,34,59,77,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_free_48k_heap
+ type: assert.screen
+ params:
+ contains: "D-MAXFREE 1"
+ - id: assert_direct_free_48k_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+ - id: direct_screen_heap_edge
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,50,52,13,50,48,32,83,37,61,83,67,82,67,65,80,40,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,68,45,83,77,65,88,34,59,83,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 5.0
+ - id: assert_direct_screen_heap_edge
+ type: assert.screen
+ params:
+ contains: "D-SMAX 24"
+ - id: direct_screen_heap_full
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,83,37,61,83,67,82,67,65,80,40,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_screen_heap_full
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 34"
+ - id: direct_free_screen_heap
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,50,52,13,50,48,32,66,85,70,70,82,69,69,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,68,45,83,70,82,69,69,68,34,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 5.0
+ - id: assert_direct_free_screen_heap
+ type: assert.screen
+ params:
+ contains: "D-SFREED"
+ - id: assert_direct_free_screen_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: direct_tempscratch
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,84,69,77,80,32,82,69,85,32,84,69,77,80,32,80,65,71,69,83,32,82,69,84,85,82,78,32,84,37,61,51,32,83,67,82,69,69,78,32,68,45,84,69,77,80,13,84,37,61,90,84,69,77,80,83,67,82,65,84,67,72,40,53,49,51,41,13,80,82,73,78,84,32,34,68,45,84,69,77,80,34,59,84,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_tempscratch
+ type: assert.screen
+ params:
+ contains: "D-TEMP 3"
+
+ - id: direct_fail_clears_output
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,90,70,65,73,76,32,69,82,82,79,82,32,80,65,84,72,32,67,76,69,65,82,83,32,88,37,32,84,72,69,78,32,82,66,32,69,82,82,79,82,32,55,13,88,37,61,57,57,13,90,70,65,73,76,40,55,44,88,37,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_fail_error
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 7"
+ - id: direct_fail_print_cleared
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,68,45,70,67,76,82,34,59,88,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_fail_cleared
+ type: assert.screen
+ params:
+ contains: "D-FCLR 0"
+
+ - id: direct_unknown_command
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,78,79,80,69,32,82,69,71,73,83,84,82,89,32,77,73,83,83,32,83,72,79,85,76,68,32,82,66,32,69,82,82,79,82,32,49,13,78,79,80,69,40,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_unknown_command
+ type: assert.screen
+ params:
+ contains: "SYNTAX"
+
+ - id: direct_old_ping_rejected
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,79,76,68,32,83,67,65,76,65,82,32,72,65,83,32,78,79,32,65,76,73,65,83,13,83,67,65,76,65,82,40,80,37,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_old_ping_rejected
+ type: assert.screen
+ params:
+ contains: "ERROR"
+
+ - id: direct_old_add16_rejected
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,79,76,68,32,65,68,68,49,54,32,72,65,83,32,78,79,32,65,76,73,65,83,13,65,68,68,49,54,40,49,44,50,44,65,37,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_old_add16_rejected
+ type: assert.screen
+ params:
+ contains: "ERROR"
+
+ - id: direct_old_strup_rejected
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,79,76,68,32,83,84,82,85,80,32,72,65,83,32,78,79,32,65,76,73,65,83,13,83,84,82,85,80,40,34,97,98,99,34,44,84,36,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_old_strup_rejected
+ type: assert.screen
+ params:
+ contains: "ERROR"
+
+ - id: direct_old_hcrc_rejected
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,79,76,68,32,72,67,82,67,32,72,65,83,32,78,79,32,65,76,73,65,83,13,72,67,82,67,40,34,65,66,34,44,72,37,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_old_hcrc_rejected
+ type: assert.screen
+ params:
+ contains: "ERROR"
+
+ - id: direct_old_sumai_rejected
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,79,76,68,32,83,85,77,65,73,32,72,65,83,32,78,79,32,65,76,73,65,83,13,83,85,77,65,73,40,65,37,40,48,41,44,49,44,83,37,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_old_sumai_rejected
+ type: assert.screen
+ params:
+ contains: "ERROR"
+
+ - id: direct_old_rangeai_rejected
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,79,76,68,32,82,65,78,71,69,65,73,32,72,65,83,32,78,79,32,65,76,73,65,83,13,82,65,78,71,69,65,73,40,49,44,49,44,65,37,40,48,41,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_old_rangeai_rejected
+ type: assert.screen
+ params:
+ contains: "ERROR"
+
+ - id: direct_command_name_in_string
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,67,79,77,77,65,78,68,32,78,65,77,69,32,73,78,32,83,84,82,73,78,71,32,83,72,79,85,76,68,32,78,79,84,32,68,73,83,80,65,84,67,72,13,80,82,73,78,84,32,34,78,79,80,69,40,41,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_command_name_in_string
+ type: assert.screen
+ params:
+ contains: "NOPE()"
+ - id: assert_direct_command_name_in_string_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: direct_command_name_in_rem
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,78,79,80,69,40,41,13,80,82,73,78,84,32,34,68,45,82,69,77,79,75,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_command_name_in_rem
+ type: assert.screen
+ params:
+ contains: "D-REMOK"
+ - id: assert_direct_command_name_in_rem_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: direct_first_comma_rejected
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,70,73,82,83,84,32,65,82,71,32,67,79,77,77,65,32,73,83,32,78,79,84,32,67,65,78,79,78,73,67,65,76,13,90,65,68,68,49,54,40,44,49,44,50,44,65,37,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_first_comma_rejected
+ type: assert.screen
+ params:
+ contains: "SYNTAX"
+
+ - id: direct_missing_out_marker_rejected
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,76,69,71,65,67,89,32,83,80,65,67,69,32,70,79,82,77,32,82,69,74,69,67,84,69,68,13,90,65,68,68,49,54,32,49,44,50,44,65,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_missing_out_marker_rejected
+ type: assert.screen
+ params:
+ contains: "SYNTAX"
+
+ - id: direct_seed_resume_vars
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,82,69,83,85,77,69,32,83,65,86,69,32,66,65,83,73,67,32,86,65,82,83,32,84,72,82,79,85,71,72,32,82,69,65,68,89,79,83,32,69,88,73,84,13,86,37,61,51,50,49,58,86,83,36,61,34,79,75,34,13,80,82,73,78,84,32,34,68,45,83,69,69,68,34,59,86,37,59,34,58,34,59,86,83,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_seed_resume_vars
+ type: assert.screen
+ params:
+ contains: "D-SEED 321 :OK"
+ - id: direct_exit_to_launcher
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: wait_launcher_after_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: resume_after_exit
+ type: input.sequence
+ params:
+ keys: [145,17,13]
+ inter_key_delay_s: 0.10
+ post_delay_s: 3.0
+ - id: wait_readybasic_after_resume
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 30
+ capture_label: readybasic_full_suite_visual_after_resume
+ - id: direct_registry_after_resume
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,80,79,83,84,82,69,83,32,66,65,83,73,67,32,86,65,82,83,32,65,78,68,32,82,69,71,73,83,84,82,89,32,83,84,73,76,76,32,65,67,84,73,86,69,13,80,82,73,78,84,32,34,68,45,83,84,65,84,69,34,59,86,37,59,34,58,34,59,86,83,36,13,80,37,61,90,65,68,68,49,54,40,48,44,49,41,13,80,82,73,78,84,32,34,68,45,82,69,83,85,77,69,34,59,80,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_state_after_resume
+ type: assert.screen
+ params:
+ contains: "D-STATE 321 :OK"
+ - id: assert_direct_registry_after_resume
+ type: assert.screen
+ params:
+ contains: "D-RESUME 1"
+
+ - id: program_ping_enter_and_list
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,77,32,90,69,67,72,79,49,32,72,69,65,76,84,72,32,76,79,87,32,79,86,76,32,83,84,65,84,69,77,69,78,84,32,83,84,79,82,69,83,32,80,37,61,49,32,83,67,82,69,69,78,32,80,45,90,69,67,72,79,13,50,48,32,90,69,67,72,79,49,40,80,37,41,13,51,48,32,80,82,73,78,84,32,34,80,45,90,69,67,72,79,34,59,80,37,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_ping_rem
+ type: assert.screen
+ params:
+ contains: "REM ZECHO1 HEALTH"
+ - id: program_ping_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_ping_run
+ type: assert.screen
+ params:
+ contains: "P-ZECHO 1"
+
+ - id: program_chain_enter_and_list
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,77,32,65,68,68,32,78,85,77,32,80,65,82,65,77,83,32,83,65,77,69,32,76,73,78,69,32,82,69,84,85,82,78,32,65,37,61,51,32,83,67,82,69,69,78,32,80,45,67,72,65,73,78,13,50,48,32,65,37,61,90,65,68,68,49,54,40,49,44,50,41,58,80,82,73,78,84,32,34,80,45,67,72,65,73,78,34,59,65,37,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_chain_rem
+ type: assert.screen
+ params:
+ contains: "REM ADD NUM PARAMS"
+ - id: program_chain_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_chain_run
+ type: assert.screen
+ params:
+ contains: "P-CHAIN 3"
+
+ - id: program_if_true_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,77,32,73,70,32,84,82,85,69,32,84,72,69,78,32,82,69,84,85,82,78,32,67,79,77,77,65,78,68,32,83,67,82,69,69,78,32,80,45,73,70,84,82,85,69,13,50,48,32,80,37,61,48,13,51,48,32,73,70,32,49,32,84,72,69,78,32,80,37,61,90,65,68,68,49,54,40,48,44,49,41,13,52,48,32,80,82,73,78,84,32,34,80,45,73,70,84,82,85,69,34,59,80,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_if_true_run
+ type: assert.screen
+ params:
+ contains: "P-IFTRUE 1"
+
+ - id: program_if_false_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,77,32,73,70,32,70,65,76,83,69,32,83,75,73,80,83,32,82,69,84,85,82,78,32,67,79,77,77,65,78,68,32,83,67,82,69,69,78,32,80,45,73,70,70,65,76,83,69,13,50,48,32,80,37,61,48,13,51,48,32,73,70,32,48,32,84,72,69,78,32,80,37,61,90,65,68,68,49,54,40,48,44,49,41,13,52,48,32,80,82,73,78,84,32,34,80,45,73,70,70,65,76,83,69,34,59,80,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_if_false_run
+ type: assert.screen
+ params:
+ contains: "P-IFFALSE 0"
+
+ - id: program_for_next_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,77,32,70,79,82,32,78,69,88,84,32,67,79,77,77,65,78,68,32,82,69,84,85,82,78,32,83,67,82,69,69,78,32,80,45,70,79,82,13,50,48,32,70,79,82,32,73,61,49,32,84,79,32,51,13,51,48,32,65,37,61,90,65,68,68,49,54,40,73,44,49,48,41,13,52,48,32,78,69,88,84,13,53,48,32,80,82,73,78,84,32,34,80,45,70,79,82,34,59,65,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_for_next_run
+ type: assert.screen
+ params:
+ contains: "P-FOR 13"
+
+ - id: program_strup_enter_and_list
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,77,32,85,80,80,69,82,32,86,65,82,32,83,84,82,73,78,71,32,82,69,84,85,82,78,32,84,36,61,65,66,67,32,83,67,82,69,69,78,32,80,45,83,84,82,13,50,48,32,83,36,61,34,97,98,99,34,13,51,48,32,84,36,61,85,80,80,69,82,40,83,36,41,13,52,48,32,80,82,73,78,84,32,34,80,45,83,84,82,34,59,84,36,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_strup_rem
+ type: assert.screen
+ params:
+ contains: "REM UPPER VAR STRING"
+ - id: program_strup_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_strup_run
+ type: assert.screen
+ params:
+ contains: "P-STRABC"
+
+ - id: program_lower_enter_and_list
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,77,32,76,79,87,69,82,32,86,65,82,32,83,84,82,73,78,71,32,82,69,84,85,82,78,32,84,36,61,97,98,99,32,83,67,82,69,69,78,32,80,45,76,79,87,13,50,48,32,83,36,61,34,65,66,67,34,13,51,48,32,84,36,61,76,79,87,69,82,40,83,36,41,13,52,48,32,80,82,73,78,84,32,34,80,45,76,79,87,65,83,67,34,59,65,83,67,40,84,36,41,59,65,83,67,40,77,73,68,36,40,84,36,44,50,44,49,41,41,59,65,83,67,40,77,73,68,36,40,84,36,44,51,44,49,41,41,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_lower_rem
+ type: assert.screen
+ params:
+ contains: "REM LOWER VAR STRING"
+ - id: program_lower_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_lower_run
+ type: assert.screen
+ params:
+ contains: "P-LOWASC 97 98 99"
+
+ - id: program_hcrc_enter_and_list
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,77,32,90,72,73,68,68,69,78,82,65,77,32,72,73,68,68,69,78,32,65,48,48,48,32,87,79,82,75,69,82,32,82,69,84,85,82,78,32,72,37,61,49,51,49,32,83,67,82,69,69,78,32,80,45,90,72,73,68,68,69,78,82,65,77,13,50,48,32,72,37,61,90,72,73,68,68,69,78,82,65,77,40,34,65,66,34,41,13,51,48,32,80,82,73,78,84,32,34,80,45,90,72,73,68,68,69,78,82,65,77,34,59,72,37,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_hcrc_rem
+ type: assert.screen
+ params:
+ contains: "REM ZHIDDENRAM HIDDEN"
+ - id: program_hcrc_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_hcrc_run
+ type: assert.screen
+ params:
+ contains: "P-ZHIDDENRAM 131"
+ - id: dump_program_hidden_worker
+ type: dump.memory_ranges
+ params:
+ ranges: *plugin_ranges
+
+ - id: program_sumai_enter_and_list
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,77,32,90,83,85,77,78,85,77,65,82,82,65,89,32,73,78,84,32,65,82,82,65,89,32,80,84,82,32,67,79,85,78,84,32,82,69,84,85,82,78,32,83,37,61,54,32,83,67,82,69,69,78,32,80,45,83,85,77,13,50,48,32,68,73,77,32,65,37,40,51,41,13,51,48,32,65,37,40,48,41,61,49,58,65,37,40,49,41,61,50,58,65,37,40,50,41,61,51,13,52,48,32,83,37,61,90,83,85,77,78,85,77,65,82,82,65,89,40,65,37,40,48,41,44,51,41,13,53,48,32,80,82,73,78,84,32,34,80,45,83,85,77,34,59,83,37,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_sumai_rem
+ type: assert.screen
+ params:
+ contains: "REM ZSUMNUMARRAY INT ARRAY"
+ - id: program_sumai_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_sumai_run
+ type: assert.screen
+ params:
+ contains: "P-SUM 6"
+
+ - id: program_range_enter_and_list
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,77,32,82,65,78,71,69,32,82,69,83,85,76,84,32,70,82,65,77,69,32,84,79,32,73,78,84,32,65,82,82,65,89,32,83,67,82,69,69,78,32,80,45,82,65,78,71,69,13,50,48,32,68,73,77,32,82,37,40,52,41,13,51,48,32,90,82,65,78,71,69,78,85,77,65,82,82,65,89,40,55,44,52,44,82,37,40,48,41,41,13,52,48,32,80,82,73,78,84,32,34,80,45,82,65,78,71,69,34,59,82,37,40,48,41,59,82,37,40,51,41,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_range_rem
+ type: assert.screen
+ params:
+ contains: "REM RANGE RESULT FRAME"
+ - id: program_range_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_range_run
+ type: assert.screen
+ params:
+ contains: "P-RANGE 7 10"
+
+ - id: program_handle_enter_and_list
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,77,32,66,85,70,32,82,69,85,32,72,65,78,68,76,69,32,65,76,76,79,67,32,82,69,84,85,82,78,32,70,73,76,76,32,70,82,69,69,32,72,37,61,49,32,83,67,82,69,69,78,32,80,45,66,85,70,13,50,48,32,72,37,61,66,85,70,78,69,87,40,51,48,48,41,13,51,48,32,80,82,73,78,84,32,34,80,45,66,85,70,34,59,72,37,13,52,48,32,66,85,70,70,73,76,76,40,72,37,44,49,55,48,41,13,53,48,32,66,85,70,70,82,69,69,40,72,37,41,13,54,48,32,80,82,73,78,84,32,34,80,45,70,82,69,69,34,59,72,37,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_handle_rem
+ type: assert.screen
+ params:
+ contains: "REM BUF REU HANDLE"
+ - id: program_handle_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_handle_new
+ type: assert.screen
+ params:
+ contains: "P-BUF 1"
+ - id: assert_program_handle_free
+ type: assert.screen
+ params:
+ contains: "P-FREE 1"
+ - id: dump_program_handle
+ type: dump.memory_ranges
+ params:
+ ranges: *plugin_ranges
+
+ - id: program_fail_enter_and_list
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,77,32,90,70,65,73,76,32,69,82,82,79,82,32,67,76,69,65,82,83,32,88,37,32,66,69,70,79,82,69,32,82,66,32,69,82,82,79,82,32,55,32,83,67,82,69,69,78,32,80,45,70,67,76,82,13,50,48,32,88,37,61,57,57,13,51,48,32,90,70,65,73,76,40,55,44,88,37,41,13,52,48,32,80,82,73,78,84,32,34,80,45,65,70,84,69,82,34,59,88,37,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_fail_rem
+ type: assert.screen
+ params:
+ contains: "REM ZFAIL ERROR"
+ - id: program_fail_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_fail_error
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 7"
+ - id: program_fail_print_cleared
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,80,45,70,67,76,82,34,59,88,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_fail_cleared
+ type: assert.screen
+ params:
+ contains: "P-FCLR 0"
+
+ - id: procfunc_load_rbproc1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,76,79,65,68,32,34,82,66,80,82,79,67,49,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: procfunc_list_rbproc1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,76,73,83,84,32,49,48,48,48,45,49,48,50,48,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: assert_procfunc_list_proc
+ type: assert.screen
+ params:
+ contains: "PROC SHOW0"
+ - id: assert_procfunc_list_endp
+ type: assert.screen
+ params:
+ contains: "ENDP"
+ - id: procfunc_list_func_addi
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,76,73,83,84,32,49,51,48,48,45,49,51,50,48,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: assert_procfunc_list_func
+ type: assert.screen
+ params:
+ contains: "FUNC ADDI"
+ - id: procfunc_list_nested_func
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,76,73,83,84,32,49,54,48,48,45,49,54,51,48,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: assert_procfunc_list_exec_out
+ type: assert.screen
+ params:
+ contains: "R%=INNER(X%)"
+ - id: procfunc_run_rbproc1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 4.0
+ - id: assert_procfunc_run_float_nested
+ type: assert.screen
+ params:
+ contains: "NFADD"
+ - id: assert_procfunc_run_string_nested
+ type: assert.screen
+ params:
+ contains: "NGS MIX"
+ - id: assert_procfunc_run_float_statement
+ type: assert.screen
+ params:
+ contains: "SFADD"
+
+ - id: dump_final_plugin_state
+ type: dump.memory_ranges
+ params:
+ ranges: *plugin_ranges
+ - id: regs_final
+ type: monitor.command
+ params:
+ command: "r"
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_full_suite_visual_verification.regular.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_full_suite_visual_verification.regular.yaml
new file mode 100644
index 0000000..0168c0b
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_full_suite_visual_verification.regular.yaml
@@ -0,0 +1,977 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_full_suite_visual_verification
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 1
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 120
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "readybasic"
+ wait_timeout_s: 180
+ capture_label: readybasic_full_suite_visual_prompt
+ - id: dump_initial_plugin_state
+ type: dump.memory_ranges
+ params:
+ ranges: &plugin_ranges
+ - { label: entry_1000, start: 0x1000, end: 0x1120 }
+ - { label: resident_1200, start: 0x1200, end: 0x1BFF }
+ - { label: low_overlay_1c00, start: 0x1C00, end: 0x23FF }
+ - { label: shared_frames_2400, start: 0x2400, end: 0x27FF }
+ - { label: hidden_shadow_9a00, start: 0x9A00, end: 0x9FFF }
+ - { label: hidden_visible_a000, start: 0xA000, end: 0xA5FF }
+ - { label: hidden_overlay_a800, start: 0xA800, end: 0xA8FF }
+ - { label: bridge_c000, start: 0xC000, end: 0xC5FF }
+ - { label: reu_alloc_table_c600, start: 0xC600, end: 0xC6FF }
+
+ - id: direct_ping
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,90,69,67,72,79,32,72,69,65,76,84,72,32,76,79,87,32,79,86,76,32,83,84,65,84,69,77,69,78,84,32,83,84,79,82,69,83,32,80,37,61,49,32,83,67,82,69,69,78,32,68,45,90,69,67,72,79,13,90,69,67,72,79,49,40,80,37,41,13,80,82,73,78,84,32,34,68,45,90,69,67,72,79,34,59,80,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_ping
+ type: assert.screen
+ params:
+ contains: "D-ZECHO 1"
+ - id: dump_direct_ping
+ type: dump.memory_ranges
+ params:
+ ranges: *plugin_ranges
+
+ - id: direct_add16
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,65,68,68,32,78,85,77,32,80,65,82,65,77,83,32,82,69,84,85,82,78,32,65,37,61,49,53,32,83,67,82,69,69,78,32,68,45,65,68,68,13,65,37,61,90,65,68,68,49,54,40,53,44,49,48,41,13,80,82,73,78,84,32,34,68,45,65,68,68,34,59,65,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_add16
+ type: assert.screen
+ params:
+ contains: "D-ADD 15"
+
+ - id: direct_module_slots
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,83,76,79,84,83,32,66,85,73,76,84,73,78,32,77,79,68,85,76,69,32,83,76,79,84,32,80,82,79,79,70,83,13,80,82,73,78,84,32,34,68,45,83,48,34,59,90,83,76,79,84,48,40,41,13,80,82,73,78,84,32,34,68,45,83,49,34,59,90,83,76,79,84,49,40,41,13,80,82,73,78,84,32,34,68,45,83,50,34,59,90,83,76,79,84,50,40,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_module_slot0
+ type: assert.screen
+ params:
+ contains: "D-S0 30"
+ - id: assert_direct_module_slot1
+ type: assert.screen
+ params:
+ contains: "D-S1 31"
+ - id: assert_direct_module_slot2
+ type: assert.screen
+ params:
+ contains: "D-S2 32"
+
+ - id: direct_module_span_overlay_copy
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,77,79,68,32,83,80,65,78,32,79,86,69,82,76,65,89,32,67,79,80,89,32,80,82,79,79,70,83,13,80,82,73,78,84,32,34,68,45,82,83,84,34,59,90,67,80,89,82,83,84,40,41,13,80,82,73,78,84,32,34,68,45,83,80,65,78,34,59,90,83,80,65,78,40,41,13,80,82,73,78,84,32,34,68,45,79,86,76,34,59,90,79,86,76,49,40,41,59,34,47,34,59,90,79,86,76,50,40,41,13,80,82,73,78,84,32,34,68,45,82,83,84,34,59,90,67,80,89,82,83,84,40,41,13,65,61,90,83,76,79,84,49,40,41,13,66,61,90,83,76,79,84,49,40,41,13,80,82,73,78,84,32,34,68,45,67,79,80,89,34,59,90,67,79,80,89,40,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_module_span
+ type: assert.screen
+ params:
+ contains: "D-SPAN 40"
+ - id: assert_direct_module_overlay
+ type: assert.screen
+ params:
+ contains: "D-OVL 51 / 52"
+ - id: assert_direct_module_copy_skip
+ type: assert.screen
+ params:
+ contains: "D-COPY 2"
+
+ - id: direct_disk_module_load12
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,68,73,83,75,77,79,68,85,76,69,32,76,79,65,68,32,80,82,79,79,70,83,13,80,82,73,78,84,32,34,68,45,76,68,49,34,59,90,77,79,68,76,68,40,34,82,66,77,46,83,65,77,80,76,69,49,34,41,13,80,82,73,78,84,32,34,68,45,68,77,49,34,59,90,68,77,49,40,41,13,80,82,73,78,84,32,34,68,45,76,68,50,34,59,90,77,79,68,76,68,40,34,82,66,77,46,83,65,77,80,76,69,50,34,41,13,80,82,73,78,84,32,34,68,45,68,77,50,34,59,90,68,77,50,83,40,41,13,80,82,73,78,84,32,34,68,45,68,79,86,34,59,90,68,79,86,49,40,41,59,34,47,34,59,90,68,79,86,50,40,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_disk_module_load1
+ type: assert.screen
+ params:
+ contains: "D-LD1 1"
+ - id: assert_direct_disk_module_cmd1
+ type: assert.screen
+ params:
+ contains: "D-DM1 61"
+ - id: assert_direct_disk_module_load2
+ type: assert.screen
+ params:
+ contains: "D-LD2 3"
+ - id: assert_direct_disk_module_span
+ type: assert.screen
+ params:
+ contains: "D-DM2 74"
+ - id: assert_direct_disk_module_overlay
+ type: assert.screen
+ params:
+ contains: "D-DOV 72 / 73"
+
+ - id: direct_disk_module_load3
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,68,73,83,75,77,79,68,85,76,69,32,82,66,77,51,32,80,82,79,79,70,83,13,80,82,73,78,84,32,34,68,45,76,68,51,34,59,90,77,79,68,76,68,40,34,82,66,77,46,83,65,77,80,76,69,51,34,41,13,80,82,73,78,84,32,34,68,45,77,51,34,59,90,83,65,65,40,41,59,34,47,34,59,90,85,69,66,40,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_disk_module_load3
+ type: assert.screen
+ params:
+ contains: "D-LD3 30"
+ - id: assert_direct_disk_module_rbm3
+ type: assert.screen
+ params:
+ contains: "D-M3 4 / 113"
+
+ - id: direct_strup_variable
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,83,84,82,32,86,65,82,32,83,84,82,73,78,71,32,82,69,84,85,82,78,32,84,36,61,65,66,67,32,83,67,82,69,69,78,32,68,45,83,84,82,13,83,36,61,34,97,98,99,34,13,84,36,61,85,80,80,69,82,40,83,36,41,13,80,82,73,78,84,32,34,68,45,83,84,82,34,59,84,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_strup_variable
+ type: assert.screen
+ params:
+ contains: "D-STRABC"
+
+ - id: direct_strup_literal
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,76,73,84,32,81,85,79,84,69,68,32,83,84,82,73,78,71,32,82,69,84,85,82,78,32,85,36,61,68,69,70,32,83,67,82,69,69,78,32,68,45,76,73,84,13,85,36,61,85,80,80,69,82,40,34,100,101,102,34,41,13,80,82,73,78,84,32,34,68,45,76,73,84,34,59,85,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_strup_literal
+ type: assert.screen
+ params:
+ contains: "D-LITDEF"
+
+ - id: direct_lower_variable
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,76,79,87,69,82,32,86,65,82,32,83,84,82,73,78,71,32,82,69,84,85,82,78,32,76,36,61,97,98,99,32,83,67,82,69,69,78,32,68,45,76,79,87,13,83,36,61,34,65,66,67,34,13,76,36,61,76,79,87,69,82,40,83,36,41,13,80,82,73,78,84,32,34,68,45,76,79,87,65,83,67,34,59,65,83,67,40,76,36,41,59,65,83,67,40,77,73,68,36,40,76,36,44,50,44,49,41,41,59,65,83,67,40,77,73,68,36,40,76,36,44,51,44,49,41,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_lower_variable
+ type: assert.screen
+ params:
+ contains: "D-LOWASC 97 98 99"
+
+ - id: direct_lower_literal
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,76,79,87,69,82,32,76,73,84,69,82,65,76,32,83,84,82,73,78,71,32,82,69,84,85,82,78,32,76,36,61,103,104,105,32,83,67,82,69,69,78,32,68,45,76,76,79,87,13,76,36,61,76,79,87,69,82,40,34,71,72,73,34,41,13,80,82,73,78,84,32,34,68,45,76,76,79,87,65,83,67,34,59,65,83,67,40,76,36,41,59,65,83,67,40,77,73,68,36,40,76,36,44,50,44,49,41,41,59,65,83,67,40,77,73,68,36,40,76,36,44,51,44,49,41,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_lower_literal
+ type: assert.screen
+ params:
+ contains: "D-LLOWASC 103 104 105"
+
+ - id: direct_hcrc_hidden
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,90,72,73,68,68,69,78,82,65,77,32,72,73,68,68,69,78,32,65,48,48,48,32,87,79,82,75,69,82,32,82,69,84,85,82,78,32,72,37,61,49,51,49,32,83,67,82,69,69,78,32,68,45,90,72,73,68,68,69,78,82,65,77,13,72,37,61,90,72,73,68,68,69,78,82,65,77,40,34,65,66,34,41,13,80,82,73,78,84,32,34,68,45,90,72,73,68,68,69,78,82,65,77,34,59,72,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_hcrc_hidden
+ type: assert.screen
+ params:
+ contains: "D-ZHIDDENRAM 131"
+ - id: dump_direct_hidden_worker
+ type: dump.memory_ranges
+ params:
+ ranges: *plugin_ranges
+
+ - id: direct_sumai
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,83,85,77,32,73,78,84,32,65,82,82,65,89,32,80,84,82,32,67,79,85,78,84,32,82,69,84,85,82,78,32,83,37,61,54,32,83,67,82,69,69,78,32,68,45,83,85,77,13,68,73,77,32,65,37,40,51,41,13,65,37,40,48,41,61,49,58,65,37,40,49,41,61,50,58,65,37,40,50,41,61,51,13,83,37,61,90,83,85,77,78,85,77,65,82,82,65,89,40,65,37,40,48,41,44,51,41,13,80,82,73,78,84,32,34,68,45,83,85,77,34,59,83,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_sumai
+ type: assert.screen
+ params:
+ contains: "D-SUM 6"
+
+ - id: direct_rangeai
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,82,65,78,71,69,32,82,69,83,85,76,84,32,70,82,65,77,69,32,84,79,32,73,78,84,32,65,82,82,65,89,32,83,67,82,69,69,78,32,68,45,82,65,78,71,69,13,68,73,77,32,82,37,40,52,41,13,90,82,65,78,71,69,78,85,77,65,82,82,65,89,40,55,44,52,44,82,37,40,48,41,41,13,80,82,73,78,84,32,34,68,45,82,65,78,71,69,34,59,82,37,40,48,41,59,82,37,40,51,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_rangeai
+ type: assert.screen
+ params:
+ contains: "D-RANGE 7 10"
+
+ - id: direct_bufnew
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,66,85,70,78,69,87,32,82,69,85,32,72,65,78,68,76,69,32,84,65,66,76,69,32,82,69,84,85,82,78,32,72,37,61,49,32,83,67,82,69,69,78,32,68,45,66,85,70,13,72,37,61,66,85,70,78,69,87,40,51,48,48,41,13,80,82,73,78,84,32,34,68,45,66,85,70,34,59,72,37,59,34,58,69,78,68,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_bufnew
+ type: assert.screen
+ params:
+ contains: "D-BUF 1 :END"
+ - id: dump_direct_bufnew
+ type: dump.memory_ranges
+ params:
+ ranges: *plugin_ranges
+
+ - id: direct_buffill
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,66,85,70,70,73,76,76,32,82,69,85,32,72,65,78,68,76,69,32,72,37,32,66,89,84,69,32,49,55,48,32,83,67,82,69,69,78,32,68,45,70,73,76,76,13,66,85,70,70,73,76,76,40,72,37,44,49,55,48,41,13,80,82,73,78,84,32,34,68,45,70,73,76,76,32,79,75,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_buffill
+ type: assert.screen
+ params:
+ contains: "D-FILL OK"
+ - id: assert_direct_buffill_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: direct_buffree
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,66,85,70,70,82,69,69,32,82,69,76,69,65,83,69,32,82,69,85,32,72,65,78,68,76,69,32,72,37,32,83,67,82,69,69,78,32,68,45,70,82,69,69,13,66,85,70,70,82,69,69,40,72,37,41,13,80,82,73,78,84,32,34,68,45,70,82,69,69,32,79,75,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_buffree
+ type: assert.screen
+ params:
+ contains: "D-FREE OK"
+ - id: assert_direct_buffree_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: direct_scrcap_scrput_slot128
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,83,67,82,67,65,80,32,84,69,88,84,32,67,79,76,79,82,32,72,65,78,68,76,69,32,82,69,84,85,82,78,32,65,78,68,32,83,76,79,84,49,50,56,32,83,67,82,80,85,84,13,80,82,73,78,84,32,34,68,45,83,67,82,77,65,82,75,34,13,83,37,61,83,67,82,67,65,80,40,41,13,80,82,73,78,84,32,34,68,45,67,72,65,78,71,69,68,34,13,83,67,82,80,85,84,40,83,37,41,13,80,82,73,78,84,32,34,68,45,83,67,82,80,85,84,34,59,83,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_scrcap_restored_text
+ type: assert.screen
+ params:
+ contains: "D-SCRMARK"
+ - id: assert_direct_scrput_slot128
+ type: assert.screen
+ params:
+ contains: "D-SCRPUT 1"
+ - id: direct_buffill_rejects_screen_handle
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,66,85,70,70,73,76,76,32,77,85,83,84,32,82,69,74,69,67,84,32,83,67,82,69,69,78,32,72,65,78,68,76,69,32,84,89,80,69,13,66,85,70,70,73,76,76,40,83,37,44,49,55,48,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_buffill_rejects_screen_handle
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 40"
+ - id: direct_buffree_screen_handle
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,66,85,70,70,82,69,69,32,82,69,76,69,65,83,69,83,32,83,67,82,69,69,78,32,72,65,78,68,76,69,32,84,89,80,69,13,66,85,70,70,82,69,69,40,83,37,41,13,80,82,73,78,84,32,34,68,45,83,67,82,70,82,69,69,34,59,83,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_buffree_screen_handle
+ type: assert.screen
+ params:
+ contains: "D-SCRFREE 1"
+ - id: assert_direct_buffree_screen_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+ - id: direct_scrput_rejects_buffer_handle
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,83,67,82,80,85,84,32,77,85,83,84,32,82,69,74,69,67,84,32,66,85,70,70,69,82,32,72,65,78,68,76,69,32,84,89,80,69,13,66,37,61,66,85,70,78,69,87,40,51,48,48,41,13,83,67,82,80,85,84,40,66,37,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_scrput_rejects_buffer_handle
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 40"
+ - id: direct_free_buffer_after_type_error
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,70,82,69,69,40,66,37,41,13,80,82,73,78,84,32,34,68,45,66,85,70,82,69,69,34,59,66,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_free_buffer_after_type_error
+ type: assert.screen
+ params:
+ contains: "D-BUFREE 1"
+ - id: assert_direct_free_buffer_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: direct_handle_128_edge
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,72,37,61,66,85,70,78,69,87,40,49,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,68,45,72,77,65,88,34,59,72,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 5.0
+ - id: assert_direct_handle_128_edge
+ type: assert.screen
+ params:
+ contains: "D-HMAX 128"
+ - id: assert_direct_handle_128_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+ - id: direct_handle_129_rejected
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,69,37,61,66,85,70,78,69,87,40,49,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_handle_129_rejected
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 33"
+ - id: direct_free_128_handles
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,66,85,70,70,82,69,69,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,68,45,72,70,82,69,69,68,34,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 5.0
+ - id: assert_direct_free_128_handles
+ type: assert.screen
+ params:
+ contains: "D-HFREED"
+ - id: assert_direct_free_128_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+ - id: direct_48k_heap_edge
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,77,37,61,66,85,70,78,69,87,40,52,57,49,53,50,41,13,80,82,73,78,84,32,34,68,45,77,65,88,66,85,70,34,59,77,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_48k_heap_edge
+ type: assert.screen
+ params:
+ contains: "D-MAXBUF 1"
+ - id: direct_48k_heap_full
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,69,37,61,66,85,70,78,69,87,40,49,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_48k_heap_full
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 34"
+ - id: direct_free_48k_heap
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,70,82,69,69,40,77,37,41,13,80,82,73,78,84,32,34,68,45,77,65,88,70,82,69,69,34,59,77,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_free_48k_heap
+ type: assert.screen
+ params:
+ contains: "D-MAXFREE 1"
+ - id: assert_direct_free_48k_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+ - id: direct_screen_heap_edge
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,50,52,13,50,48,32,83,37,61,83,67,82,67,65,80,40,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,68,45,83,77,65,88,34,59,83,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 5.0
+ - id: assert_direct_screen_heap_edge
+ type: assert.screen
+ params:
+ contains: "D-SMAX 24"
+ - id: direct_screen_heap_full
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,83,37,61,83,67,82,67,65,80,40,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_screen_heap_full
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 34"
+ - id: direct_free_screen_heap
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,50,52,13,50,48,32,66,85,70,70,82,69,69,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,68,45,83,70,82,69,69,68,34,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 5.0
+ - id: assert_direct_free_screen_heap
+ type: assert.screen
+ params:
+ contains: "D-SFREED"
+ - id: assert_direct_free_screen_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: direct_tempscratch
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,84,69,77,80,32,82,69,85,32,84,69,77,80,32,80,65,71,69,83,32,82,69,84,85,82,78,32,84,37,61,51,32,83,67,82,69,69,78,32,68,45,84,69,77,80,13,84,37,61,90,84,69,77,80,83,67,82,65,84,67,72,40,53,49,51,41,13,80,82,73,78,84,32,34,68,45,84,69,77,80,34,59,84,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_tempscratch
+ type: assert.screen
+ params:
+ contains: "D-TEMP 3"
+
+ - id: direct_fail_clears_output
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,90,70,65,73,76,32,69,82,82,79,82,32,80,65,84,72,32,67,76,69,65,82,83,32,88,37,32,84,72,69,78,32,82,66,32,69,82,82,79,82,32,55,13,88,37,61,57,57,13,90,70,65,73,76,40,55,44,88,37,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_fail_error
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 7"
+ - id: direct_fail_print_cleared
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,68,45,70,67,76,82,34,59,88,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_fail_cleared
+ type: assert.screen
+ params:
+ contains: "D-FCLR 0"
+
+ - id: direct_unknown_command
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,78,79,80,69,32,82,69,71,73,83,84,82,89,32,77,73,83,83,32,83,72,79,85,76,68,32,82,66,32,69,82,82,79,82,32,49,13,78,79,80,69,40,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_unknown_command
+ type: assert.screen
+ params:
+ contains: "SYNTAX"
+
+ - id: direct_old_ping_rejected
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,79,76,68,32,83,67,65,76,65,82,32,72,65,83,32,78,79,32,65,76,73,65,83,13,83,67,65,76,65,82,40,80,37,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_old_ping_rejected
+ type: assert.screen
+ params:
+ contains: "ERROR"
+
+ - id: direct_old_add16_rejected
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,79,76,68,32,65,68,68,49,54,32,72,65,83,32,78,79,32,65,76,73,65,83,13,65,68,68,49,54,40,49,44,50,44,65,37,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_old_add16_rejected
+ type: assert.screen
+ params:
+ contains: "ERROR"
+
+ - id: direct_old_strup_rejected
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,79,76,68,32,83,84,82,85,80,32,72,65,83,32,78,79,32,65,76,73,65,83,13,83,84,82,85,80,40,34,97,98,99,34,44,84,36,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_old_strup_rejected
+ type: assert.screen
+ params:
+ contains: "ERROR"
+
+ - id: direct_old_hcrc_rejected
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,79,76,68,32,72,67,82,67,32,72,65,83,32,78,79,32,65,76,73,65,83,13,72,67,82,67,40,34,65,66,34,44,72,37,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_old_hcrc_rejected
+ type: assert.screen
+ params:
+ contains: "ERROR"
+
+ - id: direct_old_sumai_rejected
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,79,76,68,32,83,85,77,65,73,32,72,65,83,32,78,79,32,65,76,73,65,83,13,83,85,77,65,73,40,65,37,40,48,41,44,49,44,83,37,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_old_sumai_rejected
+ type: assert.screen
+ params:
+ contains: "ERROR"
+
+ - id: direct_old_rangeai_rejected
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,79,76,68,32,82,65,78,71,69,65,73,32,72,65,83,32,78,79,32,65,76,73,65,83,13,82,65,78,71,69,65,73,40,49,44,49,44,65,37,40,48,41,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_old_rangeai_rejected
+ type: assert.screen
+ params:
+ contains: "ERROR"
+
+ - id: direct_command_name_in_string
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,67,79,77,77,65,78,68,32,78,65,77,69,32,73,78,32,83,84,82,73,78,71,32,83,72,79,85,76,68,32,78,79,84,32,68,73,83,80,65,84,67,72,13,80,82,73,78,84,32,34,78,79,80,69,40,41,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_command_name_in_string
+ type: assert.screen
+ params:
+ contains: "NOPE()"
+ - id: assert_direct_command_name_in_string_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: direct_command_name_in_rem
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,78,79,80,69,40,41,13,80,82,73,78,84,32,34,68,45,82,69,77,79,75,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_command_name_in_rem
+ type: assert.screen
+ params:
+ contains: "D-REMOK"
+ - id: assert_direct_command_name_in_rem_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: direct_first_comma_rejected
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,70,73,82,83,84,32,65,82,71,32,67,79,77,77,65,32,73,83,32,78,79,84,32,67,65,78,79,78,73,67,65,76,13,90,65,68,68,49,54,40,44,49,44,50,44,65,37,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_first_comma_rejected
+ type: assert.screen
+ params:
+ contains: "SYNTAX"
+
+ - id: direct_missing_out_marker_rejected
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,76,69,71,65,67,89,32,83,80,65,67,69,32,70,79,82,77,32,82,69,74,69,67,84,69,68,13,90,65,68,68,49,54,32,49,44,50,44,65,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_missing_out_marker_rejected
+ type: assert.screen
+ params:
+ contains: "SYNTAX"
+
+ - id: direct_seed_resume_vars
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,82,69,83,85,77,69,32,83,65,86,69,32,66,65,83,73,67,32,86,65,82,83,32,84,72,82,79,85,71,72,32,82,69,65,68,89,79,83,32,69,88,73,84,13,86,37,61,51,50,49,58,86,83,36,61,34,79,75,34,13,80,82,73,78,84,32,34,68,45,83,69,69,68,34,59,86,37,59,34,58,34,59,86,83,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_seed_resume_vars
+ type: assert.screen
+ params:
+ contains: "D-SEED 321 :OK"
+ - id: direct_exit_to_launcher
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: wait_launcher_after_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: resume_after_exit
+ type: input.sequence
+ params:
+ keys: [145,17,13]
+ inter_key_delay_s: 0.10
+ post_delay_s: 3.0
+ - id: wait_readybasic_after_resume
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 30
+ capture_label: readybasic_full_suite_visual_after_resume
+ - id: direct_registry_after_resume
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,80,79,83,84,82,69,83,32,66,65,83,73,67,32,86,65,82,83,32,65,78,68,32,82,69,71,73,83,84,82,89,32,83,84,73,76,76,32,65,67,84,73,86,69,13,80,82,73,78,84,32,34,68,45,83,84,65,84,69,34,59,86,37,59,34,58,34,59,86,83,36,13,80,37,61,90,65,68,68,49,54,40,48,44,49,41,13,80,82,73,78,84,32,34,68,45,82,69,83,85,77,69,34,59,80,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_direct_state_after_resume
+ type: assert.screen
+ params:
+ contains: "D-STATE 321 :OK"
+ - id: assert_direct_registry_after_resume
+ type: assert.screen
+ params:
+ contains: "D-RESUME 1"
+
+ - id: program_ping_enter_and_list
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,77,32,90,69,67,72,79,49,32,72,69,65,76,84,72,32,76,79,87,32,79,86,76,32,83,84,65,84,69,77,69,78,84,32,83,84,79,82,69,83,32,80,37,61,49,32,83,67,82,69,69,78,32,80,45,90,69,67,72,79,13,50,48,32,90,69,67,72,79,49,40,80,37,41,13,51,48,32,80,82,73,78,84,32,34,80,45,90,69,67,72,79,34,59,80,37,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_ping_rem
+ type: assert.screen
+ params:
+ contains: "REM ZECHO1 HEALTH"
+ - id: program_ping_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_ping_run
+ type: assert.screen
+ params:
+ contains: "P-ZECHO 1"
+
+ - id: program_chain_enter_and_list
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,77,32,65,68,68,32,78,85,77,32,80,65,82,65,77,83,32,83,65,77,69,32,76,73,78,69,32,82,69,84,85,82,78,32,65,37,61,51,32,83,67,82,69,69,78,32,80,45,67,72,65,73,78,13,50,48,32,65,37,61,90,65,68,68,49,54,40,49,44,50,41,58,80,82,73,78,84,32,34,80,45,67,72,65,73,78,34,59,65,37,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_chain_rem
+ type: assert.screen
+ params:
+ contains: "REM ADD NUM PARAMS"
+ - id: program_chain_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_chain_run
+ type: assert.screen
+ params:
+ contains: "P-CHAIN 3"
+
+ - id: program_if_true_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,77,32,73,70,32,84,82,85,69,32,84,72,69,78,32,82,69,84,85,82,78,32,67,79,77,77,65,78,68,32,83,67,82,69,69,78,32,80,45,73,70,84,82,85,69,13,50,48,32,80,37,61,48,13,51,48,32,73,70,32,49,32,84,72,69,78,32,80,37,61,90,65,68,68,49,54,40,48,44,49,41,13,52,48,32,80,82,73,78,84,32,34,80,45,73,70,84,82,85,69,34,59,80,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_if_true_run
+ type: assert.screen
+ params:
+ contains: "P-IFTRUE 1"
+
+ - id: program_if_false_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,77,32,73,70,32,70,65,76,83,69,32,83,75,73,80,83,32,82,69,84,85,82,78,32,67,79,77,77,65,78,68,32,83,67,82,69,69,78,32,80,45,73,70,70,65,76,83,69,13,50,48,32,80,37,61,48,13,51,48,32,73,70,32,48,32,84,72,69,78,32,80,37,61,90,65,68,68,49,54,40,48,44,49,41,13,52,48,32,80,82,73,78,84,32,34,80,45,73,70,70,65,76,83,69,34,59,80,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_if_false_run
+ type: assert.screen
+ params:
+ contains: "P-IFFALSE 0"
+
+ - id: program_for_next_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,77,32,70,79,82,32,78,69,88,84,32,67,79,77,77,65,78,68,32,82,69,84,85,82,78,32,83,67,82,69,69,78,32,80,45,70,79,82,13,50,48,32,70,79,82,32,73,61,49,32,84,79,32,51,13,51,48,32,65,37,61,90,65,68,68,49,54,40,73,44,49,48,41,13,52,48,32,78,69,88,84,13,53,48,32,80,82,73,78,84,32,34,80,45,70,79,82,34,59,65,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_for_next_run
+ type: assert.screen
+ params:
+ contains: "P-FOR 13"
+
+ - id: program_strup_enter_and_list
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,77,32,85,80,80,69,82,32,86,65,82,32,83,84,82,73,78,71,32,82,69,84,85,82,78,32,84,36,61,65,66,67,32,83,67,82,69,69,78,32,80,45,83,84,82,13,50,48,32,83,36,61,34,97,98,99,34,13,51,48,32,84,36,61,85,80,80,69,82,40,83,36,41,13,52,48,32,80,82,73,78,84,32,34,80,45,83,84,82,34,59,84,36,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_strup_rem
+ type: assert.screen
+ params:
+ contains: "REM UPPER VAR STRING"
+ - id: program_strup_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_strup_run
+ type: assert.screen
+ params:
+ contains: "P-STRABC"
+
+ - id: program_lower_enter_and_list
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,77,32,76,79,87,69,82,32,86,65,82,32,83,84,82,73,78,71,32,82,69,84,85,82,78,32,84,36,61,97,98,99,32,83,67,82,69,69,78,32,80,45,76,79,87,13,50,48,32,83,36,61,34,65,66,67,34,13,51,48,32,84,36,61,76,79,87,69,82,40,83,36,41,13,52,48,32,80,82,73,78,84,32,34,80,45,76,79,87,65,83,67,34,59,65,83,67,40,84,36,41,59,65,83,67,40,77,73,68,36,40,84,36,44,50,44,49,41,41,59,65,83,67,40,77,73,68,36,40,84,36,44,51,44,49,41,41,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_lower_rem
+ type: assert.screen
+ params:
+ contains: "REM LOWER VAR STRING"
+ - id: program_lower_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_lower_run
+ type: assert.screen
+ params:
+ contains: "P-LOWASC 97 98 99"
+
+ - id: program_hcrc_enter_and_list
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,77,32,90,72,73,68,68,69,78,82,65,77,32,72,73,68,68,69,78,32,65,48,48,48,32,87,79,82,75,69,82,32,82,69,84,85,82,78,32,72,37,61,49,51,49,32,83,67,82,69,69,78,32,80,45,90,72,73,68,68,69,78,82,65,77,13,50,48,32,72,37,61,90,72,73,68,68,69,78,82,65,77,40,34,65,66,34,41,13,51,48,32,80,82,73,78,84,32,34,80,45,90,72,73,68,68,69,78,82,65,77,34,59,72,37,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_hcrc_rem
+ type: assert.screen
+ params:
+ contains: "REM ZHIDDENRAM HIDDEN"
+ - id: program_hcrc_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_hcrc_run
+ type: assert.screen
+ params:
+ contains: "P-ZHIDDENRAM 131"
+ - id: dump_program_hidden_worker
+ type: dump.memory_ranges
+ params:
+ ranges: *plugin_ranges
+
+ - id: program_sumai_enter_and_list
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,77,32,90,83,85,77,78,85,77,65,82,82,65,89,32,73,78,84,32,65,82,82,65,89,32,80,84,82,32,67,79,85,78,84,32,82,69,84,85,82,78,32,83,37,61,54,32,83,67,82,69,69,78,32,80,45,83,85,77,13,50,48,32,68,73,77,32,65,37,40,51,41,13,51,48,32,65,37,40,48,41,61,49,58,65,37,40,49,41,61,50,58,65,37,40,50,41,61,51,13,52,48,32,83,37,61,90,83,85,77,78,85,77,65,82,82,65,89,40,65,37,40,48,41,44,51,41,13,53,48,32,80,82,73,78,84,32,34,80,45,83,85,77,34,59,83,37,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_sumai_rem
+ type: assert.screen
+ params:
+ contains: "REM ZSUMNUMARRAY INT ARRAY"
+ - id: program_sumai_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_sumai_run
+ type: assert.screen
+ params:
+ contains: "P-SUM 6"
+
+ - id: program_range_enter_and_list
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,77,32,82,65,78,71,69,32,82,69,83,85,76,84,32,70,82,65,77,69,32,84,79,32,73,78,84,32,65,82,82,65,89,32,83,67,82,69,69,78,32,80,45,82,65,78,71,69,13,50,48,32,68,73,77,32,82,37,40,52,41,13,51,48,32,90,82,65,78,71,69,78,85,77,65,82,82,65,89,40,55,44,52,44,82,37,40,48,41,41,13,52,48,32,80,82,73,78,84,32,34,80,45,82,65,78,71,69,34,59,82,37,40,48,41,59,82,37,40,51,41,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_range_rem
+ type: assert.screen
+ params:
+ contains: "REM RANGE RESULT FRAME"
+ - id: program_range_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_range_run
+ type: assert.screen
+ params:
+ contains: "P-RANGE 7 10"
+
+ - id: program_handle_enter_and_list
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,77,32,66,85,70,32,82,69,85,32,72,65,78,68,76,69,32,65,76,76,79,67,32,82,69,84,85,82,78,32,70,73,76,76,32,70,82,69,69,32,72,37,61,49,32,83,67,82,69,69,78,32,80,45,66,85,70,13,50,48,32,72,37,61,66,85,70,78,69,87,40,51,48,48,41,13,51,48,32,80,82,73,78,84,32,34,80,45,66,85,70,34,59,72,37,13,52,48,32,66,85,70,70,73,76,76,40,72,37,44,49,55,48,41,13,53,48,32,66,85,70,70,82,69,69,40,72,37,41,13,54,48,32,80,82,73,78,84,32,34,80,45,70,82,69,69,34,59,72,37,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_handle_rem
+ type: assert.screen
+ params:
+ contains: "REM BUF REU HANDLE"
+ - id: program_handle_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_handle_new
+ type: assert.screen
+ params:
+ contains: "P-BUF 1"
+ - id: assert_program_handle_free
+ type: assert.screen
+ params:
+ contains: "P-FREE 1"
+ - id: dump_program_handle
+ type: dump.memory_ranges
+ params:
+ ranges: *plugin_ranges
+
+ - id: program_fail_enter_and_list
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,77,32,90,70,65,73,76,32,69,82,82,79,82,32,67,76,69,65,82,83,32,88,37,32,66,69,70,79,82,69,32,82,66,32,69,82,82,79,82,32,55,32,83,67,82,69,69,78,32,80,45,70,67,76,82,13,50,48,32,88,37,61,57,57,13,51,48,32,90,70,65,73,76,40,55,44,88,37,41,13,52,48,32,80,82,73,78,84,32,34,80,45,65,70,84,69,82,34,59,88,37,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_fail_rem
+ type: assert.screen
+ params:
+ contains: "REM ZFAIL ERROR"
+ - id: program_fail_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_fail_error
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 7"
+ - id: program_fail_print_cleared
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,80,45,70,67,76,82,34,59,88,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: assert_program_fail_cleared
+ type: assert.screen
+ params:
+ contains: "P-FCLR 0"
+
+ - id: procfunc_load_rbproc1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,76,79,65,68,32,34,82,66,80,82,79,67,49,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: procfunc_list_rbproc1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,76,73,83,84,32,49,48,48,48,45,49,48,50,48,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: assert_procfunc_list_proc
+ type: assert.screen
+ params:
+ contains: "PROC SHOW0"
+ - id: assert_procfunc_list_endp
+ type: assert.screen
+ params:
+ contains: "ENDP"
+ - id: procfunc_list_func_addi
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,76,73,83,84,32,49,51,48,48,45,49,51,50,48,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: assert_procfunc_list_func
+ type: assert.screen
+ params:
+ contains: "FUNC ADDI"
+ - id: procfunc_list_nested_func
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,76,73,83,84,32,49,54,48,48,45,49,54,51,48,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: assert_procfunc_list_exec_out
+ type: assert.screen
+ params:
+ contains: "R%=INNER(X%)"
+ - id: procfunc_run_rbproc1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 4.0
+ - id: assert_procfunc_run_float_nested
+ type: assert.screen
+ params:
+ contains: "NFADD"
+ - id: assert_procfunc_run_string_nested
+ type: assert.screen
+ params:
+ contains: "NGS MIX"
+ - id: assert_procfunc_run_float_statement
+ type: assert.screen
+ params:
+ contains: "SFADD"
+
+ - id: dump_final_plugin_state
+ type: dump.memory_ranges
+ params:
+ ranges: *plugin_ranges
+ - id: regs_final
+ type: monitor.command
+ params:
+ command: "r"
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_hotkey_f2_probe.easyflash.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_hotkey_f2_probe.easyflash.yaml
new file mode 100644
index 0000000..aeea792
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_hotkey_f2_probe.easyflash.yaml
@@ -0,0 +1,106 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_hotkey_f2_probe_easyflash
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
+ autostart_enabled: false
+ disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
+ drive8_enabled: true
+ drive8_type: 1541
+ drive9_enabled: false
+ true_drive: true
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: easyflash_wait_launcher
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ pre_delay_s: 4
+ poll_s: 0.5
+ wait_timeout_s: 420
+ capture_label: easyflash_readybasic_launcher
+ - id: easyflash_start_readybasic
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 180
+ capture_label: readybasic_hotkey_f2_prompt
+ - id: assert_chrin_vector_installed
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "08 12"
+ - id: assert_keylog_vector_installed
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "7E C1"
+ - id: f2_to_next_loaded_app_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 4C 74 A4"
+ - id: f2_to_next_loaded_app_clear_keylog_breakpoints
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: f2_to_next_loaded_app
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_target_after_f2
+ type: screen.wait_contains
+ params:
+ text: "CALENDAR 26"
+ wait_timeout_s: 60
+ capture_label: target_after_readybasic_f2
+ - id: assert_keyboard_buffer_empty_after_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: wait_target_stable_after_f2
+ type: screen.wait_contains
+ params:
+ text: "CALENDAR 26"
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: target_stable_after_readybasic_f2
+ - id: assert_keyboard_buffer_empty_stable_after_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_hotkey_f2_probe.regular.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_hotkey_f2_probe.regular.yaml
new file mode 100644
index 0000000..4848e49
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_hotkey_f2_probe.regular.yaml
@@ -0,0 +1,91 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_hotkey_f2_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "readybasic"
+ wait_timeout_s: 180
+ capture_label: readybasic_hotkey_f2_prompt
+ - id: assert_chrin_vector_installed
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "08 12"
+ - id: assert_keylog_vector_installed
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "7E C1"
+ - id: f2_to_next_loaded_app_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 4C 74 A4"
+ - id: f2_to_next_loaded_app_clear_keylog_breakpoints
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: f2_to_next_loaded_app
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_target_after_f2
+ type: screen.wait_contains
+ params:
+ text: "CALENDAR 26"
+ wait_timeout_s: 60
+ capture_label: target_after_readybasic_f2
+ - id: assert_keyboard_buffer_empty_after_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: wait_target_stable_after_f2
+ type: screen.wait_contains
+ params:
+ text: "CALENDAR 26"
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: target_stable_after_readybasic_f2
+ - id: assert_keyboard_buffer_empty_stable_after_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_hotkey_f4_probe.easyflash.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_hotkey_f4_probe.easyflash.yaml
new file mode 100644
index 0000000..9a0766e
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_hotkey_f4_probe.easyflash.yaml
@@ -0,0 +1,231 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_hotkey_probe_easyflash
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
+ autostart_enabled: false
+ disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
+ drive8_enabled: true
+ drive8_type: 1541
+ drive9_enabled: false
+ true_drive: true
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: easyflash_wait_launcher
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ pre_delay_s: 4
+ poll_s: 0.5
+ wait_timeout_s: 420
+ capture_label: easyflash_readybasic_launcher
+ - id: easyflash_start_readybasic
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 180
+ capture_label: readybasic_hotkey_prompt
+ - id: assert_chrin_vector_installed
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "08 12"
+ - id: assert_keylog_vector_installed
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "7E C1"
+ - id: seed_readybasic_state
+ type: input.sequence
+ params:
+ keys: [86,37,61,51,50,49,58,86,83,36,61,34,72,79,84,34,13,80,82,73,78,84,32,34,72,79,84,83,69,69,68,34,59,86,37,59,34,58,34,59,86,83,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: seed_readybasic_state_capture
+ type: screen.capture
+ params:
+ label: seed_readybasic_state
+ note: after seeding ReadyBASIC state before hotkey tests
+ - id: assert_seed_state
+ type: assert.screen
+ params:
+ contains: "HOTSEED 321 :HOT"
+ - id: ctrl_b_from_readybasic_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 4C 74 A4"
+ - id: ctrl_b_from_readybasic_clear_keylog_breakpoints
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: ctrl_b_from_readybasic
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: ctrl_b_from_readybasic_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_ctrl_b_from_readybasic_after_input
+ note: after Ctrl+B input before launcher wait
+ - id: wait_launcher_after_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ capture_label: launcher_after_readybasic_ctrl_b
+ - id: assert_keyboard_buffer_empty_after_ctrl_b
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: move_readybasic_to_editor
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: move_readybasic_to_editor_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_readybasic_to_editor_menu
+ note: after navigating to editor from launcher
+ - id: wait_editor_loaded
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ capture_label: editor_loaded_for_hotkey_probe
+ - id: ctrl_b_from_editor
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
+ - id: ctrl_b_from_editor_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_ctrl_b_from_editor_after_input
+ note: after Ctrl+B input from editor before launcher wait
+ - id: wait_launcher_after_editor
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ - id: move_editor_to_readybasic_for_f4
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: move_editor_to_readybasic_for_f4_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_editor_to_readybasic_menu
+ note: after navigating back to ReadyBASIC before F4 test
+ - id: wait_readybasic_resume_for_f4
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_resume_before_f4
+ - id: assert_readybasic_state_after_ctrl_b
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,72,79,84,83,84,65,84,69,34,59,86,37,59,34,58,34,59,86,83,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_state_after_ctrl_b_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_state_after_ctrl_b
+ note: after typing HOTSTATE verification command
+ - id: assert_hot_state_after_ctrl_b
+ type: assert.screen
+ params:
+ contains: "HOTSTATE 321 :HOT"
+ - id: build_list_timing_program
+ type: input.sequence
+ params:
+ keys: [49,48,32,80,82,73,78,84,32,34,72,79,84,76,73,83,84,49,34,13,50,48,32,80,82,73,78,84,32,34,72,79,84,76,73,83,84,50,34,13,51,48,32,80,82,73,78,84,32,34,72,79,84,76,73,83,84,51,34,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.2
+ - id: build_list_timing_program_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_list_before_f4
+ note: after building LIST program before F4
+ - id: wait_list_visible_before_f4
+ type: screen.wait_contains
+ params:
+ text: "HOTLIST3"
+ wait_timeout_s: 20
+ capture_label: readybasic_list_before_f4
+ - id: f4_to_prev_loaded_app_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 01 8D 8D 02 A9 05 85 CB 20 7E C1 A9 01 8D 8D 02 A9 05 85 CB 20 7E C1 4C 74 A4"
+ - id: f4_to_prev_loaded_app_clear_keylog_breakpoints
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: f4_to_prev_loaded_app
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_target_after_f4
+ type: screen.wait_contains
+ params:
+ text: "CLIPBOARD"
+ wait_timeout_s: 60
+ capture_label: target_after_readybasic_f4
+ - id: assert_keyboard_buffer_empty_after_f4
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: wait_target_stable_after_f4
+ type: screen.wait_contains
+ params:
+ text: "CLIPBOARD"
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: target_stable_after_readybasic_f4
+ - id: assert_keyboard_buffer_empty_stable_after_f4
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_hotkey_f4_probe.regular.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_hotkey_f4_probe.regular.yaml
new file mode 100644
index 0000000..b9c02de
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_hotkey_f4_probe.regular.yaml
@@ -0,0 +1,216 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_hotkey_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "readybasic"
+ wait_timeout_s: 180
+ capture_label: readybasic_hotkey_prompt
+ - id: assert_chrin_vector_installed
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "08 12"
+ - id: assert_keylog_vector_installed
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "7E C1"
+ - id: seed_readybasic_state
+ type: input.sequence
+ params:
+ keys: [86,37,61,51,50,49,58,86,83,36,61,34,72,79,84,34,13,80,82,73,78,84,32,34,72,79,84,83,69,69,68,34,59,86,37,59,34,58,34,59,86,83,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: seed_readybasic_state_capture
+ type: screen.capture
+ params:
+ label: seed_readybasic_state
+ note: after seeding ReadyBASIC state before hotkey tests
+ - id: assert_seed_state
+ type: assert.screen
+ params:
+ contains: "HOTSEED 321 :HOT"
+ - id: ctrl_b_from_readybasic_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 4C 74 A4"
+ - id: ctrl_b_from_readybasic_clear_keylog_breakpoints
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: ctrl_b_from_readybasic
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: ctrl_b_from_readybasic_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_ctrl_b_from_readybasic_after_input
+ note: after Ctrl+B input before launcher wait
+ - id: wait_launcher_after_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ capture_label: launcher_after_readybasic_ctrl_b
+ - id: assert_keyboard_buffer_empty_after_ctrl_b
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: move_readybasic_to_editor
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: move_readybasic_to_editor_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_readybasic_to_editor_menu
+ note: after navigating to editor from launcher
+ - id: wait_editor_loaded
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ capture_label: editor_loaded_for_hotkey_probe
+ - id: ctrl_b_from_editor
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
+ - id: ctrl_b_from_editor_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_ctrl_b_from_editor_after_input
+ note: after Ctrl+B input from editor before launcher wait
+ - id: wait_launcher_after_editor
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ - id: move_editor_to_readybasic_for_f4
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: move_editor_to_readybasic_for_f4_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_editor_to_readybasic_menu
+ note: after navigating back to ReadyBASIC before F4 test
+ - id: wait_readybasic_resume_for_f4
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_resume_before_f4
+ - id: assert_readybasic_state_after_ctrl_b
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,72,79,84,83,84,65,84,69,34,59,86,37,59,34,58,34,59,86,83,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_state_after_ctrl_b_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_state_after_ctrl_b
+ note: after typing HOTSTATE verification command
+ - id: assert_hot_state_after_ctrl_b
+ type: assert.screen
+ params:
+ contains: "HOTSTATE 321 :HOT"
+ - id: build_list_timing_program
+ type: input.sequence
+ params:
+ keys: [49,48,32,80,82,73,78,84,32,34,72,79,84,76,73,83,84,49,34,13,50,48,32,80,82,73,78,84,32,34,72,79,84,76,73,83,84,50,34,13,51,48,32,80,82,73,78,84,32,34,72,79,84,76,73,83,84,51,34,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.2
+ - id: build_list_timing_program_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_list_before_f4
+ note: after building LIST program before F4
+ - id: wait_list_visible_before_f4
+ type: screen.wait_contains
+ params:
+ text: "HOTLIST3"
+ wait_timeout_s: 20
+ capture_label: readybasic_list_before_f4
+ - id: f4_to_prev_loaded_app_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 01 8D 8D 02 A9 05 85 CB 20 7E C1 A9 01 8D 8D 02 A9 05 85 CB 20 7E C1 4C 74 A4"
+ - id: f4_to_prev_loaded_app_clear_keylog_breakpoints
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: f4_to_prev_loaded_app
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_target_after_f4
+ type: screen.wait_contains
+ params:
+ text: "CLIPBOARD"
+ wait_timeout_s: 60
+ capture_label: target_after_readybasic_f4
+ - id: assert_keyboard_buffer_empty_after_f4
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: wait_target_stable_after_f4
+ type: screen.wait_contains
+ params:
+ text: "CLIPBOARD"
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: target_stable_after_readybasic_f4
+ - id: assert_keyboard_buffer_empty_stable_after_f4
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_keyboard_regression_probe.easyflash.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_keyboard_regression_probe.easyflash.yaml
new file mode 100644
index 0000000..3937c99
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_keyboard_regression_probe.easyflash.yaml
@@ -0,0 +1,258 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_keyboard_regression_probe_easyflash
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
+ autostart_enabled: false
+ disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
+ drive8_enabled: true
+ drive8_type: 1541
+ drive9_enabled: false
+ true_drive: true
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_launcher_initial
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 420
+ capture_label: keyboard_regression_launcher_initial
+ - id: launch_readybasic_from_launcher
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_initial
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 180
+ capture_label: keyboard_regression_readybasic_initial
+ - id: assert_readybasic_bank_initial
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "05"
+ - id: assert_chrin_vector_initial
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "08 12"
+ - id: assert_keylog_vector_initial
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "7E C1"
+ - id: assert_warp_enabled
+ type: warp.set
+ params:
+ enabled: true
+ capture_after: false
+ - id: type_space_string_once
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,65,32,66,32,67,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_single_space_string_output
+ type: assert.screen
+ params:
+ contains: "A B C"
+ - id: assert_keyboard_buffer_empty_after_space_string
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: type_partial_line_10
+ type: input.sequence
+ params:
+ keys: [49,48]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.1
+ - id: partial_line_ctrl_b_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 4C 74 A4"
+ - id: partial_line_ctrl_b_clear_keylog_breakpoints
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: partial_line_ctrl_b
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_launcher_after_partial_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ capture_label: keyboard_regression_launcher_after_partial_ctrl_b
+ - id: assert_no_rem_after_partial_ctrl_b
+ type: assert.screen_not_contains
+ params:
+ not_contains: "REM"
+ - id: assert_launcher_bank_after_partial_ctrl_b
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "00"
+ - id: reenter_readybasic_after_partial_ctrl_b
+ type: input.sequence
+ params:
+ keys: [13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_after_partial_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: keyboard_regression_readybasic_after_partial_ctrl_b
+ - id: list_after_partial_ctrl_b
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_no_rem_listed_after_partial_ctrl_b
+ type: assert.screen_not_contains
+ params:
+ not_contains: "REM"
+ - id: type_after_partial_ctrl_b
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,65,70,84,69,82,67,84,82,76,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_type_after_partial_ctrl_b
+ type: assert.screen
+ params:
+ contains: "AFTERCTRL"
+ - id: clean_ctrl_b_to_launcher_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 4C 74 A4"
+ - id: clean_ctrl_b_to_launcher_clear_keylog_breakpoints
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: clean_ctrl_b_to_launcher
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_launcher_to_load_editor
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ - id: move_readybasic_to_editor
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_loaded
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ capture_label: keyboard_regression_editor_loaded
+ - id: editor_ctrl_b_to_launcher
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
+ - id: wait_launcher_after_editor_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ - id: move_editor_to_readybasic
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_before_partial_f2
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: keyboard_regression_readybasic_before_partial_f2
+ - id: type_partial_line_20
+ type: input.sequence
+ params:
+ keys: [50,48]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.1
+ - id: partial_line_f2_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 4C 74 A4"
+ - id: partial_line_f2_clear_keylog_breakpoints
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: partial_line_f2
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_editor_after_partial_f2
+ type: screen.wait_contains
+ params:
+ text: "CALENDAR 26"
+ wait_timeout_s: 60
+ capture_label: keyboard_regression_editor_after_partial_f2
+ - id: assert_no_rem_after_partial_f2
+ type: assert.screen_not_contains
+ params:
+ not_contains: "REM"
+ - id: assert_keylog_restored_after_partial_f2
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "48 EB"
+ - id: assert_chrin_restored_after_partial_f2
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "57 F1"
+ - id: assert_keyboard_buffer_empty_after_partial_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_keyboard_regression_probe.regular.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_keyboard_regression_probe.regular.yaml
new file mode 100644
index 0000000..d048a61
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_keyboard_regression_probe.regular.yaml
@@ -0,0 +1,257 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_keyboard_regression_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_launcher_initial
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 180
+ capture_label: keyboard_regression_launcher_initial
+ - id: launch_readybasic_from_launcher
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_initial
+ type: screen.wait_contains
+ params:
+ text: "readybasic"
+ wait_timeout_s: 180
+ capture_label: keyboard_regression_readybasic_initial
+ - id: assert_readybasic_bank_initial
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "05"
+ - id: assert_chrin_vector_initial
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "08 12"
+ - id: assert_keylog_vector_initial
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "7E C1"
+ - id: assert_warp_enabled
+ type: warp.set
+ params:
+ enabled: true
+ capture_after: false
+ - id: type_space_string_once
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,65,32,66,32,67,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_single_space_string_output
+ type: assert.screen
+ params:
+ contains: "A B C"
+ - id: assert_keyboard_buffer_empty_after_space_string
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: type_partial_line_10
+ type: input.sequence
+ params:
+ keys: [49,48]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.1
+ - id: partial_line_ctrl_b_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 4C 74 A4"
+ - id: partial_line_ctrl_b_clear_keylog_breakpoints
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: partial_line_ctrl_b
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_launcher_after_partial_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ capture_label: keyboard_regression_launcher_after_partial_ctrl_b
+ - id: assert_no_rem_after_partial_ctrl_b
+ type: assert.screen_not_contains
+ params:
+ not_contains: "REM"
+ - id: assert_launcher_bank_after_partial_ctrl_b
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "00"
+ - id: reenter_readybasic_after_partial_ctrl_b
+ type: input.sequence
+ params:
+ keys: [13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_after_partial_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: keyboard_regression_readybasic_after_partial_ctrl_b
+ - id: list_after_partial_ctrl_b
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_no_rem_listed_after_partial_ctrl_b
+ type: assert.screen_not_contains
+ params:
+ not_contains: "REM"
+ - id: type_after_partial_ctrl_b
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,65,70,84,69,82,67,84,82,76,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_type_after_partial_ctrl_b
+ type: assert.screen
+ params:
+ contains: "AFTERCTRL"
+ - id: clean_ctrl_b_to_launcher_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 4C 74 A4"
+ - id: clean_ctrl_b_to_launcher_clear_keylog_breakpoints
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: clean_ctrl_b_to_launcher
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_launcher_to_load_editor
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ - id: move_readybasic_to_editor
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_loaded
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ capture_label: keyboard_regression_editor_loaded
+ - id: editor_ctrl_b_to_launcher
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
+ - id: wait_launcher_after_editor_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ - id: move_editor_to_readybasic
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_before_partial_f2
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: keyboard_regression_readybasic_before_partial_f2
+ - id: type_partial_line_20
+ type: input.sequence
+ params:
+ keys: [50,48]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.1
+ - id: partial_line_f2_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 4C 74 A4"
+ - id: partial_line_f2_clear_keylog_breakpoints
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: partial_line_f2
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_editor_after_partial_f2
+ type: screen.wait_contains
+ params:
+ text: "CALENDAR 26"
+ wait_timeout_s: 60
+ capture_label: keyboard_regression_editor_after_partial_f2
+ - id: assert_no_rem_after_partial_f2
+ type: assert.screen_not_contains
+ params:
+ not_contains: "REM"
+ - id: assert_keylog_restored_after_partial_f2
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "48 EB"
+ - id: assert_chrin_restored_after_partial_f2
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "57 F1"
+ - id: assert_keyboard_buffer_empty_after_partial_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_large_vars_probe.easyflash.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_large_vars_probe.easyflash.yaml
new file mode 100644
index 0000000..adc1cd8
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_large_vars_probe.easyflash.yaml
@@ -0,0 +1,261 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_large_vars_probe_easyflash
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
+ autostart_enabled: false
+ disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
+ drive8_enabled: true
+ drive8_type: 1541
+ drive9_enabled: false
+ true_drive: true
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: easyflash_wait_launcher
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ pre_delay_s: 4
+ poll_s: 0.5
+ wait_timeout_s: 420
+ capture_label: easyflash_readybasic_launcher
+ - id: easyflash_start_readybasic
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 180
+ capture_label: readybasic_prompt
+ - id: build_program_lines
+ type: input.sequence
+ params:
+ keys: [78,69,87,13,49,48,32,80,82,73,78,84,32,34,79,78,69,34,13,50,48,32,80,82,73,78,84,32,34,84,87,79,34,13,51,48,32,80,82,73,78,84,32,34,84,72,82,69,69,34,13,52,48,32,80,82,73,78,84,32,34,70,79,85,82,34,13,53,48,32,80,82,73,78,84,32,34,70,73,86,69,34,13]
+ inter_key_delay_s: 0.04
+ post_delay_s: 0.8
+ - id: clear_variables
+ type: input.sequence
+ params:
+ keys: [67,76,82,13]
+ inter_key_delay_s: 0.04
+ post_delay_s: 2.0
+ - id: assign_alpha_string
+ type: input.sequence
+ params:
+ keys: [65,36,61,34,65,76,80,72,65,34,13]
+ inter_key_delay_s: 0.05
+ post_delay_s: 2.0
+ - id: assign_bravo_string
+ type: input.sequence
+ params:
+ keys: [66,36,61,34,66,82,65,86,79,34,13]
+ inter_key_delay_s: 0.05
+ post_delay_s: 2.0
+ - id: assign_charlie_string
+ type: input.sequence
+ params:
+ keys: [71,36,61,34,67,72,65,82,76,73,69,34,13]
+ inter_key_delay_s: 0.05
+ post_delay_s: 2.0
+ - id: dump_after_abc_assignment
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
+ - { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
+ - { label: bridge_c000, start: 0xC000, end: 0xC5FF }
+ - id: print_charlie_after_c_assignment
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,71,36,13]
+ inter_key_delay_s: 0.04
+ post_delay_s: 2.0
+ - id: dump_after_first_print_charlie
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
+ - { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
+ - { label: bridge_c000, start: 0xC000, end: 0xC5FF }
+ - id: assert_charlie_after_c_assignment
+ type: assert.screen
+ params:
+ contains: "CHARLIE"
+ - id: assign_delta_string
+ type: input.sequence
+ params:
+ keys: [68,36,61,34,68,69,76,84,65,34,13]
+ inter_key_delay_s: 0.05
+ post_delay_s: 2.0
+ - id: dump_after_delta_assignment
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
+ - { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
+ - { label: bridge_c000, start: 0xC000, end: 0xC5FF }
+ - id: print_charlie_after_delta_assignment
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,71,36,13]
+ inter_key_delay_s: 0.04
+ post_delay_s: 2.0
+ - id: dump_after_second_print_charlie
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
+ - { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
+ - { label: bridge_c000, start: 0xC000, end: 0xC5FF }
+ - id: assert_charlie_after_delta_assignment
+ type: assert.screen
+ params:
+ contains: "CHARLIE"
+ - id: dump_after_delta_before_dim
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
+ - { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
+ - id: dim_large_array
+ type: input.sequence
+ params:
+ keys: [68,73,77,32,69,40,50,48,48,41,13,69,40,49,57,57,41,61,49,50,51,52,13]
+ inter_key_delay_s: 0.05
+ post_delay_s: 0.8
+ - id: print_large_direct_vars_before_exit
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13,80,82,73,78,84,32,66,36,13,80,82,73,78,84,32,71,36,13,80,82,73,78,84,32,68,36,13,80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.04
+ post_delay_s: 1.5
+ - id: dump_before_exit
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
+ - { label: basic_vars_start_1200, start: 0x1200, end: 0x1600 }
+ - { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
+ - { label: runtime_state_9600, start: 0x9600, end: 0x9A00 }
+ - { label: bridge_c000, start: 0xC000, end: 0xC5FF }
+ - id: assert_before_exit_alpha
+ type: assert.screen
+ params:
+ contains: "ALPHA"
+ - id: assert_before_exit_delta
+ type: assert.screen
+ params:
+ contains: "DELTA"
+ - id: assert_before_exit_charlie
+ type: assert.screen
+ params:
+ contains: "CHARLIE"
+ - id: assert_before_exit_array
+ type: assert.screen
+ params:
+ contains: "1234"
+ - id: exit_readybasic
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: resume_readybasic
+ type: input.sequence
+ params:
+ keys: [13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: wait_prompt_after_resume
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 30
+ - id: print_large_direct_vars_after_resume
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,43,66,36,43,71,36,43,68,36,13,80,82,73,78,84,32,69,40,49,57,57,41,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: dump_after_resume
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
+ - { label: basic_vars_start_1200, start: 0x1200, end: 0x1600 }
+ - { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
+ - { label: runtime_state_9600, start: 0x9600, end: 0x9A00 }
+ - { label: bridge_c000, start: 0xC000, end: 0xC5FF }
+ - id: assert_after_resume_alpha
+ type: assert.screen
+ params:
+ contains: "ALPHABRAVOCHARLIEDELTA"
+ - id: assert_after_resume_bravo
+ type: assert.screen
+ params:
+ contains: "BRAVO"
+ - id: assert_after_resume_charlie
+ type: assert.screen
+ params:
+ contains: "CHARLIE"
+ - id: assert_after_resume_delta
+ type: assert.screen
+ params:
+ contains: "DELTA"
+ - id: assert_after_resume_array
+ type: assert.screen
+ params:
+ contains: "1234"
+ - id: assert_after_resume_program
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: dump_after_resume_verified
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
+ - { label: basic_vars_start_1200, start: 0x1200, end: 0x1600 }
+ - { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
+ - { label: runtime_state_9600, start: 0x9600, end: 0x9A00 }
+ - { label: bridge_c000, start: 0xC000, end: 0xC5FF }
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_large_vars_probe.regular.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_large_vars_probe.regular.yaml
new file mode 100644
index 0000000..0874e05
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_large_vars_probe.regular.yaml
@@ -0,0 +1,246 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_large_vars_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "readybasic"
+ wait_timeout_s: 180
+ capture_label: readybasic_prompt
+ - id: build_program_lines
+ type: input.sequence
+ params:
+ keys: [78,69,87,13,49,48,32,80,82,73,78,84,32,34,79,78,69,34,13,50,48,32,80,82,73,78,84,32,34,84,87,79,34,13,51,48,32,80,82,73,78,84,32,34,84,72,82,69,69,34,13,52,48,32,80,82,73,78,84,32,34,70,79,85,82,34,13,53,48,32,80,82,73,78,84,32,34,70,73,86,69,34,13]
+ inter_key_delay_s: 0.04
+ post_delay_s: 0.8
+ - id: clear_variables
+ type: input.sequence
+ params:
+ keys: [67,76,82,13]
+ inter_key_delay_s: 0.04
+ post_delay_s: 2.0
+ - id: assign_alpha_string
+ type: input.sequence
+ params:
+ keys: [65,36,61,34,65,76,80,72,65,34,13]
+ inter_key_delay_s: 0.05
+ post_delay_s: 2.0
+ - id: assign_bravo_string
+ type: input.sequence
+ params:
+ keys: [66,36,61,34,66,82,65,86,79,34,13]
+ inter_key_delay_s: 0.05
+ post_delay_s: 2.0
+ - id: assign_charlie_string
+ type: input.sequence
+ params:
+ keys: [71,36,61,34,67,72,65,82,76,73,69,34,13]
+ inter_key_delay_s: 0.05
+ post_delay_s: 2.0
+ - id: dump_after_abc_assignment
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
+ - { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
+ - { label: bridge_c000, start: 0xC000, end: 0xC5FF }
+ - id: print_charlie_after_c_assignment
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,71,36,13]
+ inter_key_delay_s: 0.04
+ post_delay_s: 2.0
+ - id: dump_after_first_print_charlie
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
+ - { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
+ - { label: bridge_c000, start: 0xC000, end: 0xC5FF }
+ - id: assert_charlie_after_c_assignment
+ type: assert.screen
+ params:
+ contains: "CHARLIE"
+ - id: assign_delta_string
+ type: input.sequence
+ params:
+ keys: [68,36,61,34,68,69,76,84,65,34,13]
+ inter_key_delay_s: 0.05
+ post_delay_s: 2.0
+ - id: dump_after_delta_assignment
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
+ - { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
+ - { label: bridge_c000, start: 0xC000, end: 0xC5FF }
+ - id: print_charlie_after_delta_assignment
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,71,36,13]
+ inter_key_delay_s: 0.04
+ post_delay_s: 2.0
+ - id: dump_after_second_print_charlie
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
+ - { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
+ - { label: bridge_c000, start: 0xC000, end: 0xC5FF }
+ - id: assert_charlie_after_delta_assignment
+ type: assert.screen
+ params:
+ contains: "CHARLIE"
+ - id: dump_after_delta_before_dim
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
+ - { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
+ - id: dim_large_array
+ type: input.sequence
+ params:
+ keys: [68,73,77,32,69,40,50,48,48,41,13,69,40,49,57,57,41,61,49,50,51,52,13]
+ inter_key_delay_s: 0.05
+ post_delay_s: 0.8
+ - id: print_large_direct_vars_before_exit
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13,80,82,73,78,84,32,66,36,13,80,82,73,78,84,32,71,36,13,80,82,73,78,84,32,68,36,13,80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.04
+ post_delay_s: 1.5
+ - id: dump_before_exit
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
+ - { label: basic_vars_start_1200, start: 0x1200, end: 0x1600 }
+ - { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
+ - { label: runtime_state_9600, start: 0x9600, end: 0x9A00 }
+ - { label: bridge_c000, start: 0xC000, end: 0xC5FF }
+ - id: assert_before_exit_alpha
+ type: assert.screen
+ params:
+ contains: "ALPHA"
+ - id: assert_before_exit_delta
+ type: assert.screen
+ params:
+ contains: "DELTA"
+ - id: assert_before_exit_charlie
+ type: assert.screen
+ params:
+ contains: "CHARLIE"
+ - id: assert_before_exit_array
+ type: assert.screen
+ params:
+ contains: "1234"
+ - id: exit_readybasic
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: resume_readybasic
+ type: input.sequence
+ params:
+ keys: [13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: wait_prompt_after_resume
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 30
+ - id: print_large_direct_vars_after_resume
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,43,66,36,43,71,36,43,68,36,13,80,82,73,78,84,32,69,40,49,57,57,41,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: dump_after_resume
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
+ - { label: basic_vars_start_1200, start: 0x1200, end: 0x1600 }
+ - { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
+ - { label: runtime_state_9600, start: 0x9600, end: 0x9A00 }
+ - { label: bridge_c000, start: 0xC000, end: 0xC5FF }
+ - id: assert_after_resume_alpha
+ type: assert.screen
+ params:
+ contains: "ALPHABRAVOCHARLIEDELTA"
+ - id: assert_after_resume_bravo
+ type: assert.screen
+ params:
+ contains: "BRAVO"
+ - id: assert_after_resume_charlie
+ type: assert.screen
+ params:
+ contains: "CHARLIE"
+ - id: assert_after_resume_delta
+ type: assert.screen
+ params:
+ contains: "DELTA"
+ - id: assert_after_resume_array
+ type: assert.screen
+ params:
+ contains: "1234"
+ - id: assert_after_resume_program
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: dump_after_resume_verified
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
+ - { label: basic_vars_start_1200, start: 0x1200, end: 0x1600 }
+ - { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
+ - { label: runtime_state_9600, start: 0x9600, end: 0x9A00 }
+ - { label: bridge_c000, start: 0xC000, end: 0xC5FF }
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_lifecycle_probe.easyflash.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_lifecycle_probe.easyflash.yaml
new file mode 100644
index 0000000..68ae07a
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_lifecycle_probe.easyflash.yaml
@@ -0,0 +1,290 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_lifecycle_probe_easyflash
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
+ autostart_enabled: false
+ disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
+ drive8_enabled: true
+ drive8_type: 1541
+ drive9_enabled: false
+ true_drive: true
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: easyflash_wait_launcher
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ pre_delay_s: 4
+ poll_s: 0.5
+ wait_timeout_s: 420
+ capture_label: easyflash_readybasic_launcher
+ - id: easyflash_start_readybasic
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_loading
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 180
+ - id: capture_after_readybasic_loading
+ type: screen.capture
+ params:
+ label: after_readybasic_loading
+ note: after READYBASIC first appears, before READY prompt wait
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 180
+ capture_label: readybasic_prompt
+ - id: dump_prompt_core
+ type: dump.memory_ranges
+ params:
+ ranges: &core_ranges
+ - { label: entry_1000, start: 0x1000, end: 0x1120 }
+ - { label: hidden_shadow_9a00, start: 0x9A00, end: 0x9F40 }
+ - { label: hidden_visible_a000, start: 0xA000, end: 0xA540 }
+ - { label: vectors_0300, start: 0x0300, end: 0x030B }
+ - { label: kernal_vectors_0324, start: 0x0324, end: 0x032B }
+ - { label: chrget_0073, start: 0x0073, end: 0x008A }
+ - { label: basic_zp_002b, start: 0x002B, end: 0x003F }
+ - { label: txtptr_007a, start: 0x007A, end: 0x007B }
+ - { label: kernal_mem_bounds_0280, start: 0x0280, end: 0x0287 }
+ - { label: input_buffer_0200, start: 0x0200, end: 0x0258 }
+ - { label: low_ram_0100_0600, start: 0x0100, end: 0x0600 }
+ - { label: screen_0400, start: 0x0400, end: 0x07E7 }
+ - { label: basic_text_1200, start: 0x1200, end: 0x1300 }
+ - { label: readybasic_bridge_c000, start: 0xC000, end: 0xC5FF }
+ - id: type_print_1
+ type: input.sequence
+ params:
+ keys: [80, 82, 73, 78, 84, 32, 49, 13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.5
+ - id: capture_print_1
+ type: screen.capture
+ params:
+ label: after_print_1
+ note: after direct print 1
+ - id: assert_print_1_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
+ - id: dump_print_1_core
+ type: dump.memory_ranges
+ params:
+ ranges: *core_ranges
+ - id: type_print_hello
+ type: input.sequence
+ params:
+ keys: [80, 82, 73, 78, 84, 32, 34, 72, 69, 76, 76, 79, 34, 13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.5
+ - id: capture_print_hello
+ type: screen.capture
+ params:
+ label: after_print_hello
+ note: after direct print hello
+ - id: assert_print_hello_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
+ - id: dump_print_hello_core
+ type: dump.memory_ranges
+ params:
+ ranges: *core_ranges
+ - id: type_line_10_print_1
+ type: input.sequence
+ params:
+ keys: [49, 48, 32, 80, 82, 73, 78, 84, 32, 49, 13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.5
+ - id: capture_line_entry
+ type: screen.capture
+ params:
+ label: after_10_print_1
+ note: after numbered line entry
+ - id: dump_line_entry_core
+ type: dump.memory_ranges
+ params:
+ ranges: *core_ranges
+ - id: assert_line_entry_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
+ - id: assert_line_entry_no_at_artifacts
+ type: assert.screen_not_contains
+ params:
+ not_contains: "@"
+ - id: type_list
+ type: input.sequence
+ params:
+ keys: [76, 73, 83, 84, 13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.5
+ - id: capture_list
+ type: screen.capture
+ params:
+ label: after_list
+ note: after LIST
+ - id: assert_list_has_line
+ type: assert.screen
+ params:
+ contains: "10 PRINT 1"
+ - id: type_run
+ type: input.sequence
+ params:
+ keys: [82, 85, 78, 13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: capture_run
+ type: screen.capture
+ params:
+ label: after_run
+ note: after RUN
+ - id: assert_run_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
+ - id: assert_run_no_at_artifacts
+ type: assert.screen_not_contains
+ params:
+ not_contains: "@"
+ - id: dump_run_core
+ type: dump.memory_ranges
+ params:
+ ranges: *core_ranges
+ - id: type_rb_direct_text
+ type: input.sequence
+ params:
+ keys: [80,37,61,90,65,68,68,49,54,40,48,44,49,41,13,80,82,73,78,84,32,34,76,83,67,65,76,65,82,34,59,80,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.5
+ - id: capture_rb_direct_text
+ type: screen.capture
+ params:
+ label: after_rb_direct_text
+ note: after direct scalar command statement
+ - id: dump_rb_direct_text_core
+ type: dump.memory_ranges
+ params:
+ ranges: *core_ranges
+ - id: assert_rb_direct_text
+ type: assert.screen
+ params:
+ contains: "LSCALAR 1"
+ - id: type_rb_direct_add
+ type: input.sequence
+ params:
+ keys: [65,37,61,90,65,68,68,49,54,40,53,44,49,48,41,13,80,82,73,78,84,32,34,76,65,68,68,34,59,65,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.5
+ - id: capture_rb_direct_add
+ type: screen.capture
+ params:
+ label: after_rb_direct_add
+ note: after direct ZADD16 statement
+ - id: dump_rb_direct_add_core
+ type: dump.memory_ranges
+ params:
+ ranges: *core_ranges
+ - id: assert_rb_direct_add_screen
+ type: assert.screen
+ params:
+ contains: "LADD 15"
+ - id: type_line_20_rb_text
+ type: input.sequence
+ params:
+ keys: [50,48,32,76,36,61,85,80,80,69,82,40,34,108,105,110,101,34,41,13,51,48,32,80,82,73,78,84,32,76,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.5
+ - id: type_run_with_rb_line
+ type: input.sequence
+ params:
+ keys: [82, 85, 78, 13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: capture_run_with_rb_line
+ type: screen.capture
+ params:
+ label: after_run_with_rb_line
+ note: after RUN with stored ReadyBASIC command
+ - id: assert_run_with_rb_line
+ type: assert.screen
+ params:
+ contains: "LINE"
+ - id: type_exit_upper
+ type: input.sequence
+ params:
+ keys: [69, 88, 73, 84, 13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_after_exit
+ type: screen.capture
+ params:
+ label: after_exit
+ note: after uppercase exit command
+ - id: wait_launcher_after_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: type_resume_readybasic
+ type: input.sequence
+ params:
+ keys: [145,17,13]
+ inter_key_delay_s: 0.10
+ post_delay_s: 3.0
+ - id: wait_readybasic_prompt_after_resume
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 30
+ capture_on_success: true
+ capture_label: readybasic_prompt_after_resume
+ - id: type_list_after_resume
+ type: input.sequence
+ params:
+ keys: [76, 73, 83, 84, 13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: capture_list_after_resume
+ type: screen.capture
+ params:
+ label: after_list_after_resume
+ note: after relaunching ReadyBASIC from REU and LISTing
+ - id: assert_resume_preserved_line
+ type: assert.screen
+ params:
+ contains: "10 PRINT 1"
+ - id: regs_final
+ type: monitor.command
+ params:
+ command: "r"
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_lifecycle_probe.regular.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_lifecycle_probe.regular.yaml
new file mode 100644
index 0000000..71b74b6
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_lifecycle_probe.regular.yaml
@@ -0,0 +1,275 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_lifecycle_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_loading
+ type: screen.wait_contains
+ params:
+ text: "readybasic"
+ wait_timeout_s: 180
+ - id: capture_after_readybasic_loading
+ type: screen.capture
+ params:
+ label: after_readybasic_loading
+ note: after READYBASIC first appears, before READY prompt wait
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "readybasic"
+ wait_timeout_s: 180
+ capture_label: readybasic_prompt
+ - id: dump_prompt_core
+ type: dump.memory_ranges
+ params:
+ ranges: &core_ranges
+ - { label: entry_1000, start: 0x1000, end: 0x1120 }
+ - { label: hidden_shadow_9a00, start: 0x9A00, end: 0x9F40 }
+ - { label: hidden_visible_a000, start: 0xA000, end: 0xA540 }
+ - { label: vectors_0300, start: 0x0300, end: 0x030B }
+ - { label: kernal_vectors_0324, start: 0x0324, end: 0x032B }
+ - { label: chrget_0073, start: 0x0073, end: 0x008A }
+ - { label: basic_zp_002b, start: 0x002B, end: 0x003F }
+ - { label: txtptr_007a, start: 0x007A, end: 0x007B }
+ - { label: kernal_mem_bounds_0280, start: 0x0280, end: 0x0287 }
+ - { label: input_buffer_0200, start: 0x0200, end: 0x0258 }
+ - { label: low_ram_0100_0600, start: 0x0100, end: 0x0600 }
+ - { label: screen_0400, start: 0x0400, end: 0x07E7 }
+ - { label: basic_text_1200, start: 0x1200, end: 0x1300 }
+ - { label: readybasic_bridge_c000, start: 0xC000, end: 0xC5FF }
+ - id: type_print_1
+ type: input.sequence
+ params:
+ keys: [80, 82, 73, 78, 84, 32, 49, 13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.5
+ - id: capture_print_1
+ type: screen.capture
+ params:
+ label: after_print_1
+ note: after direct print 1
+ - id: assert_print_1_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
+ - id: dump_print_1_core
+ type: dump.memory_ranges
+ params:
+ ranges: *core_ranges
+ - id: type_print_hello
+ type: input.sequence
+ params:
+ keys: [80, 82, 73, 78, 84, 32, 34, 72, 69, 76, 76, 79, 34, 13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.5
+ - id: capture_print_hello
+ type: screen.capture
+ params:
+ label: after_print_hello
+ note: after direct print hello
+ - id: assert_print_hello_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
+ - id: dump_print_hello_core
+ type: dump.memory_ranges
+ params:
+ ranges: *core_ranges
+ - id: type_line_10_print_1
+ type: input.sequence
+ params:
+ keys: [49, 48, 32, 80, 82, 73, 78, 84, 32, 49, 13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.5
+ - id: capture_line_entry
+ type: screen.capture
+ params:
+ label: after_10_print_1
+ note: after numbered line entry
+ - id: dump_line_entry_core
+ type: dump.memory_ranges
+ params:
+ ranges: *core_ranges
+ - id: assert_line_entry_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
+ - id: assert_line_entry_no_at_artifacts
+ type: assert.screen_not_contains
+ params:
+ not_contains: "@"
+ - id: type_list
+ type: input.sequence
+ params:
+ keys: [76, 73, 83, 84, 13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.5
+ - id: capture_list
+ type: screen.capture
+ params:
+ label: after_list
+ note: after LIST
+ - id: assert_list_has_line
+ type: assert.screen
+ params:
+ contains: "10 PRINT 1"
+ - id: type_run
+ type: input.sequence
+ params:
+ keys: [82, 85, 78, 13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: capture_run
+ type: screen.capture
+ params:
+ label: after_run
+ note: after RUN
+ - id: assert_run_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
+ - id: assert_run_no_at_artifacts
+ type: assert.screen_not_contains
+ params:
+ not_contains: "@"
+ - id: dump_run_core
+ type: dump.memory_ranges
+ params:
+ ranges: *core_ranges
+ - id: type_rb_direct_text
+ type: input.sequence
+ params:
+ keys: [80,37,61,90,65,68,68,49,54,40,48,44,49,41,13,80,82,73,78,84,32,34,76,83,67,65,76,65,82,34,59,80,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.5
+ - id: capture_rb_direct_text
+ type: screen.capture
+ params:
+ label: after_rb_direct_text
+ note: after direct scalar command statement
+ - id: dump_rb_direct_text_core
+ type: dump.memory_ranges
+ params:
+ ranges: *core_ranges
+ - id: assert_rb_direct_text
+ type: assert.screen
+ params:
+ contains: "LSCALAR 1"
+ - id: type_rb_direct_add
+ type: input.sequence
+ params:
+ keys: [65,37,61,90,65,68,68,49,54,40,53,44,49,48,41,13,80,82,73,78,84,32,34,76,65,68,68,34,59,65,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.5
+ - id: capture_rb_direct_add
+ type: screen.capture
+ params:
+ label: after_rb_direct_add
+ note: after direct ZADD16 statement
+ - id: dump_rb_direct_add_core
+ type: dump.memory_ranges
+ params:
+ ranges: *core_ranges
+ - id: assert_rb_direct_add_screen
+ type: assert.screen
+ params:
+ contains: "LADD 15"
+ - id: type_line_20_rb_text
+ type: input.sequence
+ params:
+ keys: [50,48,32,76,36,61,85,80,80,69,82,40,34,108,105,110,101,34,41,13,51,48,32,80,82,73,78,84,32,76,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.5
+ - id: type_run_with_rb_line
+ type: input.sequence
+ params:
+ keys: [82, 85, 78, 13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: capture_run_with_rb_line
+ type: screen.capture
+ params:
+ label: after_run_with_rb_line
+ note: after RUN with stored ReadyBASIC command
+ - id: assert_run_with_rb_line
+ type: assert.screen
+ params:
+ contains: "LINE"
+ - id: type_exit_upper
+ type: input.sequence
+ params:
+ keys: [69, 88, 73, 84, 13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_after_exit
+ type: screen.capture
+ params:
+ label: after_exit
+ note: after uppercase exit command
+ - id: wait_launcher_after_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: type_resume_readybasic
+ type: input.sequence
+ params:
+ keys: [145,17,13]
+ inter_key_delay_s: 0.10
+ post_delay_s: 3.0
+ - id: wait_readybasic_prompt_after_resume
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 30
+ capture_on_success: true
+ capture_label: readybasic_prompt_after_resume
+ - id: type_list_after_resume
+ type: input.sequence
+ params:
+ keys: [76, 73, 83, 84, 13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: capture_list_after_resume
+ type: screen.capture
+ params:
+ label: after_list_after_resume
+ note: after relaunching ReadyBASIC from REU and LISTing
+ - id: assert_resume_preserved_line
+ type: assert.screen
+ params:
+ contains: "10 PRINT 1"
+ - id: regs_final
+ type: monitor.command
+ params:
+ command: "r"
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_module_overlay_probe.easyflash.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_module_overlay_probe.easyflash.yaml
new file mode 100644
index 0000000..81ef5e6
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_module_overlay_probe.easyflash.yaml
@@ -0,0 +1,198 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_module_overlay_probe_easyflash
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
+ autostart_enabled: false
+ disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
+ drive8_enabled: true
+ drive8_type: 1541
+ drive9_enabled: false
+ true_drive: true
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: easyflash_wait_launcher
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ pre_delay_s: 4
+ poll_s: 0.5
+ wait_timeout_s: 420
+ capture_label: easyflash_readybasic_launcher
+ - id: easyflash_start_readybasic
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 180
+ capture_label: readybasic_module_overlay_prompt
+ - id: builtin_overlay_bank_probe
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,70,82,69,69,77,69,77,40,41,13,80,82,73,78,84,32,34,83,76,79,84,83,34,59,90,83,76,79,84,48,40,41,59,34,47,34,59,90,83,76,79,84,49,40,41,59,34,47,34,59,90,83,76,79,84,50,40,41,13,80,82,73,78,84,32,34,83,80,65,78,34,59,90,83,80,65,78,40,41,13,80,82,73,78,84,32,34,79,86,76,34,59,90,79,86,76,49,40,41,59,34,47,34,59,90,79,86,76,50,40,41,13,80,82,73,78,84,32,34,67,80,89,34,59,90,67,80,89,82,83,84,40,41,59,34,47,34,59,90,67,79,80,89,40,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: capture_builtin_overlay_bank_probe
+ type: screen.capture
+ params:
+ label: after_builtin_overlay_bank_probe
+ - id: assert_builtin_slots
+ type: assert.screen
+ params:
+ contains: "SLOTS 30 / 31 / 32"
+ - id: assert_builtin_span
+ type: assert.screen
+ params:
+ contains: "SPAN 40"
+ - id: assert_builtin_overlays
+ type: assert.screen
+ params:
+ contains: "OVL 51 / 52"
+ - id: rbm_sample1_2_probe
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,80,82,73,78,84,32,34,76,68,49,34,59,90,77,79,68,76,68,40,34,82,66,77,46,83,65,77,80,76,69,49,34,41,13,80,82,73,78,84,32,34,68,77,49,34,59,90,68,77,49,40,41,13,80,82,73,78,84,32,34,76,68,50,34,59,90,77,79,68,76,68,40,34,82,66,77,46,83,65,77,80,76,69,50,34,41,13,80,82,73,78,84,32,34,68,77,50,34,59,90,68,77,50,83,40,41,13,80,82,73,78,84,32,34,68,79,86,34,59,90,68,79,86,49,40,41,59,34,47,34,59,90,68,79,86,50,40,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: assert_ld1
+ type: assert.screen
+ params:
+ contains: "LD1 1"
+ - id: assert_dm1
+ type: assert.screen
+ params:
+ contains: "DM1 61"
+ - id: assert_ld2
+ type: assert.screen
+ params:
+ contains: "LD2 3"
+ - id: assert_dm2
+ type: assert.screen
+ params:
+ contains: "DM2 74"
+ - id: assert_dov
+ type: assert.screen
+ params:
+ contains: "DOV 72 / 73"
+ - id: rbm_sample3_load
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,80,82,73,78,84,32,34,76,68,51,34,59,90,77,79,68,76,68,40,34,82,66,77,46,83,65,77,80,76,69,51,34,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: capture_rbm_sample3_load
+ type: screen.capture
+ params:
+ label: after_rbm_sample3_load
+ - id: assert_ld3
+ type: assert.screen
+ params:
+ contains: "LD3 30"
+ - id: rbm_sample3_probe
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,82,66,77,51,32,70,73,82,83,84,32,67,65,76,76,83,58,32,69,65,67,72,32,79,86,69,82,76,65,89,32,83,84,65,84,69,32,83,84,65,82,84,83,32,65,84,32,90,69,82,79,32,65,70,84,69,82,32,76,79,65,68,13,80,82,73,78,84,32,34,77,51,65,34,59,90,83,65,65,40,41,59,34,47,34,59,90,83,69,66,40,41,13,80,82,73,78,84,32,34,77,51,66,34,59,90,84,65,65,40,41,59,34,47,34,59,90,84,69,66,40,41,13,80,82,73,78,84,32,34,77,51,67,34,59,90,85,65,65,40,41,59,34,47,34,59,90,85,69,66,40,41,13,70,82,69,69,77,69,77,40,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: capture_rbm_sample3
+ type: screen.capture
+ params:
+ label: after_rbm_sample3
+ - id: assert_m3a
+ type: assert.screen
+ params:
+ contains: "M3A 4 / 13"
+ - id: assert_m3b
+ type: assert.screen
+ params:
+ contains: "M3B 54 / 63"
+ - id: assert_m3c
+ type: assert.screen
+ params:
+ contains: "M3C 104 / 113"
+ - id: assert_free_same
+ type: assert.screen
+ params:
+ contains: "31113"
+ - id: rbm_sample3_copy_same_overlay_probe
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,83,65,77,69,32,79,86,69,82,76,65,89,58,32,90,83,65,65,32,76,79,65,68,83,44,32,90,83,65,66,32,82,69,85,83,69,83,32,82,69,83,73,68,69,78,84,32,73,77,65,71,69,13,80,82,73,78,84,32,34,82,49,34,59,90,67,80,89,82,83,84,40,41,13,65,61,90,83,65,65,40,41,13,66,61,90,83,65,66,40,41,13,80,82,73,78,84,32,34,83,49,34,59,65,59,34,47,34,59,66,13,80,82,73,78,84,32,34,67,49,34,59,90,67,79,80,89,40,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: capture_rbm_sample3_copy_same_overlay
+ type: screen.capture
+ params:
+ label: after_rbm_sample3_copy_same_overlay
+ - id: assert_copy_same_overlay_no_reload
+ type: assert.screen
+ params:
+ contains: "C1 2"
+ - id: assert_state_same_overlay_kept
+ type: assert.screen
+ params:
+ contains: "S1 4 / 6"
+ - id: rbm_sample3_copy_different_overlay_probe
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,73,70,70,69,82,69,78,84,32,79,86,69,82,76,65,89,58,32,90,83,66,65,32,82,69,80,76,65,67,69,83,32,90,83,65,65,32,83,76,79,84,32,73,77,65,71,69,13,80,82,73,78,84,32,34,82,50,34,59,90,67,80,89,82,83,84,40,41,13,65,61,90,83,65,65,40,41,13,66,61,90,83,66,65,40,41,13,67,61,90,83,65,65,40,41,13,80,82,73,78,84,32,34,83,50,34,59,65,59,34,47,34,59,66,59,34,47,34,59,67,13,80,82,73,78,84,32,34,67,50,34,59,90,67,79,80,89,40,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: capture_rbm_sample3_copy_different_overlay
+ type: screen.capture
+ params:
+ label: after_rbm_sample3_copy_different_overlay
+ - id: assert_copy_different_overlay_reload
+ type: assert.screen
+ params:
+ contains: "C2 4"
+ - id: assert_state_different_overlay_reloaded
+ type: assert.screen
+ params:
+ contains: "S2 4 / 6 / 4"
+ - id: rbm_sample3_copy_different_submodule_probe
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,73,70,70,69,82,69,78,84,32,83,85,66,77,79,68,85,76,69,58,32,90,84,65,65,32,82,69,80,76,65,67,69,83,32,90,83,65,65,32,83,76,79,84,32,73,77,65,71,69,13,80,82,73,78,84,32,34,82,51,34,59,90,67,80,89,82,83,84,40,41,13,65,61,90,83,65,65,40,41,13,66,61,90,84,65,65,40,41,13,67,61,90,83,65,65,40,41,13,80,82,73,78,84,32,34,83,51,34,59,65,59,34,47,34,59,66,59,34,47,34,59,67,13,80,82,73,78,84,32,34,67,51,34,59,90,67,79,80,89,40,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: capture_rbm_sample3_copy_different_submodule
+ type: screen.capture
+ params:
+ label: after_rbm_sample3_copy_different_submodule
+ - id: assert_copy_different_submodule_reload
+ type: assert.screen
+ params:
+ contains: "C3 4"
+ - id: assert_state_different_submodule_reloaded
+ type: assert.screen
+ params:
+ contains: "S3 4 / 54 / 4"
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_module_overlay_probe.regular.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_module_overlay_probe.regular.yaml
new file mode 100644
index 0000000..50e4f05
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_module_overlay_probe.regular.yaml
@@ -0,0 +1,183 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_module_overlay_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "readybasic"
+ wait_timeout_s: 180
+ capture_label: readybasic_module_overlay_prompt
+ - id: builtin_overlay_bank_probe
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,70,82,69,69,77,69,77,40,41,13,80,82,73,78,84,32,34,83,76,79,84,83,34,59,90,83,76,79,84,48,40,41,59,34,47,34,59,90,83,76,79,84,49,40,41,59,34,47,34,59,90,83,76,79,84,50,40,41,13,80,82,73,78,84,32,34,83,80,65,78,34,59,90,83,80,65,78,40,41,13,80,82,73,78,84,32,34,79,86,76,34,59,90,79,86,76,49,40,41,59,34,47,34,59,90,79,86,76,50,40,41,13,80,82,73,78,84,32,34,67,80,89,34,59,90,67,80,89,82,83,84,40,41,59,34,47,34,59,90,67,79,80,89,40,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: capture_builtin_overlay_bank_probe
+ type: screen.capture
+ params:
+ label: after_builtin_overlay_bank_probe
+ - id: assert_builtin_slots
+ type: assert.screen
+ params:
+ contains: "SLOTS 30 / 31 / 32"
+ - id: assert_builtin_span
+ type: assert.screen
+ params:
+ contains: "SPAN 40"
+ - id: assert_builtin_overlays
+ type: assert.screen
+ params:
+ contains: "OVL 51 / 52"
+ - id: rbm_sample1_2_probe
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,80,82,73,78,84,32,34,76,68,49,34,59,90,77,79,68,76,68,40,34,82,66,77,46,83,65,77,80,76,69,49,34,41,13,80,82,73,78,84,32,34,68,77,49,34,59,90,68,77,49,40,41,13,80,82,73,78,84,32,34,76,68,50,34,59,90,77,79,68,76,68,40,34,82,66,77,46,83,65,77,80,76,69,50,34,41,13,80,82,73,78,84,32,34,68,77,50,34,59,90,68,77,50,83,40,41,13,80,82,73,78,84,32,34,68,79,86,34,59,90,68,79,86,49,40,41,59,34,47,34,59,90,68,79,86,50,40,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: assert_ld1
+ type: assert.screen
+ params:
+ contains: "LD1 1"
+ - id: assert_dm1
+ type: assert.screen
+ params:
+ contains: "DM1 61"
+ - id: assert_ld2
+ type: assert.screen
+ params:
+ contains: "LD2 3"
+ - id: assert_dm2
+ type: assert.screen
+ params:
+ contains: "DM2 74"
+ - id: assert_dov
+ type: assert.screen
+ params:
+ contains: "DOV 72 / 73"
+ - id: rbm_sample3_load
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,80,82,73,78,84,32,34,76,68,51,34,59,90,77,79,68,76,68,40,34,82,66,77,46,83,65,77,80,76,69,51,34,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: capture_rbm_sample3_load
+ type: screen.capture
+ params:
+ label: after_rbm_sample3_load
+ - id: assert_ld3
+ type: assert.screen
+ params:
+ contains: "LD3 30"
+ - id: rbm_sample3_probe
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,82,66,77,51,32,70,73,82,83,84,32,67,65,76,76,83,58,32,69,65,67,72,32,79,86,69,82,76,65,89,32,83,84,65,84,69,32,83,84,65,82,84,83,32,65,84,32,90,69,82,79,32,65,70,84,69,82,32,76,79,65,68,13,80,82,73,78,84,32,34,77,51,65,34,59,90,83,65,65,40,41,59,34,47,34,59,90,83,69,66,40,41,13,80,82,73,78,84,32,34,77,51,66,34,59,90,84,65,65,40,41,59,34,47,34,59,90,84,69,66,40,41,13,80,82,73,78,84,32,34,77,51,67,34,59,90,85,65,65,40,41,59,34,47,34,59,90,85,69,66,40,41,13,70,82,69,69,77,69,77,40,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: capture_rbm_sample3
+ type: screen.capture
+ params:
+ label: after_rbm_sample3
+ - id: assert_m3a
+ type: assert.screen
+ params:
+ contains: "M3A 4 / 13"
+ - id: assert_m3b
+ type: assert.screen
+ params:
+ contains: "M3B 54 / 63"
+ - id: assert_m3c
+ type: assert.screen
+ params:
+ contains: "M3C 104 / 113"
+ - id: assert_free_same
+ type: assert.screen
+ params:
+ contains: "31113"
+ - id: rbm_sample3_copy_same_overlay_probe
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,83,65,77,69,32,79,86,69,82,76,65,89,58,32,90,83,65,65,32,76,79,65,68,83,44,32,90,83,65,66,32,82,69,85,83,69,83,32,82,69,83,73,68,69,78,84,32,73,77,65,71,69,13,80,82,73,78,84,32,34,82,49,34,59,90,67,80,89,82,83,84,40,41,13,65,61,90,83,65,65,40,41,13,66,61,90,83,65,66,40,41,13,80,82,73,78,84,32,34,83,49,34,59,65,59,34,47,34,59,66,13,80,82,73,78,84,32,34,67,49,34,59,90,67,79,80,89,40,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: capture_rbm_sample3_copy_same_overlay
+ type: screen.capture
+ params:
+ label: after_rbm_sample3_copy_same_overlay
+ - id: assert_copy_same_overlay_no_reload
+ type: assert.screen
+ params:
+ contains: "C1 2"
+ - id: assert_state_same_overlay_kept
+ type: assert.screen
+ params:
+ contains: "S1 4 / 6"
+ - id: rbm_sample3_copy_different_overlay_probe
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,73,70,70,69,82,69,78,84,32,79,86,69,82,76,65,89,58,32,90,83,66,65,32,82,69,80,76,65,67,69,83,32,90,83,65,65,32,83,76,79,84,32,73,77,65,71,69,13,80,82,73,78,84,32,34,82,50,34,59,90,67,80,89,82,83,84,40,41,13,65,61,90,83,65,65,40,41,13,66,61,90,83,66,65,40,41,13,67,61,90,83,65,65,40,41,13,80,82,73,78,84,32,34,83,50,34,59,65,59,34,47,34,59,66,59,34,47,34,59,67,13,80,82,73,78,84,32,34,67,50,34,59,90,67,79,80,89,40,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: capture_rbm_sample3_copy_different_overlay
+ type: screen.capture
+ params:
+ label: after_rbm_sample3_copy_different_overlay
+ - id: assert_copy_different_overlay_reload
+ type: assert.screen
+ params:
+ contains: "C2 4"
+ - id: assert_state_different_overlay_reloaded
+ type: assert.screen
+ params:
+ contains: "S2 4 / 6 / 4"
+ - id: rbm_sample3_copy_different_submodule_probe
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,73,70,70,69,82,69,78,84,32,83,85,66,77,79,68,85,76,69,58,32,90,84,65,65,32,82,69,80,76,65,67,69,83,32,90,83,65,65,32,83,76,79,84,32,73,77,65,71,69,13,80,82,73,78,84,32,34,82,51,34,59,90,67,80,89,82,83,84,40,41,13,65,61,90,83,65,65,40,41,13,66,61,90,84,65,65,40,41,13,67,61,90,83,65,65,40,41,13,80,82,73,78,84,32,34,83,51,34,59,65,59,34,47,34,59,66,59,34,47,34,59,67,13,80,82,73,78,84,32,34,67,51,34,59,90,67,79,80,89,40,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: capture_rbm_sample3_copy_different_submodule
+ type: screen.capture
+ params:
+ label: after_rbm_sample3_copy_different_submodule
+ - id: assert_copy_different_submodule_reload
+ type: assert.screen
+ params:
+ contains: "C3 4"
+ - id: assert_state_different_submodule_reloaded
+ type: assert.screen
+ params:
+ contains: "S3 4 / 54 / 4"
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_plugin_command_probe.easyflash.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_plugin_command_probe.easyflash.yaml
new file mode 100644
index 0000000..310b827
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_plugin_command_probe.easyflash.yaml
@@ -0,0 +1,671 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_plugin_command_probe_easyflash
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
+ autostart_enabled: false
+ disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
+ drive8_enabled: true
+ drive8_type: 1541
+ drive9_enabled: false
+ true_drive: true
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: easyflash_wait_launcher
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ pre_delay_s: 4
+ poll_s: 0.5
+ wait_timeout_s: 420
+ capture_label: easyflash_readybasic_launcher
+ - id: easyflash_start_readybasic
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 180
+ capture_label: readybasic_plugin_prompt
+ - id: dump_initial_plugin_state
+ type: dump.memory_ranges
+ params:
+ ranges: &plugin_ranges
+ - { label: entry_1000, start: 0x1000, end: 0x1120 }
+ - { label: resident_1200, start: 0x1200, end: 0x1BFF }
+ - { label: low_overlay_1c00, start: 0x1C00, end: 0x23FF }
+ - { label: shared_frames_2400, start: 0x2400, end: 0x27FF }
+ - { label: hidden_shadow_9a00, start: 0x9A00, end: 0x9FFF }
+ - { label: hidden_visible_a000, start: 0xA000, end: 0xA5FF }
+ - { label: hidden_overlay_a800, start: 0xA800, end: 0xA8FF }
+ - { label: bridge_c000, start: 0xC000, end: 0xC5FF }
+ - { label: reu_alloc_table_c600, start: 0xC600, end: 0xC6FF }
+
+ - id: probe_01_ping
+ type: input.sequence
+ params:
+ keys: [90,69,67,72,79,49,40,80,37,41,13,80,82,73,78,84,32,34,90,69,67,72,79,34,59,80,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: capture_01_ping
+ type: screen.capture
+ params:
+ label: after_zecho1
+ - id: assert_01_ping
+ type: assert.screen
+ params:
+ contains: "ZECHO 1"
+ - id: dump_01_ping
+ type: dump.memory_ranges
+ params:
+ ranges: *plugin_ranges
+
+ - id: probe_02_add16
+ type: input.sequence
+ params:
+ keys: [65,37,61,90,65,68,68,49,54,40,53,44,49,48,41,13,80,82,73,78,84,32,34,65,68,68,34,59,65,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_02_add16
+ type: assert.screen
+ params:
+ contains: "ADD 15"
+
+ - id: probe_02a_if_then_direct
+ type: input.sequence
+ params:
+ keys: [80,37,61,48,13,73,70,32,49,32,84,72,69,78,32,80,37,61,90,65,68,68,49,54,40,48,44,49,41,13,80,82,73,78,84,32,34,73,70,68,73,82,34,59,80,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: capture_02a_if_then_direct
+ type: screen.capture
+ params:
+ label: after_if_then_direct
+ - id: assert_02a_if_then_direct
+ type: assert.screen
+ params:
+ contains: "IFDIR 1"
+
+ - id: probe_03_strup_variable
+ type: input.sequence
+ params:
+ keys: [83,36,61,34,97,98,99,34,13,84,36,61,85,80,80,69,82,40,83,36,41,13,80,82,73,78,84,32,34,83,84,82,34,59,84,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_03_strup_variable
+ type: assert.screen
+ params:
+ contains: "STRABC"
+
+ - id: probe_04_strup_literal
+ type: input.sequence
+ params:
+ keys: [85,36,61,85,80,80,69,82,40,34,100,101,102,34,41,13,80,82,73,78,84,32,34,76,73,84,34,59,85,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_04_strup_literal
+ type: assert.screen
+ params:
+ contains: "LITDEF"
+
+ - id: probe_04a_lower_variable
+ type: input.sequence
+ params:
+ keys: [83,36,61,34,65,66,67,34,13,76,36,61,76,79,87,69,82,40,83,36,41,13,80,82,73,78,84,32,34,76,79,87,65,83,67,34,59,65,83,67,40,76,36,41,59,65,83,67,40,77,73,68,36,40,76,36,44,50,44,49,41,41,59,65,83,67,40,77,73,68,36,40,76,36,44,51,44,49,41,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_04a_lower_variable
+ type: assert.screen
+ params:
+ contains: "LOWASC 97 98 99"
+
+ - id: probe_04b_lower_literal
+ type: input.sequence
+ params:
+ keys: [76,36,61,76,79,87,69,82,40,34,71,72,73,34,41,13,80,82,73,78,84,32,34,76,73,84,76,79,87,65,83,67,34,59,65,83,67,40,76,36,41,59,65,83,67,40,77,73,68,36,40,76,36,44,50,44,49,41,41,59,65,83,67,40,77,73,68,36,40,76,36,44,51,44,49,41,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_04b_lower_literal
+ type: assert.screen
+ params:
+ contains: "LITLOWASC 103 104 105"
+
+ - id: probe_05_hcrc_hidden
+ type: input.sequence
+ params:
+ keys: [72,37,61,90,72,73,68,68,69,78,82,65,77,40,34,65,66,34,41,13,80,82,73,78,84,32,34,90,72,73,68,68,69,78,82,65,77,34,59,72,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_05_hcrc_hidden
+ type: assert.screen
+ params:
+ contains: "ZHIDDENRAM 131"
+ - id: dump_05_hidden_worker
+ type: dump.memory_ranges
+ params:
+ ranges: *plugin_ranges
+
+ - id: probe_06_sumai
+ type: input.sequence
+ params:
+ keys: [68,73,77,32,65,37,40,51,41,13,65,37,40,48,41,61,49,58,65,37,40,49,41,61,50,58,65,37,40,50,41,61,51,13,83,37,61,90,83,85,77,78,85,77,65,82,82,65,89,40,65,37,40,48,41,44,51,41,13,80,82,73,78,84,32,34,83,85,77,34,59,83,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_06_sumai
+ type: assert.screen
+ params:
+ contains: "SUM 6"
+
+ - id: probe_07_rangeai
+ type: input.sequence
+ params:
+ keys: [68,73,77,32,82,37,40,52,41,13,90,82,65,78,71,69,78,85,77,65,82,82,65,89,40,55,44,52,44,82,37,40,48,41,41,13,80,82,73,78,84,32,34,82,65,78,71,69,34,59,82,37,40,48,41,59,82,37,40,51,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_07_rangeai
+ type: assert.screen
+ params:
+ contains: "RANGE 7 10"
+
+ - id: probe_08_bufnew
+ type: input.sequence
+ params:
+ keys: [72,37,61,66,85,70,78,69,87,40,51,48,48,41,13,80,82,73,78,84,32,34,66,85,70,78,69,87,34,59,72,37,59,34,58,69,78,68,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_08_bufnew
+ type: assert.screen
+ params:
+ contains: "BUFNEW 1 :END"
+ - id: dump_08_bufnew
+ type: dump.memory_ranges
+ params:
+ ranges: *plugin_ranges
+
+ - id: probe_09_buffill
+ type: input.sequence
+ params:
+ keys: [66,85,70,70,73,76,76,40,72,37,44,49,55,48,41,13,80,82,73,78,84,32,34,70,73,76,76,32,79,75,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_09_buffill
+ type: assert.screen
+ params:
+ contains: "FILL OK"
+ - id: assert_09_buffill_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: probe_10_buffree
+ type: input.sequence
+ params:
+ keys: [66,85,70,70,82,69,69,40,72,37,41,13,80,82,73,78,84,32,34,70,82,69,69,32,79,75,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_10_buffree
+ type: assert.screen
+ params:
+ contains: "FREE OK"
+ - id: assert_10_buffree_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: probe_10a_scrcap_scrput_slot128
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,83,67,82,77,65,82,75,34,13,83,37,61,83,67,82,67,65,80,40,41,13,80,82,73,78,84,32,34,67,72,65,78,71,69,68,34,13,83,67,82,80,85,84,40,83,37,41,13,80,82,73,78,84,32,34,83,67,82,80,85,84,34,59,83,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_10a_scrcap_restored_text
+ type: assert.screen
+ params:
+ contains: "SCRMARK"
+ - id: assert_10a_scrput_slot128
+ type: assert.screen
+ params:
+ contains: "SCRPUT 1"
+ - id: probe_10b_buffill_rejects_screen_handle
+ type: input.sequence
+ params:
+ keys: [66,85,70,70,73,76,76,40,83,37,44,49,55,48,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_10b_buffill_rejects_screen_handle
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 40"
+ - id: probe_10c_buffree_screen_handle
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,70,82,69,69,40,83,37,41,13,80,82,73,78,84,32,34,83,67,82,70,82,69,69,34,59,83,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_10c_buffree_screen_handle
+ type: assert.screen
+ params:
+ contains: "SCRFREE 1"
+ - id: assert_10c_buffree_screen_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+ - id: probe_10d_scrput_rejects_buffer_handle
+ type: input.sequence
+ params:
+ keys: [66,37,61,66,85,70,78,69,87,40,51,48,48,41,13,83,67,82,80,85,84,40,66,37,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_10d_scrput_rejects_buffer_handle
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 40"
+ - id: probe_10e_free_buffer_after_type_error
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,70,82,69,69,40,66,37,41,13,80,82,73,78,84,32,34,66,85,70,82,69,69,34,59,66,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_10e_free_buffer_after_type_error
+ type: assert.screen
+ params:
+ contains: "BUFREE 1"
+ - id: assert_10e_free_buffer_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: probe_10f_allocate_128_handles
+ type: input.sequence
+ params:
+ keys: [78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,72,37,61,66,85,70,78,69,87,40,49,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,72,77,65,88,34,59,72,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 4.0
+ - id: assert_10f_allocate_128_handles
+ type: assert.screen
+ params:
+ contains: "HMAX 128"
+ - id: assert_10f_allocate_128_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: probe_10g_handle_129_rejected
+ type: input.sequence
+ params:
+ keys: [69,37,61,66,85,70,78,69,87,40,49,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_10g_handle_129_rejected
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 33"
+
+ - id: probe_10h_free_128_handles
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,66,85,70,70,82,69,69,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,72,70,82,69,69,68,34,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 4.0
+ - id: assert_10h_free_128_handles
+ type: assert.screen
+ params:
+ contains: "HFREED"
+ - id: assert_10h_free_128_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: probe_10i_reuse_low_handle
+ type: input.sequence
+ params:
+ keys: [82,37,61,66,85,70,78,69,87,40,49,41,13,80,82,73,78,84,32,34,72,82,69,85,83,69,34,59,82,37,13,66,85,70,70,82,69,69,40,82,37,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_10i_reuse_low_handle
+ type: assert.screen
+ params:
+ contains: "HREUSE 1"
+ - id: assert_10i_reuse_low_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: probe_10j_allocate_48k_heap
+ type: input.sequence
+ params:
+ keys: [77,37,61,66,85,70,78,69,87,40,52,57,49,53,50,41,13,80,82,73,78,84,32,34,72,77,65,88,66,85,70,34,59,77,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_10j_allocate_48k_heap
+ type: assert.screen
+ params:
+ contains: "HMAXBUF 1"
+ - id: assert_10j_allocate_48k_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: probe_10k_heap_full_rejected
+ type: input.sequence
+ params:
+ keys: [69,37,61,66,85,70,78,69,87,40,49,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_10k_heap_full_rejected
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 34"
+
+ - id: probe_10l_free_48k_heap
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,70,82,69,69,40,77,37,41,13,80,82,73,78,84,32,34,72,77,65,88,70,82,69,69,34,59,77,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_10l_free_48k_heap
+ type: assert.screen
+ params:
+ contains: "HMAXFREE 1"
+ - id: assert_10l_free_48k_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: probe_10m_screen_handles_fill_heap
+ type: input.sequence
+ params:
+ keys: [78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,50,52,13,50,48,32,83,37,61,83,67,82,67,65,80,40,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,83,77,65,88,34,59,83,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 4.0
+ - id: assert_10m_screen_handles_fill_heap
+ type: assert.screen
+ params:
+ contains: "SMAX 24"
+ - id: assert_10m_screen_handles_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: probe_10n_screen_heap_full_rejected
+ type: input.sequence
+ params:
+ keys: [83,37,61,83,67,82,67,65,80,40,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_10n_screen_heap_full_rejected
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 34"
+
+ - id: probe_10o_free_screen_handles
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,50,52,13,50,48,32,66,85,70,70,82,69,69,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,83,70,82,69,69,68,34,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 4.0
+ - id: assert_10o_free_screen_handles
+ type: assert.screen
+ params:
+ contains: "SFREED"
+ - id: assert_10o_free_screen_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: probe_11_tempscratch
+ type: input.sequence
+ params:
+ keys: [84,37,61,90,84,69,77,80,83,67,82,65,84,67,72,40,53,49,51,41,13,80,82,73,78,84,32,34,84,69,77,80,34,59,84,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_11_tempscratch
+ type: assert.screen
+ params:
+ contains: "TEMP 3"
+
+ - id: probe_12_fail_clears_output
+ type: input.sequence
+ params:
+ keys: [88,37,61,57,57,13,90,70,65,73,76,40,55,44,88,37,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_12_fail_error
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 7"
+ - id: probe_12_print_cleared_output
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,70,65,73,76,67,76,82,34,59,88,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_12_fail_cleared_output
+ type: assert.screen
+ params:
+ contains: "FAILCLR 0"
+
+ - id: probe_13_unknown_command
+ type: input.sequence
+ params:
+ keys: [78,79,80,69,40,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_13_unknown_command
+ type: assert.screen
+ params:
+ contains: "SYNTAX"
+
+ - id: probe_13_old_ping_rejected
+ type: input.sequence
+ params:
+ keys: [83,67,65,76,65,82,40,80,37,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_13_old_ping_rejected
+ type: assert.screen
+ params:
+ contains: "ERROR"
+
+ - id: probe_13_old_add16_rejected
+ type: input.sequence
+ params:
+ keys: [65,68,68,49,54,40,49,44,50,44,65,37,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_13_old_add16_rejected
+ type: assert.screen
+ params:
+ contains: "ERROR"
+
+ - id: probe_13_old_strup_rejected
+ type: input.sequence
+ params:
+ keys: [83,84,82,85,80,40,34,97,98,99,34,44,84,36,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_13_old_strup_rejected
+ type: assert.screen
+ params:
+ contains: "ERROR"
+
+ - id: probe_13_old_hcrc_rejected
+ type: input.sequence
+ params:
+ keys: [72,67,82,67,40,34,65,66,34,44,72,37,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_13_old_hcrc_rejected
+ type: assert.screen
+ params:
+ contains: "ERROR"
+
+ - id: probe_13_old_sumai_rejected
+ type: input.sequence
+ params:
+ keys: [83,85,77,65,73,40,65,37,40,48,41,44,49,44,83,37,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_13_old_sumai_rejected
+ type: assert.screen
+ params:
+ contains: "ERROR"
+
+ - id: probe_13_old_rangeai_rejected
+ type: input.sequence
+ params:
+ keys: [82,65,78,71,69,65,73,40,49,44,49,44,65,37,40,48,41,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_13_old_rangeai_rejected
+ type: assert.screen
+ params:
+ contains: "ERROR"
+
+ - id: probe_13a_command_name_in_string
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,78,79,80,69,40,41,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_13a_command_name_in_string
+ type: assert.screen
+ params:
+ contains: "NOPE()"
+ - id: assert_13a_no_rb_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: probe_13b_command_name_in_rem
+ type: input.sequence
+ params:
+ keys: [82,69,77,32,78,79,80,69,40,41,13,80,82,73,78,84,32,34,82,69,77,79,75,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_13b_command_name_in_rem
+ type: assert.screen
+ params:
+ contains: "REMOK"
+ - id: assert_13b_no_rb_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: probe_13c_first_comma_rejected
+ type: input.sequence
+ params:
+ keys: [90,65,68,68,49,54,40,44,49,44,50,44,65,37,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_13c_first_comma_rejected
+ type: assert.screen
+ params:
+ contains: "SYNTAX"
+
+ - id: probe_13d_missing_out_marker_rejected
+ type: input.sequence
+ params:
+ keys: [90,65,68,68,49,54,32,49,44,50,44,65,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_13d_missing_out_marker_rejected
+ type: assert.screen
+ params:
+ contains: "SYNTAX"
+
+ - id: probe_14_seed_resume_vars
+ type: input.sequence
+ params:
+ keys: [86,37,61,51,50,49,58,86,83,36,61,34,79,75,34,13,80,82,73,78,84,32,34,83,69,69,68,69,68,34,59,86,37,59,34,58,34,59,86,83,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_14_seed_resume_vars
+ type: assert.screen
+ params:
+ contains: "SEEDED 321 :OK"
+
+ - id: probe_15_exit_to_launcher
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: resume_after_exit
+ type: input.sequence
+ params:
+ keys: [145,17,13]
+ inter_key_delay_s: 0.10
+ post_delay_s: 3.0
+ - id: wait_readybasic_after_resume
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 30
+ capture_label: readybasic_after_plugin_resume
+ - id: probe_16_registry_after_resume
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,83,84,65,84,69,34,59,86,37,59,34,58,34,59,86,83,36,13,80,37,61,90,65,68,68,49,54,40,48,44,49,41,13,80,82,73,78,84,32,34,82,69,83,85,77,69,34,59,80,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: capture_16_registry_after_resume
+ type: screen.capture
+ params:
+ label: after_registry_resume
+ - id: dump_16_vectors_after_resume
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: page3_vectors, start: 0x0304, end: 0x030B }
+ - { label: desc_buf, start: 0xC480, end: 0xC49F }
+ - { label: bridge_tail, start: 0xC1D0, end: 0xC20F }
+ - { label: low_slot_head, start: 0xA800, end: 0xA83F }
+ - id: assert_16_basic_state_after_resume
+ type: assert.screen
+ params:
+ contains: "STATE 321 :OK"
+ - id: assert_16_registry_after_resume
+ type: assert.screen
+ params:
+ contains: "RESUME 1"
+ - id: dump_final_plugin_state
+ type: dump.memory_ranges
+ params:
+ ranges: *plugin_ranges
+ - id: regs_final
+ type: monitor.command
+ params:
+ command: "r"
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_plugin_command_probe.regular.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_plugin_command_probe.regular.yaml
new file mode 100644
index 0000000..cff2ddd
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_plugin_command_probe.regular.yaml
@@ -0,0 +1,656 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_plugin_command_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "readybasic"
+ wait_timeout_s: 180
+ capture_label: readybasic_plugin_prompt
+ - id: dump_initial_plugin_state
+ type: dump.memory_ranges
+ params:
+ ranges: &plugin_ranges
+ - { label: entry_1000, start: 0x1000, end: 0x1120 }
+ - { label: resident_1200, start: 0x1200, end: 0x1BFF }
+ - { label: low_overlay_1c00, start: 0x1C00, end: 0x23FF }
+ - { label: shared_frames_2400, start: 0x2400, end: 0x27FF }
+ - { label: hidden_shadow_9a00, start: 0x9A00, end: 0x9FFF }
+ - { label: hidden_visible_a000, start: 0xA000, end: 0xA5FF }
+ - { label: hidden_overlay_a800, start: 0xA800, end: 0xA8FF }
+ - { label: bridge_c000, start: 0xC000, end: 0xC5FF }
+ - { label: reu_alloc_table_c600, start: 0xC600, end: 0xC6FF }
+
+ - id: probe_01_ping
+ type: input.sequence
+ params:
+ keys: [90,69,67,72,79,49,40,80,37,41,13,80,82,73,78,84,32,34,90,69,67,72,79,34,59,80,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: capture_01_ping
+ type: screen.capture
+ params:
+ label: after_zecho1
+ - id: assert_01_ping
+ type: assert.screen
+ params:
+ contains: "ZECHO 1"
+ - id: dump_01_ping
+ type: dump.memory_ranges
+ params:
+ ranges: *plugin_ranges
+
+ - id: probe_02_add16
+ type: input.sequence
+ params:
+ keys: [65,37,61,90,65,68,68,49,54,40,53,44,49,48,41,13,80,82,73,78,84,32,34,65,68,68,34,59,65,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_02_add16
+ type: assert.screen
+ params:
+ contains: "ADD 15"
+
+ - id: probe_02a_if_then_direct
+ type: input.sequence
+ params:
+ keys: [80,37,61,48,13,73,70,32,49,32,84,72,69,78,32,80,37,61,90,65,68,68,49,54,40,48,44,49,41,13,80,82,73,78,84,32,34,73,70,68,73,82,34,59,80,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: capture_02a_if_then_direct
+ type: screen.capture
+ params:
+ label: after_if_then_direct
+ - id: assert_02a_if_then_direct
+ type: assert.screen
+ params:
+ contains: "IFDIR 1"
+
+ - id: probe_03_strup_variable
+ type: input.sequence
+ params:
+ keys: [83,36,61,34,97,98,99,34,13,84,36,61,85,80,80,69,82,40,83,36,41,13,80,82,73,78,84,32,34,83,84,82,34,59,84,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_03_strup_variable
+ type: assert.screen
+ params:
+ contains: "STRABC"
+
+ - id: probe_04_strup_literal
+ type: input.sequence
+ params:
+ keys: [85,36,61,85,80,80,69,82,40,34,100,101,102,34,41,13,80,82,73,78,84,32,34,76,73,84,34,59,85,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_04_strup_literal
+ type: assert.screen
+ params:
+ contains: "LITDEF"
+
+ - id: probe_04a_lower_variable
+ type: input.sequence
+ params:
+ keys: [83,36,61,34,65,66,67,34,13,76,36,61,76,79,87,69,82,40,83,36,41,13,80,82,73,78,84,32,34,76,79,87,65,83,67,34,59,65,83,67,40,76,36,41,59,65,83,67,40,77,73,68,36,40,76,36,44,50,44,49,41,41,59,65,83,67,40,77,73,68,36,40,76,36,44,51,44,49,41,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_04a_lower_variable
+ type: assert.screen
+ params:
+ contains: "LOWASC 97 98 99"
+
+ - id: probe_04b_lower_literal
+ type: input.sequence
+ params:
+ keys: [76,36,61,76,79,87,69,82,40,34,71,72,73,34,41,13,80,82,73,78,84,32,34,76,73,84,76,79,87,65,83,67,34,59,65,83,67,40,76,36,41,59,65,83,67,40,77,73,68,36,40,76,36,44,50,44,49,41,41,59,65,83,67,40,77,73,68,36,40,76,36,44,51,44,49,41,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_04b_lower_literal
+ type: assert.screen
+ params:
+ contains: "LITLOWASC 103 104 105"
+
+ - id: probe_05_hcrc_hidden
+ type: input.sequence
+ params:
+ keys: [72,37,61,90,72,73,68,68,69,78,82,65,77,40,34,65,66,34,41,13,80,82,73,78,84,32,34,90,72,73,68,68,69,78,82,65,77,34,59,72,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_05_hcrc_hidden
+ type: assert.screen
+ params:
+ contains: "ZHIDDENRAM 131"
+ - id: dump_05_hidden_worker
+ type: dump.memory_ranges
+ params:
+ ranges: *plugin_ranges
+
+ - id: probe_06_sumai
+ type: input.sequence
+ params:
+ keys: [68,73,77,32,65,37,40,51,41,13,65,37,40,48,41,61,49,58,65,37,40,49,41,61,50,58,65,37,40,50,41,61,51,13,83,37,61,90,83,85,77,78,85,77,65,82,82,65,89,40,65,37,40,48,41,44,51,41,13,80,82,73,78,84,32,34,83,85,77,34,59,83,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_06_sumai
+ type: assert.screen
+ params:
+ contains: "SUM 6"
+
+ - id: probe_07_rangeai
+ type: input.sequence
+ params:
+ keys: [68,73,77,32,82,37,40,52,41,13,90,82,65,78,71,69,78,85,77,65,82,82,65,89,40,55,44,52,44,82,37,40,48,41,41,13,80,82,73,78,84,32,34,82,65,78,71,69,34,59,82,37,40,48,41,59,82,37,40,51,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_07_rangeai
+ type: assert.screen
+ params:
+ contains: "RANGE 7 10"
+
+ - id: probe_08_bufnew
+ type: input.sequence
+ params:
+ keys: [72,37,61,66,85,70,78,69,87,40,51,48,48,41,13,80,82,73,78,84,32,34,66,85,70,78,69,87,34,59,72,37,59,34,58,69,78,68,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_08_bufnew
+ type: assert.screen
+ params:
+ contains: "BUFNEW 1 :END"
+ - id: dump_08_bufnew
+ type: dump.memory_ranges
+ params:
+ ranges: *plugin_ranges
+
+ - id: probe_09_buffill
+ type: input.sequence
+ params:
+ keys: [66,85,70,70,73,76,76,40,72,37,44,49,55,48,41,13,80,82,73,78,84,32,34,70,73,76,76,32,79,75,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_09_buffill
+ type: assert.screen
+ params:
+ contains: "FILL OK"
+ - id: assert_09_buffill_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: probe_10_buffree
+ type: input.sequence
+ params:
+ keys: [66,85,70,70,82,69,69,40,72,37,41,13,80,82,73,78,84,32,34,70,82,69,69,32,79,75,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_10_buffree
+ type: assert.screen
+ params:
+ contains: "FREE OK"
+ - id: assert_10_buffree_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: probe_10a_scrcap_scrput_slot128
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,83,67,82,77,65,82,75,34,13,83,37,61,83,67,82,67,65,80,40,41,13,80,82,73,78,84,32,34,67,72,65,78,71,69,68,34,13,83,67,82,80,85,84,40,83,37,41,13,80,82,73,78,84,32,34,83,67,82,80,85,84,34,59,83,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_10a_scrcap_restored_text
+ type: assert.screen
+ params:
+ contains: "SCRMARK"
+ - id: assert_10a_scrput_slot128
+ type: assert.screen
+ params:
+ contains: "SCRPUT 1"
+ - id: probe_10b_buffill_rejects_screen_handle
+ type: input.sequence
+ params:
+ keys: [66,85,70,70,73,76,76,40,83,37,44,49,55,48,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_10b_buffill_rejects_screen_handle
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 40"
+ - id: probe_10c_buffree_screen_handle
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,70,82,69,69,40,83,37,41,13,80,82,73,78,84,32,34,83,67,82,70,82,69,69,34,59,83,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_10c_buffree_screen_handle
+ type: assert.screen
+ params:
+ contains: "SCRFREE 1"
+ - id: assert_10c_buffree_screen_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+ - id: probe_10d_scrput_rejects_buffer_handle
+ type: input.sequence
+ params:
+ keys: [66,37,61,66,85,70,78,69,87,40,51,48,48,41,13,83,67,82,80,85,84,40,66,37,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_10d_scrput_rejects_buffer_handle
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 40"
+ - id: probe_10e_free_buffer_after_type_error
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,70,82,69,69,40,66,37,41,13,80,82,73,78,84,32,34,66,85,70,82,69,69,34,59,66,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_10e_free_buffer_after_type_error
+ type: assert.screen
+ params:
+ contains: "BUFREE 1"
+ - id: assert_10e_free_buffer_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: probe_10f_allocate_128_handles
+ type: input.sequence
+ params:
+ keys: [78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,72,37,61,66,85,70,78,69,87,40,49,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,72,77,65,88,34,59,72,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 4.0
+ - id: assert_10f_allocate_128_handles
+ type: assert.screen
+ params:
+ contains: "HMAX 128"
+ - id: assert_10f_allocate_128_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: probe_10g_handle_129_rejected
+ type: input.sequence
+ params:
+ keys: [69,37,61,66,85,70,78,69,87,40,49,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_10g_handle_129_rejected
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 33"
+
+ - id: probe_10h_free_128_handles
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,66,85,70,70,82,69,69,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,72,70,82,69,69,68,34,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 4.0
+ - id: assert_10h_free_128_handles
+ type: assert.screen
+ params:
+ contains: "HFREED"
+ - id: assert_10h_free_128_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: probe_10i_reuse_low_handle
+ type: input.sequence
+ params:
+ keys: [82,37,61,66,85,70,78,69,87,40,49,41,13,80,82,73,78,84,32,34,72,82,69,85,83,69,34,59,82,37,13,66,85,70,70,82,69,69,40,82,37,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_10i_reuse_low_handle
+ type: assert.screen
+ params:
+ contains: "HREUSE 1"
+ - id: assert_10i_reuse_low_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: probe_10j_allocate_48k_heap
+ type: input.sequence
+ params:
+ keys: [77,37,61,66,85,70,78,69,87,40,52,57,49,53,50,41,13,80,82,73,78,84,32,34,72,77,65,88,66,85,70,34,59,77,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_10j_allocate_48k_heap
+ type: assert.screen
+ params:
+ contains: "HMAXBUF 1"
+ - id: assert_10j_allocate_48k_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: probe_10k_heap_full_rejected
+ type: input.sequence
+ params:
+ keys: [69,37,61,66,85,70,78,69,87,40,49,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_10k_heap_full_rejected
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 34"
+
+ - id: probe_10l_free_48k_heap
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,70,82,69,69,40,77,37,41,13,80,82,73,78,84,32,34,72,77,65,88,70,82,69,69,34,59,77,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_10l_free_48k_heap
+ type: assert.screen
+ params:
+ contains: "HMAXFREE 1"
+ - id: assert_10l_free_48k_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: probe_10m_screen_handles_fill_heap
+ type: input.sequence
+ params:
+ keys: [78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,50,52,13,50,48,32,83,37,61,83,67,82,67,65,80,40,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,83,77,65,88,34,59,83,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 4.0
+ - id: assert_10m_screen_handles_fill_heap
+ type: assert.screen
+ params:
+ contains: "SMAX 24"
+ - id: assert_10m_screen_handles_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: probe_10n_screen_heap_full_rejected
+ type: input.sequence
+ params:
+ keys: [83,37,61,83,67,82,67,65,80,40,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_10n_screen_heap_full_rejected
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 34"
+
+ - id: probe_10o_free_screen_handles
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,50,52,13,50,48,32,66,85,70,70,82,69,69,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,83,70,82,69,69,68,34,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 4.0
+ - id: assert_10o_free_screen_handles
+ type: assert.screen
+ params:
+ contains: "SFREED"
+ - id: assert_10o_free_screen_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: probe_11_tempscratch
+ type: input.sequence
+ params:
+ keys: [84,37,61,90,84,69,77,80,83,67,82,65,84,67,72,40,53,49,51,41,13,80,82,73,78,84,32,34,84,69,77,80,34,59,84,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_11_tempscratch
+ type: assert.screen
+ params:
+ contains: "TEMP 3"
+
+ - id: probe_12_fail_clears_output
+ type: input.sequence
+ params:
+ keys: [88,37,61,57,57,13,90,70,65,73,76,40,55,44,88,37,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_12_fail_error
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 7"
+ - id: probe_12_print_cleared_output
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,70,65,73,76,67,76,82,34,59,88,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_12_fail_cleared_output
+ type: assert.screen
+ params:
+ contains: "FAILCLR 0"
+
+ - id: probe_13_unknown_command
+ type: input.sequence
+ params:
+ keys: [78,79,80,69,40,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_13_unknown_command
+ type: assert.screen
+ params:
+ contains: "SYNTAX"
+
+ - id: probe_13_old_ping_rejected
+ type: input.sequence
+ params:
+ keys: [83,67,65,76,65,82,40,80,37,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_13_old_ping_rejected
+ type: assert.screen
+ params:
+ contains: "ERROR"
+
+ - id: probe_13_old_add16_rejected
+ type: input.sequence
+ params:
+ keys: [65,68,68,49,54,40,49,44,50,44,65,37,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_13_old_add16_rejected
+ type: assert.screen
+ params:
+ contains: "ERROR"
+
+ - id: probe_13_old_strup_rejected
+ type: input.sequence
+ params:
+ keys: [83,84,82,85,80,40,34,97,98,99,34,44,84,36,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_13_old_strup_rejected
+ type: assert.screen
+ params:
+ contains: "ERROR"
+
+ - id: probe_13_old_hcrc_rejected
+ type: input.sequence
+ params:
+ keys: [72,67,82,67,40,34,65,66,34,44,72,37,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_13_old_hcrc_rejected
+ type: assert.screen
+ params:
+ contains: "ERROR"
+
+ - id: probe_13_old_sumai_rejected
+ type: input.sequence
+ params:
+ keys: [83,85,77,65,73,40,65,37,40,48,41,44,49,44,83,37,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_13_old_sumai_rejected
+ type: assert.screen
+ params:
+ contains: "ERROR"
+
+ - id: probe_13_old_rangeai_rejected
+ type: input.sequence
+ params:
+ keys: [82,65,78,71,69,65,73,40,49,44,49,44,65,37,40,48,41,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_13_old_rangeai_rejected
+ type: assert.screen
+ params:
+ contains: "ERROR"
+
+ - id: probe_13a_command_name_in_string
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,78,79,80,69,40,41,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_13a_command_name_in_string
+ type: assert.screen
+ params:
+ contains: "NOPE()"
+ - id: assert_13a_no_rb_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: probe_13b_command_name_in_rem
+ type: input.sequence
+ params:
+ keys: [82,69,77,32,78,79,80,69,40,41,13,80,82,73,78,84,32,34,82,69,77,79,75,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_13b_command_name_in_rem
+ type: assert.screen
+ params:
+ contains: "REMOK"
+ - id: assert_13b_no_rb_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: probe_13c_first_comma_rejected
+ type: input.sequence
+ params:
+ keys: [90,65,68,68,49,54,40,44,49,44,50,44,65,37,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_13c_first_comma_rejected
+ type: assert.screen
+ params:
+ contains: "SYNTAX"
+
+ - id: probe_13d_missing_out_marker_rejected
+ type: input.sequence
+ params:
+ keys: [90,65,68,68,49,54,32,49,44,50,44,65,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_13d_missing_out_marker_rejected
+ type: assert.screen
+ params:
+ contains: "SYNTAX"
+
+ - id: probe_14_seed_resume_vars
+ type: input.sequence
+ params:
+ keys: [86,37,61,51,50,49,58,86,83,36,61,34,79,75,34,13,80,82,73,78,84,32,34,83,69,69,68,69,68,34,59,86,37,59,34,58,34,59,86,83,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_14_seed_resume_vars
+ type: assert.screen
+ params:
+ contains: "SEEDED 321 :OK"
+
+ - id: probe_15_exit_to_launcher
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: resume_after_exit
+ type: input.sequence
+ params:
+ keys: [145,17,13]
+ inter_key_delay_s: 0.10
+ post_delay_s: 3.0
+ - id: wait_readybasic_after_resume
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 30
+ capture_label: readybasic_after_plugin_resume
+ - id: probe_16_registry_after_resume
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,83,84,65,84,69,34,59,86,37,59,34,58,34,59,86,83,36,13,80,37,61,90,65,68,68,49,54,40,48,44,49,41,13,80,82,73,78,84,32,34,82,69,83,85,77,69,34,59,80,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: capture_16_registry_after_resume
+ type: screen.capture
+ params:
+ label: after_registry_resume
+ - id: dump_16_vectors_after_resume
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: page3_vectors, start: 0x0304, end: 0x030B }
+ - { label: desc_buf, start: 0xC480, end: 0xC49F }
+ - { label: bridge_tail, start: 0xC1D0, end: 0xC20F }
+ - { label: low_slot_head, start: 0xA800, end: 0xA83F }
+ - id: assert_16_basic_state_after_resume
+ type: assert.screen
+ params:
+ contains: "STATE 321 :OK"
+ - id: assert_16_registry_after_resume
+ type: assert.screen
+ params:
+ contains: "RESUME 1"
+ - id: dump_final_plugin_state
+ type: dump.memory_ranges
+ params:
+ ranges: *plugin_ranges
+ - id: regs_final
+ type: monitor.command
+ params:
+ command: "r"
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_program_probe.easyflash.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_program_probe.easyflash.yaml
new file mode 100644
index 0000000..5d7e6d0
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_program_probe.easyflash.yaml
@@ -0,0 +1,236 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_program_probe_easyflash
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 1
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 45
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
+ autostart_enabled: false
+ disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
+ drive8_enabled: true
+ drive8_type: 1541
+ drive9_enabled: false
+ true_drive: true
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: easyflash_wait_launcher
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ pre_delay_s: 4
+ poll_s: 0.5
+ wait_timeout_s: 420
+ capture_label: easyflash_readybasic_launcher
+ - id: easyflash_start_readybasic
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 180
+ capture_label: readybasic_program_prompt
+
+ - id: program_ping_enter_and_list
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,90,69,67,72,79,49,40,80,37,41,13,50,48,32,80,82,73,78,84,32,34,80,82,83,67,65,76,65,82,34,59,80,37,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_ping_lists
+ type: assert.screen
+ params:
+ contains: "10 ZECHO1"
+ - id: program_ping_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_ping_run
+ type: assert.screen
+ params:
+ contains: "PRSCALAR 1"
+
+ - id: program_chain_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,65,37,61,90,65,68,68,49,54,40,49,44,50,41,58,80,82,73,78,84,32,34,80,82,67,72,65,73,78,34,59,65,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_chain_run
+ type: assert.screen
+ params:
+ contains: "PRCHAIN 3"
+
+ - id: program_if_true_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,80,37,61,48,13,50,48,32,73,70,32,49,32,84,72,69,78,32,80,37,61,90,65,68,68,49,54,40,48,44,49,41,13,51,48,32,80,82,73,78,84,32,34,80,82,73,70,84,82,85,69,34,59,80,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_if_true_run
+ type: assert.screen
+ params:
+ contains: "PRIFTRUE 1"
+
+ - id: program_if_false_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,80,37,61,48,13,50,48,32,73,70,32,48,32,84,72,69,78,32,80,37,61,90,65,68,68,49,54,40,48,44,49,41,13,51,48,32,80,82,73,78,84,32,34,80,82,73,70,70,65,76,83,69,34,59,80,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_if_false_run
+ type: assert.screen
+ params:
+ contains: "PRIFFALSE 0"
+
+ - id: program_text_then_command_name_safe
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,80,82,73,78,84,32,34,84,72,69,78,32,78,79,80,69,40,41,34,13,50,48,32,82,69,77,32,84,72,69,78,32,78,79,80,69,40,41,13,51,48,32,68,65,84,65,32,84,72,69,78,32,78,79,80,69,40,41,13,52,48,32,82,69,65,68,32,65,36,13,53,48,32,80,82,73,78,84,32,34,80,82,83,65,70,69,34,59,65,36,13,80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.2
+ - id: assert_program_text_then_command_name_safe
+ type: assert.screen
+ params:
+ contains: "PRSAFETHEN NOPE()"
+ - id: assert_program_text_then_command_name_no_colon
+ type: assert.screen_not_contains
+ params:
+ not_contains: "PRSAFETHEN :NOPE()"
+ - id: assert_program_text_then_command_name_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: program_for_next_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,51,13,50,48,32,65,37,61,90,65,68,68,49,54,40,73,44,49,48,41,13,51,48,32,78,69,88,84,13,52,48,32,80,82,73,78,84,32,34,80,82,70,79,82,34,59,65,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.2
+ - id: assert_program_for_next_run
+ type: assert.screen
+ params:
+ contains: "PRFOR 13"
+
+ - id: program_strup_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,83,36,61,34,97,98,99,34,13,50,48,32,84,36,61,85,80,80,69,82,40,83,36,41,13,51,48,32,80,82,73,78,84,32,34,80,82,83,84,82,34,59,84,36,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.2
+ - id: assert_program_strup_run
+ type: assert.screen
+ params:
+ contains: "PRSTRABC"
+
+ - id: program_lower_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,83,36,61,34,65,66,67,34,13,50,48,32,84,36,61,76,79,87,69,82,40,83,36,41,13,51,48,32,80,82,73,78,84,32,34,80,82,76,79,87,65,83,67,34,59,65,83,67,40,84,36,41,59,65,83,67,40,77,73,68,36,40,84,36,44,50,44,49,41,41,59,65,83,67,40,77,73,68,36,40,84,36,44,51,44,49,41,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.2
+ - id: assert_program_lower_run
+ type: assert.screen
+ params:
+ contains: "PRLOWASC 97 98 99"
+
+ - id: program_hidden_hcrc_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,72,37,61,90,72,73,68,68,69,78,82,65,77,40,34,65,66,34,41,13,50,48,32,80,82,73,78,84,32,34,80,82,72,67,82,67,34,59,72,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_hidden_hcrc_run
+ type: assert.screen
+ params:
+ contains: "PRHCRC 131"
+
+ - id: program_array_sum_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,68,73,77,32,65,37,40,51,41,13,50,48,32,65,37,40,48,41,61,49,58,65,37,40,49,41,61,50,58,65,37,40,50,41,61,51,13,51,48,32,83,37,61,90,83,85,77,78,85,77,65,82,82,65,89,40,65,37,40,48,41,44,51,41,13,52,48,32,80,82,73,78,84,32,34,80,82,83,85,77,34,59,83,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.3
+ - id: assert_program_array_sum_run
+ type: assert.screen
+ params:
+ contains: "PRSUM 6"
+
+ - id: program_array_range_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,68,73,77,32,82,37,40,52,41,13,50,48,32,90,82,65,78,71,69,78,85,77,65,82,82,65,89,40,55,44,52,44,82,37,40,48,41,41,13,51,48,32,80,82,73,78,84,32,34,80,82,82,65,78,71,69,34,59,82,37,40,48,41,59,82,37,40,51,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.3
+ - id: assert_program_array_range_run
+ type: assert.screen
+ params:
+ contains: "PRRANGE 7 10"
+
+ - id: program_handle_lifecycle_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,72,37,61,66,85,70,78,69,87,40,51,48,48,41,13,50,48,32,80,82,73,78,84,32,34,80,82,66,85,70,34,59,72,37,13,51,48,32,66,85,70,70,73,76,76,40,72,37,44,49,55,48,41,13,52,48,32,66,85,70,70,82,69,69,40,72,37,41,13,53,48,32,80,82,73,78,84,32,34,80,82,70,82,69,69,34,59,72,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: assert_program_handle_new
+ type: assert.screen
+ params:
+ contains: "PRBUF 1"
+ - id: assert_program_handle_free
+ type: assert.screen
+ params:
+ contains: "PRFREE 1"
+
+ - id: program_fail_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,88,37,61,57,57,13,50,48,32,90,70,65,73,76,40,55,44,88,37,41,13,51,48,32,80,82,73,78,84,32,34,80,82,65,70,84,69,82,34,59,88,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_fail_error
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 7"
+ - id: program_fail_cleared_check
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,80,82,70,65,73,76,67,76,82,34,59,88,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_program_fail_cleared
+ type: assert.screen
+ params:
+ contains: "PRFAILCLR 0"
+
+ - id: regs_final
+ type: monitor.command
+ params:
+ command: "r"
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_program_probe.regular.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_program_probe.regular.yaml
new file mode 100644
index 0000000..dae6807
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_program_probe.regular.yaml
@@ -0,0 +1,221 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_program_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 1
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 45
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "readybasic"
+ wait_timeout_s: 180
+ capture_label: readybasic_program_prompt
+
+ - id: program_ping_enter_and_list
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,90,69,67,72,79,49,40,80,37,41,13,50,48,32,80,82,73,78,84,32,34,80,82,83,67,65,76,65,82,34,59,80,37,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_ping_lists
+ type: assert.screen
+ params:
+ contains: "10 ZECHO1"
+ - id: program_ping_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_ping_run
+ type: assert.screen
+ params:
+ contains: "PRSCALAR 1"
+
+ - id: program_chain_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,65,37,61,90,65,68,68,49,54,40,49,44,50,41,58,80,82,73,78,84,32,34,80,82,67,72,65,73,78,34,59,65,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_chain_run
+ type: assert.screen
+ params:
+ contains: "PRCHAIN 3"
+
+ - id: program_if_true_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,80,37,61,48,13,50,48,32,73,70,32,49,32,84,72,69,78,32,80,37,61,90,65,68,68,49,54,40,48,44,49,41,13,51,48,32,80,82,73,78,84,32,34,80,82,73,70,84,82,85,69,34,59,80,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_if_true_run
+ type: assert.screen
+ params:
+ contains: "PRIFTRUE 1"
+
+ - id: program_if_false_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,80,37,61,48,13,50,48,32,73,70,32,48,32,84,72,69,78,32,80,37,61,90,65,68,68,49,54,40,48,44,49,41,13,51,48,32,80,82,73,78,84,32,34,80,82,73,70,70,65,76,83,69,34,59,80,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_if_false_run
+ type: assert.screen
+ params:
+ contains: "PRIFFALSE 0"
+
+ - id: program_text_then_command_name_safe
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,80,82,73,78,84,32,34,84,72,69,78,32,78,79,80,69,40,41,34,13,50,48,32,82,69,77,32,84,72,69,78,32,78,79,80,69,40,41,13,51,48,32,68,65,84,65,32,84,72,69,78,32,78,79,80,69,40,41,13,52,48,32,82,69,65,68,32,65,36,13,53,48,32,80,82,73,78,84,32,34,80,82,83,65,70,69,34,59,65,36,13,80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.2
+ - id: assert_program_text_then_command_name_safe
+ type: assert.screen
+ params:
+ contains: "PRSAFETHEN NOPE()"
+ - id: assert_program_text_then_command_name_no_colon
+ type: assert.screen_not_contains
+ params:
+ not_contains: "PRSAFETHEN :NOPE()"
+ - id: assert_program_text_then_command_name_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?RB ERROR"
+
+ - id: program_for_next_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,51,13,50,48,32,65,37,61,90,65,68,68,49,54,40,73,44,49,48,41,13,51,48,32,78,69,88,84,13,52,48,32,80,82,73,78,84,32,34,80,82,70,79,82,34,59,65,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.2
+ - id: assert_program_for_next_run
+ type: assert.screen
+ params:
+ contains: "PRFOR 13"
+
+ - id: program_strup_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,83,36,61,34,97,98,99,34,13,50,48,32,84,36,61,85,80,80,69,82,40,83,36,41,13,51,48,32,80,82,73,78,84,32,34,80,82,83,84,82,34,59,84,36,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.2
+ - id: assert_program_strup_run
+ type: assert.screen
+ params:
+ contains: "PRSTRABC"
+
+ - id: program_lower_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,83,36,61,34,65,66,67,34,13,50,48,32,84,36,61,76,79,87,69,82,40,83,36,41,13,51,48,32,80,82,73,78,84,32,34,80,82,76,79,87,65,83,67,34,59,65,83,67,40,84,36,41,59,65,83,67,40,77,73,68,36,40,84,36,44,50,44,49,41,41,59,65,83,67,40,77,73,68,36,40,84,36,44,51,44,49,41,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.2
+ - id: assert_program_lower_run
+ type: assert.screen
+ params:
+ contains: "PRLOWASC 97 98 99"
+
+ - id: program_hidden_hcrc_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,72,37,61,90,72,73,68,68,69,78,82,65,77,40,34,65,66,34,41,13,50,48,32,80,82,73,78,84,32,34,80,82,72,67,82,67,34,59,72,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_hidden_hcrc_run
+ type: assert.screen
+ params:
+ contains: "PRHCRC 131"
+
+ - id: program_array_sum_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,68,73,77,32,65,37,40,51,41,13,50,48,32,65,37,40,48,41,61,49,58,65,37,40,49,41,61,50,58,65,37,40,50,41,61,51,13,51,48,32,83,37,61,90,83,85,77,78,85,77,65,82,82,65,89,40,65,37,40,48,41,44,51,41,13,52,48,32,80,82,73,78,84,32,34,80,82,83,85,77,34,59,83,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.3
+ - id: assert_program_array_sum_run
+ type: assert.screen
+ params:
+ contains: "PRSUM 6"
+
+ - id: program_array_range_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,68,73,77,32,82,37,40,52,41,13,50,48,32,90,82,65,78,71,69,78,85,77,65,82,82,65,89,40,55,44,52,44,82,37,40,48,41,41,13,51,48,32,80,82,73,78,84,32,34,80,82,82,65,78,71,69,34,59,82,37,40,48,41,59,82,37,40,51,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.3
+ - id: assert_program_array_range_run
+ type: assert.screen
+ params:
+ contains: "PRRANGE 7 10"
+
+ - id: program_handle_lifecycle_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,72,37,61,66,85,70,78,69,87,40,51,48,48,41,13,50,48,32,80,82,73,78,84,32,34,80,82,66,85,70,34,59,72,37,13,51,48,32,66,85,70,70,73,76,76,40,72,37,44,49,55,48,41,13,52,48,32,66,85,70,70,82,69,69,40,72,37,41,13,53,48,32,80,82,73,78,84,32,34,80,82,70,82,69,69,34,59,72,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: assert_program_handle_new
+ type: assert.screen
+ params:
+ contains: "PRBUF 1"
+ - id: assert_program_handle_free
+ type: assert.screen
+ params:
+ contains: "PRFREE 1"
+
+ - id: program_fail_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,88,37,61,57,57,13,50,48,32,90,70,65,73,76,40,55,44,88,37,41,13,51,48,32,80,82,73,78,84,32,34,80,82,65,70,84,69,82,34,59,88,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_program_fail_error
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 7"
+ - id: program_fail_cleared_check
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,80,82,70,65,73,76,67,76,82,34,59,88,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_program_fail_cleared
+ type: assert.screen
+ params:
+ contains: "PRFAILCLR 0"
+
+ - id: regs_final
+ type: monitor.command
+ params:
+ command: "r"
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_rbtest1_probe.easyflash.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_rbtest1_probe.easyflash.yaml
new file mode 100644
index 0000000..a1be66e
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_rbtest1_probe.easyflash.yaml
@@ -0,0 +1,102 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_rbtest1_probe_easyflash
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
+ autostart_enabled: false
+ disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
+ drive8_enabled: true
+ drive8_type: 1541
+ drive9_enabled: false
+ true_drive: true
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: easyflash_wait_launcher
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ pre_delay_s: 4
+ poll_s: 0.5
+ wait_timeout_s: 420
+ capture_label: easyflash_readybasic_launcher
+ - id: easyflash_start_readybasic
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 180
+ capture_label: readybasic_prompt
+ - id: load_rbtest1
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,84,69,83,84,49,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: capture_after_load
+ type: screen.capture
+ params:
+ label: after_rbtest1_load
+ - id: assert_load_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
+ - id: list_rbtest1
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: capture_after_list
+ type: screen.capture
+ params:
+ label: after_rbtest1_list
+ - id: assert_list_line_10
+ type: assert.screen
+ params:
+ contains: "10 ZECHO1"
+ - id: assert_list_line_30
+ type: assert.screen
+ params:
+ contains: "40 ZADD16"
+ - id: run_rbtest1
+ type: input.sequence
+ params:
+ keys: [82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: capture_after_run
+ type: screen.capture
+ params:
+ label: after_rbtest1_run
+ - id: assert_run_output
+ type: assert.screen
+ params:
+ contains: "LOOP 13"
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_rbtest1_probe.regular.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_rbtest1_probe.regular.yaml
new file mode 100644
index 0000000..8ba525a
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_rbtest1_probe.regular.yaml
@@ -0,0 +1,87 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_rbtest1_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "readybasic"
+ wait_timeout_s: 180
+ capture_label: readybasic_prompt
+ - id: load_rbtest1
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,84,69,83,84,49,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: capture_after_load
+ type: screen.capture
+ params:
+ label: after_rbtest1_load
+ - id: assert_load_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
+ - id: list_rbtest1
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: capture_after_list
+ type: screen.capture
+ params:
+ label: after_rbtest1_list
+ - id: assert_list_line_10
+ type: assert.screen
+ params:
+ contains: "10 ZECHO1"
+ - id: assert_list_line_30
+ type: assert.screen
+ params:
+ contains: "40 ZADD16"
+ - id: run_rbtest1
+ type: input.sequence
+ params:
+ keys: [82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: capture_after_run
+ type: screen.capture
+ params:
+ label: after_rbtest1_run
+ - id: assert_run_output
+ type: assert.screen
+ params:
+ contains: "LOOP 13"
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_repeat_label_probe.easyflash.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_repeat_label_probe.easyflash.yaml
new file mode 100644
index 0000000..3ba7098
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_repeat_label_probe.easyflash.yaml
@@ -0,0 +1,198 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_repeat_label_probe_easyflash
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 1
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 60
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
+ autostart_enabled: false
+ disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
+ drive8_enabled: true
+ drive8_type: 1541
+ drive9_enabled: false
+ true_drive: true
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: easyflash_wait_launcher
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ pre_delay_s: 4
+ poll_s: 0.5
+ wait_timeout_s: 420
+ capture_label: easyflash_readybasic_launcher
+ - id: easyflash_start_readybasic
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "FREE:"
+ wait_timeout_s: 180
+ capture_label: readybasic_repeat_label_prompt
+
+ - id: repeat_multiline
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,73,37,61,48,13,50,48,32,82,69,80,69,65,84,13,51,48,32,73,37,61,73,37,43,49,13,52,48,32,85,78,84,73,76,32,73,37,61,51,13,53,48,32,80,82,73,78,84,32,34,82,80,84,65,34,59,73,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.2
+ - id: assert_repeat_multiline
+ type: assert.screen
+ params:
+ contains: "RPTA 3"
+
+ - id: repeat_colon
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,73,37,61,51,13,50,48,32,82,69,80,69,65,84,58,73,37,61,73,37,45,49,58,85,78,84,73,76,32,73,37,61,48,13,51,48,32,80,82,73,78,84,32,34,82,80,84,66,34,59,73,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.2
+ - id: assert_repeat_colon
+ type: assert.screen
+ params:
+ contains: "RPTB 0"
+
+ - id: repeat_nested
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,65,37,61,48,58,66,37,61,48,13,50,48,32,82,69,80,69,65,84,13,51,48,32,65,37,61,65,37,43,49,58,66,37,61,48,13,52,48,32,82,69,80,69,65,84,58,66,37,61,66,37,43,49,58,85,78,84,73,76,32,66,37,61,50,13,53,48,32,85,78,84,73,76,32,65,37,61,51,13,54,48,32,80,82,73,78,84,32,34,82,80,84,78,34,59,65,37,59,66,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.4
+ - id: assert_repeat_nested
+ type: assert.screen
+ params:
+ contains: "RPTN 3 2"
+
+ - id: until_without_repeat
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,85,78,84,73,76,32,49,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_until_without_repeat
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 36"
+
+ - id: repeat_overflow
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,80,69,65,84,58,82,69,80,69,65,84,58,82,69,80,69,65,84,58,82,69,80,69,65,84,58,82,69,80,69,65,84,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_repeat_overflow
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 35"
+
+ - id: label_backward_if_then
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,76,65,66,69,76,32,76,80,13,50,48,32,73,37,61,73,37,43,49,13,51,48,32,73,70,32,73,37,60,51,32,84,72,69,78,32,74,85,77,80,32,76,80,13,52,48,32,80,82,73,78,84,32,34,76,66,76,66,34,59,73,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.4
+ - id: assert_label_backward_if_then
+ type: assert.screen
+ params:
+ contains: "LBLB 3"
+
+ - id: label_forward
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,80,82,73,78,84,32,34,65,34,13,50,48,32,74,85,77,80,32,83,75,73,80,13,51,48,32,80,82,73,78,84,32,34,66,65,68,34,13,52,48,32,76,65,66,69,76,32,83,75,73,80,58,80,82,73,78,84,32,34,76,66,76,70,34,13,80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.2
+ - id: assert_label_forward
+ type: assert.screen
+ params:
+ contains: "LBLF"
+ - id: assert_label_forward_no_bad
+ type: assert.screen_not_contains
+ params:
+ not_contains: "BAD"
+
+ - id: label_noop
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,76,65,66,69,76,32,72,69,82,69,58,80,82,73,78,84,32,34,76,66,76,78,34,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_label_noop
+ type: assert.screen
+ params:
+ contains: "LBLN"
+
+ - id: missing_label
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,74,85,77,80,32,77,73,83,83,73,78,71,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_missing_label
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 39"
+
+ - id: numeric_goto_still_rom
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,71,79,84,79,32,51,48,13,50,48,32,80,82,73,78,84,32,34,66,65,68,34,13,51,48,32,80,82,73,78,84,32,34,71,84,79,78,34,13,80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_numeric_goto
+ type: assert.screen
+ params:
+ contains: "GTON"
+ - id: assert_numeric_goto_no_bad
+ type: assert.screen_not_contains
+ params:
+ not_contains: "BAD"
+
+ - id: err_status_after_error
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,90,70,65,73,76,40,54,44,88,37,41,13,82,85,78,13,80,82,73,78,84,32,34,69,82,88,34,59,69,82,82,67,79,68,69,40,41,59,69,82,82,76,73,78,69,40,41,13,69,82,82,67,79,68,69,40,69,37,41,58,69,82,82,76,73,78,69,40,76,37,41,58,80,82,73,78,84,32,34,69,82,83,34,59,69,37,59,76,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.4
+ - id: assert_err_error
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 6"
+ - id: assert_err_expr
+ type: assert.screen
+ params:
+ contains: "ERX 6 10"
+ - id: assert_err_stmt
+ type: assert.screen
+ params:
+ contains: "ERS 6 10"
+
+ - id: regs_final
+ type: monitor.command
+ params:
+ command: "r"
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_repeat_label_probe.regular.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_repeat_label_probe.regular.yaml
new file mode 100644
index 0000000..3e0c215
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_repeat_label_probe.regular.yaml
@@ -0,0 +1,183 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_repeat_label_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 1
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 60
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "FREE:"
+ wait_timeout_s: 180
+ capture_label: readybasic_repeat_label_prompt
+
+ - id: repeat_multiline
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,73,37,61,48,13,50,48,32,82,69,80,69,65,84,13,51,48,32,73,37,61,73,37,43,49,13,52,48,32,85,78,84,73,76,32,73,37,61,51,13,53,48,32,80,82,73,78,84,32,34,82,80,84,65,34,59,73,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.2
+ - id: assert_repeat_multiline
+ type: assert.screen
+ params:
+ contains: "RPTA 3"
+
+ - id: repeat_colon
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,73,37,61,51,13,50,48,32,82,69,80,69,65,84,58,73,37,61,73,37,45,49,58,85,78,84,73,76,32,73,37,61,48,13,51,48,32,80,82,73,78,84,32,34,82,80,84,66,34,59,73,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.2
+ - id: assert_repeat_colon
+ type: assert.screen
+ params:
+ contains: "RPTB 0"
+
+ - id: repeat_nested
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,65,37,61,48,58,66,37,61,48,13,50,48,32,82,69,80,69,65,84,13,51,48,32,65,37,61,65,37,43,49,58,66,37,61,48,13,52,48,32,82,69,80,69,65,84,58,66,37,61,66,37,43,49,58,85,78,84,73,76,32,66,37,61,50,13,53,48,32,85,78,84,73,76,32,65,37,61,51,13,54,48,32,80,82,73,78,84,32,34,82,80,84,78,34,59,65,37,59,66,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.4
+ - id: assert_repeat_nested
+ type: assert.screen
+ params:
+ contains: "RPTN 3 2"
+
+ - id: until_without_repeat
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,85,78,84,73,76,32,49,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_until_without_repeat
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 36"
+
+ - id: repeat_overflow
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,80,69,65,84,58,82,69,80,69,65,84,58,82,69,80,69,65,84,58,82,69,80,69,65,84,58,82,69,80,69,65,84,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_repeat_overflow
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 35"
+
+ - id: label_backward_if_then
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,76,65,66,69,76,32,76,80,13,50,48,32,73,37,61,73,37,43,49,13,51,48,32,73,70,32,73,37,60,51,32,84,72,69,78,32,74,85,77,80,32,76,80,13,52,48,32,80,82,73,78,84,32,34,76,66,76,66,34,59,73,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.4
+ - id: assert_label_backward_if_then
+ type: assert.screen
+ params:
+ contains: "LBLB 3"
+
+ - id: label_forward
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,80,82,73,78,84,32,34,65,34,13,50,48,32,74,85,77,80,32,83,75,73,80,13,51,48,32,80,82,73,78,84,32,34,66,65,68,34,13,52,48,32,76,65,66,69,76,32,83,75,73,80,58,80,82,73,78,84,32,34,76,66,76,70,34,13,80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.2
+ - id: assert_label_forward
+ type: assert.screen
+ params:
+ contains: "LBLF"
+ - id: assert_label_forward_no_bad
+ type: assert.screen_not_contains
+ params:
+ not_contains: "BAD"
+
+ - id: label_noop
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,76,65,66,69,76,32,72,69,82,69,58,80,82,73,78,84,32,34,76,66,76,78,34,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_label_noop
+ type: assert.screen
+ params:
+ contains: "LBLN"
+
+ - id: missing_label
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,74,85,77,80,32,77,73,83,83,73,78,71,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_missing_label
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 39"
+
+ - id: numeric_goto_still_rom
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,71,79,84,79,32,51,48,13,50,48,32,80,82,73,78,84,32,34,66,65,68,34,13,51,48,32,80,82,73,78,84,32,34,71,84,79,78,34,13,80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_numeric_goto
+ type: assert.screen
+ params:
+ contains: "GTON"
+ - id: assert_numeric_goto_no_bad
+ type: assert.screen_not_contains
+ params:
+ not_contains: "BAD"
+
+ - id: err_status_after_error
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,90,70,65,73,76,40,54,44,88,37,41,13,82,85,78,13,80,82,73,78,84,32,34,69,82,88,34,59,69,82,82,67,79,68,69,40,41,59,69,82,82,76,73,78,69,40,41,13,69,82,82,67,79,68,69,40,69,37,41,58,69,82,82,76,73,78,69,40,76,37,41,58,80,82,73,78,84,32,34,69,82,83,34,59,69,37,59,76,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.4
+ - id: assert_err_error
+ type: assert.screen
+ params:
+ contains: "?RB ERROR 6"
+ - id: assert_err_expr
+ type: assert.screen
+ params:
+ contains: "ERX 6 10"
+ - id: assert_err_stmt
+ type: assert.screen
+ params:
+ contains: "ERS 6 10"
+
+ - id: regs_final
+ type: monitor.command
+ params:
+ command: "r"
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_resume_min_probe.easyflash.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_resume_min_probe.easyflash.yaml
new file mode 100644
index 0000000..795d5d9
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_resume_min_probe.easyflash.yaml
@@ -0,0 +1,173 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_resume_min_probe_easyflash
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
+ autostart_enabled: false
+ disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
+ drive8_enabled: true
+ drive8_type: 1541
+ drive9_enabled: false
+ true_drive: true
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: easyflash_wait_launcher
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ pre_delay_s: 4
+ poll_s: 0.5
+ wait_timeout_s: 420
+ capture_label: easyflash_readybasic_launcher
+ - id: easyflash_start_readybasic
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 180
+ capture_label: readybasic_resume_min_prompt
+ - id: initial_builtin_probe
+ type: input.sequence
+ params:
+ keys: [65,37,61,90,65,68,68,49,54,40,53,44,49,48,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: capture_initial_add16_probe
+ type: screen.capture
+ params:
+ label: initial_add16_probe
+ - id: initial_ping_probe
+ type: input.sequence
+ params:
+ keys: [90,69,67,72,79,49,40,80,37,41,13,80,82,73,78,84,32,34,80,82,69,34,59,65,37,59,34,58,34,59,80,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: capture_initial_builtin_probe
+ type: screen.capture
+ params:
+ label: initial_builtin_probe
+ - id: assert_initial_builtin_probe
+ type: assert.screen
+ params:
+ contains: "PRE 15 : 1"
+ - id: initial_state_seed
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,86,37,61,51,50,49,58,86,83,36,61,34,79,75,34,13,80,82,73,78,84,32,34,83,84,65,84,69,34,59,86,37,59,34,58,34,59,86,83,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_initial_state_seed
+ type: assert.screen
+ params:
+ contains: "STATE 321 :OK"
+ - id: dump_before_first_exit
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: page3_vectors, start: 0x0304, end: 0x030B }
+ - { label: bridge_c000, start: 0xC000, end: 0xC5FF }
+ - { label: regseed_live_5000, start: 0x5000, end: 0x503F }
+ - id: exit_to_launcher_1
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_1
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: resume_1
+ type: input.sequence
+ params:
+ keys: [13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: wait_readybasic_after_resume_1
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 30
+ - id: builtin_after_resume_1
+ type: input.sequence
+ params:
+ keys: [13,80,82,73,78,84,32,34,83,84,65,84,69,34,59,86,37,59,34,58,34,59,86,83,36,13,65,37,61,90,65,68,68,49,54,40,53,44,49,48,41,13,90,69,67,72,79,49,40,80,37,41,13,80,82,73,78,84,32,34,82,49,34,59,65,37,59,34,58,34,59,80,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: capture_after_resume_1
+ type: screen.capture
+ params:
+ label: after_resume_1
+ - id: assert_state_after_resume_1
+ type: assert.screen
+ params:
+ contains: "STATE 321 :OK"
+ - id: assert_builtin_after_resume_1
+ type: assert.screen
+ params:
+ contains: "R1 15 : 1"
+ - id: exit_to_launcher_2
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_2
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: resume_2
+ type: input.sequence
+ params:
+ keys: [13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: wait_readybasic_after_resume_2
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 30
+ - id: builtin_after_resume_2
+ type: input.sequence
+ params:
+ keys: [65,37,61,90,65,68,68,49,54,40,55,44,56,41,13,90,69,67,72,79,49,40,80,37,41,13,80,82,73,78,84,32,34,82,50,34,59,65,37,59,34,58,34,59,80,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: capture_after_resume_2
+ type: screen.capture
+ params:
+ label: after_resume_2
+ - id: assert_builtin_after_resume_2
+ type: assert.screen
+ params:
+ contains: "R2 15 : 1"
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_resume_min_probe.regular.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_resume_min_probe.regular.yaml
new file mode 100644
index 0000000..ca67cb2
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_resume_min_probe.regular.yaml
@@ -0,0 +1,158 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_resume_min_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "__READYBASIC_D81__"
+ disk9: "__READYBASIC_D81__"
+ autostart_prg: "__READYBASIC_PREBOOT__"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "readybasic"
+ wait_timeout_s: 180
+ capture_label: readybasic_resume_min_prompt
+ - id: initial_builtin_probe
+ type: input.sequence
+ params:
+ keys: [65,37,61,90,65,68,68,49,54,40,53,44,49,48,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: capture_initial_add16_probe
+ type: screen.capture
+ params:
+ label: initial_add16_probe
+ - id: initial_ping_probe
+ type: input.sequence
+ params:
+ keys: [90,69,67,72,79,49,40,80,37,41,13,80,82,73,78,84,32,34,80,82,69,34,59,65,37,59,34,58,34,59,80,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: capture_initial_builtin_probe
+ type: screen.capture
+ params:
+ label: initial_builtin_probe
+ - id: assert_initial_builtin_probe
+ type: assert.screen
+ params:
+ contains: "PRE 15 : 1"
+ - id: initial_state_seed
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,86,37,61,51,50,49,58,86,83,36,61,34,79,75,34,13,80,82,73,78,84,32,34,83,84,65,84,69,34,59,86,37,59,34,58,34,59,86,83,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_initial_state_seed
+ type: assert.screen
+ params:
+ contains: "STATE 321 :OK"
+ - id: dump_before_first_exit
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: page3_vectors, start: 0x0304, end: 0x030B }
+ - { label: bridge_c000, start: 0xC000, end: 0xC5FF }
+ - { label: regseed_live_5000, start: 0x5000, end: 0x503F }
+ - id: exit_to_launcher_1
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_1
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: resume_1
+ type: input.sequence
+ params:
+ keys: [13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: wait_readybasic_after_resume_1
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 30
+ - id: builtin_after_resume_1
+ type: input.sequence
+ params:
+ keys: [13,80,82,73,78,84,32,34,83,84,65,84,69,34,59,86,37,59,34,58,34,59,86,83,36,13,65,37,61,90,65,68,68,49,54,40,53,44,49,48,41,13,90,69,67,72,79,49,40,80,37,41,13,80,82,73,78,84,32,34,82,49,34,59,65,37,59,34,58,34,59,80,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: capture_after_resume_1
+ type: screen.capture
+ params:
+ label: after_resume_1
+ - id: assert_state_after_resume_1
+ type: assert.screen
+ params:
+ contains: "STATE 321 :OK"
+ - id: assert_builtin_after_resume_1
+ type: assert.screen
+ params:
+ contains: "R1 15 : 1"
+ - id: exit_to_launcher_2
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_2
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: resume_2
+ type: input.sequence
+ params:
+ keys: [13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: wait_readybasic_after_resume_2
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 30
+ - id: builtin_after_resume_2
+ type: input.sequence
+ params:
+ keys: [65,37,61,90,65,68,68,49,54,40,55,44,56,41,13,90,69,67,72,79,49,40,80,37,41,13,80,82,73,78,84,32,34,82,50,34,59,65,37,59,34,58,34,59,80,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: capture_after_resume_2
+ type: screen.capture
+ params:
+ label: after_resume_2
+ - id: assert_builtin_after_resume_2
+ type: assert.screen
+ params:
+ contains: "R2 15 : 1"
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_reuviewer_f2_chain_probe.easyflash.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_reuviewer_f2_chain_probe.easyflash.yaml
new file mode 100644
index 0000000..c55bae2
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_reuviewer_f2_chain_probe.easyflash.yaml
@@ -0,0 +1,397 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_reuviewer_f2_chain_probe_easyflash
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
+ autostart_enabled: false
+ disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
+ drive8_enabled: true
+ drive8_type: 1541
+ drive9_enabled: false
+ true_drive: true
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_launcher_initial
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 420
+ capture_label: chain_launcher_initial
+ - id: launch_readybasic_from_launcher
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_initial
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 120
+ capture_label: chain_readybasic_initial
+ - id: assert_readybasic_bank_initial
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "05"
+ - id: assert_chrin_vector_initial
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "08 12"
+ - id: assert_keylog_vector_initial
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "7E C1"
+ - id: readybasic_first_type
+ type: input.sequence
+ params:
+ keys: [81,37,61,49,48,49,58,80,82,73,78,84,32,34,67,72,65,73,78,49,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_first_type
+ type: assert.screen
+ params:
+ contains: "CHAIN1 101"
+ - id: readybasic_ctrl_b_1_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 4C 74 A4"
+ - id: readybasic_ctrl_b_1_clear_keylog_breakpoints
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: readybasic_ctrl_b_1
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_launcher_after_readybasic_ctrl_b_1
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ pre_delay_s: 1.0
+ capture_label: chain_launcher_after_rb_ctrl_b_1
+ - id: assert_launcher_bank_after_ctrl_b_1
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "00"
+ - id: reenter_readybasic_1
+ type: input.sequence
+ params:
+ keys: [13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: capture_readybasic_reentry_1
+ type: screen.capture
+ params:
+ label: chain_readybasic_reentry_1
+ note: warm ReadyBASIC entry evidence; bank/vector assertions and typed sentinel prove keyboard liveness
+ - id: assert_readybasic_bank_reentry_1
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "05"
+ - id: readybasic_second_type
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,67,72,65,73,78,50,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_second_type
+ type: assert.screen
+ params:
+ contains: "CHAIN2 101"
+ - id: readybasic_ctrl_b_2_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 4C 74 A4"
+ - id: readybasic_ctrl_b_2_clear_keylog_breakpoints
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: readybasic_ctrl_b_2
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_launcher_after_readybasic_ctrl_b_2
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ pre_delay_s: 1.0
+ capture_label: chain_launcher_after_rb_ctrl_b_2
+ - id: launch_reuviewer_from_readybasic_position
+ type: input.sequence
+ params:
+ keys: [17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_reuviewer
+ type: screen.wait_contains
+ params:
+ text: "REU MEMORY"
+ wait_timeout_s: 90
+ capture_label: chain_reuviewer_loaded
+ - id: assert_reuviewer_bank
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "08"
+ - id: constrain_loaded_bitmap_for_readybasic_reuviewer_chain
+ type: memory.write
+ params:
+ start: 51254
+ bytes_hex: "20 01 00"
+ - id: reuviewer_f2_to_readybasic
+ type: input.sequence
+ params:
+ keys: [137]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.2
+ - id: capture_readybasic_after_reuviewer_f2
+ type: screen.capture
+ params:
+ label: chain_readybasic_after_reuviewer_f2
+ note: warm ReadyBASIC entry evidence; bank/vector assertions and typed sentinel prove keyboard liveness
+ - id: assert_readybasic_bank_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "05"
+ - id: assert_chrin_vector_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "08 12"
+ - id: assert_keylog_vector_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "7E C1"
+ - id: assert_keyboard_buffer_empty_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: wait_readybasic_stable_after_reuviewer_f2
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: chain_readybasic_stable_after_reuviewer_f2
+ - id: assert_readybasic_bank_stable_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "05"
+ - id: assert_keyboard_buffer_empty_stable_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: readybasic_type_after_reuviewer_f2
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,67,72,65,73,78,51,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_type_after_reuviewer_f2
+ type: assert.screen
+ params:
+ contains: "CHAIN3 101"
+ - id: readybasic_f2_back_to_reuviewer_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 4C 74 A4"
+ - id: readybasic_f2_back_to_reuviewer_clear_keylog_breakpoints
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: readybasic_f2_back_to_reuviewer
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_reuviewer_after_readybasic_f2
+ type: screen.wait_contains
+ params:
+ text: "REU MEMORY"
+ wait_timeout_s: 80
+ pre_delay_s: 1.0
+ capture_label: chain_reuviewer_after_readybasic_f2
+ - id: assert_app_keylog_vector_restored_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "48 EB"
+ - id: assert_app_chrin_vector_restored_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "57 F1"
+ - id: assert_default_input_device_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 153
+ end: 153
+ equals_hex: "00"
+ - id: assert_reuviewer_bank_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "08"
+ - id: assert_keyboard_buffer_empty_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: wait_reuviewer_stable_after_readybasic_f2
+ type: screen.wait_contains
+ params:
+ text: "REU MEMORY"
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: chain_reuviewer_stable_after_readybasic_f2
+ - id: assert_reuviewer_bank_stable_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "08"
+ - id: assert_keyboard_buffer_empty_stable_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: reuviewer_ctrl_b_after_readybasic_f2
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
+ - id: capture_after_reuviewer_ctrl_b_input
+ type: screen.capture
+ params:
+ label: chain_after_reuviewer_ctrl_b_hotkey
+ note: capture after resumed REU Viewer Ctrl+B hotkey
+ - id: wait_launcher_after_reuviewer_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ capture_label: chain_launcher_after_reuviewer_ctrl_b
+ - id: assert_launcher_bank_after_reuviewer_ctrl_b
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "00"
+ - id: reenter_readybasic_after_reuviewer_ctrl_b
+ type: input.sequence
+ params:
+ keys: [145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: capture_readybasic_after_reuviewer_ctrl_b_reentry
+ type: screen.capture
+ params:
+ label: chain_readybasic_after_reuviewer_ctrl_b_reentry
+ note: warm ReadyBASIC entry evidence; bank/vector assertions and typed sentinel prove keyboard liveness
+ - id: readybasic_type_after_reuviewer_ctrl_b_reentry
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,67,72,65,73,78,52,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_type_after_reuviewer_ctrl_b_reentry
+ type: assert.screen
+ params:
+ contains: "CHAIN4 101"
+ - id: readybasic_exit_after_multi_hop_reentry
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: wait_launcher_stable_after_readybasic_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ pre_delay_s: 2.0
+ capture_label: chain_launcher_stable_after_readybasic_exit
+ - id: assert_launcher_bank_after_readybasic_exit
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "00"
+ - id: assert_readybasic_not_auto_reentered_after_exit
+ type: assert.screen_not_contains
+ params:
+ not_contains: "ready."
+ - id: reenter_readybasic_after_exit_guard
+ type: input.sequence
+ params:
+ keys: [13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: capture_readybasic_after_exit_guard_reentry
+ type: screen.capture
+ params:
+ label: chain_readybasic_after_exit_guard_reentry
+ note: warm ReadyBASIC entry evidence; bank/vector assertions and typed sentinel prove keyboard liveness
+ - id: readybasic_type_after_exit_guard_reentry
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,67,72,65,73,78,53,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_type_after_exit_guard_reentry
+ type: assert.screen
+ params:
+ contains: "CHAIN5 101"
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_reuviewer_f2_chain_probe.regular.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_reuviewer_f2_chain_probe.regular.yaml
new file mode 100644
index 0000000..d523732
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_reuviewer_f2_chain_probe.regular.yaml
@@ -0,0 +1,396 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_reuviewer_f2_chain_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_launcher_initial
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 180
+ capture_label: chain_launcher_initial
+ - id: launch_readybasic_from_launcher
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_initial
+ type: screen.wait_contains
+ params:
+ text: "READYBASIC"
+ wait_timeout_s: 120
+ capture_label: chain_readybasic_initial
+ - id: assert_readybasic_bank_initial
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "05"
+ - id: assert_chrin_vector_initial
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "08 12"
+ - id: assert_keylog_vector_initial
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "7E C1"
+ - id: readybasic_first_type
+ type: input.sequence
+ params:
+ keys: [81,37,61,49,48,49,58,80,82,73,78,84,32,34,67,72,65,73,78,49,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_first_type
+ type: assert.screen
+ params:
+ contains: "CHAIN1 101"
+ - id: readybasic_ctrl_b_1_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 4C 74 A4"
+ - id: readybasic_ctrl_b_1_clear_keylog_breakpoints
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: readybasic_ctrl_b_1
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_launcher_after_readybasic_ctrl_b_1
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ pre_delay_s: 1.0
+ capture_label: chain_launcher_after_rb_ctrl_b_1
+ - id: assert_launcher_bank_after_ctrl_b_1
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "00"
+ - id: reenter_readybasic_1
+ type: input.sequence
+ params:
+ keys: [13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: capture_readybasic_reentry_1
+ type: screen.capture
+ params:
+ label: chain_readybasic_reentry_1
+ note: warm ReadyBASIC entry evidence; bank/vector assertions and typed sentinel prove keyboard liveness
+ - id: assert_readybasic_bank_reentry_1
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "05"
+ - id: readybasic_second_type
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,67,72,65,73,78,50,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_second_type
+ type: assert.screen
+ params:
+ contains: "CHAIN2 101"
+ - id: readybasic_ctrl_b_2_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 4C 74 A4"
+ - id: readybasic_ctrl_b_2_clear_keylog_breakpoints
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: readybasic_ctrl_b_2
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_launcher_after_readybasic_ctrl_b_2
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ pre_delay_s: 1.0
+ capture_label: chain_launcher_after_rb_ctrl_b_2
+ - id: launch_reuviewer_from_readybasic_position
+ type: input.sequence
+ params:
+ keys: [17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_reuviewer
+ type: screen.wait_contains
+ params:
+ text: "REU MEMORY"
+ wait_timeout_s: 90
+ capture_label: chain_reuviewer_loaded
+ - id: assert_reuviewer_bank
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "08"
+ - id: constrain_loaded_bitmap_for_readybasic_reuviewer_chain
+ type: memory.write
+ params:
+ start: 51254
+ bytes_hex: "20 01 00"
+ - id: reuviewer_f2_to_readybasic
+ type: input.sequence
+ params:
+ keys: [137]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.2
+ - id: capture_readybasic_after_reuviewer_f2
+ type: screen.capture
+ params:
+ label: chain_readybasic_after_reuviewer_f2
+ note: warm ReadyBASIC entry evidence; bank/vector assertions and typed sentinel prove keyboard liveness
+ - id: assert_readybasic_bank_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "05"
+ - id: assert_chrin_vector_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "08 12"
+ - id: assert_keylog_vector_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "7E C1"
+ - id: assert_keyboard_buffer_empty_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: wait_readybasic_stable_after_reuviewer_f2
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: chain_readybasic_stable_after_reuviewer_f2
+ - id: assert_readybasic_bank_stable_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "05"
+ - id: assert_keyboard_buffer_empty_stable_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: readybasic_type_after_reuviewer_f2
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,67,72,65,73,78,51,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_type_after_reuviewer_f2
+ type: assert.screen
+ params:
+ contains: "CHAIN3 101"
+ - id: readybasic_f2_back_to_reuviewer_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 4C 74 A4"
+ - id: readybasic_f2_back_to_reuviewer_clear_keylog_breakpoints
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: readybasic_f2_back_to_reuviewer
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_reuviewer_after_readybasic_f2
+ type: screen.wait_contains
+ params:
+ text: "REU MEMORY"
+ wait_timeout_s: 80
+ pre_delay_s: 1.0
+ capture_label: chain_reuviewer_after_readybasic_f2
+ - id: assert_app_keylog_vector_restored_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "48 EB"
+ - id: assert_app_chrin_vector_restored_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "57 F1"
+ - id: assert_default_input_device_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 153
+ end: 153
+ equals_hex: "00"
+ - id: assert_reuviewer_bank_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "08"
+ - id: assert_keyboard_buffer_empty_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: wait_reuviewer_stable_after_readybasic_f2
+ type: screen.wait_contains
+ params:
+ text: "REU MEMORY"
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: chain_reuviewer_stable_after_readybasic_f2
+ - id: assert_reuviewer_bank_stable_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "08"
+ - id: assert_keyboard_buffer_empty_stable_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: reuviewer_ctrl_b_after_readybasic_f2
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
+ - id: capture_after_reuviewer_ctrl_b_input
+ type: screen.capture
+ params:
+ label: chain_after_reuviewer_ctrl_b_hotkey
+ note: capture after resumed REU Viewer Ctrl+B hotkey
+ - id: wait_launcher_after_reuviewer_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ capture_label: chain_launcher_after_reuviewer_ctrl_b
+ - id: assert_launcher_bank_after_reuviewer_ctrl_b
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "00"
+ - id: reenter_readybasic_after_reuviewer_ctrl_b
+ type: input.sequence
+ params:
+ keys: [145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: capture_readybasic_after_reuviewer_ctrl_b_reentry
+ type: screen.capture
+ params:
+ label: chain_readybasic_after_reuviewer_ctrl_b_reentry
+ note: warm ReadyBASIC entry evidence; bank/vector assertions and typed sentinel prove keyboard liveness
+ - id: readybasic_type_after_reuviewer_ctrl_b_reentry
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,67,72,65,73,78,52,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_type_after_reuviewer_ctrl_b_reentry
+ type: assert.screen
+ params:
+ contains: "CHAIN4 101"
+ - id: readybasic_exit_after_multi_hop_reentry
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: wait_launcher_stable_after_readybasic_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ pre_delay_s: 2.0
+ capture_label: chain_launcher_stable_after_readybasic_exit
+ - id: assert_launcher_bank_after_readybasic_exit
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "00"
+ - id: assert_readybasic_not_auto_reentered_after_exit
+ type: assert.screen_not_contains
+ params:
+ not_contains: "ready."
+ - id: reenter_readybasic_after_exit_guard
+ type: input.sequence
+ params:
+ keys: [13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: capture_readybasic_after_exit_guard_reentry
+ type: screen.capture
+ params:
+ label: chain_readybasic_after_exit_guard_reentry
+ note: warm ReadyBASIC entry evidence; bank/vector assertions and typed sentinel prove keyboard liveness
+ - id: readybasic_type_after_exit_guard_reentry
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,67,72,65,73,78,53,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_type_after_exit_guard_reentry
+ type: assert.screen
+ params:
+ contains: "CHAIN5 101"
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_screen_reu_temp_probe.easyflash.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_screen_reu_temp_probe.easyflash.yaml
new file mode 100644
index 0000000..5136dba
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_screen_reu_temp_probe.easyflash.yaml
@@ -0,0 +1,102 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_screen_reu_temp_probe_easyflash
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 1
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
+ autostart_enabled: false
+ disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
+ drive8_enabled: true
+ drive8_type: 1541
+ drive9_enabled: false
+ true_drive: true
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: easyflash_wait_launcher
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ pre_delay_s: 4
+ poll_s: 0.5
+ wait_timeout_s: 420
+ capture_label: easyflash_readybasic_launcher
+ - id: easyflash_start_readybasic
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 180
+ capture_label: scrreu_prompt
+ - id: dump_initial_ranges
+ type: dump.memory_ranges
+ params:
+ ranges: &scrreu_ranges
+ - { label: screen_0400, start: 0x0400, end: 0x07E7 }
+ - { label: color_d800, start: 0xD800, end: 0xDBE7 }
+ - { label: descriptors_1000, start: 0x1000, end: 0x11FF }
+ - { label: resident_1200, start: 0x1200, end: 0x1BFF }
+ - { label: command_overlay_a800, start: 0xA800, end: 0xAFFF }
+ - { label: reu_alloc_c600, start: 0xC600, end: 0xC6FF }
+ - id: load_temp_program
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,76,79,65,68,32,34,82,66,83,67,82,82,69,85,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_load_ready
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 30
+ capture_label: scrreu_loaded
+ - id: dump_after_load
+ type: dump.memory_ranges
+ params:
+ ranges: *scrreu_ranges
+ - id: run_temp_program
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 75.0
+ - id: assert_done
+ type: assert.memory
+ params:
+ start: 1024
+ end: 1036
+ equals_hex: "52 42 53 43 52 52 45 55 20 44 4F 4E 45"
+ - id: dump_after_done
+ type: dump.memory_ranges
+ params:
+ ranges: *scrreu_ranges
+ - id: regs_final
+ type: monitor.command
+ params:
+ command: "r"
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_screen_reu_temp_probe.regular.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_screen_reu_temp_probe.regular.yaml
new file mode 100644
index 0000000..1556ba0
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_screen_reu_temp_probe.regular.yaml
@@ -0,0 +1,87 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_screen_reu_temp_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 1
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "readybasic"
+ wait_timeout_s: 180
+ capture_label: scrreu_prompt
+ - id: dump_initial_ranges
+ type: dump.memory_ranges
+ params:
+ ranges: &scrreu_ranges
+ - { label: screen_0400, start: 0x0400, end: 0x07E7 }
+ - { label: color_d800, start: 0xD800, end: 0xDBE7 }
+ - { label: descriptors_1000, start: 0x1000, end: 0x11FF }
+ - { label: resident_1200, start: 0x1200, end: 0x1BFF }
+ - { label: command_overlay_a800, start: 0xA800, end: 0xAFFF }
+ - { label: reu_alloc_c600, start: 0xC600, end: 0xC6FF }
+ - id: load_temp_program
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,76,79,65,68,32,34,82,66,83,67,82,82,69,85,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_load_ready
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 30
+ capture_label: scrreu_loaded
+ - id: dump_after_load
+ type: dump.memory_ranges
+ params:
+ ranges: *scrreu_ranges
+ - id: run_temp_program
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 30.0
+ - id: assert_done
+ type: screen.wait_contains
+ params:
+ text: "RBSCRREU DONE"
+ wait_timeout_s: 300
+ capture_label: scrreu_done
+ - id: dump_after_done
+ type: dump.memory_ranges
+ params:
+ ranges: *scrreu_ranges
+ - id: regs_final
+ type: monitor.command
+ params:
+ command: "r"
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_second_entry_editor_probe.easyflash.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_second_entry_editor_probe.easyflash.yaml
new file mode 100644
index 0000000..8491d6e
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_second_entry_editor_probe.easyflash.yaml
@@ -0,0 +1,865 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_second_entry_editor_probe_easyflash
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 240
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
+ autostart_enabled: false
+ disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
+ drive8_enabled: true
+ drive8_type: 1541
+ drive9_enabled: false
+ true_drive: true
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: easyflash_wait_launcher
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ pre_delay_s: 4
+ poll_s: 0.5
+ wait_timeout_s: 420
+ capture_label: easyflash_readybasic_launcher
+ - id: easyflash_start_readybasic
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_first_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "FREE:"
+ wait_timeout_s: 180
+ capture_label: first_readybasic_prompt
+ - id: first_entry_print_hello
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,72,69,76,76,79,34,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: first_entry_print_dirty
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,68,73,82,84,89,32,70,73,82,83,84,32,69,78,84,82,89,34,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: first_entry_assign_x
+ type: input.sequence
+ params:
+ keys: [88,61,55,55,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: first_entry_print_x
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,88,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_first_entry_print_hello
+ type: assert.screen
+ params:
+ contains: "HELLO"
+ - id: assert_first_entry_print_dirty
+ type: assert.screen
+ params:
+ contains: "DIRTY FIRST ENTRY"
+ - id: assert_first_entry_print_x
+ type: assert.screen
+ params:
+ contains: " 77"
+ - id: first_readybasic_exit
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 1.2
+ - id: wait_launcher_after_first_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_readybasic_to_editor_before_setup
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.10
+ post_delay_s: 1.0
+ - id: wait_editor_before_setup
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: type_editor_chars_before_setup
+ type: input.sequence
+ params:
+ keys: [80,82,79,66,69,32,76,73,78,69,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: ctrl_b_editor_before_setup
+ type: input.sequence
+ params:
+ keys: [2]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_before_setup
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_editor_to_readybasic_before_setup
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.10
+ post_delay_s: 1.0
+ - id: wait_readybasic_after_tour_before_setup
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_after_tour_before_setup
+ - id: enter_line_10
+ type: input.sequence
+ params:
+ keys: [49,48,32,80,82,73,78,84,32,34,72,69,76,76,79,34,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: enter_line_20
+ type: input.sequence
+ params:
+ keys: [50,48,32,80,82,73,78,84,32,34,66,34,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: enter_line_30
+ type: input.sequence
+ params:
+ keys: [51,48,32,80,82,73,78,84,32,34,67,34,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: enter_line_40
+ type: input.sequence
+ params:
+ keys: [52,48,32,80,82,73,78,84,32,34,68,34,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: enter_line_50
+ type: input.sequence
+ params:
+ keys: [53,48,32,80,82,73,78,84,32,34,69,34,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: list_before_run
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_program_before_run
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: run_program
+ type: input.sequence
+ params:
+ keys: [82,85,78,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_run_output
+ type: assert.screen
+ params:
+ contains: "HELLO"
+ - id: assign_a
+ type: input.sequence
+ params:
+ keys: [65,36,61,34,65,45,48,49,50,51,52,53,54,55,56,57,48,49,50,51,52,53,54,55,56,57,48,49,50,51,52,53,54,55,56,57,48,49,50,51,52,53,54,55,56,57,48,49,50,51,52,53,54,55,34,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: print_a_before_exit
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_a_before_exit
+ type: assert.screen
+ params:
+ contains: "A-0123456789"
+ - id: assign_b
+ type: input.sequence
+ params:
+ keys: [66,36,61,34,66,45,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,34,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: print_b_before_exit
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_b_before_exit
+ type: assert.screen
+ params:
+ contains: "B-ABCDEFGHIJ"
+ - id: assign_c
+ type: input.sequence
+ params:
+ keys: [67,36,61,34,67,45,82,69,65,68,89,66,65,83,73,67,45,83,84,82,73,78,71,45,83,84,65,84,69,45,83,72,79,85,76,68,45,83,85,82,86,73,86,69,45,69,68,73,84,79,82,45,48,48,49,34,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: print_c_before_exit
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_c_before_exit
+ type: assert.screen
+ params:
+ contains: "C-READYBASIC"
+ - id: assign_d
+ type: input.sequence
+ params:
+ keys: [68,36,61,34,68,45,83,69,67,79,78,68,45,69,78,84,82,89,45,69,68,73,84,79,82,45,82,79,85,78,68,84,82,73,80,45,76,79,78,71,45,83,84,82,73,78,71,45,83,84,65,84,69,34,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: print_d_before_exit
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_d_before_exit
+ type: assert.screen
+ params:
+ contains: "D-SECOND"
+ - id: dim_e
+ type: input.sequence
+ params:
+ keys: [68,73,77,32,69,40,50,48,48,41,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assign_e199
+ type: input.sequence
+ params:
+ keys: [69,40,49,57,57,41,61,53,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: print_e_before_exit
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 1.2
+ - id: assert_e_before_exit
+ type: assert.screen
+ params:
+ contains: " 5"
+ - id: dump_before_editor_roundtrip
+ type: dump.memory_ranges
+ params:
+ ranges: &state_ranges
+ - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_text_and_vars_1200, start: 0x1200, end: 0x1800 }
+ - { label: string_heap_9300, start: 0x9300, end: 0x9600 }
+ - { label: runtime_state_9600, start: 0x9600, end: 0x9A00 }
+ - { label: bridge_c000, start: 0xC000, end: 0xC5FF }
+ - id: exit_readybasic_1
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 1.2
+ - id: wait_launcher_after_exit_1
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_readybasic_to_editor_verify_1
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.10
+ post_delay_s: 1.0
+ - id: wait_editor_verify_1
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: type_editor_chars_verify_1
+ type: input.sequence
+ params:
+ keys: [80,82,79,66,69,32,76,73,78,69,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: ctrl_b_editor_verify_1
+ type: input.sequence
+ params:
+ keys: [2]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_verify_1
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_editor_to_readybasic_verify_1
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.10
+ post_delay_s: 1.0
+ - id: wait_readybasic_after_tour_verify_1
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_after_tour_verify_1
+ - id: list_after_editor_1
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_program_after_editor_1
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: print_a_after_editor_1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_a_after_editor_1
+ type: assert.screen
+ params:
+ contains: "A-0123456789"
+ - id: print_b_after_editor_1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_b_after_editor_1
+ type: assert.screen
+ params:
+ contains: "B-ABCDEFGHIJ"
+ - id: print_c_after_editor_1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_c_after_editor_1
+ type: assert.screen
+ params:
+ contains: "C-READYBASIC"
+ - id: print_d_after_editor_1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_d_after_editor_1
+ type: assert.screen
+ params:
+ contains: "D-SECOND"
+ - id: print_e_after_editor_1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_e_after_editor_1
+ type: assert.screen
+ params:
+ contains: " 5"
+ - id: exit_readybasic_2
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 1.2
+ - id: wait_launcher_after_exit_2
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_readybasic_to_editor_verify_2
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.10
+ post_delay_s: 1.0
+ - id: wait_editor_verify_2
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: type_editor_chars_verify_2
+ type: input.sequence
+ params:
+ keys: [80,82,79,66,69,32,76,73,78,69,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: ctrl_b_editor_verify_2
+ type: input.sequence
+ params:
+ keys: [2]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_verify_2
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_editor_to_readybasic_verify_2
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.10
+ post_delay_s: 1.0
+ - id: wait_readybasic_after_tour_verify_2
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_after_tour_verify_2
+ - id: list_after_editor_2
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_program_after_editor_2
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: print_a_after_editor_2
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_a_after_editor_2
+ type: assert.screen
+ params:
+ contains: "A-0123456789"
+ - id: print_b_after_editor_2
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_b_after_editor_2
+ type: assert.screen
+ params:
+ contains: "B-ABCDEFGHIJ"
+ - id: print_c_after_editor_2
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_c_after_editor_2
+ type: assert.screen
+ params:
+ contains: "C-READYBASIC"
+ - id: print_d_after_editor_2
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_d_after_editor_2
+ type: assert.screen
+ params:
+ contains: "D-SECOND"
+ - id: print_e_after_editor_2
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_e_after_editor_2
+ type: assert.screen
+ params:
+ contains: " 5"
+ - id: exit_readybasic_3
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 1.2
+ - id: wait_launcher_after_exit_3
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_readybasic_to_editor_verify_3
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.10
+ post_delay_s: 1.0
+ - id: wait_editor_verify_3
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: type_editor_chars_verify_3
+ type: input.sequence
+ params:
+ keys: [80,82,79,66,69,32,76,73,78,69,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: ctrl_b_editor_verify_3
+ type: input.sequence
+ params:
+ keys: [2]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_verify_3
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_editor_to_readybasic_verify_3
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.10
+ post_delay_s: 1.0
+ - id: wait_readybasic_after_tour_verify_3
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_after_tour_verify_3
+ - id: list_after_editor_3
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_program_after_editor_3
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: print_a_after_editor_3
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_a_after_editor_3
+ type: assert.screen
+ params:
+ contains: "A-0123456789"
+ - id: print_b_after_editor_3
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_b_after_editor_3
+ type: assert.screen
+ params:
+ contains: "B-ABCDEFGHIJ"
+ - id: print_c_after_editor_3
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_c_after_editor_3
+ type: assert.screen
+ params:
+ contains: "C-READYBASIC"
+ - id: print_d_after_editor_3
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_d_after_editor_3
+ type: assert.screen
+ params:
+ contains: "D-SECOND"
+ - id: print_e_after_editor_3
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_e_after_editor_3
+ type: assert.screen
+ params:
+ contains: " 5"
+ - id: exit_readybasic_4
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 1.2
+ - id: wait_launcher_after_exit_4
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_readybasic_to_editor_verify_4
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.10
+ post_delay_s: 1.0
+ - id: wait_editor_verify_4
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: type_editor_chars_verify_4
+ type: input.sequence
+ params:
+ keys: [80,82,79,66,69,32,76,73,78,69,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: ctrl_b_editor_verify_4
+ type: input.sequence
+ params:
+ keys: [2]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_verify_4
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_editor_to_readybasic_verify_4
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.10
+ post_delay_s: 1.0
+ - id: wait_readybasic_after_tour_verify_4
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_after_tour_verify_4
+ - id: list_after_editor_4
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_program_after_editor_4
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: print_a_after_editor_4
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_a_after_editor_4
+ type: assert.screen
+ params:
+ contains: "A-0123456789"
+ - id: print_b_after_editor_4
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_b_after_editor_4
+ type: assert.screen
+ params:
+ contains: "B-ABCDEFGHIJ"
+ - id: print_c_after_editor_4
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_c_after_editor_4
+ type: assert.screen
+ params:
+ contains: "C-READYBASIC"
+ - id: print_d_after_editor_4
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_d_after_editor_4
+ type: assert.screen
+ params:
+ contains: "D-SECOND"
+ - id: print_e_after_editor_4
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_e_after_editor_4
+ type: assert.screen
+ params:
+ contains: " 5"
+ - id: exit_readybasic_5
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 1.2
+ - id: wait_launcher_after_exit_5
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_readybasic_to_editor_verify_5
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.10
+ post_delay_s: 1.0
+ - id: wait_editor_verify_5
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: type_editor_chars_verify_5
+ type: input.sequence
+ params:
+ keys: [80,82,79,66,69,32,76,73,78,69,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: ctrl_b_editor_verify_5
+ type: input.sequence
+ params:
+ keys: [2]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_verify_5
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_editor_to_readybasic_verify_5
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.10
+ post_delay_s: 1.0
+ - id: wait_readybasic_after_tour_verify_5
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_after_tour_verify_5
+ - id: list_after_editor_5
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_program_after_editor_5
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: print_a_after_editor_5
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_a_after_editor_5
+ type: assert.screen
+ params:
+ contains: "A-0123456789"
+ - id: print_b_after_editor_5
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_b_after_editor_5
+ type: assert.screen
+ params:
+ contains: "B-ABCDEFGHIJ"
+ - id: print_c_after_editor_5
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_c_after_editor_5
+ type: assert.screen
+ params:
+ contains: "C-READYBASIC"
+ - id: print_d_after_editor_5
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_d_after_editor_5
+ type: assert.screen
+ params:
+ contains: "D-SECOND"
+ - id: print_e_after_editor_5
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_e_after_editor_5
+ type: assert.screen
+ params:
+ contains: " 5"
+ - id: dump_final_state
+ type: dump.memory_ranges
+ params:
+ ranges: *state_ranges
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_second_entry_editor_probe.regular.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_second_entry_editor_probe.regular.yaml
new file mode 100644
index 0000000..7d0541d
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_second_entry_editor_probe.regular.yaml
@@ -0,0 +1,850 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_second_entry_editor_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 240
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_first_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "FREE:"
+ wait_timeout_s: 180
+ capture_label: first_readybasic_prompt
+ - id: first_entry_print_hello
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,72,69,76,76,79,34,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: first_entry_print_dirty
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,68,73,82,84,89,32,70,73,82,83,84,32,69,78,84,82,89,34,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: first_entry_assign_x
+ type: input.sequence
+ params:
+ keys: [88,61,55,55,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: first_entry_print_x
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,88,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_first_entry_print_hello
+ type: assert.screen
+ params:
+ contains: "HELLO"
+ - id: assert_first_entry_print_dirty
+ type: assert.screen
+ params:
+ contains: "DIRTY FIRST ENTRY"
+ - id: assert_first_entry_print_x
+ type: assert.screen
+ params:
+ contains: " 77"
+ - id: first_readybasic_exit
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 1.2
+ - id: wait_launcher_after_first_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_readybasic_to_editor_before_setup
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.10
+ post_delay_s: 1.0
+ - id: wait_editor_before_setup
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: type_editor_chars_before_setup
+ type: input.sequence
+ params:
+ keys: [80,82,79,66,69,32,76,73,78,69,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: ctrl_b_editor_before_setup
+ type: input.sequence
+ params:
+ keys: [2]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_before_setup
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_editor_to_readybasic_before_setup
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.10
+ post_delay_s: 1.0
+ - id: wait_readybasic_after_tour_before_setup
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_after_tour_before_setup
+ - id: enter_line_10
+ type: input.sequence
+ params:
+ keys: [49,48,32,80,82,73,78,84,32,34,72,69,76,76,79,34,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: enter_line_20
+ type: input.sequence
+ params:
+ keys: [50,48,32,80,82,73,78,84,32,34,66,34,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: enter_line_30
+ type: input.sequence
+ params:
+ keys: [51,48,32,80,82,73,78,84,32,34,67,34,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: enter_line_40
+ type: input.sequence
+ params:
+ keys: [52,48,32,80,82,73,78,84,32,34,68,34,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: enter_line_50
+ type: input.sequence
+ params:
+ keys: [53,48,32,80,82,73,78,84,32,34,69,34,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: list_before_run
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_program_before_run
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: run_program
+ type: input.sequence
+ params:
+ keys: [82,85,78,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_run_output
+ type: assert.screen
+ params:
+ contains: "HELLO"
+ - id: assign_a
+ type: input.sequence
+ params:
+ keys: [65,36,61,34,65,45,48,49,50,51,52,53,54,55,56,57,48,49,50,51,52,53,54,55,56,57,48,49,50,51,52,53,54,55,56,57,48,49,50,51,52,53,54,55,56,57,48,49,50,51,52,53,54,55,34,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: print_a_before_exit
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_a_before_exit
+ type: assert.screen
+ params:
+ contains: "A-0123456789"
+ - id: assign_b
+ type: input.sequence
+ params:
+ keys: [66,36,61,34,66,45,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,34,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: print_b_before_exit
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_b_before_exit
+ type: assert.screen
+ params:
+ contains: "B-ABCDEFGHIJ"
+ - id: assign_c
+ type: input.sequence
+ params:
+ keys: [67,36,61,34,67,45,82,69,65,68,89,66,65,83,73,67,45,83,84,82,73,78,71,45,83,84,65,84,69,45,83,72,79,85,76,68,45,83,85,82,86,73,86,69,45,69,68,73,84,79,82,45,48,48,49,34,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: print_c_before_exit
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_c_before_exit
+ type: assert.screen
+ params:
+ contains: "C-READYBASIC"
+ - id: assign_d
+ type: input.sequence
+ params:
+ keys: [68,36,61,34,68,45,83,69,67,79,78,68,45,69,78,84,82,89,45,69,68,73,84,79,82,45,82,79,85,78,68,84,82,73,80,45,76,79,78,71,45,83,84,82,73,78,71,45,83,84,65,84,69,34,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: print_d_before_exit
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_d_before_exit
+ type: assert.screen
+ params:
+ contains: "D-SECOND"
+ - id: dim_e
+ type: input.sequence
+ params:
+ keys: [68,73,77,32,69,40,50,48,48,41,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assign_e199
+ type: input.sequence
+ params:
+ keys: [69,40,49,57,57,41,61,53,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: print_e_before_exit
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 1.2
+ - id: assert_e_before_exit
+ type: assert.screen
+ params:
+ contains: " 5"
+ - id: dump_before_editor_roundtrip
+ type: dump.memory_ranges
+ params:
+ ranges: &state_ranges
+ - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_text_and_vars_1200, start: 0x1200, end: 0x1800 }
+ - { label: string_heap_9300, start: 0x9300, end: 0x9600 }
+ - { label: runtime_state_9600, start: 0x9600, end: 0x9A00 }
+ - { label: bridge_c000, start: 0xC000, end: 0xC5FF }
+ - id: exit_readybasic_1
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 1.2
+ - id: wait_launcher_after_exit_1
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_readybasic_to_editor_verify_1
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.10
+ post_delay_s: 1.0
+ - id: wait_editor_verify_1
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: type_editor_chars_verify_1
+ type: input.sequence
+ params:
+ keys: [80,82,79,66,69,32,76,73,78,69,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: ctrl_b_editor_verify_1
+ type: input.sequence
+ params:
+ keys: [2]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_verify_1
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_editor_to_readybasic_verify_1
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.10
+ post_delay_s: 1.0
+ - id: wait_readybasic_after_tour_verify_1
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_after_tour_verify_1
+ - id: list_after_editor_1
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_program_after_editor_1
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: print_a_after_editor_1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_a_after_editor_1
+ type: assert.screen
+ params:
+ contains: "A-0123456789"
+ - id: print_b_after_editor_1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_b_after_editor_1
+ type: assert.screen
+ params:
+ contains: "B-ABCDEFGHIJ"
+ - id: print_c_after_editor_1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_c_after_editor_1
+ type: assert.screen
+ params:
+ contains: "C-READYBASIC"
+ - id: print_d_after_editor_1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_d_after_editor_1
+ type: assert.screen
+ params:
+ contains: "D-SECOND"
+ - id: print_e_after_editor_1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_e_after_editor_1
+ type: assert.screen
+ params:
+ contains: " 5"
+ - id: exit_readybasic_2
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 1.2
+ - id: wait_launcher_after_exit_2
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_readybasic_to_editor_verify_2
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.10
+ post_delay_s: 1.0
+ - id: wait_editor_verify_2
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: type_editor_chars_verify_2
+ type: input.sequence
+ params:
+ keys: [80,82,79,66,69,32,76,73,78,69,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: ctrl_b_editor_verify_2
+ type: input.sequence
+ params:
+ keys: [2]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_verify_2
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_editor_to_readybasic_verify_2
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.10
+ post_delay_s: 1.0
+ - id: wait_readybasic_after_tour_verify_2
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_after_tour_verify_2
+ - id: list_after_editor_2
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_program_after_editor_2
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: print_a_after_editor_2
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_a_after_editor_2
+ type: assert.screen
+ params:
+ contains: "A-0123456789"
+ - id: print_b_after_editor_2
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_b_after_editor_2
+ type: assert.screen
+ params:
+ contains: "B-ABCDEFGHIJ"
+ - id: print_c_after_editor_2
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_c_after_editor_2
+ type: assert.screen
+ params:
+ contains: "C-READYBASIC"
+ - id: print_d_after_editor_2
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_d_after_editor_2
+ type: assert.screen
+ params:
+ contains: "D-SECOND"
+ - id: print_e_after_editor_2
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_e_after_editor_2
+ type: assert.screen
+ params:
+ contains: " 5"
+ - id: exit_readybasic_3
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 1.2
+ - id: wait_launcher_after_exit_3
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_readybasic_to_editor_verify_3
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.10
+ post_delay_s: 1.0
+ - id: wait_editor_verify_3
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: type_editor_chars_verify_3
+ type: input.sequence
+ params:
+ keys: [80,82,79,66,69,32,76,73,78,69,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: ctrl_b_editor_verify_3
+ type: input.sequence
+ params:
+ keys: [2]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_verify_3
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_editor_to_readybasic_verify_3
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.10
+ post_delay_s: 1.0
+ - id: wait_readybasic_after_tour_verify_3
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_after_tour_verify_3
+ - id: list_after_editor_3
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_program_after_editor_3
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: print_a_after_editor_3
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_a_after_editor_3
+ type: assert.screen
+ params:
+ contains: "A-0123456789"
+ - id: print_b_after_editor_3
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_b_after_editor_3
+ type: assert.screen
+ params:
+ contains: "B-ABCDEFGHIJ"
+ - id: print_c_after_editor_3
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_c_after_editor_3
+ type: assert.screen
+ params:
+ contains: "C-READYBASIC"
+ - id: print_d_after_editor_3
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_d_after_editor_3
+ type: assert.screen
+ params:
+ contains: "D-SECOND"
+ - id: print_e_after_editor_3
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_e_after_editor_3
+ type: assert.screen
+ params:
+ contains: " 5"
+ - id: exit_readybasic_4
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 1.2
+ - id: wait_launcher_after_exit_4
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_readybasic_to_editor_verify_4
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.10
+ post_delay_s: 1.0
+ - id: wait_editor_verify_4
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: type_editor_chars_verify_4
+ type: input.sequence
+ params:
+ keys: [80,82,79,66,69,32,76,73,78,69,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: ctrl_b_editor_verify_4
+ type: input.sequence
+ params:
+ keys: [2]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_verify_4
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_editor_to_readybasic_verify_4
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.10
+ post_delay_s: 1.0
+ - id: wait_readybasic_after_tour_verify_4
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_after_tour_verify_4
+ - id: list_after_editor_4
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_program_after_editor_4
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: print_a_after_editor_4
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_a_after_editor_4
+ type: assert.screen
+ params:
+ contains: "A-0123456789"
+ - id: print_b_after_editor_4
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_b_after_editor_4
+ type: assert.screen
+ params:
+ contains: "B-ABCDEFGHIJ"
+ - id: print_c_after_editor_4
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_c_after_editor_4
+ type: assert.screen
+ params:
+ contains: "C-READYBASIC"
+ - id: print_d_after_editor_4
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_d_after_editor_4
+ type: assert.screen
+ params:
+ contains: "D-SECOND"
+ - id: print_e_after_editor_4
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_e_after_editor_4
+ type: assert.screen
+ params:
+ contains: " 5"
+ - id: exit_readybasic_5
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 1.2
+ - id: wait_launcher_after_exit_5
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_readybasic_to_editor_verify_5
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.10
+ post_delay_s: 1.0
+ - id: wait_editor_verify_5
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ - id: type_editor_chars_verify_5
+ type: input.sequence
+ params:
+ keys: [80,82,79,66,69,32,76,73,78,69,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: ctrl_b_editor_verify_5
+ type: input.sequence
+ params:
+ keys: [2]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_verify_5
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_editor_to_readybasic_verify_5
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ pre_delay_s: 0
+ inter_key_delay_s: 0.10
+ post_delay_s: 1.0
+ - id: wait_readybasic_after_tour_verify_5
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_after_tour_verify_5
+ - id: list_after_editor_5
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_program_after_editor_5
+ type: assert.screen
+ params:
+ contains: "50 PRINT"
+ - id: print_a_after_editor_5
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_a_after_editor_5
+ type: assert.screen
+ params:
+ contains: "A-0123456789"
+ - id: print_b_after_editor_5
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,66,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_b_after_editor_5
+ type: assert.screen
+ params:
+ contains: "B-ABCDEFGHIJ"
+ - id: print_c_after_editor_5
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_c_after_editor_5
+ type: assert.screen
+ params:
+ contains: "C-READYBASIC"
+ - id: print_d_after_editor_5
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,68,36,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_d_after_editor_5
+ type: assert.screen
+ params:
+ contains: "D-SECOND"
+ - id: print_e_after_editor_5
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,69,40,49,57,57,41,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.6
+ - id: assert_e_after_editor_5
+ type: assert.screen
+ params:
+ contains: " 5"
+ - id: dump_final_state
+ type: dump.memory_ranges
+ params:
+ ranges: *state_ranges
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_state_probe.easyflash.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_state_probe.easyflash.yaml
new file mode 100644
index 0000000..8212dd4
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_state_probe.easyflash.yaml
@@ -0,0 +1,350 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_state_probe_easyflash
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
+ autostart_enabled: false
+ disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
+ drive8_enabled: true
+ drive8_type: 1541
+ drive9_enabled: false
+ true_drive: true
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: easyflash_wait_launcher
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ pre_delay_s: 4
+ poll_s: 0.5
+ wait_timeout_s: 420
+ capture_label: easyflash_readybasic_launcher
+ - id: easyflash_start_readybasic
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 180
+ capture_label: readybasic_prompt
+ - id: dump_initial_state
+ type: dump.memory_ranges
+ params:
+ ranges: &state_ranges
+ - { label: basic_zp_002b, start: 0x002B, end: 0x003F }
+ - { label: chrget_0073, start: 0x0073, end: 0x008A }
+ - { label: stack_0100, start: 0x0100, end: 0x01FF }
+ - { label: basic_text_1200, start: 0x1200, end: 0x1300 }
+ - { label: runtime_9500, start: 0x9500, end: 0x9A00 }
+ - { label: bridge_c000, start: 0xC000, end: 0xC5FF }
+ - { label: screen_0400, start: 0x0400, end: 0x07E7 }
+
+ - id: direct_string_assignment
+ type: input.sequence
+ params:
+ keys: [78,69,87,13,65,36,61,34,72,69,76,76,79,34,13,80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_direct_string_before_exit
+ type: assert.screen
+ params:
+ contains: "HELLO"
+ - id: dump_direct_string_before_exit
+ type: dump.memory_ranges
+ params:
+ ranges: *state_ranges
+ - id: exit_direct_string
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_direct_string_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: resume_direct_string
+ type: input.sequence
+ params:
+ keys: [13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: wait_prompt_after_direct_string_resume
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 30
+ - id: print_direct_string_after_resume
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,43,34,33,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_direct_string_after_resume
+ type: assert.screen
+ params:
+ contains: "HELLO!"
+ - id: allocate_second_direct_string
+ type: input.sequence
+ params:
+ keys: [66,36,61,34,87,79,82,76,68,34,13,80,82,73,78,84,32,65,36,43,34,50,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_direct_string_after_second_allocation
+ type: assert.screen
+ params:
+ contains: "HELLO2"
+ - id: dump_direct_string_after_resume
+ type: dump.memory_ranges
+ params:
+ ranges: *state_ranges
+ - id: reset_after_direct_string_case
+ type: input.sequence
+ params:
+ keys: [78,69,87,13,80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+
+ - id: type_multiline_program
+ type: input.sequence
+ params:
+ keys: [49,48,32,80,82,73,78,84,32,34,72,69,76,76,79,34,13,50,48,32,80,82,73,78,84,32,34,66,34,13,51,48,32,80,82,73,78,84,32,34,67,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.5
+ - id: list_multiline_before_exit
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_multiline_before_exit
+ type: assert.screen
+ params:
+ contains: "30 PRINT"
+ - id: exit_multiline
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_multiline_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: resume_multiline
+ type: input.sequence
+ params:
+ keys: [13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: wait_prompt_after_multiline_resume
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 30
+ - id: list_multiline_after_resume
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: capture_multiline_after_resume
+ type: screen.capture
+ params:
+ label: multiline_after_resume
+ - id: assert_multiline_after_resume
+ type: assert.screen
+ params:
+ contains: "30 PRINT"
+ - id: dump_multiline_after_resume
+ type: dump.memory_ranges
+ params:
+ ranges: *state_ranges
+
+ - id: new_and_clear_screen
+ type: input.sequence
+ params:
+ keys: [78,69,87,13,80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: list_after_new
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_new_empty
+ type: assert.screen_not_contains
+ params:
+ not_contains: "10 PRINT"
+ - id: exit_after_new
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_new_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: resume_after_new
+ type: input.sequence
+ params:
+ keys: [13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: wait_prompt_after_new_resume
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 30
+ - id: clear_and_list_after_new_resume
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_new_still_empty
+ type: assert.screen_not_contains
+ params:
+ not_contains: "10 PRINT"
+
+ - id: type_variable_program
+ type: input.sequence
+ params:
+ keys: [49,48,32,65,61,52,50,13,50,48,32,66,36,61,34,89,79,34,13,51,48,32,68,73,77,32,88,40,50,41,13,52,48,32,88,40,49,41,61,55,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: print_variables_before_exit
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,13,80,82,73,78,84,32,66,36,13,80,82,73,78,84,32,88,40,49,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_variables_before_exit
+ type: assert.screen
+ params:
+ contains: "YO"
+ - id: exit_variables
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_variables_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: resume_variables
+ type: input.sequence
+ params:
+ keys: [13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: wait_prompt_after_variables_resume
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 30
+ - id: print_variables_after_resume
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,13,80,82,73,78,84,32,66,36,13,80,82,73,78,84,32,88,40,49,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_string_after_resume
+ type: assert.screen
+ params:
+ contains: "YO"
+ - id: assert_numeric_after_resume
+ type: assert.screen
+ params:
+ contains: "42"
+ - id: clr_then_list
+ type: input.sequence
+ params:
+ keys: [67,76,82,13,80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_clr_keeps_program
+ type: assert.screen
+ params:
+ contains: "40 X"
+
+ - id: new_rb_program
+ type: input.sequence
+ params:
+ keys: [78,69,87,13,49,48,32,80,82,73,78,84,32,34,65,34,13,50,48,32,65,37,61,90,65,68,68,49,54,40,53,44,49,48,41,13,51,48,32,80,82,73,78,84,32,34,83,65,68,68,34,59,65,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_rb_program_output
+ type: assert.screen
+ params:
+ contains: "SADD 15"
+ - id: exit_rb_program
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_rb_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: resume_rb_program
+ type: input.sequence
+ params:
+ keys: [13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: wait_prompt_after_rb_resume
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 30
+ - id: list_rb_after_resume
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_rb_line_after_resume
+ type: assert.screen
+ params:
+ contains: "20 A%=ZADD16"
+ - id: dump_final_state
+ type: dump.memory_ranges
+ params:
+ ranges: *state_ranges
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_state_probe.regular.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_state_probe.regular.yaml
new file mode 100644
index 0000000..926c839
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readybasic_state_probe.regular.yaml
@@ -0,0 +1,335 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_state_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5l-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "readybasic"
+ wait_timeout_s: 180
+ capture_label: readybasic_prompt
+ - id: dump_initial_state
+ type: dump.memory_ranges
+ params:
+ ranges: &state_ranges
+ - { label: basic_zp_002b, start: 0x002B, end: 0x003F }
+ - { label: chrget_0073, start: 0x0073, end: 0x008A }
+ - { label: stack_0100, start: 0x0100, end: 0x01FF }
+ - { label: basic_text_1200, start: 0x1200, end: 0x1300 }
+ - { label: runtime_9500, start: 0x9500, end: 0x9A00 }
+ - { label: bridge_c000, start: 0xC000, end: 0xC5FF }
+ - { label: screen_0400, start: 0x0400, end: 0x07E7 }
+
+ - id: direct_string_assignment
+ type: input.sequence
+ params:
+ keys: [78,69,87,13,65,36,61,34,72,69,76,76,79,34,13,80,82,73,78,84,32,65,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_direct_string_before_exit
+ type: assert.screen
+ params:
+ contains: "HELLO"
+ - id: dump_direct_string_before_exit
+ type: dump.memory_ranges
+ params:
+ ranges: *state_ranges
+ - id: exit_direct_string
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_direct_string_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: resume_direct_string
+ type: input.sequence
+ params:
+ keys: [13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: wait_prompt_after_direct_string_resume
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 30
+ - id: print_direct_string_after_resume
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,36,43,34,33,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_direct_string_after_resume
+ type: assert.screen
+ params:
+ contains: "HELLO!"
+ - id: allocate_second_direct_string
+ type: input.sequence
+ params:
+ keys: [66,36,61,34,87,79,82,76,68,34,13,80,82,73,78,84,32,65,36,43,34,50,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_direct_string_after_second_allocation
+ type: assert.screen
+ params:
+ contains: "HELLO2"
+ - id: dump_direct_string_after_resume
+ type: dump.memory_ranges
+ params:
+ ranges: *state_ranges
+ - id: reset_after_direct_string_case
+ type: input.sequence
+ params:
+ keys: [78,69,87,13,80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+
+ - id: type_multiline_program
+ type: input.sequence
+ params:
+ keys: [49,48,32,80,82,73,78,84,32,34,72,69,76,76,79,34,13,50,48,32,80,82,73,78,84,32,34,66,34,13,51,48,32,80,82,73,78,84,32,34,67,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.5
+ - id: list_multiline_before_exit
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_multiline_before_exit
+ type: assert.screen
+ params:
+ contains: "30 PRINT"
+ - id: exit_multiline
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_multiline_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: resume_multiline
+ type: input.sequence
+ params:
+ keys: [13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: wait_prompt_after_multiline_resume
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 30
+ - id: list_multiline_after_resume
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: capture_multiline_after_resume
+ type: screen.capture
+ params:
+ label: multiline_after_resume
+ - id: assert_multiline_after_resume
+ type: assert.screen
+ params:
+ contains: "30 PRINT"
+ - id: dump_multiline_after_resume
+ type: dump.memory_ranges
+ params:
+ ranges: *state_ranges
+
+ - id: new_and_clear_screen
+ type: input.sequence
+ params:
+ keys: [78,69,87,13,80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: list_after_new
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_new_empty
+ type: assert.screen_not_contains
+ params:
+ not_contains: "10 PRINT"
+ - id: exit_after_new
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_new_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: resume_after_new
+ type: input.sequence
+ params:
+ keys: [13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: wait_prompt_after_new_resume
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 30
+ - id: clear_and_list_after_new_resume
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_new_still_empty
+ type: assert.screen_not_contains
+ params:
+ not_contains: "10 PRINT"
+
+ - id: type_variable_program
+ type: input.sequence
+ params:
+ keys: [49,48,32,65,61,52,50,13,50,48,32,66,36,61,34,89,79,34,13,51,48,32,68,73,77,32,88,40,50,41,13,52,48,32,88,40,49,41,61,55,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: print_variables_before_exit
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,13,80,82,73,78,84,32,66,36,13,80,82,73,78,84,32,88,40,49,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_variables_before_exit
+ type: assert.screen
+ params:
+ contains: "YO"
+ - id: exit_variables
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_variables_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: resume_variables
+ type: input.sequence
+ params:
+ keys: [13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: wait_prompt_after_variables_resume
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 30
+ - id: print_variables_after_resume
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,65,13,80,82,73,78,84,32,66,36,13,80,82,73,78,84,32,88,40,49,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_string_after_resume
+ type: assert.screen
+ params:
+ contains: "YO"
+ - id: assert_numeric_after_resume
+ type: assert.screen
+ params:
+ contains: "42"
+ - id: clr_then_list
+ type: input.sequence
+ params:
+ keys: [67,76,82,13,80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_clr_keeps_program
+ type: assert.screen
+ params:
+ contains: "40 X"
+
+ - id: new_rb_program
+ type: input.sequence
+ params:
+ keys: [78,69,87,13,49,48,32,80,82,73,78,84,32,34,65,34,13,50,48,32,65,37,61,90,65,68,68,49,54,40,53,44,49,48,41,13,51,48,32,80,82,73,78,84,32,34,83,65,68,68,34,59,65,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_rb_program_output
+ type: assert.screen
+ params:
+ contains: "SADD 15"
+ - id: exit_rb_program
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_rb_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: resume_rb_program
+ type: input.sequence
+ params:
+ keys: [13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: wait_prompt_after_rb_resume
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 30
+ - id: list_rb_after_resume
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_rb_line_after_resume
+ type: assert.screen
+ params:
+ contains: "20 A%=ZADD16"
+ - id: dump_final_state
+ type: dump.memory_ranges
+ params:
+ ranges: *state_ranges
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64 b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64
new file mode 100644
index 0000000..da92db2
Binary files /dev/null and b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64 differ
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readyshell_cross_app_resume_probe.easyflash.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readyshell_cross_app_resume_probe.easyflash.yaml
new file mode 100644
index 0000000..eaa3bd0
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readyshell_cross_app_resume_probe.easyflash.yaml
@@ -0,0 +1,204 @@
+version: 1
+kind: vice_task_plan
+plan_id: readyshell_cross_app_resume_probe_easyflash
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 240
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.4/precog-easyflash/readyos_easyflash.crt"
+ autostart_enabled: false
+ disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
+ drive8_enabled: true
+ drive8_type: 1541
+ drive9_enabled: false
+ true_drive: true
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: easyflash_wait_launcher
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ pre_delay_s: 4
+ poll_s: 0.5
+ wait_timeout_s: 240
+ capture_label: easyflash_editor_launcher
+ - id: easyflash_start_editor
+ type: input.sequence
+ params:
+ keys: [13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_editor_initial
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 180
+ capture_label: editor_initial
+ - id: editor_touch_1
+ type: input.sequence
+ params:
+ keys: [82,69,65,68,89,83,72,69,76,76,32,80,82,79,66,69,32,69,68,73,84,79,82,32,76,69,71,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.8
+ - id: ctrl_b_editor_to_launcher_1
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_1
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_editor_to_readybasic_1
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_from_editor_1
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_from_editor_1
+ - id: readybasic_touch_1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,82,66,79,75,34,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.8
+ - id: assert_readybasic_touch_1
+ type: assert.screen
+ params:
+ contains: "RBOK"
+ - id: exit_readybasic_1
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 1.0
+ - id: wait_launcher_after_readybasic_1
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_readybasic_to_editor_1
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_after_readybasic_1
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ capture_label: editor_after_readybasic_1
+ - id: ctrl_b_editor_to_launcher_before_readyshell_1
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_before_readyshell_1
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_editor_to_readyshell_1
+ type: input.sequence
+ params:
+ keys: [17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readyshell_loaded_from_editor_1
+ type: screen.wait_contains
+ params:
+ text: "run: cat"
+ wait_timeout_s: 90
+ capture_label: readyshell_from_editor_1
+ - id: readyshell_ver_from_editor_1
+ type: input.sequence
+ params:
+ keys: [86,69,82,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 1.0
+ - id: assert_readyshell_ver_from_editor_1
+ type: assert.screen
+ params:
+ contains: "version 0.2"
+ - id: readyshell_lst_from_editor_1
+ type: input.sequence
+ params:
+ keys: [76,83,84,32,34,82,83,72,69,76,80,34,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 2.0
+ - id: wait_readyshell_lst_result_from_editor_1
+ type: screen.wait_contains
+ params:
+ text: "BLOCKS"
+ wait_timeout_s: 60
+ - id: readyshell_ver_after_lst_from_editor_1
+ type: input.sequence
+ params:
+ keys: [86,69,82,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 1.0
+ - id: assert_readyshell_ver_after_lst_from_editor_1
+ type: assert.screen
+ params:
+ contains: "version 0.2"
+ - id: readyshell_cat_from_editor_1
+ type: input.sequence
+ params:
+ keys: [67,65,84,32,34,82,83,72,69,76,80,34,32,33,32,84,79,80,32,49,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 2.0
+ - id: capture_readyshell_cat_from_editor_1
+ type: screen.capture
+ params:
+ label: readyshell_cat_from_editor_1
+ - id: wait_readyshell_cat_result_from_editor_1
+ type: screen.wait_contains
+ params:
+ text: "readyshell quick ref"
+ wait_timeout_s: 60
+ - id: readyshell_ver_after_cat_from_editor_1
+ type: input.sequence
+ params:
+ keys: [86,69,82,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 1.0
+ - id: assert_readyshell_ver_after_cat_from_editor_1
+ type: assert.screen
+ params:
+ contains: "version 0.2"
+ - id: dump_final_state
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: launcher_shim_c800, start: 0xC800, end: 0xCA00 }
+ - { label: app_work_1000, start: 0x1000, end: 0x1800 }
+ - { label: upper_app_a000, start: 0xA000, end: 0xC600 }
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readyshell_cross_app_resume_probe.regular.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readyshell_cross_app_resume_probe.regular.yaml
new file mode 100644
index 0000000..cc1a63d
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_full_vice_plans/readyshell_cross_app_resume_probe.regular.yaml
@@ -0,0 +1,189 @@
+version: 1
+kind: vice_task_plan
+plan_id: readyshell_cross_app_resume_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 240
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4-d81.d81"
+ disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4-d81.d81"
+ autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_editor_initial
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 180
+ capture_label: editor_initial
+ - id: editor_touch_1
+ type: input.sequence
+ params:
+ keys: [82,69,65,68,89,83,72,69,76,76,32,80,82,79,66,69,32,69,68,73,84,79,82,32,76,69,71,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.8
+ - id: ctrl_b_editor_to_launcher_1
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_1
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_editor_to_readybasic_1
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_from_editor_1
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_from_editor_1
+ - id: readybasic_touch_1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,82,66,79,75,34,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 0.8
+ - id: assert_readybasic_touch_1
+ type: assert.screen
+ params:
+ contains: "RBOK"
+ - id: exit_readybasic_1
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 1.0
+ - id: wait_launcher_after_readybasic_1
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_readybasic_to_editor_1
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_after_readybasic_1
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ capture_label: editor_after_readybasic_1
+ - id: ctrl_b_editor_to_launcher_before_readyshell_1
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_before_readyshell_1
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ - id: move_editor_to_readyshell_1
+ type: input.sequence
+ params:
+ keys: [17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readyshell_loaded_from_editor_1
+ type: screen.wait_contains
+ params:
+ text: "run: cat"
+ wait_timeout_s: 90
+ capture_label: readyshell_from_editor_1
+ - id: readyshell_ver_from_editor_1
+ type: input.sequence
+ params:
+ keys: [86,69,82,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 1.0
+ - id: assert_readyshell_ver_from_editor_1
+ type: assert.screen
+ params:
+ contains: "version 0.2"
+ - id: readyshell_lst_from_editor_1
+ type: input.sequence
+ params:
+ keys: [76,83,84,32,34,82,83,72,69,76,80,34,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 2.0
+ - id: wait_readyshell_lst_result_from_editor_1
+ type: screen.wait_contains
+ params:
+ text: "BLOCKS"
+ wait_timeout_s: 60
+ - id: readyshell_ver_after_lst_from_editor_1
+ type: input.sequence
+ params:
+ keys: [86,69,82,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 1.0
+ - id: assert_readyshell_ver_after_lst_from_editor_1
+ type: assert.screen
+ params:
+ contains: "version 0.2"
+ - id: readyshell_cat_from_editor_1
+ type: input.sequence
+ params:
+ keys: [67,65,84,32,34,82,83,72,69,76,80,34,32,33,32,84,79,80,32,49,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 2.0
+ - id: capture_readyshell_cat_from_editor_1
+ type: screen.capture
+ params:
+ label: readyshell_cat_from_editor_1
+ - id: wait_readyshell_cat_result_from_editor_1
+ type: screen.wait_contains
+ params:
+ text: "readyshell quick ref"
+ wait_timeout_s: 60
+ - id: readyshell_ver_after_cat_from_editor_1
+ type: input.sequence
+ params:
+ keys: [86,69,82,13]
+ inter_key_delay_s: 0.035
+ post_delay_s: 1.0
+ - id: assert_readyshell_ver_after_cat_from_editor_1
+ type: assert.screen
+ params:
+ contains: "version 0.2"
+ - id: dump_final_state
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: launcher_shim_c800, start: 0xC800, end: 0xCA00 }
+ - { label: app_work_1000, start: 0x1000, end: 0x1800 }
+ - { label: upper_app_a000, start: 0xA000, end: 0xC600 }
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_hotkey_probe/readybasic_hotkey_f2_probe.easyflash.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_hotkey_probe/readybasic_hotkey_f2_probe.easyflash.yaml
new file mode 100644
index 0000000..9dba2b7
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_hotkey_probe/readybasic_hotkey_f2_probe.easyflash.yaml
@@ -0,0 +1,68 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_hotkey_f2_probe_easyflash
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
+ autostart_enabled: false
+ disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_hotkey_probe/readyos_data.easyflash-vice.d64"
+ drive8_enabled: true
+ drive8_type: 1541
+ drive9_enabled: false
+ true_drive: true
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: easyflash_wait_launcher
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ pre_delay_s: 4
+ poll_s: 0.5
+ wait_timeout_s: 240
+ capture_label: easyflash_readybasic_launcher
+ - id: easyflash_start_readybasic
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "readybasic"
+ wait_timeout_s: 180
+ capture_label: readybasic_hotkey_f2_prompt
+ - id: f2_to_next_loaded_app
+ type: input.sequence
+ params:
+ keys: [80,79,75,69,32,52,57,53,51,49,44,49,51,55,13,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: wait_target_after_f2
+ type: screen.wait_contains
+ params:
+ text: "CALENDAR 26"
+ wait_timeout_s: 60
+ capture_label: target_after_readybasic_f2
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_hotkey_probe/readybasic_hotkey_f2_probe.regular.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_hotkey_probe/readybasic_hotkey_f2_probe.regular.yaml
new file mode 100644
index 0000000..24e3a0a
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_hotkey_probe/readybasic_hotkey_f2_probe.regular.yaml
@@ -0,0 +1,53 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_hotkey_f2_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5j-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5j-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5j-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "readybasic"
+ wait_timeout_s: 180
+ capture_label: readybasic_hotkey_f2_prompt
+ - id: f2_to_next_loaded_app
+ type: input.sequence
+ params:
+ keys: [80,79,75,69,32,52,57,53,51,49,44,49,51,55,13,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: wait_target_after_f2
+ type: screen.wait_contains
+ params:
+ text: "CALENDAR 26"
+ wait_timeout_s: 60
+ capture_label: target_after_readybasic_f2
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_hotkey_probe/readybasic_hotkey_f4_probe.easyflash.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_hotkey_probe/readybasic_hotkey_f4_probe.easyflash.yaml
new file mode 100644
index 0000000..6e505aa
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_hotkey_probe/readybasic_hotkey_f4_probe.easyflash.yaml
@@ -0,0 +1,138 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_hotkey_probe_easyflash
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
+ autostart_enabled: false
+ disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_hotkey_probe/readyos_data.easyflash-vice.d64"
+ drive8_enabled: true
+ drive8_type: 1541
+ drive9_enabled: false
+ true_drive: true
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: easyflash_wait_launcher
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ pre_delay_s: 4
+ poll_s: 0.5
+ wait_timeout_s: 240
+ capture_label: easyflash_readybasic_launcher
+ - id: easyflash_start_readybasic
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "readybasic"
+ wait_timeout_s: 180
+ capture_label: readybasic_hotkey_prompt
+ - id: seed_readybasic_state
+ type: input.sequence
+ params:
+ keys: [86,37,61,51,50,49,58,86,83,36,61,34,72,79,84,34,13,80,82,73,78,84,32,34,72,79,84,83,69,69,68,34,59,86,37,59,34,58,34,59,86,83,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_seed_state
+ type: assert.screen
+ params:
+ contains: "HOTSEED 321 :HOT"
+ - id: ctrl_b_from_readybasic
+ type: input.sequence
+ params:
+ # input.sequence pokes the KERNAL keyboard buffer, so it cannot emulate
+ # the physical KEYLOG hook. POKE the same pending action byte KEYLOG sets,
+ # then send a blank Return to unwind the BASIC editor.
+ keys: [80,79,75,69,32,52,57,53,51,49,44,50,13,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ capture_label: launcher_after_readybasic_ctrl_b
+ - id: move_readybasic_to_editor
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_loaded
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ capture_label: editor_loaded_for_hotkey_probe
+ - id: ctrl_b_from_editor
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ - id: move_editor_to_readybasic_for_f4
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_resume_for_f4
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_resume_before_f4
+ - id: assert_readybasic_state_after_ctrl_b
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,72,79,84,83,84,65,84,69,34,59,86,37,59,34,58,34,59,86,83,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_hot_state_after_ctrl_b
+ type: assert.screen
+ params:
+ contains: "HOTSTATE 321 :HOT"
+ - id: f4_to_prev_loaded_app
+ type: input.sequence
+ params:
+ keys: [80,79,75,69,32,52,57,53,51,49,44,49,51,56,13,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: wait_target_after_f4
+ type: screen.wait_contains
+ params:
+ text: "CLIPBOARD"
+ wait_timeout_s: 60
+ capture_label: target_after_readybasic_f4
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_hotkey_probe/readybasic_hotkey_f4_probe.regular.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_hotkey_probe/readybasic_hotkey_f4_probe.regular.yaml
new file mode 100644
index 0000000..8ae4998
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_hotkey_probe/readybasic_hotkey_f4_probe.regular.yaml
@@ -0,0 +1,123 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_hotkey_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5j-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5j-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5j-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "readybasic"
+ wait_timeout_s: 180
+ capture_label: readybasic_hotkey_prompt
+ - id: seed_readybasic_state
+ type: input.sequence
+ params:
+ keys: [86,37,61,51,50,49,58,86,83,36,61,34,72,79,84,34,13,80,82,73,78,84,32,34,72,79,84,83,69,69,68,34,59,86,37,59,34,58,34,59,86,83,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_seed_state
+ type: assert.screen
+ params:
+ contains: "HOTSEED 321 :HOT"
+ - id: ctrl_b_from_readybasic
+ type: input.sequence
+ params:
+ # input.sequence pokes the KERNAL keyboard buffer, so it cannot emulate
+ # the physical KEYLOG hook. POKE the same pending action byte KEYLOG sets,
+ # then send a blank Return to unwind the BASIC editor.
+ keys: [80,79,75,69,32,52,57,53,51,49,44,50,13,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ capture_label: launcher_after_readybasic_ctrl_b
+ - id: move_readybasic_to_editor
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_loaded
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ capture_label: editor_loaded_for_hotkey_probe
+ - id: ctrl_b_from_editor
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ - id: move_editor_to_readybasic_for_f4
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_resume_for_f4
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_resume_before_f4
+ - id: assert_readybasic_state_after_ctrl_b
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,72,79,84,83,84,65,84,69,34,59,86,37,59,34,58,34,59,86,83,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_hot_state_after_ctrl_b
+ type: assert.screen
+ params:
+ contains: "HOTSTATE 321 :HOT"
+ - id: f4_to_prev_loaded_app
+ type: input.sequence
+ params:
+ keys: [80,79,75,69,32,52,57,53,51,49,44,49,51,56,13,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: wait_target_after_f4
+ type: screen.wait_contains
+ params:
+ text: "CLIPBOARD"
+ wait_timeout_s: 60
+ capture_label: target_after_readybasic_f4
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_hotkey_probe/readybasic_hotkey_probe.easyflash.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_hotkey_probe/readybasic_hotkey_probe.easyflash.yaml
new file mode 100644
index 0000000..18e9ac6
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_hotkey_probe/readybasic_hotkey_probe.easyflash.yaml
@@ -0,0 +1,174 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_hotkey_probe_easyflash
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
+ autostart_enabled: false
+ disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_hotkey_probe/readyos_data.easyflash-vice.d64"
+ drive8_enabled: true
+ drive8_type: 1541
+ drive9_enabled: false
+ true_drive: true
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: easyflash_wait_launcher
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ pre_delay_s: 4
+ poll_s: 0.5
+ wait_timeout_s: 240
+ capture_label: easyflash_readybasic_launcher
+ - id: easyflash_start_readybasic
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "readybasic"
+ wait_timeout_s: 180
+ capture_label: readybasic_hotkey_prompt
+ - id: seed_readybasic_state
+ type: input.sequence
+ params:
+ keys: [86,37,61,51,50,49,58,86,83,36,61,34,72,79,84,34,13,80,82,73,78,84,32,34,72,79,84,83,69,69,68,34,59,86,37,59,34,58,34,59,86,83,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_seed_state
+ type: assert.screen
+ params:
+ contains: "HOTSEED 321 :HOT"
+ - id: ctrl_b_from_readybasic
+ type: input.sequence
+ params:
+ # input.sequence pokes the KERNAL keyboard buffer, so it cannot emulate
+ # the physical KEYLOG hook. POKE the same pending action byte KEYLOG sets,
+ # then send a blank Return to unwind the BASIC editor.
+ keys: [80,79,75,69,32,52,57,53,51,49,44,50,13,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ capture_label: launcher_after_readybasic_ctrl_b
+ - id: move_readybasic_to_editor
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_loaded
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ capture_label: editor_loaded_for_hotkey_probe
+ - id: ctrl_b_from_editor
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ - id: move_editor_to_readybasic_for_f4
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_resume_for_f4
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_resume_before_f4
+ - id: assert_readybasic_state_after_ctrl_b
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,72,79,84,83,84,65,84,69,34,59,86,37,59,34,58,34,59,86,83,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_hot_state_after_ctrl_b
+ type: assert.screen
+ params:
+ contains: "HOTSTATE 321 :HOT"
+ - id: f4_to_prev_loaded_app
+ type: input.sequence
+ params:
+ keys: [80,79,75,69,32,52,57,53,51,49,44,49,51,56,13,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: wait_target_after_f4
+ type: screen.wait_contains
+ params:
+ text: "CLIPBOARD"
+ wait_timeout_s: 60
+ capture_label: target_after_readybasic_f4
+ - id: relaunch_easyflash_for_f2
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_easyflash_launcher_for_f2
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ pre_delay_s: 4
+ poll_s: 0.5
+ wait_timeout_s: 240
+ capture_label: easyflash_readybasic_launcher_for_f2
+ - id: start_readybasic_for_f2
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_resume_for_f2
+ type: screen.wait_contains
+ params:
+ text: "readybasic"
+ wait_timeout_s: 180
+ capture_label: readybasic_resume_before_f2
+ - id: f2_to_next_loaded_app
+ type: input.sequence
+ params:
+ keys: [80,79,75,69,32,52,57,53,51,49,44,49,51,55,13,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: wait_target_after_f2
+ type: screen.wait_contains
+ params:
+ text: "CALENDAR 26"
+ wait_timeout_s: 60
+ capture_label: target_after_readybasic_f2
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_hotkey_probe/readybasic_hotkey_probe.regular.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_hotkey_probe/readybasic_hotkey_probe.regular.yaml
new file mode 100644
index 0000000..b02df9c
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_hotkey_probe/readybasic_hotkey_probe.regular.yaml
@@ -0,0 +1,159 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_hotkey_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5j-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5j-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5j-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "readybasic"
+ wait_timeout_s: 180
+ capture_label: readybasic_hotkey_prompt
+ - id: seed_readybasic_state
+ type: input.sequence
+ params:
+ keys: [86,37,61,51,50,49,58,86,83,36,61,34,72,79,84,34,13,80,82,73,78,84,32,34,72,79,84,83,69,69,68,34,59,86,37,59,34,58,34,59,86,83,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_seed_state
+ type: assert.screen
+ params:
+ contains: "HOTSEED 321 :HOT"
+ - id: ctrl_b_from_readybasic
+ type: input.sequence
+ params:
+ # input.sequence pokes the KERNAL keyboard buffer, so it cannot emulate
+ # the physical KEYLOG hook. POKE the same pending action byte KEYLOG sets,
+ # then send a blank Return to unwind the BASIC editor.
+ keys: [80,79,75,69,32,52,57,53,51,49,44,50,13,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ capture_label: launcher_after_readybasic_ctrl_b
+ - id: move_readybasic_to_editor
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_loaded
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ capture_label: editor_loaded_for_hotkey_probe
+ - id: ctrl_b_from_editor
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ - id: move_editor_to_readybasic_for_f4
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_resume_for_f4
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_resume_before_f4
+ - id: assert_readybasic_state_after_ctrl_b
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,72,79,84,83,84,65,84,69,34,59,86,37,59,34,58,34,59,86,83,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_hot_state_after_ctrl_b
+ type: assert.screen
+ params:
+ contains: "HOTSTATE 321 :HOT"
+ - id: f4_to_prev_loaded_app
+ type: input.sequence
+ params:
+ keys: [80,79,75,69,32,52,57,53,51,49,44,49,51,56,13,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: wait_target_after_f4
+ type: screen.wait_contains
+ params:
+ text: "CLIPBOARD"
+ wait_timeout_s: 60
+ capture_label: target_after_readybasic_f4
+ - id: relaunch_easyflash_for_f2
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_easyflash_launcher_for_f2
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ pre_delay_s: 4
+ poll_s: 0.5
+ wait_timeout_s: 240
+ capture_label: easyflash_readybasic_launcher_for_f2
+ - id: start_readybasic_for_f2
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_resume_for_f2
+ type: screen.wait_contains
+ params:
+ text: "readybasic"
+ wait_timeout_s: 180
+ capture_label: readybasic_resume_before_f2
+ - id: f2_to_next_loaded_app
+ type: input.sequence
+ params:
+ keys: [80,79,75,69,32,52,57,53,51,49,44,49,51,55,13,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: wait_target_after_f2
+ type: screen.wait_contains
+ params:
+ text: "CALENDAR 26"
+ wait_timeout_s: 60
+ capture_label: target_after_readybasic_f2
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_hotkey_probe/readyos_data.easyflash-vice.d64 b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_hotkey_probe/readyos_data.easyflash-vice.d64
new file mode 100644
index 0000000..61aa86d
Binary files /dev/null and b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_hotkey_probe/readyos_data.easyflash-vice.d64 differ
diff --git a/agentworking/easyflash_launcher_probes/easyflash_readybasic_from_launcher.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_launcher_probes/easyflash_readybasic_from_launcher.yaml
similarity index 100%
rename from agentworking/easyflash_launcher_probes/easyflash_readybasic_from_launcher.yaml
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_launcher_probes/easyflash_readybasic_from_launcher.yaml
diff --git a/agentworking/easyflash_launcher_probes/easyflash_readyshell_from_launcher.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_launcher_probes/easyflash_readyshell_from_launcher.yaml
similarity index 100%
rename from agentworking/easyflash_launcher_probes/easyflash_readyshell_from_launcher.yaml
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_launcher_probes/easyflash_readyshell_from_launcher.yaml
diff --git a/agentworking/easyflash_vice_suite_refactor_notes.md b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_vice_suite_refactor_notes.md
similarity index 100%
rename from agentworking/easyflash_vice_suite_refactor_notes.md
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/easyflash_vice_suite_refactor_notes.md
diff --git a/agentworking/launcher_current_reu_map.png b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/launcher_current_reu_map.png
similarity index 100%
rename from agentworking/launcher_current_reu_map.png
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/launcher_current_reu_map.png
diff --git a/agentworking/launcher_reu_slot_headroom_after.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/launcher_reu_slot_headroom_after.json
similarity index 100%
rename from agentworking/launcher_reu_slot_headroom_after.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/launcher_reu_slot_headroom_after.json
diff --git a/agentworking/launcher_reu_slot_headroom_after_regular.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/launcher_reu_slot_headroom_after_regular.json
similarity index 100%
rename from agentworking/launcher_reu_slot_headroom_after_regular.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/launcher_reu_slot_headroom_after_regular.json
diff --git a/agentworking/launcher_reu_slot_headroom_before.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/launcher_reu_slot_headroom_before.json
similarity index 100%
rename from agentworking/launcher_reu_slot_headroom_before.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/launcher_reu_slot_headroom_before.json
diff --git a/agentworking/launcher_reu_slot_headroom_before_regular.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/launcher_reu_slot_headroom_before_regular.json
similarity index 100%
rename from agentworking/launcher_reu_slot_headroom_before_regular.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/launcher_reu_slot_headroom_before_regular.json
diff --git a/agentworking/launcher_screenshot_easyflash.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/launcher_screenshot_easyflash.yaml
similarity index 100%
rename from agentworking/launcher_screenshot_easyflash.yaml
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/launcher_screenshot_easyflash.yaml
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/launchers/launch_regular_d81_fast.command b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/launchers/launch_regular_d81_fast.command
new file mode 100755
index 0000000..575dad1
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/launchers/launch_regular_d81_fast.command
@@ -0,0 +1,3 @@
+#!/bin/bash
+cd /Users/karlprosserpp/dev/c64projects/readyosprecog || exit 1
+exec ./run.sh --profile precog-d81 --vice-fast
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/PLAN.md b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/PLAN.md
new file mode 100644
index 0000000..7cb184a
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/PLAN.md
@@ -0,0 +1,111 @@
+# ReadyBASIC Hotkey Timing Fix Plan
+
+## Objective
+
+Make ReadyBASIC honor `Ctrl+B`, `F2`, and `F4` immediately when pressed at the prompt, after/during `LIST`, and across app round trips. The fix must call the same suspend/yield/switch machinery used by `EXIT` without injecting the text command `EXIT`.
+
+## Non-Negotiable Acceptance Criteria
+
+- No hotkey may be delayed until a later command, `LIST`, or Return.
+- No hotkey byte may remain in `KEYD_COUNT` / `KEYD_BUFFER`.
+- `Ctrl+B` from ReadyBASIC returns to launcher.
+- `F2` and `F4` from ReadyBASIC switch to the expected loaded apps.
+- Round trips through at least Editor and one non-editor app preserve behavior.
+- Hotkeys remain disabled during actual BASIC program execution, but work during prompt editing and `LIST` output.
+- Empty BASIC free bytes do not regress.
+- Visible resident code does not overlap `$2AC0` / `$2AC1`.
+- `$A000-$A7FF` helper budget deltas are measured and documented.
+- Focused key-path tests pass before full regular and EasyFlash suites are run.
+
+## Current Lessons
+
+- Poking `rb_hotkey_pending` proves only the yield plumbing. It is not a hotkey test.
+- Poking `$0277/$00C6` proves only artificial keyboard-buffer behavior. It is not the same as the existing app automation path.
+- VICE `input.sequence` with `keys: [2]`, `[137]`, and `[138]` is already a valid control path because other app tests use it successfully for `Ctrl+B`, `F2`, and `F4`.
+- The focused proof must compare ReadyBASIC against a known-good app in the same run: same image, same app-entry delay, same key bytes. If Editor/another app switches and ReadyBASIC does not, ReadyBASIC is broken.
+- GUI/host-key injection is not the primary proof path. It can stay optional/manual only if needed later.
+- Injecting `EXIT` is semantically wrong; hotkeys must call the internal suspend/yield/switch path directly.
+
+## Implementation Plan
+
+1. Stabilize the worktree.
+ - Preserve existing user/generated changes.
+ - Remove any temporary debug writes and failed diagnostic markers.
+ - Keep or replace harness changes only if they become part of the verified key-path proof.
+ - Record the exact starting diff and map in `agentworking/readybasic_hotkeys_fix/notes.md`.
+
+2. Build the correct ReadyBASIC hotkey service.
+ - Add one shared service routine for `Ctrl+B`, `F2`, and `F4`.
+ - The service drains `KEYD_COUNT` and clears any hotkey bytes in `$0277`.
+ - `Ctrl+B` calls the internal ready/exit yield path directly, not `EXIT` text injection.
+ - `F2`/`F4` call the hidden app selection helpers, then the normal shim switch path.
+ - Keep all final routines within the existing resident/hidden/bridge contracts.
+
+3. Choose safe polling points.
+ - First trace where the existing VICE app hotkey bytes enter ReadyBASIC:
+ - prompt input,
+ - KERNAL GETIN vector,
+ - KERNAL CHRIN vector,
+ - IRQ/CINV buffered key path,
+ - LIST output path.
+ - Service the hotkey at the first safe point that actually sees the same bytes other apps receive:
+ - prompt input / GETIN / CHRIN path,
+ - ReadyBASIC execute vector before ordinary statement dispatch,
+ - LIST/vector path if LIST bypasses the prompt input path.
+ - Do not depend on Return, `LIST`, or a later command to notice the pending action.
+ - Preserve the “disabled during actual RUN” guard with an explicit runtime-state check, not a prompt-only `TXTPTR < BASIC_START` check that breaks LIST.
+
+4. Add A/B VICE automation using the established app hotkey path.
+ - Use `input.sequence`, not `memory.write`, for accepted hotkey proof.
+ - Use the same byte values existing app automation uses:
+ - `Ctrl+B`: `keys: [2]`
+ - `F2`: `keys: [137]`
+ - `F4`: `keys: [138]`
+ - In one focused run, first enter Editor and one non-editor app, wait a couple seconds after app entry, then prove `Ctrl+B`, `F2`, and `F4` switch immediately there.
+ - Enter ReadyBASIC with the same pause and send the same hotkey bytes. ReadyBASIC must behave the same way.
+ - If the control apps pass and ReadyBASIC fails, treat that as conclusive ReadyBASIC failure, not a harness failure.
+
+5. Replace the focused ReadyBASIC hotkey probe.
+ - Remove `POKE rb_hotkey_pending` and `$0277/$00C6` hotkey simulation from acceptance tests.
+ - Use the same `input.sequence` key steps proven by the control app phase.
+ - Exercise:
+ - ReadyBASIC prompt -> `Ctrl+B` -> launcher.
+ - Launcher -> Editor -> launcher -> ReadyBASIC -> `Ctrl+B` again.
+ - ReadyBASIC `LIST` active/just completed -> `F4` -> previous app.
+ - Return to ReadyBASIC -> `F2` -> next app.
+ - Repeat with at least one non-editor app.
+ - After each hotkey transition assert:
+ - expected screen/app,
+ - `KEYD_COUNT == 0`,
+ - `$0277` does not contain `2`, `137`, or `138`,
+ - `rb_hotkey_pending == 0`,
+ - no delayed switch occurs after a harmless command such as `PRINT "QUEUEOK"` or `LIST`.
+
+6. Add negative RUN coverage.
+ - Start a BASIC program that loops or prints.
+ - Press `Ctrl+B`, `F2`, and `F4`.
+ - Assert no app switch occurs during actual program execution.
+ - Stop/return to prompt and assert hotkeys work again.
+
+7. Memory and size checks.
+ - Run `make readybasic-plugin-static-check`.
+ - Run `make readybasic-memory-report`.
+ - Record before/after map lines for `ENTRY`, `RESIDENT`, `HIDDEN`, `BRIDGE`.
+ - Record empty BASIC free bytes.
+ - Confirm resident end remains below `$2AC0`.
+ - Document any `$A000-$A7FF` delta.
+
+8. Full verification sequence.
+ - Focused matrix-smoke VICE test.
+ - Focused ReadyBASIC hotkey timing probe.
+ - `make readybasic-plugin-static-check`.
+ - `make readybasic-memory-report`.
+ - `make readybasic-vice-suites`.
+ - `make easyflash-readybasic-vice-suites`.
+ - Record every run directory in `agentworking/readybasic_hotkeys_fix/notes.md`.
+
+## Stop Conditions
+
+- Do not run full suites until the real key-path focused probe passes.
+- Do not declare success if the test uses `POKE rb_hotkey_pending`, `$0277/$00C6`, or `EXIT` injection as the final proof.
+- If VICE cannot automate real matrix key states locally, produce a clear blocked result with the matrix-smoke fixture evidence and keep the code changes out of “accepted” status.
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/hotkey_regular.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/hotkey_regular.yaml
new file mode 100644
index 0000000..55fa33f
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/hotkey_regular.yaml
@@ -0,0 +1,166 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_hotkey_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "readybasic"
+ wait_timeout_s: 180
+ capture_label: readybasic_hotkey_prompt
+ - id: assert_keyboard_state_not_vector_clobbered
+ type: assert.memory
+ params:
+ start: 788
+ end: 789
+ equals_hex: "07 01"
+ - id: seed_readybasic_state
+ type: input.sequence
+ params:
+ keys: [86,37,61,51,50,49,58,86,83,36,61,34,72,79,84,34,13,80,82,73,78,84,32,34,72,79,84,83,69,69,68,34,59,86,37,59,34,58,34,59,86,83,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_seed_state
+ type: assert.screen
+ params:
+ contains: "HOTSEED 321 :HOT"
+ - id: ctrl_b_from_readybasic
+ type: input.sequence
+ params:
+ # input.sequence pokes the KERNAL keyboard buffer, so it cannot emulate
+ # physical matrix timing. Assert CINV above, then POKE the same pending
+ # action byte the IRQ hook sets and send Return to unwind the editor.
+ keys: [80,79,75,69,32,52,57,53,51,49,44,50,13,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ capture_label: launcher_after_readybasic_ctrl_b
+ - id: move_readybasic_to_editor
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_loaded
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ capture_label: editor_loaded_for_hotkey_probe
+ - id: ctrl_b_from_editor
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ - id: move_editor_to_readybasic_for_f4
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_resume_for_f4
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_resume_before_f4
+ - id: assert_readybasic_state_after_ctrl_b
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,72,79,84,83,84,65,84,69,34,59,86,37,59,34,58,34,59,86,83,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_hot_state_after_ctrl_b
+ type: assert.screen
+ params:
+ contains: "HOTSTATE 321 :HOT"
+ - id: f4_to_prev_loaded_app
+ type: input.sequence
+ params:
+ keys: [80,79,75,69,32,52,57,53,51,49,44,49,51,56,13,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: wait_target_after_f4
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ capture_label: target_after_readybasic_f4
+ - id: ctrl_b_from_f4_target
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: wait_launcher_after_f4_target
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ - id: move_editor_to_readybasic_for_f2
+ type: input.sequence
+ params:
+ # F4 switched ReadyBASIC directly to another app, so the launcher's saved
+ # selection remains ReadyBASIC when that app returns via CTRL+B.
+ keys: [13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_resume_for_f2
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_resume_before_f2
+ - id: f2_to_next_loaded_app
+ type: input.sequence
+ params:
+ keys: [80,79,75,69,32,52,57,53,51,49,44,49,51,55,13,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: wait_target_after_f2
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ capture_label: target_after_readybasic_f2
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/notes.md b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/notes.md
new file mode 100644
index 0000000..a5bf3d0
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/notes.md
@@ -0,0 +1,188 @@
+# ReadyBASIC Hotkey Re-entry Scratch
+
+## 2026-06-10 field failure to reproduce
+
+- Rebuilt regular D81 still reports `0.2.5F`, but manual testing does not match the previous passing probes.
+- Entering another app and pressing F2 back into ReadyBASIC can leave the READY prompt blinking while typed letters, F2, and Ctrl+B are ignored.
+- A multi-hop chain can lock on the second F2; Ctrl+B may still return to the launcher from some states.
+- Typed `EXIT` after some re-entry paths can return to the launcher and then automatically re-enter ReadyBASIC, which means pending keyboard/editor state is not clean enough at yield.
+- The previous `readybasic_reuviewer_f2_chain_probe` rewrote `$C836-$C838` to only ReadyBASIC and REU Viewer before exercising F2. That can hide real app/resource bitmap selection failures and does not prove the full manual path.
+
+## Current acceptance bar
+
+- Prove ReadyBASIC remains keyboard-live after F2 from another ReadyOS app back into ReadyBASIC.
+- Prove ReadyBASIC F2/F4/Ctrl+B work after multiple ReadyBASIC app exits and re-entries.
+- Prove typed `EXIT` returns to the launcher and stays there until an explicit new selection.
+- Cover the same path in regular D81 and EasyFlash ReadyBASIC suites, without changing other apps or the shim unless the repro proves the contract itself is broken.
+- Keep the ReadyOS memory contract: no BASIC-start movement, no `$C800-$C9FF` assumptions beyond shim ABI, and no expansion into normal BASIC RAM.
+
+## 2026-06-10 implementation notes
+
+- Historical note: this pass used CINV `$0314/$0315` plus KEYLOG `$028F/$0290` and queued a visible `REM` line. The 2026-06-11 keyboard-regression pass below supersedes that design.
+- The earlier CINV path directly scanned CIA1 only for Ctrl+B, Shift+F1/F2, and Shift+F3/F4, restored the CIA scan-port state, recorded `rb_hotkey_pending`, and queued `REM` plus Return so BASIC reached the execute hook normally.
+- KEYLOG caught KERNAL-decoded special-key cases, consumed the key state, and preserved the CIA port state.
+- Every ReadyBASIC yield path clears `rb_hotkey_pending`, `$C6`, `$0277`, `SHFLAG`, `LSTX`, and `SFDX`; typed `EXIT` and Ctrl+B set the launcher suppress-startup flag so run-first configs do not auto-reenter ReadyBASIC.
+- F2/F4 store the selected target bank in `rb_hotkey_target_bank` before `prepare_shim_yield`, then write `$C820` only after hidden save, `CLRCHN`, and vector restore.
+- Double-switch follow-up: cold/warm entry now scans the physical matrix and quarantines any still-held ReadyBASIC hotkey until release. Prompt hotkey yield waits for the selected chord to release with a jiffy-clock timeout, then clears editor/KERNAL key state again.
+- The loaded-app scan uses the shim bitmap plus the control-bank app registry so ReadyBASIC resource/code banks do not look like app-switch targets.
+- Hidden helper warm restore comes from the assigned ReadyBASIC core bank shadow at `$3000`, not from a visible `$C280` shadow.
+
+## 2026-06-10 harness rules
+
+- Cold/first ReadyBASIC entry may wait for the `READYBASIC` title.
+- Warm entries must not rely on the title being present. The chain probe uses a small delay plus `ready.`, then proves the state with `$C834`, ReadyBASIC CHRIN/KEYLOG vectors, empty keyboard buffer, and an actual typed `PRINT` sentinel.
+- The boot screen can contain `ready.` text; do not use `ready.` as the only proof of ReadyBASIC entry.
+- In app context, VICE Binary `input.sequence` for Ctrl+B can drain `$C6` without exercising the app hotkey path. The focused chain uses monitor `keybuf \x02` for app Ctrl+B and normal function-key input for app F2.
+- Host-key mode is useful for manual-like proof but can fail on macOS automation permissions (`osascript is not allowed to send keystrokes`) independent of ReadyBASIC.
+
+## 2026-06-11 keyboard regression implementation notes
+
+- ReadyBASIC now owns prompt hotkeys only while the ROM editor is inside ReadyBASIC's CHRIN hook, input is from the keyboard, and BASIC is at a direct prompt.
+- KEYLOG `$028F/$0290` records Ctrl+B/F2/F4, consumes `SHFLAG`/`SFDX`, and queues only Return. It does not inject command text.
+- CHRIN `$0324/$0325` wraps original CHRIN, preserves ordinary `A` and status flags, then dispatches a pending hotkey before BASIC can store or execute a partial prompt line.
+- The hotkey gate should follow `TXTPTR < BASIC_START`, not `CURLIN`, so partially typed prompt lines stay eligible while RUN-mode input still stays out of scope.
+- The CINV/IRQ matrix scanner is not installed for prompt hotkeys. Ordinary typing, repeat timing, cursor state, and space handling remain owned by the ROM editor.
+- READY-mode hotkey yields force saved `RUNTIME_SP` to `$F8` instead of preserving transient CHRIN/editor stack depth.
+- Entry-time hotkey quarantine and yield-time release waits remain: cold/warm entry clears editor state and suppresses a still-held ReadyOS hotkey until release; accepted Ctrl+B/F2/F4 waits for the selected chord to release before yielding.
+- Focused regression coverage now includes `10`+Ctrl+B and `20`+F2 without storing partial lines, absence of visible `REM`, warp-mode single-space typing, normal typing after reentry, and app liveness after switch. The cartridge regression probe should keep the partial-line F2 case as a first-class check until it passes cleanly on both regular and EasyFlash builds.
+
+## Current memory/headroom
+
+- `BASIC_START` remains `$2AC1`; empty BASIC free bytes remain `30013`.
+- `ENTRY` is `$1000-$11FF`, `$0200` / 512B.
+- `RESIDENT` is `$1200-$2ABD`, `$18BE` / 6334B, leaving 2B before the `$2ABF` resident budget end and the `$2AC0` sentinel.
+- `HIDDEN` is `$A000-$A6E9`, `$06EA` / 1770B, leaving `$0116` / 278B in the 2K common helper area.
+- `BRIDGE` is `$C000-$C1FE`, `$01FF` / 511B, leaving 1B before `$C200`.
+- BASIC RAM contract is unchanged; the added cost is paid in entry/helper/bridge/resident bytes, not by moving BASIC start.
+
+## Proof run log
+
+- `make readybasic-plugin-static-check readybasic-memory-report`: passed after the hotkey implementation; regenerated `docs/readybasic_memory_diagrams.html`.
+- Focused regular D81 run-first chain: `/bin/bash build_support/run_readybasic_reuviewer_f2_chain_probe.sh` passed, manifest `logs/vice_auto_20260610_181217/manifest.json`, `failed_step=null`, `degraded_steps=[]`.
+- Focused regular D81 keylog/monitor chain: `READYBASIC_SKIP_BUILD=1 READYBASIC_HOTKEY_INPUT_MODE=keylog /bin/bash build_support/run_readybasic_reuviewer_f2_chain_probe.sh` passed, manifest `logs/vice_auto_20260610_181305/manifest.json`.
+- Focused regular D81 launcher-mode chain passed, manifest `logs/vice_auto_20260610_180903/manifest.json`.
+- Focused host-key chain was environment-blocked by macOS keyboard automation permission, manifest `logs/vice_auto_20260610_181352/manifest.json`.
+
+## 2026-06-10 final proof run
+
+- `make readybasic-plugin-static-check readybasic-memory-report`: passed after the final rebuild. `verify_readybasic_plugin.py` reported `readybasic plugin static check OK`; `docs/readybasic_memory_diagrams.html` was regenerated from `obj/readybasic.map`.
+- Clean regular D81 aggregate: `READYBASIC_SKIP_BUILD=1 make readybasic-vice-suites` passed. Manifest audit: all listed manifests have `status=success`, `failed_step=null`, and `degraded_steps=[]`.
+ - `logs/vice_auto_20260610_195856/manifest.json` - demo suite.
+ - `logs/vice_auto_20260610_200925/manifest.json` - repeat/label.
+ - `logs/vice_auto_20260610_201013/manifest.json` - lifecycle.
+ - `logs/vice_auto_20260610_201034/manifest.json` - module overlay.
+ - `logs/vice_auto_20260610_201125/manifest.json` - plugin command.
+ - `logs/vice_auto_20260610_201322/manifest.json` - program mode.
+ - `logs/vice_auto_20260610_201426/manifest.json` - rbtest1.
+ - `logs/vice_auto_20260610_201434/manifest.json` - state preservation.
+ - `logs/vice_auto_20260610_201520/manifest.json` - large vars.
+ - `logs/vice_auto_20260610_201557/manifest.json` - Ctrl+B/F2/F4 focused hotkey.
+ - `logs/vice_auto_20260610_201620/manifest.json` - ReadyBASIC/REU Viewer F2 chain.
+ - `logs/vice_auto_20260610_201649/manifest.json` - 10-hop cross-app resume.
+ - `logs/vice_auto_20260610_201904/manifest.json` - second-entry editor stress.
+ - `logs/vice_auto_20260610_202049/manifest.json` - full visual verification.
+- Clean EasyFlash aggregate: `make easyflash-readybasic-vice-suites` rebuilt the cartridge SKU and passed. Manifest audit: all listed manifests have `status=success`, `failed_step=null`, and `degraded_steps=[]`.
+ - `logs/vice_auto_20260610_202900/manifest.json` - demo suite.
+ - `logs/vice_auto_20260610_204104/manifest.json` - repeat/label.
+ - `logs/vice_auto_20260610_204202/manifest.json` - lifecycle.
+ - `logs/vice_auto_20260610_204232/manifest.json` - module overlay.
+ - `logs/vice_auto_20260610_204335/manifest.json` - plugin command.
+ - `logs/vice_auto_20260610_204542/manifest.json` - program mode.
+ - `logs/vice_auto_20260610_204657/manifest.json` - rbtest1.
+ - `logs/vice_auto_20260610_204716/manifest.json` - minimal resume.
+ - `logs/vice_auto_20260610_204750/manifest.json` - screen/REU temp.
+ - `logs/vice_auto_20260610_204922/manifest.json` - state preservation.
+ - `logs/vice_auto_20260610_205019/manifest.json` - large vars.
+ - `logs/vice_auto_20260610_205107/manifest.json` - F4 hotkey.
+ - `logs/vice_auto_20260610_205136/manifest.json` - F2 hotkey.
+ - `logs/vice_auto_20260610_205151/manifest.json` - ReadyBASIC/REU Viewer F2 chain.
+ - `logs/vice_auto_20260610_205229/manifest.json` - 10-hop cross-app resume.
+ - `logs/vice_auto_20260610_205455/manifest.json` - second-entry editor stress.
+ - `logs/vice_auto_20260610_205649/manifest.json` - full visual verification.
+- The chain proof now matches the field failure instead of only a cold title wait: first entry may wait for `READYBASIC`, warm entries use capture plus `$C834` app-bank checks, ReadyBASIC CHRIN/KEYLOG vector checks, `$C6==0`, and typed `PRINT` sentinels. The boot screen's `READY.` text is not accepted as sufficient proof.
+- The chain proof includes: ReadyBASIC Ctrl+B, explicit reentry, ReadyBASIC Ctrl+B again, REU Viewer launch, REU Viewer F2 to ReadyBASIC, typed ReadyBASIC liveness, ReadyBASIC F2 back to REU Viewer, app vectors restored, REU Viewer Ctrl+B to launcher, ReadyBASIC reentry/liveness, typed `EXIT`, launcher stability/no auto-reenter, and final ReadyBASIC liveness.
+
+## 2026-06-10 final memory/headroom
+
+- `BASIC_START` remains `$2AC1`; empty BASIC formula free bytes remain `30013`.
+- `ENTRY` is `$1000-$11F6`, `$01F7` / 503B.
+- `RESIDENT` is `$1200-$2AB8`, `$18B9` / 6329B, leaving 7B before `$2ABF` / `$2AC0`.
+- `HIDDEN` is `$A000-$A6C7`, `$06C8` / 1736B, leaving `$0138` / 312B in the 2K common helper area.
+- `LOWPACK` is `$A800-$AECD`, `$06CE` / 1742B.
+- `SLOTPACK1` is `$B000-$B23A`, `$023B` / 571B.
+- `BRIDGE` is `$C000-$C1FD`, `$01FE` / 510B, leaving 2B before `$C200`.
+- The ReadyOS contract is preserved: no BASIC-start movement, no normal BASIC RAM expansion, no shim/app changes for this fix, and no ReadyBASIC private assumptions in `$C800-$C9FF` beyond the shim ABI.
+
+## 2026-06-11 final proof refresh
+
+- `make readybasic-plugin-static-check readybasic-memory-report`: passed; `verify_readybasic_plugin.py` reported `readybasic plugin static check OK`; `docs/readybasic_memory_diagrams.html` was regenerated from `obj/readybasic.map`.
+- Regular D81 focused chain:
+ - `/bin/bash build_support/run_readybasic_reuviewer_f2_chain_probe.sh` passed, manifest `logs/vice_auto_20260611_002202/manifest.json`.
+ - `READYBASIC_HOTKEY_INPUT_MODE=keylog /bin/bash build_support/run_readybasic_reuviewer_f2_chain_probe.sh` passed, manifest `logs/vice_auto_20260611_002247/manifest.json`.
+- Regular D81 aggregate: `make readybasic-vice-suites` passed. Manifest audit for `002428`, `003503`, `003556`, `003621`, `003719`, `003921`, `004030`, `004045`, `004136`, `004219`, `004254`, `004334`, `004555`, and `004745` found `status=success`, `failed_step=null`, and `degraded_steps=[]` for every manifest.
+- EasyFlash focused chain after launcher-navigation adaptation passed, manifest `logs/vice_auto_20260611_025528/manifest.json`.
+- EasyFlash aggregate: `make easyflash-readybasic-vice-suites` rebuilt the cartridge SKU and completed. Successful final/retry manifests `025643`, `030852`, `031001`, `031041`, `031153`, `031410`, `031535`, `032434`, `032519`, `032701`, `032807`, `032906`, `032948`, `033638`, `033728`, `034003`, and `034208` all have `status=success`, `failed_step=null`, and `degraded_steps=[]`.
+- EasyFlash produced two pre-app boot/preload flake manifests during the final aggregate (`031604`, `033016`), both stuck before ReadyBASIC at `READYOS EASYFLASH BOOT` / `BOOTER PRELOADING REU SNAPSHOTS`; suite retries passed with the successful manifests above. These did not exercise ReadyBASIC app code.
+- EasyFlash chain generation now keeps the chain launcher-owned, with no `--start-app readybasic` wrapper. The converter adapts only the chain's first launcher navigation to the EasyFlash app order: ReadyBASIC is four cursor-downs from the top, while REU Viewer remains three down from ReadyBASIC.
+- `run_easyflash_vice_suites.sh` now has configurable plan start/retry pauses (`EASYFLASH_PLAN_START_PAUSE_S`, `EASYFLASH_PLAN_RETRY_PAUSE_S`) to reduce VICE/EasyFlash cold-start flakiness without changing boot, launcher, shim, or app code. The default first-attempt pause now matches the proven 20s retry pause.
+
+## 2026-06-11 remaining failure to reproduce
+
+- The newest keyboard regression probe added partial prompt-line coverage that is stricter than the earlier focused hotkey suites.
+- Latest failed run: `logs/vice_auto_20260611_153009`, plan `readybasic_keyboard_regression_probe_easyflash`, failed step `wait_editor_after_partial_f2`.
+- What passed before that failure: ReadyBASIC launch, CHRIN/KEYLOG vector checks, warp-mode `PRINT "A B C"` spacing, partial-line `10` plus Ctrl+B to launcher, no visible or listed `REM`, ReadyBASIC reentry/liveness, Editor launch, and Editor Ctrl+B back to launcher.
+- Remaining unresolved case: after an Editor round trip, type `20` at the ReadyBASIC prompt without Return, then press F2. Expected result is an immediate switch to Editor; latest EasyFlash automation timed out waiting for `editor`.
+- Reproduction details are recorded in `agentworking/readybasic_hotkeys_fix/reproduce_remaining_failure.md`.
+
+## 2026-06-12 launcher-owned Editor/REU Viewer proof refresh
+
+- Supersedes the 2026-06-11 remaining-failure note for the regular D81 path. The root cause was prompt detection after `RUN`: BASIC could be visibly at `READY.` while `CURLIN/TXTPTR` still pointed into the just-run program, so KEYLOG rejected Ctrl+B/F2/F4. ReadyBASIC now hooks IMAIN `$0302/$0303` to mark the direct prompt active and clears that flag at execute entry.
+- The focused launcher-cycle probe now uses only launcher-owned app loading and exactly these companion apps: Editor, REU Viewer, and ReadyBASIC. It does not preload ReadyBASIC and does not use ReadyShell.
+- Test shape:
+ - Boot regular D81 to the launcher.
+ - Select Editor and press F3 to load it to REU.
+ - Return to launcher, select REU Viewer, and press F3 to load it to REU.
+ - Return to launcher, select ReadyBASIC, and launch it.
+ - Enter a one-line BASIC program, `LIST`, then run two full F2 cycles: ReadyBASIC -> Editor -> REU Viewer -> ReadyBASIC, twice, with `$C834`, `$C6`, screen text, capture, and post-delay stability assertions at every hop.
+ - Run two full F4 cycles: ReadyBASIC -> REU Viewer -> Editor -> ReadyBASIC, twice, with the same assertions.
+ - Return to ReadyBASIC, `LIST`, `RUN`, Ctrl+B to launcher, explicitly re-enter ReadyBASIC, `LIST`, `RUN`, then typed `EXIT`; assert the launcher remains stable and does not auto-reenter an app.
+- Focused regular D81 result: `READYBASIC_HOTKEY_BOOT_MODE=launcher READYBASIC_HOTKEY_SCENARIO=launcher_cycle /bin/bash build_support/run_readybasic_hotkey_probe.sh` passed, manifest `logs/vice_auto_20260612_001111/manifest.json`, `status=success`, `failed_step=null`, `degraded_steps=[]`.
+- Fresh focused regular D81 rerun for the Editor + REU Viewer acceptance path passed all 161 steps after a launcher-mode rebuild, manifest `logs/vice_auto_20260612_005705/manifest.json`, `status=success`, `failed_step=null`, `degraded_steps=[]`.
+- Keyboard regression result: `READYBASIC_SKIP_BUILD=1 READYBASIC_KEYBOARD_BOOT_MODE=launcher /bin/bash build_support/run_readybasic_keyboard_regression_probe.sh` passed, manifest `logs/vice_auto_20260612_001321/manifest.json`, `status=success`, `failed_step=null`, `degraded_steps=[]`. This includes warp-mode single-space typing, `10`+Ctrl+B, `20`+F2, no `REM`, normal typing after reentry, and app liveness after switch.
+- REU Viewer chain result after removing stale harness assumptions: `READYBASIC_SKIP_BUILD=1 /bin/bash build_support/run_readybasic_reuviewer_f2_chain_probe.sh` passed, manifest `logs/vice_auto_20260612_003840/manifest.json`.
+- Remaining regular ReadyBASIC suite targets after the harness correction also passed: cross-app resume `logs/vice_auto_20260612_003938/manifest.json`, second-entry editor `logs/vice_auto_20260612_004200/manifest.json`, and full visual verification `logs/vice_auto_20260612_004350/manifest.json`.
+- Static/memory guardrails: `make readybasic-plugin-static-check readybasic-memory-report` passed. Current map: `BASIC_START=$2AC1`, empty BASIC free bytes `30013`, `ENTRY=$1000-$11FF` / `$0200`, `RESIDENT=$1200-$2ABD` / `$18BE`, `HIDDEN=$A000-$A6E9` / `$06EA`, `LOWPACK=$A800-$AECD` / `$06CE`, `SLOTPACK1=$B000-$B23A` / `$023B`, `BRIDGE=$C000-$C1FE` / `$01FF`.
+- Scope stayed within ReadyBASIC source, ReadyBASIC harness/docs/notes, and generated artifacts. No shim, boot, launcher, or other app source change was required for this fix.
+
+## 2026-06-12 should be done working checkpoint
+
+- Status: should be done working. This branch now has the ReadyBASIC prompt hotkeys implemented, documented, and proved by the regular and EasyFlash ReadyBASIC VICE suites.
+- Final regular proof: `make readybasic-vice-suites` passed with 15 ReadyBASIC manifests, all `status=success`, `failed_step=null`, and `degraded_steps=[]`.
+- Final EasyFlash proof: `make easyflash-readybasic-vice-suites` passed with 18 final ReadyBASIC manifests, all `status=success`, `failed_step=null`, and `degraded_steps=[]`.
+- Final focused hotkey proof includes the launcher-owned Editor + REU Viewer + ReadyBASIC path, not ReadyShell and not a single preloaded ReadyBASIC shortcut. It loads Editor and REU Viewer, launches ReadyBASIC from the launcher, writes/lists/runs a one-line BASIC program, cycles F2 through ReadyBASIC -> Editor -> REU Viewer -> ReadyBASIC twice, cycles F4 the other direction twice, proves `$C834`, `$C6`, screen text, screenshots/captures, and delayed stability at each hop, then checks Ctrl+B, explicit reentry, `LIST`, `RUN`, and typed `EXIT` launcher stability.
+- The REU Viewer chain proof covers the original manual failure family: ReadyBASIC Ctrl+B, ReadyBASIC reentry, Ctrl+B again, REU Viewer launch, REU Viewer F2 back into ReadyBASIC, ReadyBASIC keyboard liveness, ReadyBASIC F2 back to REU Viewer, REU Viewer Ctrl+B to launcher, ReadyBASIC reentry/liveness, and `EXIT` not auto-reentering ReadyBASIC.
+
+### Regressions and false fixes that mattered
+
+- Waiting for the word `READY.` alone was not a proof of ReadyBASIC readiness because boot screens and transitional screens can contain `READY.`. First entry may use the ReadyBASIC title, but warm entries and EasyFlash conversion must prove readiness with the BASIC prompt plus app-bank/vector/keyboard liveness checks.
+- Waiting for the ReadyBASIC title in EasyFlash was also wrong: the title can be visible while free bytes still show `MMMM BASIC BYTES` and BASIC is not ready for typed input. The EasyFlash converted plans now wait for the actual `READY.` prompt before entering BASIC text.
+- The visible `REM` deferred-dispatch path was a bad design. It could appear on screen, become part of a partial prompt line such as `10`, and lock or store unintended BASIC text. The final path queues only Return and dispatches from the CHRIN hook before BASIC stores or executes the partial line.
+- A prompt-level CINV/IRQ matrix scanner was too invasive. It disturbed normal ROM-editor ownership of repeat timing and could make VICE fast/warp typing produce repeated spaces. The final design leaves ordinary key scanning/repeat/cursor editing to the ROM editor and accepts hotkeys through KEYLOG plus CHRIN only at the direct prompt.
+- Treating F2/F4 as just another typed character was insufficient. F-keys and Ctrl+B live in the C64 keyboard matrix/KERNAL preprocessing path, not the normal BASIC line text stream. The final tests exercise the ReadyBASIC KEYLOG/CHRIN hotkey path through monitor/keylog stubs and app keyboard input, not by poking `rb_hotkey_pending` or typing `EXIT`.
+- The selected F2/F4 target bank must survive suspend/yield preparation. The fix stores the selected bank immediately after the loaded-app scan and writes the shim switch target after `prepare_shim_yield`, instead of relying on scratch bytes that hidden save logic can reuse.
+- A single F2/F4 must not be observed twice. Entry-time hotkey quarantine and yield-time release waits are required so a held key does not switch ReadyBASIC to the next app and then immediately switch again. The focused probes now assert delayed stability and `$C6==0` after every hotkey switch.
+- Prompt state cannot be inferred only from `CURLIN`. After `RUN`, BASIC may visually be at `READY.` while interpreter pointers still make the prompt look like program context. The final implementation uses the IMAIN vector to mark direct-prompt readiness and clears that flag at execute entry.
+- Ctrl+B/F2/F4 must be ignored while BASIC is running. The final gate is keyboard-device and direct-prompt aware, so file/device input and RUN-mode BASIC execution do not become ReadyOS navigation.
+- Every ReadyBASIC yield path must scrub editor/KERNAL state: `rb_hotkey_pending`, `$C6`, `$0277`, `SHFLAG`, `LSTX`, and `SFDX`. Typed `EXIT`, Ctrl+B, F2, and F4 all need the same cleanup discipline.
+- ReadyBASIC must restore global page-3 vectors before yielding to ReadyOS. Those vectors are not part of the app snapshot, so leaving CHRIN/KEYLOG/execute/crunch hooks installed can break the launcher or next app.
+- Cartridge/EasyFlash app order is different from the regular D81 focused set. The cartridge F2/F4 tests should walk a few apps forward and back and assert actual screens/banks, not assume a small two- or three-app universe or try to cycle the entire preloaded cartridge list.
+- EasyFlash cold preload can occasionally stall before the launcher at `READYOS EASYFLASH BOOT` / `BOOTER PRELOADING REU SNAPSHOTS`. That is a harness/VICE cold-start issue before ReadyBASIC code runs. The suite now gives launcher waits and wrapper timeouts enough budget and retries whole plans after a cold-start pause.
+
+### Final design rules for future BASIC extensions
+
+- For prompt hotkeys, do not inject command text. Consume the physical/editor hotkey, queue Return only, and make the CHRIN hook discard the editor-returned character before BASIC can store or execute a partial line.
+- Keep ROM editor behavior intact. Do not install an IRQ scanner for ordinary prompt handling unless a future test proves there is no other option and then proves normal repeat/space/cursor behavior under warp.
+- Treat partial prompt lines as first-class acceptance cases. `10`+Ctrl+B and `20`+F2/F4 must not create program lines, show `REM`, lock the prompt, or leave the destination app keyboard-dead.
+- Prove app switching with launcher-owned multi-app journeys. Load companion apps through the launcher, switch both directions more than once, and assert no double-hop after a single F2/F4.
+- For ReadyBASIC specifically, every hotkey test must prove all of: app bank `$C834`, vector ownership/restoration, empty keyboard buffer `$C6`, screen identity, delayed stability, and typed input liveness after reentry.
+- Keep the memory contract visible in every final proof: `BASIC_START=$2AC1`, empty BASIC free bytes `30013`, bridge below `$C200`, no private use of `$C800-$C9FF`, and no shim/launcher/other-app changes unless a focused repro proves a contract bug outside ReadyBASIC.
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/reproduce_remaining_failure.md b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/reproduce_remaining_failure.md
new file mode 100644
index 0000000..4f6717d
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/reproduce_remaining_failure.md
@@ -0,0 +1,68 @@
+# Remaining Keyboard Regression Failure
+
+Status as of 2026-06-11: the focused regular and EasyFlash hotkey suites passed, but the newer keyboard regression probe still exposes one unresolved case.
+
+## Failure
+
+- Probe: `readybasic_keyboard_regression_probe_easyflash`
+- Latest failed run: `logs/vice_auto_20260611_153009`
+- Failed step: `wait_editor_after_partial_f2`
+- Failure text: timeout waiting for screen text `editor`
+
+The probe proves these earlier cases before the failure:
+
+- ReadyBASIC launches from the EasyFlash launcher.
+- ReadyBASIC CHRIN and KEYLOG vectors are installed.
+- Warp-mode normal typing preserves spaces (`PRINT "A B C"`).
+- A partially typed prompt line `10` plus `Ctrl+B` switches immediately to the launcher.
+- No visible `REM` line is injected or later listed.
+- ReadyBASIC remains usable after reentry.
+- Editor can be loaded and can return to the launcher via `Ctrl+B`.
+
+The remaining failure is the later partial-line `F2` case after an Editor round trip:
+
+1. Enter ReadyBASIC from the launcher.
+2. Type `20` at the ReadyBASIC prompt, without pressing Return.
+3. Press `F2`.
+4. Expected: immediate switch to Editor.
+5. Actual in the latest automated EasyFlash run: the probe timed out waiting for `editor`.
+
+## Manual Regular D81 Reproduction
+
+The regular D81 can be launched interactively with:
+
+```sh
+cd /Users/karlprosserpp/dev/c64projects/readyosprecog
+/opt/homebrew/bin/x64sc -logtostdout -verbose -warp \
+ -8 Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81.d81 \
+ -autostart Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81-preboot.prg
+```
+
+Manual check:
+
+1. At the launcher, enter ReadyBASIC.
+2. Type `10`, then press `Ctrl+B`; it should switch to the launcher immediately.
+3. Reenter ReadyBASIC and run `LIST`; `REM` should not appear.
+4. Switch to Editor, then back to ReadyBASIC.
+5. Type `20`, then press `F2`; this is the unresolved case to test carefully.
+
+## Automated Reproduction
+
+Regular D81:
+
+```sh
+cd /Users/karlprosserpp/dev/c64projects/readyosprecog
+READYBASIC_KEYBOARD_BOOT_MODE=launcher \
+READYBASIC_KEYBOARD_LAUNCH_KEYS=17,17,17,17,13 \
+READYBASIC_SKIP_BUILD=1 \
+bash build_support/run_readybasic_keyboard_regression_probe.sh
+```
+
+EasyFlash:
+
+```sh
+cd /Users/karlprosserpp/dev/c64projects/readyosprecog
+bash build_support/run_easyflash_vice_suites.sh readybasic_keyboard_regression_probe
+```
+
+Expected current automated failure for the unresolved case: `failed_step=wait_editor_after_partial_f2`.
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/run_terminal_hotkey_probe.command b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/run_terminal_hotkey_probe.command
new file mode 100755
index 0000000..a2d3c3e
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/run_terminal_hotkey_probe.command
@@ -0,0 +1,8 @@
+#!/bin/bash
+cd /Users/karlprosserpp/dev/c64projects/readyosprecog || exit 1
+export DISABLE_AUTO_UPDATE=true
+export READYBASIC_HOTKEY_HOST_KEYS=1
+/bin/bash build_support/run_readybasic_hotkey_probe.sh > agentworking/readybasic_hotkeys_fix/terminal_probe.log 2>&1
+status=$?
+printf 'EXIT:%s\n' "$status" > agentworking/readybasic_hotkeys_fix/terminal_probe.status
+exit "$status"
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/screenshot_contact_sheets_20260612_005705/01_launch_preload_readybasic.png b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/screenshot_contact_sheets_20260612_005705/01_launch_preload_readybasic.png
new file mode 100644
index 0000000..331a211
Binary files /dev/null and b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/screenshot_contact_sheets_20260612_005705/01_launch_preload_readybasic.png differ
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/screenshot_contact_sheets_20260612_005705/02_f2_cycles.png b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/screenshot_contact_sheets_20260612_005705/02_f2_cycles.png
new file mode 100644
index 0000000..e29aeed
Binary files /dev/null and b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/screenshot_contact_sheets_20260612_005705/02_f2_cycles.png differ
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/screenshot_contact_sheets_20260612_005705/02_f2_cycles_stable_only.png b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/screenshot_contact_sheets_20260612_005705/02_f2_cycles_stable_only.png
new file mode 100644
index 0000000..35adf0d
Binary files /dev/null and b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/screenshot_contact_sheets_20260612_005705/02_f2_cycles_stable_only.png differ
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/screenshot_contact_sheets_20260612_005705/03_f4_cycles.png b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/screenshot_contact_sheets_20260612_005705/03_f4_cycles.png
new file mode 100644
index 0000000..ecf03d3
Binary files /dev/null and b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/screenshot_contact_sheets_20260612_005705/03_f4_cycles.png differ
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/screenshot_contact_sheets_20260612_005705/04_ctrlb_exit_final.png b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/screenshot_contact_sheets_20260612_005705/04_ctrlb_exit_final.png
new file mode 100644
index 0000000..f6c49e2
Binary files /dev/null and b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/screenshot_contact_sheets_20260612_005705/04_ctrlb_exit_final.png differ
diff --git a/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/screenshot_contact_sheets_20260612_005705/index.txt b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/screenshot_contact_sheets_20260612_005705/index.txt
new file mode 100644
index 0000000..b15bbc7
--- /dev/null
+++ b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readybasic_hotkeys_fix/screenshot_contact_sheets_20260612_005705/index.txt
@@ -0,0 +1,67 @@
+[01_launch_preload_readybasic]
+01 row 1 col 1: logs/vice_auto_20260612_005705/screens/boot_initial.png
+02 row 1 col 2: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_launcher_initial.png
+03 row 1 col 3: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_launcher_editor_selected.png
+04 row 2 col 1: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_launcher_editor_preloaded.png
+05 row 2 col 2: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_editor_preload_done.png
+06 row 2 col 3: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_launcher_after_editor_preload.png
+07 row 3 col 1: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_launcher_reuviewer_selected.png
+08 row 3 col 2: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_launcher_reuviewer_preloaded.png
+09 row 3 col 3: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_reuviewer_preload_done.png
+10 row 4 col 1: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_launcher_after_reuviewer_preload.png
+11 row 4 col 2: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_launcher_after_readybasic_nav.png
+12 row 4 col 3: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_prompt.png
+13 row 5 col 1: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_seed_list_program.png
+
+[02_f2_cycles]
+01 row 1 col 1: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f2_round1_editor_after_input.png
+02 row 1 col 2: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f2_round1_editor.png
+03 row 1 col 3: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f2_round1_editor_stable.png
+04 row 2 col 1: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f2_round1_reuviewer_after_input.png
+05 row 2 col 2: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f2_round1_reuviewer.png
+06 row 2 col 3: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f2_round1_reuviewer_stable.png
+07 row 3 col 1: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f2_round1_readybasic_after_input.png
+08 row 3 col 2: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f2_round1_readybasic.png
+09 row 3 col 3: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f2_round1_readybasic_stable.png
+10 row 4 col 1: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f2_round2_editor_after_input.png
+11 row 4 col 2: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f2_round2_editor.png
+12 row 4 col 3: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f2_round2_editor_stable.png
+13 row 5 col 1: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f2_round2_reuviewer_after_input.png
+14 row 5 col 2: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f2_round2_reuviewer.png
+15 row 5 col 3: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f2_round2_reuviewer_stable.png
+16 row 6 col 1: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f2_round2_readybasic_after_input.png
+17 row 6 col 2: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f2_round2_readybasic.png
+18 row 6 col 3: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f2_round2_readybasic_stable.png
+
+[03_f4_cycles]
+01 row 1 col 1: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f4_round1_reuviewer_after_input.png
+02 row 1 col 2: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f4_round1_reuviewer.png
+03 row 1 col 3: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f4_round1_reuviewer_stable.png
+04 row 2 col 1: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f4_round1_editor_after_input.png
+05 row 2 col 2: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f4_round1_editor.png
+06 row 2 col 3: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f4_round1_editor_stable.png
+07 row 3 col 1: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f4_round1_readybasic_after_input.png
+08 row 3 col 2: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f4_round1_readybasic.png
+09 row 3 col 3: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f4_round1_readybasic_stable.png
+10 row 4 col 1: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f4_round2_reuviewer_after_input.png
+11 row 4 col 2: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f4_round2_reuviewer.png
+12 row 4 col 3: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f4_round2_reuviewer_stable.png
+13 row 5 col 1: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f4_round2_editor_after_input.png
+14 row 5 col 2: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f4_round2_editor.png
+15 row 5 col 3: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f4_round2_editor_stable.png
+16 row 6 col 1: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f4_round2_readybasic_after_input.png
+17 row 6 col 2: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f4_round2_readybasic.png
+18 row 6 col 3: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_f4_round2_readybasic_stable.png
+
+[04_ctrlb_exit_final]
+01 row 1 col 1: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_list_after_cycles_before_ctrl_b.png
+02 row 1 col 2: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_run_after_cycles_before_ctrl_b.png
+03 row 1 col 3: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_ctrl_b_after_cycles.png
+04 row 2 col 1: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_launcher_after_readybasic_ctrl_b.png
+05 row 2 col 2: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_reenter_after_ctrl_b.png
+06 row 2 col 3: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_readybasic_after_ctrl_b.png
+07 row 3 col 1: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_final_list_after_reentry.png
+08 row 3 col 2: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_final_run_after_reentry.png
+09 row 3 col 3: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_exit_after_final_run.png
+10 row 4 col 1: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_launcher_after_exit.png
+11 row 4 col 2: logs/vice_auto_20260612_005705/screens/readybasic_hotkey_launcher_stable_after_exit.png
diff --git a/agentworking/readyshell_dynamic_state_before.prg b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readyshell_dynamic_state_before.prg
similarity index 100%
rename from agentworking/readyshell_dynamic_state_before.prg
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/readyshell_dynamic_state_before.prg
diff --git a/agentworking/readyshell_dynamic_state_before_easyflash.prg b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readyshell_dynamic_state_before_easyflash.prg
similarity index 100%
rename from agentworking/readyshell_dynamic_state_before_easyflash.prg
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/readyshell_dynamic_state_before_easyflash.prg
diff --git a/agentworking/readyshell_dynamic_state_headroom_after_cache_seed.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readyshell_dynamic_state_headroom_after_cache_seed.json
similarity index 100%
rename from agentworking/readyshell_dynamic_state_headroom_after_cache_seed.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/readyshell_dynamic_state_headroom_after_cache_seed.json
diff --git a/agentworking/readyshell_dynamic_state_headroom_after_easyflash_build.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readyshell_dynamic_state_headroom_after_easyflash_build.json
similarity index 100%
rename from agentworking/readyshell_dynamic_state_headroom_after_easyflash_build.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/readyshell_dynamic_state_headroom_after_easyflash_build.json
diff --git a/agentworking/readyshell_dynamic_state_headroom_before.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readyshell_dynamic_state_headroom_before.json
similarity index 100%
rename from agentworking/readyshell_dynamic_state_headroom_before.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/readyshell_dynamic_state_headroom_before.json
diff --git a/agentworking/readyshell_dynamic_state_headroom_final.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readyshell_dynamic_state_headroom_final.json
similarity index 100%
rename from agentworking/readyshell_dynamic_state_headroom_final.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/readyshell_dynamic_state_headroom_final.json
diff --git a/agentworking/readyshell_dynamic_state_headroom_mid.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readyshell_dynamic_state_headroom_mid.json
similarity index 100%
rename from agentworking/readyshell_dynamic_state_headroom_mid.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/readyshell_dynamic_state_headroom_mid.json
diff --git a/agentworking/readyshell_dynamic_state_headroom_post_tests.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readyshell_dynamic_state_headroom_post_tests.json
similarity index 100%
rename from agentworking/readyshell_dynamic_state_headroom_post_tests.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/readyshell_dynamic_state_headroom_post_tests.json
diff --git a/agentworking/readyshell_dynamic_state_working_notes.md b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readyshell_dynamic_state_working_notes.md
similarity index 100%
rename from agentworking/readyshell_dynamic_state_working_notes.md
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/readyshell_dynamic_state_working_notes.md
diff --git a/agentworking/readyshell_statebank_debug_cat_headroom_after.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readyshell_statebank_debug_cat_headroom_after.json
similarity index 100%
rename from agentworking/readyshell_statebank_debug_cat_headroom_after.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/readyshell_statebank_debug_cat_headroom_after.json
diff --git a/agentworking/readyshell_statebank_debug_cat_headroom_before.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readyshell_statebank_debug_cat_headroom_before.json
similarity index 100%
rename from agentworking/readyshell_statebank_debug_cat_headroom_before.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/readyshell_statebank_debug_cat_headroom_before.json
diff --git a/agentworking/readyshell_statebank_debug_cat_notes.md b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/readyshell_statebank_debug_cat_notes.md
similarity index 100%
rename from agentworking/readyshell_statebank_debug_cat_notes.md
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/readyshell_statebank_debug_cat_notes.md
diff --git a/agentworking/regular_reuviewer_no_gap_entry.png b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/regular_reuviewer_no_gap_entry.png
similarity index 100%
rename from agentworking/regular_reuviewer_no_gap_entry.png
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/regular_reuviewer_no_gap_entry.png
diff --git a/agentworking/regular_reuviewer_no_gap_launcher_bank.png b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/regular_reuviewer_no_gap_launcher_bank.png
similarity index 100%
rename from agentworking/regular_reuviewer_no_gap_launcher_bank.png
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/regular_reuviewer_no_gap_launcher_bank.png
diff --git a/agentworking/regular_reuviewer_no_gap_start_row.png b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/regular_reuviewer_no_gap_start_row.png
similarity index 100%
rename from agentworking/regular_reuviewer_no_gap_start_row.png
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/regular_reuviewer_no_gap_start_row.png
diff --git a/agentworking/reu_bank0_lookup_headroom_after.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_bank0_lookup_headroom_after.json
similarity index 100%
rename from agentworking/reu_bank0_lookup_headroom_after.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_bank0_lookup_headroom_after.json
diff --git a/agentworking/reu_bank0_lookup_headroom_before.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_bank0_lookup_headroom_before.json
similarity index 100%
rename from agentworking/reu_bank0_lookup_headroom_before.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_bank0_lookup_headroom_before.json
diff --git a/agentworking/reu_bank0_lookup_working_notes.md b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_bank0_lookup_working_notes.md
similarity index 100%
rename from agentworking/reu_bank0_lookup_working_notes.md
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_bank0_lookup_working_notes.md
diff --git a/agentworking/reu_cartridge_fix_headroom_current.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_cartridge_fix_headroom_current.json
similarity index 100%
rename from agentworking/reu_cartridge_fix_headroom_current.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_cartridge_fix_headroom_current.json
diff --git a/agentworking/reu_owned_alloc_headroom_after.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_owned_alloc_headroom_after.json
similarity index 100%
rename from agentworking/reu_owned_alloc_headroom_after.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_owned_alloc_headroom_after.json
diff --git a/agentworking/reu_owned_alloc_headroom_before.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_owned_alloc_headroom_before.json
similarity index 100%
rename from agentworking/reu_owned_alloc_headroom_before.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_owned_alloc_headroom_before.json
diff --git a/agentworking/reu_owned_alloc_notes.md b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_owned_alloc_notes.md
similarity index 100%
rename from agentworking/reu_owned_alloc_notes.md
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_owned_alloc_notes.md
diff --git a/agentworking/reu_physical_size_easyflash_headroom_after.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_physical_size_easyflash_headroom_after.json
similarity index 100%
rename from agentworking/reu_physical_size_easyflash_headroom_after.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_physical_size_easyflash_headroom_after.json
diff --git a/agentworking/reu_physical_size_easyflash_headroom_before.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_physical_size_easyflash_headroom_before.json
similarity index 100%
rename from agentworking/reu_physical_size_easyflash_headroom_before.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_physical_size_easyflash_headroom_before.json
diff --git a/agentworking/reu_physical_size_headroom_after.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_physical_size_headroom_after.json
similarity index 100%
rename from agentworking/reu_physical_size_headroom_after.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_physical_size_headroom_after.json
diff --git a/agentworking/reu_physical_size_headroom_before.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_physical_size_headroom_before.json
similarity index 100%
rename from agentworking/reu_physical_size_headroom_before.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_physical_size_headroom_before.json
diff --git a/agentworking/reu_physical_size_working_notes.md b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_physical_size_working_notes.md
similarity index 100%
rename from agentworking/reu_physical_size_working_notes.md
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_physical_size_working_notes.md
diff --git a/agentworking/reu_refactor_headroom_after_readybasic_dynamic.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_refactor_headroom_after_readybasic_dynamic.json
similarity index 100%
rename from agentworking/reu_refactor_headroom_after_readybasic_dynamic.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_refactor_headroom_after_readybasic_dynamic.json
diff --git a/agentworking/reu_refactor_headroom_before_readybasic_dynamic.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_refactor_headroom_before_readybasic_dynamic.json
similarity index 100%
rename from agentworking/reu_refactor_headroom_before_readybasic_dynamic.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_refactor_headroom_before_readybasic_dynamic.json
diff --git a/agentworking/reu_refactor_headroom_current.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_refactor_headroom_current.json
similarity index 100%
rename from agentworking/reu_refactor_headroom_current.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_refactor_headroom_current.json
diff --git a/agentworking/reu_refactor_headroom_delta.md b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_refactor_headroom_delta.md
similarity index 100%
rename from agentworking/reu_refactor_headroom_delta.md
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_refactor_headroom_delta.md
diff --git a/agentworking/reu_refactor_progress.md b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_refactor_progress.md
similarity index 100%
rename from agentworking/reu_refactor_progress.md
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_refactor_progress.md
diff --git a/agentworking/reu_refactor_readybasic_dynamic_headroom.md b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_refactor_readybasic_dynamic_headroom.md
similarity index 100%
rename from agentworking/reu_refactor_readybasic_dynamic_headroom.md
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_refactor_readybasic_dynamic_headroom.md
diff --git a/agentworking/reu_registry_headroom_after_array_writer.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_registry_headroom_after_array_writer.json
similarity index 100%
rename from agentworking/reu_registry_headroom_after_array_writer.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_registry_headroom_after_array_writer.json
diff --git a/agentworking/reu_registry_headroom_after_compile.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_registry_headroom_after_compile.json
similarity index 100%
rename from agentworking/reu_registry_headroom_after_compile.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_registry_headroom_after_compile.json
diff --git a/agentworking/reu_registry_headroom_after_parser_trim.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_registry_headroom_after_parser_trim.json
similarity index 100%
rename from agentworking/reu_registry_headroom_after_parser_trim.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_registry_headroom_after_parser_trim.json
diff --git a/agentworking/reu_registry_headroom_after_split.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_registry_headroom_after_split.json
similarity index 100%
rename from agentworking/reu_registry_headroom_after_split.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_registry_headroom_after_split.json
diff --git a/agentworking/reu_registry_headroom_after_verify.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_registry_headroom_after_verify.json
similarity index 100%
rename from agentworking/reu_registry_headroom_after_verify.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_registry_headroom_after_verify.json
diff --git a/agentworking/reu_registry_headroom_before.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_registry_headroom_before.json
similarity index 100%
rename from agentworking/reu_registry_headroom_before.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_registry_headroom_before.json
diff --git a/agentworking/reu_registry_v2_working_notes.md b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_registry_v2_working_notes.md
similarity index 100%
rename from agentworking/reu_registry_v2_working_notes.md
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_registry_v2_working_notes.md
diff --git a/agentworking/reu_rich_registry_headroom_before.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_rich_registry_headroom_before.json
similarity index 100%
rename from agentworking/reu_rich_registry_headroom_before.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_rich_registry_headroom_before.json
diff --git a/agentworking/reu_rich_registry_headroom_final.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_rich_registry_headroom_final.json
similarity index 100%
rename from agentworking/reu_rich_registry_headroom_final.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_rich_registry_headroom_final.json
diff --git a/agentworking/reu_rich_registry_working_notes.md b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_rich_registry_working_notes.md
similarity index 100%
rename from agentworking/reu_rich_registry_working_notes.md
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_rich_registry_working_notes.md
diff --git a/agentworking/reu_stale_last_saved_notes.md b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_stale_last_saved_notes.md
similarity index 100%
rename from agentworking/reu_stale_last_saved_notes.md
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_stale_last_saved_notes.md
diff --git a/agentworking/reu_stale_state_headroom_after.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_stale_state_headroom_after.json
similarity index 100%
rename from agentworking/reu_stale_state_headroom_after.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_stale_state_headroom_after.json
diff --git a/agentworking/reu_stale_state_headroom_before.json b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_stale_state_headroom_before.json
similarity index 100%
rename from agentworking/reu_stale_state_headroom_before.json
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reu_stale_state_headroom_before.json
diff --git a/agentworking/reuviewer_after_app_roundtrip_capture.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reuviewer_after_app_roundtrip_capture.yaml
similarity index 100%
rename from agentworking/reuviewer_after_app_roundtrip_capture.yaml
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reuviewer_after_app_roundtrip_capture.yaml
diff --git a/agentworking/reuviewer_after_app_roundtrip_dump_reu_table.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reuviewer_after_app_roundtrip_dump_reu_table.yaml
similarity index 100%
rename from agentworking/reuviewer_after_app_roundtrip_dump_reu_table.yaml
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reuviewer_after_app_roundtrip_dump_reu_table.yaml
diff --git a/agentworking/reuviewer_capture_version.txt b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reuviewer_capture_version.txt
similarity index 100%
rename from agentworking/reuviewer_capture_version.txt
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reuviewer_capture_version.txt
diff --git a/agentworking/reuviewer_extra_slot_type_capture_8mb.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reuviewer_extra_slot_type_capture_8mb.yaml
similarity index 100%
rename from agentworking/reuviewer_extra_slot_type_capture_8mb.yaml
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reuviewer_extra_slot_type_capture_8mb.yaml
diff --git a/agentworking/reuviewer_no_gap_easyflash.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reuviewer_no_gap_easyflash.yaml
similarity index 100%
rename from agentworking/reuviewer_no_gap_easyflash.yaml
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reuviewer_no_gap_easyflash.yaml
diff --git a/agentworking/reuviewer_no_gap_entry.png b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reuviewer_no_gap_entry.png
similarity index 100%
rename from agentworking/reuviewer_no_gap_entry.png
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reuviewer_no_gap_entry.png
diff --git a/agentworking/reuviewer_no_gap_launcher_bank.png b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reuviewer_no_gap_launcher_bank.png
similarity index 100%
rename from agentworking/reuviewer_no_gap_launcher_bank.png
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reuviewer_no_gap_launcher_bank.png
diff --git a/agentworking/reuviewer_no_gap_regular_d81.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reuviewer_no_gap_regular_d81.yaml
similarity index 100%
rename from agentworking/reuviewer_no_gap_regular_d81.yaml
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reuviewer_no_gap_regular_d81.yaml
diff --git a/agentworking/reuviewer_slot_type_capture_8mb.yaml b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/reuviewer_slot_type_capture_8mb.yaml
similarity index 100%
rename from agentworking/reuviewer_slot_type_capture_8mb.yaml
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/reuviewer_slot_type_capture_8mb.yaml
diff --git a/agentworking/run_easyflash_launcher_app_probes.sh b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/run_easyflash_launcher_app_probes.sh
similarity index 100%
rename from agentworking/run_easyflash_launcher_app_probes.sh
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/run_easyflash_launcher_app_probes.sh
diff --git a/agentworking/vice8mb/x64sc b/agentworking/archive-pre-readybasic-gfx-phase1-20260615/vice8mb/x64sc
similarity index 100%
rename from agentworking/vice8mb/x64sc
rename to agentworking/archive-pre-readybasic-gfx-phase1-20260615/vice8mb/x64sc
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_cross_app_resume_probe.easyflash.yaml b/agentworking/easyflash_full_vice_plans/readybasic_cross_app_resume_probe.easyflash.yaml
index ae59894..b29efcc 100644
--- a/agentworking/easyflash_full_vice_plans/readybasic_cross_app_resume_probe.easyflash.yaml
+++ b/agentworking/easyflash_full_vice_plans/readybasic_cross_app_resume_probe.easyflash.yaml
@@ -19,7 +19,7 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.4/precog-easyflash/readyos_easyflash.crt"
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
autostart_enabled: false
disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
drive8_enabled: true
@@ -40,7 +40,7 @@ steps:
text: "READY OS"
pre_delay_s: 4
poll_s: 0.5
- wait_timeout_s: 240
+ wait_timeout_s: 420
capture_label: easyflash_readybasic_launcher
- id: easyflash_start_readybasic
type: input.sequence
@@ -54,6 +54,17 @@ steps:
text: "ready."
wait_timeout_s: 180
capture_label: readybasic_prompt
+ - id: wait_readybasic_prompt_stable_before_program_entry
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ pre_delay_s: 1.5
+ wait_timeout_s: 30
+ - id: clear_keyboard_buffer_before_program_entry
+ type: memory.write
+ params:
+ start: 198
+ bytes_hex: "00"
- id: build_program_lines
type: input.sequence
params:
@@ -108,20 +119,32 @@ steps:
- id: move_from_readybasic_to_editor_1
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_1
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_1
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_1
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
- id: ctrl_b_to_launcher_from_editor_1
- type: input.sequence
+ type: memory.write
params:
- keys: [2]
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: inject_ctrl_b_to_launcher_from_editor_1
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_1
type: screen.wait_contains
params:
@@ -130,9 +153,18 @@ steps:
- id: move_from_editor_to_readybasic_1
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_1
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_1
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_resume_1
type: screen.wait_contains
params:
@@ -215,20 +247,32 @@ steps:
- id: move_from_readybasic_to_editor_2
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_2
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_2
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_2
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
- id: ctrl_b_to_launcher_from_editor_2
- type: input.sequence
+ type: memory.write
params:
- keys: [2]
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: inject_ctrl_b_to_launcher_from_editor_2
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_2
type: screen.wait_contains
params:
@@ -237,9 +281,18 @@ steps:
- id: move_from_editor_to_readybasic_2
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_2
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_2
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_resume_2
type: screen.wait_contains
params:
@@ -322,20 +375,32 @@ steps:
- id: move_from_readybasic_to_editor_3
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_3
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_3
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_3
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
- id: ctrl_b_to_launcher_from_editor_3
- type: input.sequence
+ type: memory.write
params:
- keys: [2]
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: inject_ctrl_b_to_launcher_from_editor_3
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_3
type: screen.wait_contains
params:
@@ -344,9 +409,18 @@ steps:
- id: move_from_editor_to_readybasic_3
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_3
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_3
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_resume_3
type: screen.wait_contains
params:
@@ -429,20 +503,32 @@ steps:
- id: move_from_readybasic_to_editor_4
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_4
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_4
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_4
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
- id: ctrl_b_to_launcher_from_editor_4
- type: input.sequence
+ type: memory.write
params:
- keys: [2]
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: inject_ctrl_b_to_launcher_from_editor_4
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_4
type: screen.wait_contains
params:
@@ -451,9 +537,18 @@ steps:
- id: move_from_editor_to_readybasic_4
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_4
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_4
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_resume_4
type: screen.wait_contains
params:
@@ -536,20 +631,32 @@ steps:
- id: move_from_readybasic_to_editor_5
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_5
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_5
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_5
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
- id: ctrl_b_to_launcher_from_editor_5
- type: input.sequence
+ type: memory.write
params:
- keys: [2]
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: inject_ctrl_b_to_launcher_from_editor_5
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_5
type: screen.wait_contains
params:
@@ -558,9 +665,18 @@ steps:
- id: move_from_editor_to_readybasic_5
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_5
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_5
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_resume_5
type: screen.wait_contains
params:
@@ -643,20 +759,32 @@ steps:
- id: move_from_readybasic_to_editor_6
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_6
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_6
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_6
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
- id: ctrl_b_to_launcher_from_editor_6
- type: input.sequence
+ type: memory.write
params:
- keys: [2]
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: inject_ctrl_b_to_launcher_from_editor_6
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_6
type: screen.wait_contains
params:
@@ -665,9 +793,18 @@ steps:
- id: move_from_editor_to_readybasic_6
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_6
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_6
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_resume_6
type: screen.wait_contains
params:
@@ -750,20 +887,32 @@ steps:
- id: move_from_readybasic_to_editor_7
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_7
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_7
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_7
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
- id: ctrl_b_to_launcher_from_editor_7
- type: input.sequence
+ type: memory.write
params:
- keys: [2]
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: inject_ctrl_b_to_launcher_from_editor_7
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_7
type: screen.wait_contains
params:
@@ -772,9 +921,18 @@ steps:
- id: move_from_editor_to_readybasic_7
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_7
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_7
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_resume_7
type: screen.wait_contains
params:
@@ -857,20 +1015,32 @@ steps:
- id: move_from_readybasic_to_editor_8
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_8
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_8
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_8
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
- id: ctrl_b_to_launcher_from_editor_8
- type: input.sequence
+ type: memory.write
params:
- keys: [2]
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: inject_ctrl_b_to_launcher_from_editor_8
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_8
type: screen.wait_contains
params:
@@ -879,9 +1049,18 @@ steps:
- id: move_from_editor_to_readybasic_8
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_8
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_8
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_resume_8
type: screen.wait_contains
params:
@@ -964,20 +1143,32 @@ steps:
- id: move_from_readybasic_to_editor_9
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_9
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_9
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_9
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
- id: ctrl_b_to_launcher_from_editor_9
- type: input.sequence
+ type: memory.write
params:
- keys: [2]
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: inject_ctrl_b_to_launcher_from_editor_9
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_9
type: screen.wait_contains
params:
@@ -986,9 +1177,18 @@ steps:
- id: move_from_editor_to_readybasic_9
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_9
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_9
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_resume_9
type: screen.wait_contains
params:
@@ -1071,20 +1271,32 @@ steps:
- id: move_from_readybasic_to_editor_10
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_10
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_10
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_10
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
- id: ctrl_b_to_launcher_from_editor_10
- type: input.sequence
+ type: memory.write
params:
- keys: [2]
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: inject_ctrl_b_to_launcher_from_editor_10
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_10
type: screen.wait_contains
params:
@@ -1093,9 +1305,18 @@ steps:
- id: move_from_editor_to_readybasic_10
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_10
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_10
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_resume_10
type: screen.wait_contains
params:
@@ -1166,7 +1387,7 @@ steps:
type: dump.memory_ranges
params:
ranges:
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_text_and_vars_1200, start: 0x1200, end: 0x1700 }
- { label: string_heap_9400, start: 0x9400, end: 0x9600 }
- { label: runtime_state_9600, start: 0x9600, end: 0x9A00 }
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_cross_app_resume_probe.regular.yaml b/agentworking/easyflash_full_vice_plans/readybasic_cross_app_resume_probe.regular.yaml
index 2b62bfd..f0b9097 100644
--- a/agentworking/easyflash_full_vice_plans/readybasic_cross_app_resume_probe.regular.yaml
+++ b/agentworking/easyflash_full_vice_plans/readybasic_cross_app_resume_probe.regular.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
@@ -39,6 +39,17 @@ steps:
text: "ready."
wait_timeout_s: 180
capture_label: readybasic_prompt
+ - id: wait_readybasic_prompt_stable_before_program_entry
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ pre_delay_s: 1.5
+ wait_timeout_s: 30
+ - id: clear_keyboard_buffer_before_program_entry
+ type: memory.write
+ params:
+ start: 198
+ bytes_hex: "00"
- id: build_program_lines
type: input.sequence
params:
@@ -93,20 +104,32 @@ steps:
- id: move_from_readybasic_to_editor_1
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_1
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_1
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_1
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
- id: ctrl_b_to_launcher_from_editor_1
- type: input.sequence
+ type: memory.write
params:
- keys: [2]
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: inject_ctrl_b_to_launcher_from_editor_1
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_1
type: screen.wait_contains
params:
@@ -115,9 +138,18 @@ steps:
- id: move_from_editor_to_readybasic_1
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_1
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_1
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_resume_1
type: screen.wait_contains
params:
@@ -200,20 +232,32 @@ steps:
- id: move_from_readybasic_to_editor_2
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_2
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_2
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_2
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
- id: ctrl_b_to_launcher_from_editor_2
- type: input.sequence
+ type: memory.write
params:
- keys: [2]
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: inject_ctrl_b_to_launcher_from_editor_2
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_2
type: screen.wait_contains
params:
@@ -222,9 +266,18 @@ steps:
- id: move_from_editor_to_readybasic_2
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_2
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_2
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_resume_2
type: screen.wait_contains
params:
@@ -307,20 +360,32 @@ steps:
- id: move_from_readybasic_to_editor_3
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_3
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_3
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_3
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
- id: ctrl_b_to_launcher_from_editor_3
- type: input.sequence
+ type: memory.write
params:
- keys: [2]
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: inject_ctrl_b_to_launcher_from_editor_3
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_3
type: screen.wait_contains
params:
@@ -329,9 +394,18 @@ steps:
- id: move_from_editor_to_readybasic_3
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_3
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_3
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_resume_3
type: screen.wait_contains
params:
@@ -414,20 +488,32 @@ steps:
- id: move_from_readybasic_to_editor_4
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_4
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_4
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_4
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
- id: ctrl_b_to_launcher_from_editor_4
- type: input.sequence
+ type: memory.write
params:
- keys: [2]
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: inject_ctrl_b_to_launcher_from_editor_4
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_4
type: screen.wait_contains
params:
@@ -436,9 +522,18 @@ steps:
- id: move_from_editor_to_readybasic_4
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_4
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_4
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_resume_4
type: screen.wait_contains
params:
@@ -521,20 +616,32 @@ steps:
- id: move_from_readybasic_to_editor_5
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_5
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_5
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_5
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
- id: ctrl_b_to_launcher_from_editor_5
- type: input.sequence
+ type: memory.write
params:
- keys: [2]
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: inject_ctrl_b_to_launcher_from_editor_5
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_5
type: screen.wait_contains
params:
@@ -543,9 +650,18 @@ steps:
- id: move_from_editor_to_readybasic_5
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_5
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_5
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_resume_5
type: screen.wait_contains
params:
@@ -628,20 +744,32 @@ steps:
- id: move_from_readybasic_to_editor_6
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_6
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_6
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_6
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
- id: ctrl_b_to_launcher_from_editor_6
- type: input.sequence
+ type: memory.write
params:
- keys: [2]
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: inject_ctrl_b_to_launcher_from_editor_6
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_6
type: screen.wait_contains
params:
@@ -650,9 +778,18 @@ steps:
- id: move_from_editor_to_readybasic_6
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_6
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_6
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_resume_6
type: screen.wait_contains
params:
@@ -735,20 +872,32 @@ steps:
- id: move_from_readybasic_to_editor_7
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_7
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_7
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_7
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
- id: ctrl_b_to_launcher_from_editor_7
- type: input.sequence
+ type: memory.write
params:
- keys: [2]
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: inject_ctrl_b_to_launcher_from_editor_7
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_7
type: screen.wait_contains
params:
@@ -757,9 +906,18 @@ steps:
- id: move_from_editor_to_readybasic_7
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_7
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_7
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_resume_7
type: screen.wait_contains
params:
@@ -842,20 +1000,32 @@ steps:
- id: move_from_readybasic_to_editor_8
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_8
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_8
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_8
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
- id: ctrl_b_to_launcher_from_editor_8
- type: input.sequence
+ type: memory.write
params:
- keys: [2]
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: inject_ctrl_b_to_launcher_from_editor_8
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_8
type: screen.wait_contains
params:
@@ -864,9 +1034,18 @@ steps:
- id: move_from_editor_to_readybasic_8
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_8
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_8
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_resume_8
type: screen.wait_contains
params:
@@ -949,20 +1128,32 @@ steps:
- id: move_from_readybasic_to_editor_9
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_9
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_9
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_9
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
- id: ctrl_b_to_launcher_from_editor_9
- type: input.sequence
+ type: memory.write
params:
- keys: [2]
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: inject_ctrl_b_to_launcher_from_editor_9
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_9
type: screen.wait_contains
params:
@@ -971,9 +1162,18 @@ steps:
- id: move_from_editor_to_readybasic_9
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_9
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_9
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_resume_9
type: screen.wait_contains
params:
@@ -1056,20 +1256,32 @@ steps:
- id: move_from_readybasic_to_editor_10
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_10
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_10
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_10
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
- id: ctrl_b_to_launcher_from_editor_10
- type: input.sequence
+ type: memory.write
params:
- keys: [2]
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: inject_ctrl_b_to_launcher_from_editor_10
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_10
type: screen.wait_contains
params:
@@ -1078,9 +1290,18 @@ steps:
- id: move_from_editor_to_readybasic_10
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_10
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_10
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_resume_10
type: screen.wait_contains
params:
@@ -1151,7 +1372,7 @@ steps:
type: dump.memory_ranges
params:
ranges:
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_text_and_vars_1200, start: 0x1200, end: 0x1700 }
- { label: string_heap_9400, start: 0x9400, end: 0x9600 }
- { label: runtime_state_9600, start: 0x9600, end: 0x9A00 }
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_demo_suite.easyflash.yaml b/agentworking/easyflash_full_vice_plans/readybasic_demo_suite.easyflash.yaml
index 2577773..6bda5ad 100644
--- a/agentworking/easyflash_full_vice_plans/readybasic_demo_suite.easyflash.yaml
+++ b/agentworking/easyflash_full_vice_plans/readybasic_demo_suite.easyflash.yaml
@@ -19,7 +19,7 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.4/precog-easyflash/readyos_easyflash.crt"
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
autostart_enabled: false
disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
drive8_enabled: true
@@ -40,7 +40,7 @@ steps:
text: "READY OS"
pre_delay_s: 4
poll_s: 0.5
- wait_timeout_s: 240
+ wait_timeout_s: 420
capture_label: easyflash_readybasic_launcher
- id: easyflash_start_readybasic
type: input.sequence
@@ -54,16 +54,27 @@ steps:
text: "FREE:"
wait_timeout_s: 180
capture_label: demo_readybasic_prompt
+ - id: warp_off_for_visible_demo
+ type: warp.set
+ params:
+ enabled: false
+ capture_after: false
- id: demo_01_intro
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,49,58,32,82,69,65,68,89,66,65,83,73,67,32,66,65,83,73,67,83,34,13,80,82,73,78,84,32,34,70,82,69,69,77,69,77,44,32,86,65,82,73,65,66,76,69,83,44,32,65,78,68,32,65,32,80,82,79,71,82,65,77,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,49,58,32,82,69,65,68,89,66,65,83,73,67,32,66,65,83,73,67,83,34,13,80,82,73,78,84,32,34,77,69,77,65,86,76,44,32,86,65,82,73,65,66,76,69,83,44,32,65,78,68,32,65,32,80,82,79,71,82,65,77,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
inter_key_delay_s: 0.08
post_delay_s: 3.5
- id: demo_01_setup
type: input.sequence
params:
- keys: [70,82,69,69,77,69,77,40,41,13,78,69,87,13,65,37,61,52,50,13,49,48,32,66,37,61,90,65,68,68,49,54,40,52,50,44,56,41,13,50,48,32,80,82,73,78,84,32,34,80,82,79,71,82,65,77,32,83,85,77,34,59,66,37,13,76,73,83,84,13]
+ keys: [77,69,77,65,86,76,40,41,13,78,69,87,13,65,37,61,52,50,13,49,48,32,66,37,61,90,65,68,68,49,54,40,52,50,44,56,41,13,50,48,32,80,82,73,78,84,32,34,80,82,79,71,82,65,77,32,83,85,77,34,59,66,37,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_01_list
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
inter_key_delay_s: 0.08
post_delay_s: 3.5
- id: demo_01_basics
@@ -136,16 +147,32 @@ steps:
params:
text: "READY."
wait_timeout_s: 60
- - id: demo_03_resume_intro
+ - id: demo_03_resume_liveness
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,82,69,83,85,77,69,32,76,73,86,69,34,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: assert_demo_03_resume_liveness
+ type: assert.screen
+ params:
+ contains: "RESUME LIVE"
+ - id: demo_03_resume_intro_clear
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,66,65,67,75,32,73,78,32,82,69,65,68,89,66,65,83,73,67,34,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_03_resume_intro_detail
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,66,65,67,75,32,73,78,32,82,69,65,68,89,66,65,83,73,67,34,13,80,82,73,78,84,32,34,86,65,82,73,65,66,76,69,83,32,65,78,68,32,80,82,79,71,82,65,77,32,84,69,88,84,32,83,72,79,85,76,68,32,82,69,77,65,73,78,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ keys: [80,82,73,78,84,32,34,86,65,82,73,65,66,76,69,83,32,65,78,68,32,80,82,79,71,82,65,77,32,84,69,88,84,32,83,72,79,85,76,68,32,82,69,77,65,73,78,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
inter_key_delay_s: 0.08
post_delay_s: 3.5
- id: demo_03_resume_var_proof
type: input.sequence
params:
- keys: [70,82,69,69,77,69,77,40,41,13,80,82,73,78,84,32,34,65,32,83,84,73,76,76,34,59,65,37,13,80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,65,32,73,83,32,52,50,32,65,78,68,32,82,85,78,32,83,84,73,76,76,32,87,79,82,75,83,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ keys: [77,69,77,65,86,76,40,41,13,80,82,73,78,84,32,34,65,32,83,84,73,76,76,34,59,65,37,13,80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,65,32,73,83,32,52,50,32,65,78,68,32,82,85,78,32,83,84,73,76,76,32,87,79,82,75,83,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
inter_key_delay_s: 0.08
post_delay_s: 3.5
- id: capture_demo_03_resume_var_proof
@@ -311,13 +338,13 @@ steps:
- id: demo_07_intro
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,56,58,32,82,69,85,32,66,85,70,70,69,82,32,67,79,77,77,65,78,68,83,34,13,80,82,73,78,84,32,34,66,85,70,78,69,87,32,82,69,84,85,82,78,83,59,32,70,73,76,76,32,65,78,68,32,70,82,69,69,32,68,79,32,87,79,82,75,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,56,58,32,82,69,85,32,66,85,70,70,69,82,32,67,79,77,77,65,78,68,83,34,13,80,82,73,78,84,32,34,66,85,70,77,65,75,69,32,82,69,84,85,82,78,83,59,32,70,73,76,76,32,65,78,68,32,70,82,69,69,32,68,79,32,87,79,82,75,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
inter_key_delay_s: 0.08
post_delay_s: 3.5
- id: demo_07_reu
type: input.sequence
params:
- keys: [72,37,61,66,85,70,78,69,87,40,54,52,41,13,66,85,70,70,73,76,76,40,72,37,44,49,55,48,41,13,80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,72,65,78,68,76,69,32,49,44,32,84,72,69,78,32,70,82,69,69,68,32,49,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13,80,82,73,78,84,32,34,72,65,78,68,76,69,34,59,72,37,13,66,85,70,70,82,69,69,40,72,37,41,13,80,82,73,78,84,32,34,70,82,69,69,68,34,59,72,37,13]
+ keys: [72,37,61,66,85,70,77,65,75,69,40,54,52,41,13,66,85,70,70,73,76,76,40,72,37,44,49,55,48,41,13,80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,72,65,78,68,76,69,32,49,44,32,84,72,69,78,32,70,82,69,69,68,32,49,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13,80,82,73,78,84,32,34,72,65,78,68,76,69,34,59,72,37,13,66,85,70,68,82,79,80,40,72,37,41,13,80,82,73,78,84,32,34,70,82,69,69,68,34,59,72,37,13]
inter_key_delay_s: 0.08
post_delay_s: 3.5
- id: assert_demo_07_handle
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_demo_suite.regular.yaml b/agentworking/easyflash_full_vice_plans/readybasic_demo_suite.regular.yaml
index ece15ca..6554df9 100644
--- a/agentworking/easyflash_full_vice_plans/readybasic_demo_suite.regular.yaml
+++ b/agentworking/easyflash_full_vice_plans/readybasic_demo_suite.regular.yaml
@@ -19,14 +19,14 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
close_vice: true
- headless: true
+ headless: false
speed_percent: 100
steps:
- id: launch_preboot
@@ -39,16 +39,27 @@ steps:
text: "FREE:"
wait_timeout_s: 180
capture_label: demo_readybasic_prompt
+ - id: warp_off_for_visible_demo
+ type: warp.set
+ params:
+ enabled: false
+ capture_after: false
- id: demo_01_intro
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,49,58,32,82,69,65,68,89,66,65,83,73,67,32,66,65,83,73,67,83,34,13,80,82,73,78,84,32,34,70,82,69,69,77,69,77,44,32,86,65,82,73,65,66,76,69,83,44,32,65,78,68,32,65,32,80,82,79,71,82,65,77,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,49,58,32,82,69,65,68,89,66,65,83,73,67,32,66,65,83,73,67,83,34,13,80,82,73,78,84,32,34,77,69,77,65,86,76,44,32,86,65,82,73,65,66,76,69,83,44,32,65,78,68,32,65,32,80,82,79,71,82,65,77,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
inter_key_delay_s: 0.08
post_delay_s: 3.5
- id: demo_01_setup
type: input.sequence
params:
- keys: [70,82,69,69,77,69,77,40,41,13,78,69,87,13,65,37,61,52,50,13,49,48,32,66,37,61,90,65,68,68,49,54,40,52,50,44,56,41,13,50,48,32,80,82,73,78,84,32,34,80,82,79,71,82,65,77,32,83,85,77,34,59,66,37,13,76,73,83,84,13]
+ keys: [77,69,77,65,86,76,40,41,13,78,69,87,13,65,37,61,52,50,13,49,48,32,66,37,61,90,65,68,68,49,54,40,52,50,44,56,41,13,50,48,32,80,82,73,78,84,32,34,80,82,79,71,82,65,77,32,83,85,77,34,59,66,37,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_01_list
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
inter_key_delay_s: 0.08
post_delay_s: 3.5
- id: demo_01_basics
@@ -121,16 +132,32 @@ steps:
params:
text: "READY."
wait_timeout_s: 60
- - id: demo_03_resume_intro
+ - id: demo_03_resume_liveness
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,82,69,83,85,77,69,32,76,73,86,69,34,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: assert_demo_03_resume_liveness
+ type: assert.screen
+ params:
+ contains: "RESUME LIVE"
+ - id: demo_03_resume_intro_clear
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,66,65,67,75,32,73,78,32,82,69,65,68,89,66,65,83,73,67,34,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_03_resume_intro_detail
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,66,65,67,75,32,73,78,32,82,69,65,68,89,66,65,83,73,67,34,13,80,82,73,78,84,32,34,86,65,82,73,65,66,76,69,83,32,65,78,68,32,80,82,79,71,82,65,77,32,84,69,88,84,32,83,72,79,85,76,68,32,82,69,77,65,73,78,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ keys: [80,82,73,78,84,32,34,86,65,82,73,65,66,76,69,83,32,65,78,68,32,80,82,79,71,82,65,77,32,84,69,88,84,32,83,72,79,85,76,68,32,82,69,77,65,73,78,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
inter_key_delay_s: 0.08
post_delay_s: 3.5
- id: demo_03_resume_var_proof
type: input.sequence
params:
- keys: [70,82,69,69,77,69,77,40,41,13,80,82,73,78,84,32,34,65,32,83,84,73,76,76,34,59,65,37,13,80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,65,32,73,83,32,52,50,32,65,78,68,32,82,85,78,32,83,84,73,76,76,32,87,79,82,75,83,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ keys: [77,69,77,65,86,76,40,41,13,80,82,73,78,84,32,34,65,32,83,84,73,76,76,34,59,65,37,13,80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,65,32,73,83,32,52,50,32,65,78,68,32,82,85,78,32,83,84,73,76,76,32,87,79,82,75,83,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
inter_key_delay_s: 0.08
post_delay_s: 3.5
- id: capture_demo_03_resume_var_proof
@@ -296,13 +323,13 @@ steps:
- id: demo_07_intro
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,56,58,32,82,69,85,32,66,85,70,70,69,82,32,67,79,77,77,65,78,68,83,34,13,80,82,73,78,84,32,34,66,85,70,78,69,87,32,82,69,84,85,82,78,83,59,32,70,73,76,76,32,65,78,68,32,70,82,69,69,32,68,79,32,87,79,82,75,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,56,58,32,82,69,85,32,66,85,70,70,69,82,32,67,79,77,77,65,78,68,83,34,13,80,82,73,78,84,32,34,66,85,70,77,65,75,69,32,82,69,84,85,82,78,83,59,32,70,73,76,76,32,65,78,68,32,70,82,69,69,32,68,79,32,87,79,82,75,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
inter_key_delay_s: 0.08
post_delay_s: 3.5
- id: demo_07_reu
type: input.sequence
params:
- keys: [72,37,61,66,85,70,78,69,87,40,54,52,41,13,66,85,70,70,73,76,76,40,72,37,44,49,55,48,41,13,80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,72,65,78,68,76,69,32,49,44,32,84,72,69,78,32,70,82,69,69,68,32,49,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13,80,82,73,78,84,32,34,72,65,78,68,76,69,34,59,72,37,13,66,85,70,70,82,69,69,40,72,37,41,13,80,82,73,78,84,32,34,70,82,69,69,68,34,59,72,37,13]
+ keys: [72,37,61,66,85,70,77,65,75,69,40,54,52,41,13,66,85,70,70,73,76,76,40,72,37,44,49,55,48,41,13,80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,72,65,78,68,76,69,32,49,44,32,84,72,69,78,32,70,82,69,69,68,32,49,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13,80,82,73,78,84,32,34,72,65,78,68,76,69,34,59,72,37,13,66,85,70,68,82,79,80,40,72,37,41,13,80,82,73,78,84,32,34,70,82,69,69,68,34,59,72,37,13]
inter_key_delay_s: 0.08
post_delay_s: 3.5
- id: assert_demo_07_handle
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_full_suite_visual_verification.easyflash.yaml b/agentworking/easyflash_full_vice_plans/readybasic_full_suite_visual_verification.easyflash.yaml
index da1e906..772ff6b 100644
--- a/agentworking/easyflash_full_vice_plans/readybasic_full_suite_visual_verification.easyflash.yaml
+++ b/agentworking/easyflash_full_vice_plans/readybasic_full_suite_visual_verification.easyflash.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.4/precog-easyflash/readyos_easyflash.crt"
+ cart_crt: "Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
autostart_enabled: false
- disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
+ disk8: "agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
drive8_enabled: true
drive8_type: 1541
drive9_enabled: false
@@ -35,12 +35,16 @@ steps:
params:
kill_stale: true
- id: easyflash_wait_launcher
+ retry:
+ max_attempts: 1
+ backoff_ms: 0
+ jitter: false
type: screen.wait_contains
params:
text: "READY OS"
pre_delay_s: 4
poll_s: 0.5
- wait_timeout_s: 240
+ wait_timeout_s: 420
capture_label: easyflash_readybasic_launcher
- id: easyflash_start_readybasic
type: input.sequence
@@ -51,7 +55,7 @@ steps:
- id: wait_readybasic_prompt
type: screen.wait_contains
params:
- text: "readybasic"
+ text: "READY."
wait_timeout_s: 180
capture_label: readybasic_full_suite_visual_prompt
- id: dump_initial_plugin_state
@@ -66,7 +70,7 @@ steps:
- { label: hidden_visible_a000, start: 0xA000, end: 0xA5FF }
- { label: hidden_overlay_a800, start: 0xA800, end: 0xA8FF }
- { label: bridge_c000, start: 0xC000, end: 0xC5FF }
- - { label: reu_alloc_table_c600, start: 0xC600, end: 0xC6FF }
+ - { label: shim_resident_c600, start: 0xC600, end: 0xC9FF }
- id: direct_ping
type: input.sequence
@@ -255,17 +259,17 @@ steps:
params:
contains: "D-RANGE 7 10"
- - id: direct_bufnew
+ - id: direct_bufmake
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,66,85,70,78,69,87,32,82,69,85,32,72,65,78,68,76,69,32,84,65,66,76,69,32,82,69,84,85,82,78,32,72,37,61,49,32,83,67,82,69,69,78,32,68,45,66,85,70,13,72,37,61,66,85,70,78,69,87,40,51,48,48,41,13,80,82,73,78,84,32,34,68,45,66,85,70,34,59,72,37,59,34,58,69,78,68,34,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,66,85,70,77,65,75,69,32,82,69,85,32,72,65,78,68,76,69,32,84,65,66,76,69,32,82,69,84,85,82,78,32,72,37,61,49,32,83,67,82,69,69,78,32,68,45,66,85,70,13,72,37,61,66,85,70,77,65,75,69,40,51,48,48,41,13,80,82,73,78,84,32,34,68,45,66,85,70,34,59,72,37,59,34,58,69,78,68,34,13]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- - id: assert_direct_bufnew
+ - id: assert_direct_bufmake
type: assert.screen
params:
contains: "D-BUF 1 :END"
- - id: dump_direct_bufnew
+ - id: dump_direct_bufmake
type: dump.memory_ranges
params:
ranges: *plugin_ranges
@@ -285,17 +289,17 @@ steps:
params:
not_contains: "?RB ERROR"
- - id: direct_buffree
+ - id: direct_bufdrop
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,66,85,70,70,82,69,69,32,82,69,76,69,65,83,69,32,82,69,85,32,72,65,78,68,76,69,32,72,37,32,83,67,82,69,69,78,32,68,45,70,82,69,69,13,66,85,70,70,82,69,69,40,72,37,41,13,80,82,73,78,84,32,34,68,45,70,82,69,69,32,79,75,34,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,66,85,70,68,82,79,80,32,82,69,76,69,65,83,69,32,82,69,85,32,72,65,78,68,76,69,32,72,37,32,83,67,82,69,69,78,32,68,45,70,82,69,69,13,66,85,70,68,82,79,80,40,72,37,41,13,80,82,73,78,84,32,34,68,45,70,82,69,69,32,79,75,34,13]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- - id: assert_direct_buffree
+ - id: assert_direct_bufdrop
type: assert.screen
params:
contains: "D-FREE OK"
- - id: assert_direct_buffree_no_error
+ - id: assert_direct_bufdrop_no_error
type: assert.screen_not_contains
params:
not_contains: "?RB ERROR"
@@ -324,24 +328,24 @@ steps:
type: assert.screen
params:
contains: "?RB ERROR 40"
- - id: direct_buffree_screen_handle
+ - id: direct_bufdrop_screen_handle
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,66,85,70,70,82,69,69,32,82,69,76,69,65,83,69,83,32,83,67,82,69,69,78,32,72,65,78,68,76,69,32,84,89,80,69,13,66,85,70,70,82,69,69,40,83,37,41,13,80,82,73,78,84,32,34,68,45,83,67,82,70,82,69,69,34,59,83,37,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,66,85,70,68,82,79,80,32,82,69,76,69,65,83,69,83,32,83,67,82,69,69,78,32,72,65,78,68,76,69,32,84,89,80,69,13,66,85,70,68,82,79,80,40,83,37,41,13,80,82,73,78,84,32,34,68,45,83,67,82,70,82,69,69,34,59,83,37,13]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- - id: assert_direct_buffree_screen_handle
+ - id: assert_direct_bufdrop_screen_handle
type: assert.screen
params:
contains: "D-SCRFREE 1"
- - id: assert_direct_buffree_screen_no_error
+ - id: assert_direct_bufdrop_screen_no_error
type: assert.screen_not_contains
params:
not_contains: "?RB ERROR"
- id: direct_scrput_rejects_buffer_handle
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,83,67,82,80,85,84,32,77,85,83,84,32,82,69,74,69,67,84,32,66,85,70,70,69,82,32,72,65,78,68,76,69,32,84,89,80,69,13,66,37,61,66,85,70,78,69,87,40,51,48,48,41,13,83,67,82,80,85,84,40,66,37,41,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,83,67,82,80,85,84,32,77,85,83,84,32,82,69,74,69,67,84,32,66,85,70,70,69,82,32,72,65,78,68,76,69,32,84,89,80,69,13,66,37,61,66,85,70,77,65,75,69,40,51,48,48,41,13,83,67,82,80,85,84,40,66,37,41,13]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- id: assert_direct_scrput_rejects_buffer_handle
@@ -351,7 +355,7 @@ steps:
- id: direct_free_buffer_after_type_error
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,70,82,69,69,40,66,37,41,13,80,82,73,78,84,32,34,68,45,66,85,70,82,69,69,34,59,66,37,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,68,82,79,80,40,66,37,41,13,80,82,73,78,84,32,34,68,45,66,85,70,82,69,69,34,59,66,37,13]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- id: assert_direct_free_buffer_after_type_error
@@ -366,7 +370,7 @@ steps:
- id: direct_handle_128_edge
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,72,37,61,66,85,70,78,69,87,40,49,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,68,45,72,77,65,88,34,59,72,37,13,82,85,78,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,72,37,61,66,85,70,77,65,75,69,40,49,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,68,45,72,77,65,88,34,59,72,37,13,82,85,78,13]
inter_key_delay_s: 0.03
post_delay_s: 5.0
- id: assert_direct_handle_128_edge
@@ -380,7 +384,7 @@ steps:
- id: direct_handle_129_rejected
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,69,37,61,66,85,70,78,69,87,40,49,41,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,69,37,61,66,85,70,77,65,75,69,40,49,41,13]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- id: assert_direct_handle_129_rejected
@@ -390,7 +394,7 @@ steps:
- id: direct_free_128_handles
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,66,85,70,70,82,69,69,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,68,45,72,70,82,69,69,68,34,13,82,85,78,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,66,85,70,68,82,79,80,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,68,45,72,70,82,69,69,68,34,13,82,85,78,13]
inter_key_delay_s: 0.03
post_delay_s: 5.0
- id: assert_direct_free_128_handles
@@ -404,7 +408,7 @@ steps:
- id: direct_48k_heap_edge
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,77,37,61,66,85,70,78,69,87,40,52,57,49,53,50,41,13,80,82,73,78,84,32,34,68,45,77,65,88,66,85,70,34,59,77,37,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,77,37,61,66,85,70,77,65,75,69,40,52,57,49,53,50,41,13,80,82,73,78,84,32,34,68,45,77,65,88,66,85,70,34,59,77,37,13]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- id: assert_direct_48k_heap_edge
@@ -414,7 +418,7 @@ steps:
- id: direct_48k_heap_full
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,69,37,61,66,85,70,78,69,87,40,49,41,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,69,37,61,66,85,70,77,65,75,69,40,49,41,13]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- id: assert_direct_48k_heap_full
@@ -424,7 +428,7 @@ steps:
- id: direct_free_48k_heap
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,70,82,69,69,40,77,37,41,13,80,82,73,78,84,32,34,68,45,77,65,88,70,82,69,69,34,59,77,37,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,68,82,79,80,40,77,37,41,13,80,82,73,78,84,32,34,68,45,77,65,88,70,82,69,69,34,59,77,37,13]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- id: assert_direct_free_48k_heap
@@ -458,7 +462,7 @@ steps:
- id: direct_free_screen_heap
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,50,52,13,50,48,32,66,85,70,70,82,69,69,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,68,45,83,70,82,69,69,68,34,13,82,85,78,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,50,52,13,50,48,32,66,85,70,68,82,79,80,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,68,45,83,70,82,69,69,68,34,13,82,85,78,13]
inter_key_delay_s: 0.03
post_delay_s: 5.0
- id: assert_direct_free_screen_heap
@@ -655,9 +659,18 @@ steps:
- id: resume_after_exit
type: input.sequence
params:
- keys: [145,17,13]
+ keys: [145,17]
inter_key_delay_s: 0.10
- post_delay_s: 3.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_full_suite_resume
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_after_full_suite_exit
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_resume
type: screen.wait_contains
params:
@@ -866,7 +879,7 @@ steps:
- id: program_handle_enter_and_list
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,77,32,66,85,70,32,82,69,85,32,72,65,78,68,76,69,32,65,76,76,79,67,32,82,69,84,85,82,78,32,70,73,76,76,32,70,82,69,69,32,72,37,61,49,32,83,67,82,69,69,78,32,80,45,66,85,70,13,50,48,32,72,37,61,66,85,70,78,69,87,40,51,48,48,41,13,51,48,32,80,82,73,78,84,32,34,80,45,66,85,70,34,59,72,37,13,52,48,32,66,85,70,70,73,76,76,40,72,37,44,49,55,48,41,13,53,48,32,66,85,70,70,82,69,69,40,72,37,41,13,54,48,32,80,82,73,78,84,32,34,80,45,70,82,69,69,34,59,72,37,13,76,73,83,84,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,77,32,66,85,70,32,82,69,85,32,72,65,78,68,76,69,32,65,76,76,79,67,32,82,69,84,85,82,78,32,70,73,76,76,32,70,82,69,69,32,72,37,61,49,32,83,67,82,69,69,78,32,80,45,66,85,70,13,50,48,32,72,37,61,66,85,70,77,65,75,69,40,51,48,48,41,13,51,48,32,80,82,73,78,84,32,34,80,45,66,85,70,34,59,72,37,13,52,48,32,66,85,70,70,73,76,76,40,72,37,44,49,55,48,41,13,53,48,32,66,85,70,68,82,79,80,40,72,37,41,13,54,48,32,80,82,73,78,84,32,34,80,45,70,82,69,69,34,59,72,37,13,76,73,83,84,13]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- id: assert_program_handle_rem
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_full_suite_visual_verification.regular.yaml b/agentworking/easyflash_full_vice_plans/readybasic_full_suite_visual_verification.regular.yaml
index 19e5b53..e5ddb07 100644
--- a/agentworking/easyflash_full_vice_plans/readybasic_full_suite_visual_verification.regular.yaml
+++ b/agentworking/easyflash_full_vice_plans/readybasic_full_suite_visual_verification.regular.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
@@ -51,7 +51,7 @@ steps:
- { label: hidden_visible_a000, start: 0xA000, end: 0xA5FF }
- { label: hidden_overlay_a800, start: 0xA800, end: 0xA8FF }
- { label: bridge_c000, start: 0xC000, end: 0xC5FF }
- - { label: reu_alloc_table_c600, start: 0xC600, end: 0xC6FF }
+ - { label: shim_resident_c600, start: 0xC600, end: 0xC9FF }
- id: direct_ping
type: input.sequence
@@ -240,17 +240,17 @@ steps:
params:
contains: "D-RANGE 7 10"
- - id: direct_bufnew
+ - id: direct_bufmake
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,66,85,70,78,69,87,32,82,69,85,32,72,65,78,68,76,69,32,84,65,66,76,69,32,82,69,84,85,82,78,32,72,37,61,49,32,83,67,82,69,69,78,32,68,45,66,85,70,13,72,37,61,66,85,70,78,69,87,40,51,48,48,41,13,80,82,73,78,84,32,34,68,45,66,85,70,34,59,72,37,59,34,58,69,78,68,34,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,66,85,70,77,65,75,69,32,82,69,85,32,72,65,78,68,76,69,32,84,65,66,76,69,32,82,69,84,85,82,78,32,72,37,61,49,32,83,67,82,69,69,78,32,68,45,66,85,70,13,72,37,61,66,85,70,77,65,75,69,40,51,48,48,41,13,80,82,73,78,84,32,34,68,45,66,85,70,34,59,72,37,59,34,58,69,78,68,34,13]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- - id: assert_direct_bufnew
+ - id: assert_direct_bufmake
type: assert.screen
params:
contains: "D-BUF 1 :END"
- - id: dump_direct_bufnew
+ - id: dump_direct_bufmake
type: dump.memory_ranges
params:
ranges: *plugin_ranges
@@ -270,17 +270,17 @@ steps:
params:
not_contains: "?RB ERROR"
- - id: direct_buffree
+ - id: direct_bufdrop
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,66,85,70,70,82,69,69,32,82,69,76,69,65,83,69,32,82,69,85,32,72,65,78,68,76,69,32,72,37,32,83,67,82,69,69,78,32,68,45,70,82,69,69,13,66,85,70,70,82,69,69,40,72,37,41,13,80,82,73,78,84,32,34,68,45,70,82,69,69,32,79,75,34,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,66,85,70,68,82,79,80,32,82,69,76,69,65,83,69,32,82,69,85,32,72,65,78,68,76,69,32,72,37,32,83,67,82,69,69,78,32,68,45,70,82,69,69,13,66,85,70,68,82,79,80,40,72,37,41,13,80,82,73,78,84,32,34,68,45,70,82,69,69,32,79,75,34,13]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- - id: assert_direct_buffree
+ - id: assert_direct_bufdrop
type: assert.screen
params:
contains: "D-FREE OK"
- - id: assert_direct_buffree_no_error
+ - id: assert_direct_bufdrop_no_error
type: assert.screen_not_contains
params:
not_contains: "?RB ERROR"
@@ -309,24 +309,24 @@ steps:
type: assert.screen
params:
contains: "?RB ERROR 40"
- - id: direct_buffree_screen_handle
+ - id: direct_bufdrop_screen_handle
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,66,85,70,70,82,69,69,32,82,69,76,69,65,83,69,83,32,83,67,82,69,69,78,32,72,65,78,68,76,69,32,84,89,80,69,13,66,85,70,70,82,69,69,40,83,37,41,13,80,82,73,78,84,32,34,68,45,83,67,82,70,82,69,69,34,59,83,37,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,66,85,70,68,82,79,80,32,82,69,76,69,65,83,69,83,32,83,67,82,69,69,78,32,72,65,78,68,76,69,32,84,89,80,69,13,66,85,70,68,82,79,80,40,83,37,41,13,80,82,73,78,84,32,34,68,45,83,67,82,70,82,69,69,34,59,83,37,13]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- - id: assert_direct_buffree_screen_handle
+ - id: assert_direct_bufdrop_screen_handle
type: assert.screen
params:
contains: "D-SCRFREE 1"
- - id: assert_direct_buffree_screen_no_error
+ - id: assert_direct_bufdrop_screen_no_error
type: assert.screen_not_contains
params:
not_contains: "?RB ERROR"
- id: direct_scrput_rejects_buffer_handle
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,83,67,82,80,85,84,32,77,85,83,84,32,82,69,74,69,67,84,32,66,85,70,70,69,82,32,72,65,78,68,76,69,32,84,89,80,69,13,66,37,61,66,85,70,78,69,87,40,51,48,48,41,13,83,67,82,80,85,84,40,66,37,41,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,83,67,82,80,85,84,32,77,85,83,84,32,82,69,74,69,67,84,32,66,85,70,70,69,82,32,72,65,78,68,76,69,32,84,89,80,69,13,66,37,61,66,85,70,77,65,75,69,40,51,48,48,41,13,83,67,82,80,85,84,40,66,37,41,13]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- id: assert_direct_scrput_rejects_buffer_handle
@@ -336,7 +336,7 @@ steps:
- id: direct_free_buffer_after_type_error
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,70,82,69,69,40,66,37,41,13,80,82,73,78,84,32,34,68,45,66,85,70,82,69,69,34,59,66,37,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,68,82,79,80,40,66,37,41,13,80,82,73,78,84,32,34,68,45,66,85,70,82,69,69,34,59,66,37,13]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- id: assert_direct_free_buffer_after_type_error
@@ -351,7 +351,7 @@ steps:
- id: direct_handle_128_edge
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,72,37,61,66,85,70,78,69,87,40,49,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,68,45,72,77,65,88,34,59,72,37,13,82,85,78,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,72,37,61,66,85,70,77,65,75,69,40,49,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,68,45,72,77,65,88,34,59,72,37,13,82,85,78,13]
inter_key_delay_s: 0.03
post_delay_s: 5.0
- id: assert_direct_handle_128_edge
@@ -365,7 +365,7 @@ steps:
- id: direct_handle_129_rejected
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,69,37,61,66,85,70,78,69,87,40,49,41,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,69,37,61,66,85,70,77,65,75,69,40,49,41,13]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- id: assert_direct_handle_129_rejected
@@ -375,7 +375,7 @@ steps:
- id: direct_free_128_handles
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,66,85,70,70,82,69,69,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,68,45,72,70,82,69,69,68,34,13,82,85,78,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,66,85,70,68,82,79,80,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,68,45,72,70,82,69,69,68,34,13,82,85,78,13]
inter_key_delay_s: 0.03
post_delay_s: 5.0
- id: assert_direct_free_128_handles
@@ -389,7 +389,7 @@ steps:
- id: direct_48k_heap_edge
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,77,37,61,66,85,70,78,69,87,40,52,57,49,53,50,41,13,80,82,73,78,84,32,34,68,45,77,65,88,66,85,70,34,59,77,37,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,77,37,61,66,85,70,77,65,75,69,40,52,57,49,53,50,41,13,80,82,73,78,84,32,34,68,45,77,65,88,66,85,70,34,59,77,37,13]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- id: assert_direct_48k_heap_edge
@@ -399,7 +399,7 @@ steps:
- id: direct_48k_heap_full
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,69,37,61,66,85,70,78,69,87,40,49,41,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,69,37,61,66,85,70,77,65,75,69,40,49,41,13]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- id: assert_direct_48k_heap_full
@@ -409,7 +409,7 @@ steps:
- id: direct_free_48k_heap
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,70,82,69,69,40,77,37,41,13,80,82,73,78,84,32,34,68,45,77,65,88,70,82,69,69,34,59,77,37,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,68,82,79,80,40,77,37,41,13,80,82,73,78,84,32,34,68,45,77,65,88,70,82,69,69,34,59,77,37,13]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- id: assert_direct_free_48k_heap
@@ -443,7 +443,7 @@ steps:
- id: direct_free_screen_heap
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,50,52,13,50,48,32,66,85,70,70,82,69,69,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,68,45,83,70,82,69,69,68,34,13,82,85,78,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,50,52,13,50,48,32,66,85,70,68,82,79,80,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,68,45,83,70,82,69,69,68,34,13,82,85,78,13]
inter_key_delay_s: 0.03
post_delay_s: 5.0
- id: assert_direct_free_screen_heap
@@ -640,9 +640,18 @@ steps:
- id: resume_after_exit
type: input.sequence
params:
- keys: [145,17,13]
+ keys: [145,17]
inter_key_delay_s: 0.10
- post_delay_s: 3.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_full_suite_resume
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_after_full_suite_exit
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_resume
type: screen.wait_contains
params:
@@ -851,7 +860,7 @@ steps:
- id: program_handle_enter_and_list
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,77,32,66,85,70,32,82,69,85,32,72,65,78,68,76,69,32,65,76,76,79,67,32,82,69,84,85,82,78,32,70,73,76,76,32,70,82,69,69,32,72,37,61,49,32,83,67,82,69,69,78,32,80,45,66,85,70,13,50,48,32,72,37,61,66,85,70,78,69,87,40,51,48,48,41,13,51,48,32,80,82,73,78,84,32,34,80,45,66,85,70,34,59,72,37,13,52,48,32,66,85,70,70,73,76,76,40,72,37,44,49,55,48,41,13,53,48,32,66,85,70,70,82,69,69,40,72,37,41,13,54,48,32,80,82,73,78,84,32,34,80,45,70,82,69,69,34,59,72,37,13,76,73,83,84,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,77,32,66,85,70,32,82,69,85,32,72,65,78,68,76,69,32,65,76,76,79,67,32,82,69,84,85,82,78,32,70,73,76,76,32,70,82,69,69,32,72,37,61,49,32,83,67,82,69,69,78,32,80,45,66,85,70,13,50,48,32,72,37,61,66,85,70,77,65,75,69,40,51,48,48,41,13,51,48,32,80,82,73,78,84,32,34,80,45,66,85,70,34,59,72,37,13,52,48,32,66,85,70,70,73,76,76,40,72,37,44,49,55,48,41,13,53,48,32,66,85,70,68,82,79,80,40,72,37,41,13,54,48,32,80,82,73,78,84,32,34,80,45,70,82,69,69,34,59,72,37,13,76,73,83,84,13]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- id: assert_program_handle_rem
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_hotkey_f2_probe.easyflash.yaml b/agentworking/easyflash_full_vice_plans/readybasic_hotkey_f2_probe.easyflash.yaml
new file mode 100644
index 0000000..9d3c07f
--- /dev/null
+++ b/agentworking/easyflash_full_vice_plans/readybasic_hotkey_f2_probe.easyflash.yaml
@@ -0,0 +1,106 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_hotkey_f2_probe_easyflash
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
+ autostart_enabled: false
+ disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
+ drive8_enabled: true
+ drive8_type: 1541
+ drive9_enabled: false
+ true_drive: true
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: easyflash_wait_launcher
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ pre_delay_s: 4
+ poll_s: 0.5
+ wait_timeout_s: 420
+ capture_label: easyflash_readybasic_launcher
+ - id: easyflash_start_readybasic
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 180
+ capture_label: readybasic_hotkey_f2_prompt
+ - id: assert_chrin_vector_installed
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "08 12"
+ - id: assert_keylog_vector_installed
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "7E C1"
+ - id: f2_to_next_loaded_app_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 4C 74 A4"
+ - id: f2_to_next_loaded_app_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: f2_to_next_loaded_app
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_target_after_f2
+ type: screen.wait_contains
+ params:
+ text: "CALENDAR 26"
+ wait_timeout_s: 60
+ capture_label: target_after_readybasic_f2
+ - id: assert_keyboard_buffer_empty_after_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: wait_target_stable_after_f2
+ type: screen.wait_contains
+ params:
+ text: "CALENDAR 26"
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: target_stable_after_readybasic_f2
+ - id: assert_keyboard_buffer_empty_stable_after_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_hotkey_f2_probe.regular.yaml b/agentworking/easyflash_full_vice_plans/readybasic_hotkey_f2_probe.regular.yaml
new file mode 100644
index 0000000..638755e
--- /dev/null
+++ b/agentworking/easyflash_full_vice_plans/readybasic_hotkey_f2_probe.regular.yaml
@@ -0,0 +1,91 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_hotkey_f2_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "readybasic"
+ wait_timeout_s: 180
+ capture_label: readybasic_hotkey_f2_prompt
+ - id: assert_chrin_vector_installed
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "08 12"
+ - id: assert_keylog_vector_installed
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "7E C1"
+ - id: f2_to_next_loaded_app_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 4C 74 A4"
+ - id: f2_to_next_loaded_app_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: f2_to_next_loaded_app
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_target_after_f2
+ type: screen.wait_contains
+ params:
+ text: "CALENDAR 26"
+ wait_timeout_s: 60
+ capture_label: target_after_readybasic_f2
+ - id: assert_keyboard_buffer_empty_after_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: wait_target_stable_after_f2
+ type: screen.wait_contains
+ params:
+ text: "CALENDAR 26"
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: target_stable_after_readybasic_f2
+ - id: assert_keyboard_buffer_empty_stable_after_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_hotkey_f4_probe.easyflash.yaml b/agentworking/easyflash_full_vice_plans/readybasic_hotkey_f4_probe.easyflash.yaml
new file mode 100644
index 0000000..4730502
--- /dev/null
+++ b/agentworking/easyflash_full_vice_plans/readybasic_hotkey_f4_probe.easyflash.yaml
@@ -0,0 +1,231 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_hotkey_probe_easyflash
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
+ autostart_enabled: false
+ disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
+ drive8_enabled: true
+ drive8_type: 1541
+ drive9_enabled: false
+ true_drive: true
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: easyflash_wait_launcher
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ pre_delay_s: 4
+ poll_s: 0.5
+ wait_timeout_s: 420
+ capture_label: easyflash_readybasic_launcher
+ - id: easyflash_start_readybasic
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 180
+ capture_label: readybasic_hotkey_prompt
+ - id: assert_chrin_vector_installed
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "08 12"
+ - id: assert_keylog_vector_installed
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "7E C1"
+ - id: seed_readybasic_state
+ type: input.sequence
+ params:
+ keys: [86,37,61,51,50,49,58,86,83,36,61,34,72,79,84,34,13,80,82,73,78,84,32,34,72,79,84,83,69,69,68,34,59,86,37,59,34,58,34,59,86,83,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: seed_readybasic_state_capture
+ type: screen.capture
+ params:
+ label: seed_readybasic_state
+ pitch: after seeding ReadyBASIC state before hotkey tests
+ - id: assert_seed_state
+ type: assert.screen
+ params:
+ contains: "HOTSEED 321 :HOT"
+ - id: ctrl_b_from_readybasic_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 4C 74 A4"
+ - id: ctrl_b_from_readybasic_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: ctrl_b_from_readybasic
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: ctrl_b_from_readybasic_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_ctrl_b_from_readybasic_after_input
+ pitch: after Ctrl+B input before launcher wait
+ - id: wait_launcher_after_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ capture_label: launcher_after_readybasic_ctrl_b
+ - id: assert_keyboard_buffer_empty_after_ctrl_b
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: move_readybasic_to_editor
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: move_readybasic_to_editor_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_readybasic_to_editor_menu
+ pitch: after navigating to editor from launcher
+ - id: wait_editor_loaded
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ capture_label: editor_loaded_for_hotkey_probe
+ - id: ctrl_b_from_editor
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
+ - id: ctrl_b_from_editor_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_ctrl_b_from_editor_after_input
+ pitch: after Ctrl+B input from editor before launcher wait
+ - id: wait_launcher_after_editor
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ - id: move_editor_to_readybasic_for_f4
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: move_editor_to_readybasic_for_f4_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_editor_to_readybasic_menu
+ pitch: after navigating back to ReadyBASIC before F4 test
+ - id: wait_readybasic_resume_for_f4
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_resume_before_f4
+ - id: assert_readybasic_state_after_ctrl_b
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,72,79,84,83,84,65,84,69,34,59,86,37,59,34,58,34,59,86,83,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_state_after_ctrl_b_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_state_after_ctrl_b
+ pitch: after typing HOTSTATE verification command
+ - id: assert_hot_state_after_ctrl_b
+ type: assert.screen
+ params:
+ contains: "HOTSTATE 321 :HOT"
+ - id: build_list_timing_program
+ type: input.sequence
+ params:
+ keys: [49,48,32,80,82,73,78,84,32,34,72,79,84,76,73,83,84,49,34,13,50,48,32,80,82,73,78,84,32,34,72,79,84,76,73,83,84,50,34,13,51,48,32,80,82,73,78,84,32,34,72,79,84,76,73,83,84,51,34,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.2
+ - id: build_list_timing_program_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_list_before_f4
+ pitch: after building LIST program before F4
+ - id: wait_list_visible_before_f4
+ type: screen.wait_contains
+ params:
+ text: "HOTLIST3"
+ wait_timeout_s: 20
+ capture_label: readybasic_list_before_f4
+ - id: f4_to_prev_loaded_app_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 01 8D 8D 02 A9 05 85 CB 20 7E C1 A9 01 8D 8D 02 A9 05 85 CB 20 7E C1 4C 74 A4"
+ - id: f4_to_prev_loaded_app_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: f4_to_prev_loaded_app
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_target_after_f4
+ type: screen.wait_contains
+ params:
+ text: "CLIPBOARD"
+ wait_timeout_s: 60
+ capture_label: target_after_readybasic_f4
+ - id: assert_keyboard_buffer_empty_after_f4
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: wait_target_stable_after_f4
+ type: screen.wait_contains
+ params:
+ text: "CLIPBOARD"
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: target_stable_after_readybasic_f4
+ - id: assert_keyboard_buffer_empty_stable_after_f4
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_hotkey_f4_probe.regular.yaml b/agentworking/easyflash_full_vice_plans/readybasic_hotkey_f4_probe.regular.yaml
new file mode 100644
index 0000000..4a70ed6
--- /dev/null
+++ b/agentworking/easyflash_full_vice_plans/readybasic_hotkey_f4_probe.regular.yaml
@@ -0,0 +1,216 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_hotkey_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "readybasic"
+ wait_timeout_s: 180
+ capture_label: readybasic_hotkey_prompt
+ - id: assert_chrin_vector_installed
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "08 12"
+ - id: assert_keylog_vector_installed
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "7E C1"
+ - id: seed_readybasic_state
+ type: input.sequence
+ params:
+ keys: [86,37,61,51,50,49,58,86,83,36,61,34,72,79,84,34,13,80,82,73,78,84,32,34,72,79,84,83,69,69,68,34,59,86,37,59,34,58,34,59,86,83,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: seed_readybasic_state_capture
+ type: screen.capture
+ params:
+ label: seed_readybasic_state
+ pitch: after seeding ReadyBASIC state before hotkey tests
+ - id: assert_seed_state
+ type: assert.screen
+ params:
+ contains: "HOTSEED 321 :HOT"
+ - id: ctrl_b_from_readybasic_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 4C 74 A4"
+ - id: ctrl_b_from_readybasic_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: ctrl_b_from_readybasic
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: ctrl_b_from_readybasic_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_ctrl_b_from_readybasic_after_input
+ pitch: after Ctrl+B input before launcher wait
+ - id: wait_launcher_after_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ capture_label: launcher_after_readybasic_ctrl_b
+ - id: assert_keyboard_buffer_empty_after_ctrl_b
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: move_readybasic_to_editor
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: move_readybasic_to_editor_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_readybasic_to_editor_menu
+ pitch: after navigating to editor from launcher
+ - id: wait_editor_loaded
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ capture_label: editor_loaded_for_hotkey_probe
+ - id: ctrl_b_from_editor
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
+ - id: ctrl_b_from_editor_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_ctrl_b_from_editor_after_input
+ pitch: after Ctrl+B input from editor before launcher wait
+ - id: wait_launcher_after_editor
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ - id: move_editor_to_readybasic_for_f4
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: move_editor_to_readybasic_for_f4_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_editor_to_readybasic_menu
+ pitch: after navigating back to ReadyBASIC before F4 test
+ - id: wait_readybasic_resume_for_f4
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_resume_before_f4
+ - id: assert_readybasic_state_after_ctrl_b
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,72,79,84,83,84,65,84,69,34,59,86,37,59,34,58,34,59,86,83,36,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_state_after_ctrl_b_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_state_after_ctrl_b
+ pitch: after typing HOTSTATE verification command
+ - id: assert_hot_state_after_ctrl_b
+ type: assert.screen
+ params:
+ contains: "HOTSTATE 321 :HOT"
+ - id: build_list_timing_program
+ type: input.sequence
+ params:
+ keys: [49,48,32,80,82,73,78,84,32,34,72,79,84,76,73,83,84,49,34,13,50,48,32,80,82,73,78,84,32,34,72,79,84,76,73,83,84,50,34,13,51,48,32,80,82,73,78,84,32,34,72,79,84,76,73,83,84,51,34,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.2
+ - id: build_list_timing_program_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_list_before_f4
+ pitch: after building LIST program before F4
+ - id: wait_list_visible_before_f4
+ type: screen.wait_contains
+ params:
+ text: "HOTLIST3"
+ wait_timeout_s: 20
+ capture_label: readybasic_list_before_f4
+ - id: f4_to_prev_loaded_app_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 01 8D 8D 02 A9 05 85 CB 20 7E C1 A9 01 8D 8D 02 A9 05 85 CB 20 7E C1 4C 74 A4"
+ - id: f4_to_prev_loaded_app_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: f4_to_prev_loaded_app
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_target_after_f4
+ type: screen.wait_contains
+ params:
+ text: "CLIPBOARD"
+ wait_timeout_s: 60
+ capture_label: target_after_readybasic_f4
+ - id: assert_keyboard_buffer_empty_after_f4
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: wait_target_stable_after_f4
+ type: screen.wait_contains
+ params:
+ text: "CLIPBOARD"
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: target_stable_after_readybasic_f4
+ - id: assert_keyboard_buffer_empty_stable_after_f4
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_keyboard_regression_probe.easyflash.yaml b/agentworking/easyflash_full_vice_plans/readybasic_keyboard_regression_probe.easyflash.yaml
new file mode 100644
index 0000000..acb7a98
--- /dev/null
+++ b/agentworking/easyflash_full_vice_plans/readybasic_keyboard_regression_probe.easyflash.yaml
@@ -0,0 +1,258 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_keyboard_regression_probe_easyflash
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
+ autostart_enabled: false
+ disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
+ drive8_enabled: true
+ drive8_type: 1541
+ drive9_enabled: false
+ true_drive: true
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_launcher_initial
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ pre_delay_s: 4
+ poll_s: 0.5
+ wait_timeout_s: 420
+ capture_label: keyboard_regression_launcher_initial
+ - id: launch_readybasic_from_launcher
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_initial
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 180
+ capture_label: keyboard_regression_readybasic_initial
+ - id: assert_readybasic_bank_initial
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "05"
+ - id: assert_chrin_vector_initial
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "08 12"
+ - id: assert_keylog_vector_initial
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "7E C1"
+ - id: assert_warp_enabled
+ type: warp.set
+ params:
+ enabled: true
+ capture_after: false
+ - id: type_space_string_once
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,65,32,66,32,67,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_single_space_string_output
+ type: assert.screen
+ params:
+ contains: "A B C"
+ - id: assert_keyboard_buffer_empty_after_space_string
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: type_partial_line_10
+ type: input.sequence
+ params:
+ keys: [49,48]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.1
+ - id: partial_line_ctrl_b_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 4C 74 A4"
+ - id: partial_line_ctrl_b_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: partial_line_ctrl_b
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_launcher_after_partial_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ capture_label: keyboard_regression_launcher_after_partial_ctrl_b
+ - id: assert_no_rem_after_partial_ctrl_b
+ type: assert.screen_not_contains
+ params:
+ not_contains: "REM"
+ - id: assert_launcher_bank_after_partial_ctrl_b
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "00"
+ - id: reenter_readybasic_after_partial_ctrl_b
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
+ - id: wait_readybasic_after_partial_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: keyboard_regression_readybasic_after_partial_ctrl_b
+ - id: list_after_partial_ctrl_b
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_no_rem_listed_after_partial_ctrl_b
+ type: assert.screen_not_contains
+ params:
+ not_contains: "REM"
+ - id: type_after_partial_ctrl_b
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,65,70,84,69,82,67,84,82,76,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_type_after_partial_ctrl_b
+ type: assert.screen
+ params:
+ contains: "AFTERCTRL"
+ - id: clean_ctrl_b_to_launcher_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 4C 74 A4"
+ - id: clean_ctrl_b_to_launcher_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: clean_ctrl_b_to_launcher
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_launcher_to_load_editor
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ - id: move_readybasic_to_editor
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_loaded
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ capture_label: keyboard_regression_editor_loaded
+ - id: editor_ctrl_b_to_launcher
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
+ - id: wait_launcher_after_editor_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ - id: move_editor_to_readybasic
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_before_partial_f2
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: keyboard_regression_readybasic_before_partial_f2
+ - id: type_partial_line_20
+ type: input.sequence
+ params:
+ keys: [50,48]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.1
+ - id: partial_line_f2_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 4C 74 A4"
+ - id: partial_line_f2_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: partial_line_f2
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_editor_after_partial_f2
+ type: screen.wait_contains
+ params:
+ text: "CALENDAR 26"
+ wait_timeout_s: 60
+ capture_label: keyboard_regression_editor_after_partial_f2
+ - id: assert_no_rem_after_partial_f2
+ type: assert.screen_not_contains
+ params:
+ not_contains: "REM"
+ - id: assert_keylog_restored_after_partial_f2
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "48 EB"
+ - id: assert_chrin_restored_after_partial_f2
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "57 F1"
+ - id: assert_keyboard_buffer_empty_after_partial_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_keyboard_regression_probe.regular.yaml b/agentworking/easyflash_full_vice_plans/readybasic_keyboard_regression_probe.regular.yaml
new file mode 100644
index 0000000..45625aa
--- /dev/null
+++ b/agentworking/easyflash_full_vice_plans/readybasic_keyboard_regression_probe.regular.yaml
@@ -0,0 +1,255 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_keyboard_regression_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_launcher_initial
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 180
+ capture_label: keyboard_regression_launcher_initial
+ - id: launch_readybasic_from_launcher
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_initial
+ type: screen.wait_contains
+ params:
+ text: "readybasic"
+ wait_timeout_s: 180
+ capture_label: keyboard_regression_readybasic_initial
+ - id: assert_readybasic_bank_initial
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "05"
+ - id: assert_chrin_vector_initial
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "08 12"
+ - id: assert_keylog_vector_initial
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "7E C1"
+ - id: assert_warp_enabled
+ type: warp.set
+ params:
+ enabled: true
+ capture_after: false
+ - id: type_space_string_once
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,65,32,66,32,67,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_single_space_string_output
+ type: assert.screen
+ params:
+ contains: "A B C"
+ - id: assert_keyboard_buffer_empty_after_space_string
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: type_partial_line_10
+ type: input.sequence
+ params:
+ keys: [49,48]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.1
+ - id: partial_line_ctrl_b_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 4C 74 A4"
+ - id: partial_line_ctrl_b_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: partial_line_ctrl_b
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_launcher_after_partial_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ capture_label: keyboard_regression_launcher_after_partial_ctrl_b
+ - id: assert_no_rem_after_partial_ctrl_b
+ type: assert.screen_not_contains
+ params:
+ not_contains: "REM"
+ - id: assert_launcher_bank_after_partial_ctrl_b
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "00"
+ - id: reenter_readybasic_after_partial_ctrl_b
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
+ - id: wait_readybasic_after_partial_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: keyboard_regression_readybasic_after_partial_ctrl_b
+ - id: list_after_partial_ctrl_b
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_no_rem_listed_after_partial_ctrl_b
+ type: assert.screen_not_contains
+ params:
+ not_contains: "REM"
+ - id: type_after_partial_ctrl_b
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,65,70,84,69,82,67,84,82,76,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_type_after_partial_ctrl_b
+ type: assert.screen
+ params:
+ contains: "AFTERCTRL"
+ - id: clean_ctrl_b_to_launcher_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 4C 74 A4"
+ - id: clean_ctrl_b_to_launcher_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: clean_ctrl_b_to_launcher
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_launcher_to_load_editor
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ - id: move_readybasic_to_editor
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_loaded
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ capture_label: keyboard_regression_editor_loaded
+ - id: editor_ctrl_b_to_launcher
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
+ - id: wait_launcher_after_editor_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ - id: move_editor_to_readybasic
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_before_partial_f2
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: keyboard_regression_readybasic_before_partial_f2
+ - id: type_partial_line_20
+ type: input.sequence
+ params:
+ keys: [50,48]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.1
+ - id: partial_line_f2_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 4C 74 A4"
+ - id: partial_line_f2_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: partial_line_f2
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_editor_after_partial_f2
+ type: screen.wait_contains
+ params:
+ text: "CALENDAR 26"
+ wait_timeout_s: 60
+ capture_label: keyboard_regression_editor_after_partial_f2
+ - id: assert_no_rem_after_partial_f2
+ type: assert.screen_not_contains
+ params:
+ not_contains: "REM"
+ - id: assert_keylog_restored_after_partial_f2
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "48 EB"
+ - id: assert_chrin_restored_after_partial_f2
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "57 F1"
+ - id: assert_keyboard_buffer_empty_after_partial_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_large_vars_probe.easyflash.yaml b/agentworking/easyflash_full_vice_plans/readybasic_large_vars_probe.easyflash.yaml
index d075cb2..71245b6 100644
--- a/agentworking/easyflash_full_vice_plans/readybasic_large_vars_probe.easyflash.yaml
+++ b/agentworking/easyflash_full_vice_plans/readybasic_large_vars_probe.easyflash.yaml
@@ -19,7 +19,7 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.4/precog-easyflash/readyos_easyflash.crt"
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
autostart_enabled: false
disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
drive8_enabled: true
@@ -40,7 +40,7 @@ steps:
text: "READY OS"
pre_delay_s: 4
poll_s: 0.5
- wait_timeout_s: 240
+ wait_timeout_s: 420
capture_label: easyflash_readybasic_launcher
- id: easyflash_start_readybasic
type: input.sequence
@@ -51,7 +51,7 @@ steps:
- id: wait_readybasic_prompt
type: screen.wait_contains
params:
- text: "readybasic"
+ text: "READY."
wait_timeout_s: 180
capture_label: readybasic_prompt
- id: build_program_lines
@@ -88,7 +88,7 @@ steps:
type: dump.memory_ranges
params:
ranges:
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
- { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
- { label: bridge_c000, start: 0xC000, end: 0xC5FF }
@@ -102,7 +102,7 @@ steps:
type: dump.memory_ranges
params:
ranges:
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
- { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
- { label: bridge_c000, start: 0xC000, end: 0xC5FF }
@@ -120,7 +120,7 @@ steps:
type: dump.memory_ranges
params:
ranges:
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
- { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
- { label: bridge_c000, start: 0xC000, end: 0xC5FF }
@@ -134,7 +134,7 @@ steps:
type: dump.memory_ranges
params:
ranges:
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
- { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
- { label: bridge_c000, start: 0xC000, end: 0xC5FF }
@@ -146,7 +146,7 @@ steps:
type: dump.memory_ranges
params:
ranges:
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
- { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
- id: dim_large_array
@@ -165,7 +165,7 @@ steps:
type: dump.memory_ranges
params:
ranges:
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
- { label: basic_vars_start_1200, start: 0x1200, end: 0x1600 }
- { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
@@ -199,11 +199,9 @@ steps:
text: "READY OS"
wait_timeout_s: 30
- id: resume_readybasic
- type: input.sequence
+ type: monitor.command
params:
- keys: [13]
- inter_key_delay_s: 0.03
- post_delay_s: 2.0
+ command: "keybuf \\x0d"
- id: wait_prompt_after_resume
type: screen.wait_contains
params:
@@ -219,7 +217,7 @@ steps:
type: dump.memory_ranges
params:
ranges:
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
- { label: basic_vars_start_1200, start: 0x1200, end: 0x1600 }
- { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
@@ -253,7 +251,7 @@ steps:
type: dump.memory_ranges
params:
ranges:
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
- { label: basic_vars_start_1200, start: 0x1200, end: 0x1600 }
- { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_large_vars_probe.regular.yaml b/agentworking/easyflash_full_vice_plans/readybasic_large_vars_probe.regular.yaml
index 3d740e1..9d8ecc1 100644
--- a/agentworking/easyflash_full_vice_plans/readybasic_large_vars_probe.regular.yaml
+++ b/agentworking/easyflash_full_vice_plans/readybasic_large_vars_probe.regular.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
@@ -73,7 +73,7 @@ steps:
type: dump.memory_ranges
params:
ranges:
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
- { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
- { label: bridge_c000, start: 0xC000, end: 0xC5FF }
@@ -87,7 +87,7 @@ steps:
type: dump.memory_ranges
params:
ranges:
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
- { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
- { label: bridge_c000, start: 0xC000, end: 0xC5FF }
@@ -105,7 +105,7 @@ steps:
type: dump.memory_ranges
params:
ranges:
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
- { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
- { label: bridge_c000, start: 0xC000, end: 0xC5FF }
@@ -119,7 +119,7 @@ steps:
type: dump.memory_ranges
params:
ranges:
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
- { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
- { label: bridge_c000, start: 0xC000, end: 0xC5FF }
@@ -131,7 +131,7 @@ steps:
type: dump.memory_ranges
params:
ranges:
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
- { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
- id: dim_large_array
@@ -150,7 +150,7 @@ steps:
type: dump.memory_ranges
params:
ranges:
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
- { label: basic_vars_start_1200, start: 0x1200, end: 0x1600 }
- { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
@@ -184,11 +184,9 @@ steps:
text: "READY OS"
wait_timeout_s: 30
- id: resume_readybasic
- type: input.sequence
+ type: monitor.command
params:
- keys: [13]
- inter_key_delay_s: 0.03
- post_delay_s: 2.0
+ command: "keybuf \\x0d"
- id: wait_prompt_after_resume
type: screen.wait_contains
params:
@@ -204,7 +202,7 @@ steps:
type: dump.memory_ranges
params:
ranges:
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
- { label: basic_vars_start_1200, start: 0x1200, end: 0x1600 }
- { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
@@ -238,7 +236,7 @@ steps:
type: dump.memory_ranges
params:
ranges:
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
- { label: basic_vars_start_1200, start: 0x1200, end: 0x1600 }
- { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_lifecycle_probe.easyflash.yaml b/agentworking/easyflash_full_vice_plans/readybasic_lifecycle_probe.easyflash.yaml
index 7a82906..e32e882 100644
--- a/agentworking/easyflash_full_vice_plans/readybasic_lifecycle_probe.easyflash.yaml
+++ b/agentworking/easyflash_full_vice_plans/readybasic_lifecycle_probe.easyflash.yaml
@@ -19,7 +19,7 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.4/precog-easyflash/readyos_easyflash.crt"
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
autostart_enabled: false
disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
drive8_enabled: true
@@ -40,7 +40,7 @@ steps:
text: "READY OS"
pre_delay_s: 4
poll_s: 0.5
- wait_timeout_s: 240
+ wait_timeout_s: 420
capture_label: easyflash_readybasic_launcher
- id: easyflash_start_readybasic
type: input.sequence
@@ -51,17 +51,17 @@ steps:
- id: wait_readybasic_loading
type: screen.wait_contains
params:
- text: "readybasic"
+ text: "READY."
wait_timeout_s: 180
- id: capture_after_readybasic_loading
type: screen.capture
params:
label: after_readybasic_loading
- note: after READYBASIC first appears, before READY prompt wait
+ pitch: after READYBASIC first appears, before READY prompt wait
- id: wait_readybasic_prompt
type: screen.wait_contains
params:
- text: "readybasic"
+ text: "READY."
wait_timeout_s: 180
capture_label: readybasic_prompt
- id: dump_prompt_core
@@ -92,7 +92,7 @@ steps:
type: screen.capture
params:
label: after_print_1
- note: after direct print 1
+ pitch: after direct print 1
- id: assert_print_1_no_error
type: assert.screen_not_contains
params:
@@ -111,7 +111,7 @@ steps:
type: screen.capture
params:
label: after_print_hello
- note: after direct print hello
+ pitch: after direct print hello
- id: assert_print_hello_no_error
type: assert.screen_not_contains
params:
@@ -130,7 +130,7 @@ steps:
type: screen.capture
params:
label: after_10_print_1
- note: after numbered line entry
+ pitch: after numbered line entry
- id: dump_line_entry_core
type: dump.memory_ranges
params:
@@ -153,7 +153,7 @@ steps:
type: screen.capture
params:
label: after_list
- note: after LIST
+ pitch: after LIST
- id: assert_list_has_line
type: assert.screen
params:
@@ -168,7 +168,7 @@ steps:
type: screen.capture
params:
label: after_run
- note: after RUN
+ pitch: after RUN
- id: assert_run_no_error
type: assert.screen_not_contains
params:
@@ -191,7 +191,7 @@ steps:
type: screen.capture
params:
label: after_rb_direct_text
- note: after direct scalar command statement
+ pitch: after direct scalar command statement
- id: dump_rb_direct_text_core
type: dump.memory_ranges
params:
@@ -210,7 +210,7 @@ steps:
type: screen.capture
params:
label: after_rb_direct_add
- note: after direct ZADD16 statement
+ pitch: after direct ZADD16 statement
- id: dump_rb_direct_add_core
type: dump.memory_ranges
params:
@@ -235,7 +235,7 @@ steps:
type: screen.capture
params:
label: after_run_with_rb_line
- note: after RUN with stored ReadyBASIC command
+ pitch: after RUN with stored ReadyBASIC command
- id: assert_run_with_rb_line
type: assert.screen
params:
@@ -250,7 +250,7 @@ steps:
type: screen.capture
params:
label: after_exit
- note: after uppercase exit command
+ pitch: after uppercase exit command
- id: wait_launcher_after_exit
type: screen.wait_contains
params:
@@ -259,9 +259,20 @@ steps:
- id: type_resume_readybasic
type: input.sequence
params:
- keys: [145,17,13]
+ keys: [145,17]
inter_key_delay_s: 0.10
- post_delay_s: 3.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_resume
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ # The binary-monitor input helper can drop a lone RETURN immediately after
+ # ReadyBASIC's EXIT return. VICE's text-monitor keybuf path is deterministic.
+ - id: launch_readybasic_after_exit
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_prompt_after_resume
type: screen.wait_contains
params:
@@ -279,7 +290,7 @@ steps:
type: screen.capture
params:
label: after_list_after_resume
- note: after relaunching ReadyBASIC from REU and LISTing
+ pitch: after relaunching ReadyBASIC from REU and LISTing
- id: assert_resume_preserved_line
type: assert.screen
params:
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_lifecycle_probe.regular.yaml b/agentworking/easyflash_full_vice_plans/readybasic_lifecycle_probe.regular.yaml
index 5c16e2b..00df2ac 100644
--- a/agentworking/easyflash_full_vice_plans/readybasic_lifecycle_probe.regular.yaml
+++ b/agentworking/easyflash_full_vice_plans/readybasic_lifecycle_probe.regular.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
@@ -42,7 +42,7 @@ steps:
type: screen.capture
params:
label: after_readybasic_loading
- note: after READYBASIC first appears, before READY prompt wait
+ pitch: after READYBASIC first appears, before READY prompt wait
- id: wait_readybasic_prompt
type: screen.wait_contains
params:
@@ -77,7 +77,7 @@ steps:
type: screen.capture
params:
label: after_print_1
- note: after direct print 1
+ pitch: after direct print 1
- id: assert_print_1_no_error
type: assert.screen_not_contains
params:
@@ -96,7 +96,7 @@ steps:
type: screen.capture
params:
label: after_print_hello
- note: after direct print hello
+ pitch: after direct print hello
- id: assert_print_hello_no_error
type: assert.screen_not_contains
params:
@@ -115,7 +115,7 @@ steps:
type: screen.capture
params:
label: after_10_print_1
- note: after numbered line entry
+ pitch: after numbered line entry
- id: dump_line_entry_core
type: dump.memory_ranges
params:
@@ -138,7 +138,7 @@ steps:
type: screen.capture
params:
label: after_list
- note: after LIST
+ pitch: after LIST
- id: assert_list_has_line
type: assert.screen
params:
@@ -153,7 +153,7 @@ steps:
type: screen.capture
params:
label: after_run
- note: after RUN
+ pitch: after RUN
- id: assert_run_no_error
type: assert.screen_not_contains
params:
@@ -176,7 +176,7 @@ steps:
type: screen.capture
params:
label: after_rb_direct_text
- note: after direct scalar command statement
+ pitch: after direct scalar command statement
- id: dump_rb_direct_text_core
type: dump.memory_ranges
params:
@@ -195,7 +195,7 @@ steps:
type: screen.capture
params:
label: after_rb_direct_add
- note: after direct ZADD16 statement
+ pitch: after direct ZADD16 statement
- id: dump_rb_direct_add_core
type: dump.memory_ranges
params:
@@ -220,7 +220,7 @@ steps:
type: screen.capture
params:
label: after_run_with_rb_line
- note: after RUN with stored ReadyBASIC command
+ pitch: after RUN with stored ReadyBASIC command
- id: assert_run_with_rb_line
type: assert.screen
params:
@@ -235,7 +235,7 @@ steps:
type: screen.capture
params:
label: after_exit
- note: after uppercase exit command
+ pitch: after uppercase exit command
- id: wait_launcher_after_exit
type: screen.wait_contains
params:
@@ -244,9 +244,20 @@ steps:
- id: type_resume_readybasic
type: input.sequence
params:
- keys: [145,17,13]
+ keys: [145,17]
inter_key_delay_s: 0.10
- post_delay_s: 3.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_resume
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ # The binary-monitor input helper can drop a lone RETURN immediately after
+ # ReadyBASIC's EXIT return. VICE's text-monitor keybuf path is deterministic.
+ - id: launch_readybasic_after_exit
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_prompt_after_resume
type: screen.wait_contains
params:
@@ -264,7 +275,7 @@ steps:
type: screen.capture
params:
label: after_list_after_resume
- note: after relaunching ReadyBASIC from REU and LISTing
+ pitch: after relaunching ReadyBASIC from REU and LISTing
- id: assert_resume_preserved_line
type: assert.screen
params:
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_module_overlay_probe.easyflash.yaml b/agentworking/easyflash_full_vice_plans/readybasic_module_overlay_probe.easyflash.yaml
index c971dd1..fbc2615 100644
--- a/agentworking/easyflash_full_vice_plans/readybasic_module_overlay_probe.easyflash.yaml
+++ b/agentworking/easyflash_full_vice_plans/readybasic_module_overlay_probe.easyflash.yaml
@@ -19,7 +19,7 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.4/precog-easyflash/readyos_easyflash.crt"
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
autostart_enabled: false
disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
drive8_enabled: true
@@ -40,7 +40,7 @@ steps:
text: "READY OS"
pre_delay_s: 4
poll_s: 0.5
- wait_timeout_s: 240
+ wait_timeout_s: 420
capture_label: easyflash_readybasic_launcher
- id: easyflash_start_readybasic
type: input.sequence
@@ -51,13 +51,13 @@ steps:
- id: wait_readybasic_prompt
type: screen.wait_contains
params:
- text: "readybasic"
+ text: "READY."
wait_timeout_s: 180
capture_label: readybasic_module_overlay_prompt
- id: builtin_overlay_bank_probe
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,70,82,69,69,77,69,77,40,41,13,80,82,73,78,84,32,34,83,76,79,84,83,34,59,90,83,76,79,84,48,40,41,59,34,47,34,59,90,83,76,79,84,49,40,41,59,34,47,34,59,90,83,76,79,84,50,40,41,13,80,82,73,78,84,32,34,83,80,65,78,34,59,90,83,80,65,78,40,41,13,80,82,73,78,84,32,34,79,86,76,34,59,90,79,86,76,49,40,41,59,34,47,34,59,90,79,86,76,50,40,41,13,80,82,73,78,84,32,34,67,80,89,34,59,90,67,80,89,82,83,84,40,41,59,34,47,34,59,90,67,79,80,89,40,41,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,77,69,77,65,86,76,40,41,13,80,82,73,78,84,32,34,83,76,79,84,83,34,59,90,83,76,79,84,48,40,41,59,34,47,34,59,90,83,76,79,84,49,40,41,59,34,47,34,59,90,83,76,79,84,50,40,41,13,80,82,73,78,84,32,34,83,80,65,78,34,59,90,83,80,65,78,40,41,13,80,82,73,78,84,32,34,79,86,76,34,59,90,79,86,76,49,40,41,59,34,47,34,59,90,79,86,76,50,40,41,13,80,82,73,78,84,32,34,67,80,89,34,59,90,67,80,89,82,83,84,40,41,59,34,47,34,59,90,67,79,80,89,40,41,13]
inter_key_delay_s: 0.03
post_delay_s: 1.5
- id: capture_builtin_overlay_bank_probe
@@ -119,7 +119,7 @@ steps:
- id: rbm_sample3_probe
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,82,66,77,51,32,70,73,82,83,84,32,67,65,76,76,83,58,32,69,65,67,72,32,79,86,69,82,76,65,89,32,83,84,65,84,69,32,83,84,65,82,84,83,32,65,84,32,90,69,82,79,32,65,70,84,69,82,32,76,79,65,68,13,80,82,73,78,84,32,34,77,51,65,34,59,90,83,65,65,40,41,59,34,47,34,59,90,83,69,66,40,41,13,80,82,73,78,84,32,34,77,51,66,34,59,90,84,65,65,40,41,59,34,47,34,59,90,84,69,66,40,41,13,80,82,73,78,84,32,34,77,51,67,34,59,90,85,65,65,40,41,59,34,47,34,59,90,85,69,66,40,41,13,70,82,69,69,77,69,77,40,41,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,82,66,77,51,32,70,73,82,83,84,32,67,65,76,76,83,58,32,69,65,67,72,32,79,86,69,82,76,65,89,32,83,84,65,84,69,32,83,84,65,82,84,83,32,65,84,32,90,69,82,79,32,65,70,84,69,82,32,76,79,65,68,13,80,82,73,78,84,32,34,77,51,65,34,59,90,83,65,65,40,41,59,34,47,34,59,90,83,69,66,40,41,13,80,82,73,78,84,32,34,77,51,66,34,59,90,84,65,65,40,41,59,34,47,34,59,90,84,69,66,40,41,13,80,82,73,78,84,32,34,77,51,67,34,59,90,85,65,65,40,41,59,34,47,34,59,90,85,69,66,40,41,13,77,69,77,65,86,76,40,41,13]
inter_key_delay_s: 0.03
post_delay_s: 2.0
- id: capture_rbm_sample3
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_module_overlay_probe.regular.yaml b/agentworking/easyflash_full_vice_plans/readybasic_module_overlay_probe.regular.yaml
index f4c6c0a..6962aa4 100644
--- a/agentworking/easyflash_full_vice_plans/readybasic_module_overlay_probe.regular.yaml
+++ b/agentworking/easyflash_full_vice_plans/readybasic_module_overlay_probe.regular.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
@@ -42,7 +42,7 @@ steps:
- id: builtin_overlay_bank_probe
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,70,82,69,69,77,69,77,40,41,13,80,82,73,78,84,32,34,83,76,79,84,83,34,59,90,83,76,79,84,48,40,41,59,34,47,34,59,90,83,76,79,84,49,40,41,59,34,47,34,59,90,83,76,79,84,50,40,41,13,80,82,73,78,84,32,34,83,80,65,78,34,59,90,83,80,65,78,40,41,13,80,82,73,78,84,32,34,79,86,76,34,59,90,79,86,76,49,40,41,59,34,47,34,59,90,79,86,76,50,40,41,13,80,82,73,78,84,32,34,67,80,89,34,59,90,67,80,89,82,83,84,40,41,59,34,47,34,59,90,67,79,80,89,40,41,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,77,69,77,65,86,76,40,41,13,80,82,73,78,84,32,34,83,76,79,84,83,34,59,90,83,76,79,84,48,40,41,59,34,47,34,59,90,83,76,79,84,49,40,41,59,34,47,34,59,90,83,76,79,84,50,40,41,13,80,82,73,78,84,32,34,83,80,65,78,34,59,90,83,80,65,78,40,41,13,80,82,73,78,84,32,34,79,86,76,34,59,90,79,86,76,49,40,41,59,34,47,34,59,90,79,86,76,50,40,41,13,80,82,73,78,84,32,34,67,80,89,34,59,90,67,80,89,82,83,84,40,41,59,34,47,34,59,90,67,79,80,89,40,41,13]
inter_key_delay_s: 0.03
post_delay_s: 1.5
- id: capture_builtin_overlay_bank_probe
@@ -104,7 +104,7 @@ steps:
- id: rbm_sample3_probe
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,82,66,77,51,32,70,73,82,83,84,32,67,65,76,76,83,58,32,69,65,67,72,32,79,86,69,82,76,65,89,32,83,84,65,84,69,32,83,84,65,82,84,83,32,65,84,32,90,69,82,79,32,65,70,84,69,82,32,76,79,65,68,13,80,82,73,78,84,32,34,77,51,65,34,59,90,83,65,65,40,41,59,34,47,34,59,90,83,69,66,40,41,13,80,82,73,78,84,32,34,77,51,66,34,59,90,84,65,65,40,41,59,34,47,34,59,90,84,69,66,40,41,13,80,82,73,78,84,32,34,77,51,67,34,59,90,85,65,65,40,41,59,34,47,34,59,90,85,69,66,40,41,13,70,82,69,69,77,69,77,40,41,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,82,66,77,51,32,70,73,82,83,84,32,67,65,76,76,83,58,32,69,65,67,72,32,79,86,69,82,76,65,89,32,83,84,65,84,69,32,83,84,65,82,84,83,32,65,84,32,90,69,82,79,32,65,70,84,69,82,32,76,79,65,68,13,80,82,73,78,84,32,34,77,51,65,34,59,90,83,65,65,40,41,59,34,47,34,59,90,83,69,66,40,41,13,80,82,73,78,84,32,34,77,51,66,34,59,90,84,65,65,40,41,59,34,47,34,59,90,84,69,66,40,41,13,80,82,73,78,84,32,34,77,51,67,34,59,90,85,65,65,40,41,59,34,47,34,59,90,85,69,66,40,41,13,77,69,77,65,86,76,40,41,13]
inter_key_delay_s: 0.03
post_delay_s: 2.0
- id: capture_rbm_sample3
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_plugin_command_probe.easyflash.yaml b/agentworking/easyflash_full_vice_plans/readybasic_plugin_command_probe.easyflash.yaml
index 4396a40..617fc2d 100644
--- a/agentworking/easyflash_full_vice_plans/readybasic_plugin_command_probe.easyflash.yaml
+++ b/agentworking/easyflash_full_vice_plans/readybasic_plugin_command_probe.easyflash.yaml
@@ -19,7 +19,7 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.4/precog-easyflash/readyos_easyflash.crt"
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
autostart_enabled: false
disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
drive8_enabled: true
@@ -40,7 +40,7 @@ steps:
text: "READY OS"
pre_delay_s: 4
poll_s: 0.5
- wait_timeout_s: 240
+ wait_timeout_s: 420
capture_label: easyflash_readybasic_launcher
- id: easyflash_start_readybasic
type: input.sequence
@@ -51,7 +51,7 @@ steps:
- id: wait_readybasic_prompt
type: screen.wait_contains
params:
- text: "readybasic"
+ text: "READY."
wait_timeout_s: 180
capture_label: readybasic_plugin_prompt
- id: dump_initial_plugin_state
@@ -66,7 +66,7 @@ steps:
- { label: hidden_visible_a000, start: 0xA000, end: 0xA5FF }
- { label: hidden_overlay_a800, start: 0xA800, end: 0xA8FF }
- { label: bridge_c000, start: 0xC000, end: 0xC5FF }
- - { label: reu_alloc_table_c600, start: 0xC600, end: 0xC6FF }
+ - { label: shim_resident_c600, start: 0xC600, end: 0xC9FF }
- id: probe_01_ping
type: input.sequence
@@ -194,17 +194,17 @@ steps:
params:
contains: "RANGE 7 10"
- - id: probe_08_bufnew
+ - id: probe_08_bufmake
type: input.sequence
params:
- keys: [72,37,61,66,85,70,78,69,87,40,51,48,48,41,13,80,82,73,78,84,32,34,66,85,70,78,69,87,34,59,72,37,59,34,58,69,78,68,34,13]
+ keys: [72,37,61,66,85,70,77,65,75,69,40,51,48,48,41,13,80,82,73,78,84,32,34,66,85,70,77,65,75,69,34,59,72,37,59,34,58,69,78,68,34,13]
inter_key_delay_s: 0.03
post_delay_s: 0.8
- - id: assert_08_bufnew
+ - id: assert_08_bufmake
type: assert.screen
params:
- contains: "BUFNEW 1 :END"
- - id: dump_08_bufnew
+ contains: "BUFMAKE 1 :END"
+ - id: dump_08_bufmake
type: dump.memory_ranges
params:
ranges: *plugin_ranges
@@ -224,17 +224,17 @@ steps:
params:
not_contains: "?RB ERROR"
- - id: probe_10_buffree
+ - id: probe_10_bufdrop
type: input.sequence
params:
- keys: [66,85,70,70,82,69,69,40,72,37,41,13,80,82,73,78,84,32,34,70,82,69,69,32,79,75,34,13]
+ keys: [66,85,70,68,82,79,80,40,72,37,41,13,80,82,73,78,84,32,34,70,82,69,69,32,79,75,34,13]
inter_key_delay_s: 0.03
post_delay_s: 0.8
- - id: assert_10_buffree
+ - id: assert_10_bufdrop
type: assert.screen
params:
contains: "FREE OK"
- - id: assert_10_buffree_no_error
+ - id: assert_10_bufdrop_no_error
type: assert.screen_not_contains
params:
not_contains: "?RB ERROR"
@@ -263,24 +263,24 @@ steps:
type: assert.screen
params:
contains: "?RB ERROR 40"
- - id: probe_10c_buffree_screen_handle
+ - id: probe_10c_bufdrop_screen_handle
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,70,82,69,69,40,83,37,41,13,80,82,73,78,84,32,34,83,67,82,70,82,69,69,34,59,83,37,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,68,82,79,80,40,83,37,41,13,80,82,73,78,84,32,34,83,67,82,70,82,69,69,34,59,83,37,13]
inter_key_delay_s: 0.03
post_delay_s: 0.8
- - id: assert_10c_buffree_screen_handle
+ - id: assert_10c_bufdrop_screen_handle
type: assert.screen
params:
contains: "SCRFREE 1"
- - id: assert_10c_buffree_screen_no_error
+ - id: assert_10c_bufdrop_screen_no_error
type: assert.screen_not_contains
params:
not_contains: "?RB ERROR"
- id: probe_10d_scrput_rejects_buffer_handle
type: input.sequence
params:
- keys: [66,37,61,66,85,70,78,69,87,40,51,48,48,41,13,83,67,82,80,85,84,40,66,37,41,13]
+ keys: [66,37,61,66,85,70,77,65,75,69,40,51,48,48,41,13,83,67,82,80,85,84,40,66,37,41,13]
inter_key_delay_s: 0.03
post_delay_s: 0.8
- id: assert_10d_scrput_rejects_buffer_handle
@@ -290,7 +290,7 @@ steps:
- id: probe_10e_free_buffer_after_type_error
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,70,82,69,69,40,66,37,41,13,80,82,73,78,84,32,34,66,85,70,82,69,69,34,59,66,37,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,68,82,79,80,40,66,37,41,13,80,82,73,78,84,32,34,66,85,70,82,69,69,34,59,66,37,13]
inter_key_delay_s: 0.03
post_delay_s: 0.8
- id: assert_10e_free_buffer_after_type_error
@@ -305,7 +305,7 @@ steps:
- id: probe_10f_allocate_128_handles
type: input.sequence
params:
- keys: [78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,72,37,61,66,85,70,78,69,87,40,49,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,72,77,65,88,34,59,72,37,13,82,85,78,13]
+ keys: [78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,72,37,61,66,85,70,77,65,75,69,40,49,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,72,77,65,88,34,59,72,37,13,82,85,78,13]
inter_key_delay_s: 0.03
post_delay_s: 4.0
- id: assert_10f_allocate_128_handles
@@ -320,7 +320,7 @@ steps:
- id: probe_10g_handle_129_rejected
type: input.sequence
params:
- keys: [69,37,61,66,85,70,78,69,87,40,49,41,13]
+ keys: [69,37,61,66,85,70,77,65,75,69,40,49,41,13]
inter_key_delay_s: 0.03
post_delay_s: 0.8
- id: assert_10g_handle_129_rejected
@@ -331,7 +331,7 @@ steps:
- id: probe_10h_free_128_handles
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,66,85,70,70,82,69,69,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,72,70,82,69,69,68,34,13,82,85,78,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,66,85,70,68,82,79,80,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,72,70,82,69,69,68,34,13,82,85,78,13]
inter_key_delay_s: 0.03
post_delay_s: 4.0
- id: assert_10h_free_128_handles
@@ -346,7 +346,7 @@ steps:
- id: probe_10i_reuse_low_handle
type: input.sequence
params:
- keys: [82,37,61,66,85,70,78,69,87,40,49,41,13,80,82,73,78,84,32,34,72,82,69,85,83,69,34,59,82,37,13,66,85,70,70,82,69,69,40,82,37,41,13]
+ keys: [82,37,61,66,85,70,77,65,75,69,40,49,41,13,80,82,73,78,84,32,34,72,82,69,85,83,69,34,59,82,37,13,66,85,70,68,82,79,80,40,82,37,41,13]
inter_key_delay_s: 0.03
post_delay_s: 0.8
- id: assert_10i_reuse_low_handle
@@ -361,7 +361,7 @@ steps:
- id: probe_10j_allocate_48k_heap
type: input.sequence
params:
- keys: [77,37,61,66,85,70,78,69,87,40,52,57,49,53,50,41,13,80,82,73,78,84,32,34,72,77,65,88,66,85,70,34,59,77,37,13]
+ keys: [77,37,61,66,85,70,77,65,75,69,40,52,57,49,53,50,41,13,80,82,73,78,84,32,34,72,77,65,88,66,85,70,34,59,77,37,13]
inter_key_delay_s: 0.03
post_delay_s: 1.0
- id: assert_10j_allocate_48k_heap
@@ -376,7 +376,7 @@ steps:
- id: probe_10k_heap_full_rejected
type: input.sequence
params:
- keys: [69,37,61,66,85,70,78,69,87,40,49,41,13]
+ keys: [69,37,61,66,85,70,77,65,75,69,40,49,41,13]
inter_key_delay_s: 0.03
post_delay_s: 0.8
- id: assert_10k_heap_full_rejected
@@ -387,7 +387,7 @@ steps:
- id: probe_10l_free_48k_heap
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,70,82,69,69,40,77,37,41,13,80,82,73,78,84,32,34,72,77,65,88,70,82,69,69,34,59,77,37,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,68,82,79,80,40,77,37,41,13,80,82,73,78,84,32,34,72,77,65,88,70,82,69,69,34,59,77,37,13]
inter_key_delay_s: 0.03
post_delay_s: 0.8
- id: assert_10l_free_48k_heap
@@ -428,7 +428,7 @@ steps:
- id: probe_10o_free_screen_handles
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,50,52,13,50,48,32,66,85,70,70,82,69,69,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,83,70,82,69,69,68,34,13,82,85,78,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,50,52,13,50,48,32,66,85,70,68,82,79,80,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,83,70,82,69,69,68,34,13,82,85,78,13]
inter_key_delay_s: 0.03
post_delay_s: 4.0
- id: assert_10o_free_screen_handles
@@ -626,9 +626,20 @@ steps:
- id: resume_after_exit
type: input.sequence
params:
- keys: [145,17,13]
+ keys: [145,17]
inter_key_delay_s: 0.10
- post_delay_s: 3.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_plugin_resume
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ # Use VICE's text-monitor keyboard buffer for the post-EXIT RETURN; the
+ # binary-monitor input helper can otherwise drop this lone key.
+ - id: launch_readybasic_after_plugin_exit
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_resume
type: screen.wait_contains
params:
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_plugin_command_probe.regular.yaml b/agentworking/easyflash_full_vice_plans/readybasic_plugin_command_probe.regular.yaml
index da92967..4f1ac57 100644
--- a/agentworking/easyflash_full_vice_plans/readybasic_plugin_command_probe.regular.yaml
+++ b/agentworking/easyflash_full_vice_plans/readybasic_plugin_command_probe.regular.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
@@ -51,7 +51,7 @@ steps:
- { label: hidden_visible_a000, start: 0xA000, end: 0xA5FF }
- { label: hidden_overlay_a800, start: 0xA800, end: 0xA8FF }
- { label: bridge_c000, start: 0xC000, end: 0xC5FF }
- - { label: reu_alloc_table_c600, start: 0xC600, end: 0xC6FF }
+ - { label: shim_resident_c600, start: 0xC600, end: 0xC9FF }
- id: probe_01_ping
type: input.sequence
@@ -179,17 +179,17 @@ steps:
params:
contains: "RANGE 7 10"
- - id: probe_08_bufnew
+ - id: probe_08_bufmake
type: input.sequence
params:
- keys: [72,37,61,66,85,70,78,69,87,40,51,48,48,41,13,80,82,73,78,84,32,34,66,85,70,78,69,87,34,59,72,37,59,34,58,69,78,68,34,13]
+ keys: [72,37,61,66,85,70,77,65,75,69,40,51,48,48,41,13,80,82,73,78,84,32,34,66,85,70,77,65,75,69,34,59,72,37,59,34,58,69,78,68,34,13]
inter_key_delay_s: 0.03
post_delay_s: 0.8
- - id: assert_08_bufnew
+ - id: assert_08_bufmake
type: assert.screen
params:
- contains: "BUFNEW 1 :END"
- - id: dump_08_bufnew
+ contains: "BUFMAKE 1 :END"
+ - id: dump_08_bufmake
type: dump.memory_ranges
params:
ranges: *plugin_ranges
@@ -209,17 +209,17 @@ steps:
params:
not_contains: "?RB ERROR"
- - id: probe_10_buffree
+ - id: probe_10_bufdrop
type: input.sequence
params:
- keys: [66,85,70,70,82,69,69,40,72,37,41,13,80,82,73,78,84,32,34,70,82,69,69,32,79,75,34,13]
+ keys: [66,85,70,68,82,79,80,40,72,37,41,13,80,82,73,78,84,32,34,70,82,69,69,32,79,75,34,13]
inter_key_delay_s: 0.03
post_delay_s: 0.8
- - id: assert_10_buffree
+ - id: assert_10_bufdrop
type: assert.screen
params:
contains: "FREE OK"
- - id: assert_10_buffree_no_error
+ - id: assert_10_bufdrop_no_error
type: assert.screen_not_contains
params:
not_contains: "?RB ERROR"
@@ -248,24 +248,24 @@ steps:
type: assert.screen
params:
contains: "?RB ERROR 40"
- - id: probe_10c_buffree_screen_handle
+ - id: probe_10c_bufdrop_screen_handle
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,70,82,69,69,40,83,37,41,13,80,82,73,78,84,32,34,83,67,82,70,82,69,69,34,59,83,37,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,68,82,79,80,40,83,37,41,13,80,82,73,78,84,32,34,83,67,82,70,82,69,69,34,59,83,37,13]
inter_key_delay_s: 0.03
post_delay_s: 0.8
- - id: assert_10c_buffree_screen_handle
+ - id: assert_10c_bufdrop_screen_handle
type: assert.screen
params:
contains: "SCRFREE 1"
- - id: assert_10c_buffree_screen_no_error
+ - id: assert_10c_bufdrop_screen_no_error
type: assert.screen_not_contains
params:
not_contains: "?RB ERROR"
- id: probe_10d_scrput_rejects_buffer_handle
type: input.sequence
params:
- keys: [66,37,61,66,85,70,78,69,87,40,51,48,48,41,13,83,67,82,80,85,84,40,66,37,41,13]
+ keys: [66,37,61,66,85,70,77,65,75,69,40,51,48,48,41,13,83,67,82,80,85,84,40,66,37,41,13]
inter_key_delay_s: 0.03
post_delay_s: 0.8
- id: assert_10d_scrput_rejects_buffer_handle
@@ -275,7 +275,7 @@ steps:
- id: probe_10e_free_buffer_after_type_error
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,70,82,69,69,40,66,37,41,13,80,82,73,78,84,32,34,66,85,70,82,69,69,34,59,66,37,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,68,82,79,80,40,66,37,41,13,80,82,73,78,84,32,34,66,85,70,82,69,69,34,59,66,37,13]
inter_key_delay_s: 0.03
post_delay_s: 0.8
- id: assert_10e_free_buffer_after_type_error
@@ -290,7 +290,7 @@ steps:
- id: probe_10f_allocate_128_handles
type: input.sequence
params:
- keys: [78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,72,37,61,66,85,70,78,69,87,40,49,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,72,77,65,88,34,59,72,37,13,82,85,78,13]
+ keys: [78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,72,37,61,66,85,70,77,65,75,69,40,49,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,72,77,65,88,34,59,72,37,13,82,85,78,13]
inter_key_delay_s: 0.03
post_delay_s: 4.0
- id: assert_10f_allocate_128_handles
@@ -305,7 +305,7 @@ steps:
- id: probe_10g_handle_129_rejected
type: input.sequence
params:
- keys: [69,37,61,66,85,70,78,69,87,40,49,41,13]
+ keys: [69,37,61,66,85,70,77,65,75,69,40,49,41,13]
inter_key_delay_s: 0.03
post_delay_s: 0.8
- id: assert_10g_handle_129_rejected
@@ -316,7 +316,7 @@ steps:
- id: probe_10h_free_128_handles
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,66,85,70,70,82,69,69,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,72,70,82,69,69,68,34,13,82,85,78,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,66,85,70,68,82,79,80,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,72,70,82,69,69,68,34,13,82,85,78,13]
inter_key_delay_s: 0.03
post_delay_s: 4.0
- id: assert_10h_free_128_handles
@@ -331,7 +331,7 @@ steps:
- id: probe_10i_reuse_low_handle
type: input.sequence
params:
- keys: [82,37,61,66,85,70,78,69,87,40,49,41,13,80,82,73,78,84,32,34,72,82,69,85,83,69,34,59,82,37,13,66,85,70,70,82,69,69,40,82,37,41,13]
+ keys: [82,37,61,66,85,70,77,65,75,69,40,49,41,13,80,82,73,78,84,32,34,72,82,69,85,83,69,34,59,82,37,13,66,85,70,68,82,79,80,40,82,37,41,13]
inter_key_delay_s: 0.03
post_delay_s: 0.8
- id: assert_10i_reuse_low_handle
@@ -346,7 +346,7 @@ steps:
- id: probe_10j_allocate_48k_heap
type: input.sequence
params:
- keys: [77,37,61,66,85,70,78,69,87,40,52,57,49,53,50,41,13,80,82,73,78,84,32,34,72,77,65,88,66,85,70,34,59,77,37,13]
+ keys: [77,37,61,66,85,70,77,65,75,69,40,52,57,49,53,50,41,13,80,82,73,78,84,32,34,72,77,65,88,66,85,70,34,59,77,37,13]
inter_key_delay_s: 0.03
post_delay_s: 1.0
- id: assert_10j_allocate_48k_heap
@@ -361,7 +361,7 @@ steps:
- id: probe_10k_heap_full_rejected
type: input.sequence
params:
- keys: [69,37,61,66,85,70,78,69,87,40,49,41,13]
+ keys: [69,37,61,66,85,70,77,65,75,69,40,49,41,13]
inter_key_delay_s: 0.03
post_delay_s: 0.8
- id: assert_10k_heap_full_rejected
@@ -372,7 +372,7 @@ steps:
- id: probe_10l_free_48k_heap
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,70,82,69,69,40,77,37,41,13,80,82,73,78,84,32,34,72,77,65,88,70,82,69,69,34,59,77,37,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,68,82,79,80,40,77,37,41,13,80,82,73,78,84,32,34,72,77,65,88,70,82,69,69,34,59,77,37,13]
inter_key_delay_s: 0.03
post_delay_s: 0.8
- id: assert_10l_free_48k_heap
@@ -413,7 +413,7 @@ steps:
- id: probe_10o_free_screen_handles
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,50,52,13,50,48,32,66,85,70,70,82,69,69,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,83,70,82,69,69,68,34,13,82,85,78,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,50,52,13,50,48,32,66,85,70,68,82,79,80,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,83,70,82,69,69,68,34,13,82,85,78,13]
inter_key_delay_s: 0.03
post_delay_s: 4.0
- id: assert_10o_free_screen_handles
@@ -611,9 +611,20 @@ steps:
- id: resume_after_exit
type: input.sequence
params:
- keys: [145,17,13]
+ keys: [145,17]
inter_key_delay_s: 0.10
- post_delay_s: 3.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_plugin_resume
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ # Use VICE's text-monitor keyboard buffer for the post-EXIT RETURN; the
+ # binary-monitor input helper can otherwise drop this lone key.
+ - id: launch_readybasic_after_plugin_exit
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_resume
type: screen.wait_contains
params:
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_program_probe.easyflash.yaml b/agentworking/easyflash_full_vice_plans/readybasic_program_probe.easyflash.yaml
index fe33254..9535137 100644
--- a/agentworking/easyflash_full_vice_plans/readybasic_program_probe.easyflash.yaml
+++ b/agentworking/easyflash_full_vice_plans/readybasic_program_probe.easyflash.yaml
@@ -19,7 +19,7 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.4/precog-easyflash/readyos_easyflash.crt"
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
autostart_enabled: false
disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
drive8_enabled: true
@@ -40,7 +40,7 @@ steps:
text: "READY OS"
pre_delay_s: 4
poll_s: 0.5
- wait_timeout_s: 240
+ wait_timeout_s: 420
capture_label: easyflash_readybasic_launcher
- id: easyflash_start_readybasic
type: input.sequence
@@ -51,7 +51,7 @@ steps:
- id: wait_readybasic_prompt
type: screen.wait_contains
params:
- text: "readybasic"
+ text: "READY."
wait_timeout_s: 180
capture_label: readybasic_program_prompt
@@ -197,7 +197,7 @@ steps:
- id: program_handle_lifecycle_run
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,72,37,61,66,85,70,78,69,87,40,51,48,48,41,13,50,48,32,80,82,73,78,84,32,34,80,82,66,85,70,34,59,72,37,13,51,48,32,66,85,70,70,73,76,76,40,72,37,44,49,55,48,41,13,52,48,32,66,85,70,70,82,69,69,40,72,37,41,13,53,48,32,80,82,73,78,84,32,34,80,82,70,82,69,69,34,59,72,37,13,82,85,78,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,72,37,61,66,85,70,77,65,75,69,40,51,48,48,41,13,50,48,32,80,82,73,78,84,32,34,80,82,66,85,70,34,59,72,37,13,51,48,32,66,85,70,70,73,76,76,40,72,37,44,49,55,48,41,13,52,48,32,66,85,70,68,82,79,80,40,72,37,41,13,53,48,32,80,82,73,78,84,32,34,80,82,70,82,69,69,34,59,72,37,13,82,85,78,13]
inter_key_delay_s: 0.03
post_delay_s: 1.5
- id: assert_program_handle_new
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_program_probe.regular.yaml b/agentworking/easyflash_full_vice_plans/readybasic_program_probe.regular.yaml
index 0469761..5064693 100644
--- a/agentworking/easyflash_full_vice_plans/readybasic_program_probe.regular.yaml
+++ b/agentworking/easyflash_full_vice_plans/readybasic_program_probe.regular.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
@@ -182,7 +182,7 @@ steps:
- id: program_handle_lifecycle_run
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,72,37,61,66,85,70,78,69,87,40,51,48,48,41,13,50,48,32,80,82,73,78,84,32,34,80,82,66,85,70,34,59,72,37,13,51,48,32,66,85,70,70,73,76,76,40,72,37,44,49,55,48,41,13,52,48,32,66,85,70,70,82,69,69,40,72,37,41,13,53,48,32,80,82,73,78,84,32,34,80,82,70,82,69,69,34,59,72,37,13,82,85,78,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,72,37,61,66,85,70,77,65,75,69,40,51,48,48,41,13,50,48,32,80,82,73,78,84,32,34,80,82,66,85,70,34,59,72,37,13,51,48,32,66,85,70,70,73,76,76,40,72,37,44,49,55,48,41,13,52,48,32,66,85,70,68,82,79,80,40,72,37,41,13,53,48,32,80,82,73,78,84,32,34,80,82,70,82,69,69,34,59,72,37,13,82,85,78,13]
inter_key_delay_s: 0.03
post_delay_s: 1.5
- id: assert_program_handle_new
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_rbtest1_probe.easyflash.yaml b/agentworking/easyflash_full_vice_plans/readybasic_rbtest1_probe.easyflash.yaml
index 2b6fe6c..a1be66e 100644
--- a/agentworking/easyflash_full_vice_plans/readybasic_rbtest1_probe.easyflash.yaml
+++ b/agentworking/easyflash_full_vice_plans/readybasic_rbtest1_probe.easyflash.yaml
@@ -19,7 +19,7 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.4/precog-easyflash/readyos_easyflash.crt"
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
autostart_enabled: false
disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
drive8_enabled: true
@@ -40,7 +40,7 @@ steps:
text: "READY OS"
pre_delay_s: 4
poll_s: 0.5
- wait_timeout_s: 240
+ wait_timeout_s: 420
capture_label: easyflash_readybasic_launcher
- id: easyflash_start_readybasic
type: input.sequence
@@ -51,7 +51,7 @@ steps:
- id: wait_readybasic_prompt
type: screen.wait_contains
params:
- text: "readybasic"
+ text: "READY."
wait_timeout_s: 180
capture_label: readybasic_prompt
- id: load_rbtest1
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_rbtest1_probe.regular.yaml b/agentworking/easyflash_full_vice_plans/readybasic_rbtest1_probe.regular.yaml
index e07431e..8ef4efc 100644
--- a/agentworking/easyflash_full_vice_plans/readybasic_rbtest1_probe.regular.yaml
+++ b/agentworking/easyflash_full_vice_plans/readybasic_rbtest1_probe.regular.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_repeat_label_probe.easyflash.yaml b/agentworking/easyflash_full_vice_plans/readybasic_repeat_label_probe.easyflash.yaml
index 2dcf923..3ba7098 100644
--- a/agentworking/easyflash_full_vice_plans/readybasic_repeat_label_probe.easyflash.yaml
+++ b/agentworking/easyflash_full_vice_plans/readybasic_repeat_label_probe.easyflash.yaml
@@ -19,7 +19,7 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.4/precog-easyflash/readyos_easyflash.crt"
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
autostart_enabled: false
disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
drive8_enabled: true
@@ -40,7 +40,7 @@ steps:
text: "READY OS"
pre_delay_s: 4
poll_s: 0.5
- wait_timeout_s: 240
+ wait_timeout_s: 420
capture_label: easyflash_readybasic_launcher
- id: easyflash_start_readybasic
type: input.sequence
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_repeat_label_probe.regular.yaml b/agentworking/easyflash_full_vice_plans/readybasic_repeat_label_probe.regular.yaml
index 3f65822..c822d2c 100644
--- a/agentworking/easyflash_full_vice_plans/readybasic_repeat_label_probe.regular.yaml
+++ b/agentworking/easyflash_full_vice_plans/readybasic_repeat_label_probe.regular.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_resume_min_probe.easyflash.yaml b/agentworking/easyflash_full_vice_plans/readybasic_resume_min_probe.easyflash.yaml
index d90a6c3..e94b051 100644
--- a/agentworking/easyflash_full_vice_plans/readybasic_resume_min_probe.easyflash.yaml
+++ b/agentworking/easyflash_full_vice_plans/readybasic_resume_min_probe.easyflash.yaml
@@ -19,7 +19,7 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.4/precog-easyflash/readyos_easyflash.crt"
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
autostart_enabled: false
disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
drive8_enabled: true
@@ -40,7 +40,7 @@ steps:
text: "READY OS"
pre_delay_s: 4
poll_s: 0.5
- wait_timeout_s: 240
+ wait_timeout_s: 420
capture_label: easyflash_readybasic_launcher
- id: easyflash_start_readybasic
type: input.sequence
@@ -51,7 +51,7 @@ steps:
- id: wait_readybasic_prompt
type: screen.wait_contains
params:
- text: "readybasic"
+ text: "READY."
wait_timeout_s: 180
capture_label: readybasic_resume_min_prompt
- id: initial_builtin_probe
@@ -107,11 +107,9 @@ steps:
text: "READY OS"
wait_timeout_s: 30
- id: resume_1
- type: input.sequence
+ type: monitor.command
params:
- keys: [13]
- inter_key_delay_s: 0.03
- post_delay_s: 3.0
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_resume_1
type: screen.wait_contains
params:
@@ -147,11 +145,9 @@ steps:
text: "READY OS"
wait_timeout_s: 30
- id: resume_2
- type: input.sequence
+ type: monitor.command
params:
- keys: [13]
- inter_key_delay_s: 0.03
- post_delay_s: 3.0
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_resume_2
type: screen.wait_contains
params:
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_resume_min_probe.regular.yaml b/agentworking/easyflash_full_vice_plans/readybasic_resume_min_probe.regular.yaml
index ca67cb2..059367e 100644
--- a/agentworking/easyflash_full_vice_plans/readybasic_resume_min_probe.regular.yaml
+++ b/agentworking/easyflash_full_vice_plans/readybasic_resume_min_probe.regular.yaml
@@ -92,11 +92,9 @@ steps:
text: "READY OS"
wait_timeout_s: 30
- id: resume_1
- type: input.sequence
+ type: monitor.command
params:
- keys: [13]
- inter_key_delay_s: 0.03
- post_delay_s: 3.0
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_resume_1
type: screen.wait_contains
params:
@@ -132,11 +130,9 @@ steps:
text: "READY OS"
wait_timeout_s: 30
- id: resume_2
- type: input.sequence
+ type: monitor.command
params:
- keys: [13]
- inter_key_delay_s: 0.03
- post_delay_s: 3.0
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_resume_2
type: screen.wait_contains
params:
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_reuviewer_f2_chain_probe.easyflash.yaml b/agentworking/easyflash_full_vice_plans/readybasic_reuviewer_f2_chain_probe.easyflash.yaml
new file mode 100644
index 0000000..e8b53e5
--- /dev/null
+++ b/agentworking/easyflash_full_vice_plans/readybasic_reuviewer_f2_chain_probe.easyflash.yaml
@@ -0,0 +1,413 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_reuviewer_f2_chain_probe_easyflash
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
+ autostart_enabled: false
+ disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
+ drive8_enabled: true
+ drive8_type: 1541
+ drive9_enabled: false
+ true_drive: true
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_launcher_initial
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ pre_delay_s: 4
+ poll_s: 0.5
+ wait_timeout_s: 420
+ capture_label: chain_launcher_initial
+ - id: launch_readybasic_from_launcher
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_initial
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 120
+ capture_label: chain_readybasic_initial
+ - id: assert_readybasic_bank_initial
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "05"
+ - id: assert_chrin_vector_initial
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "08 12"
+ - id: assert_keylog_vector_initial
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "7E C1"
+ - id: readybasic_first_type
+ type: input.sequence
+ params:
+ keys: [81,37,61,49,48,49,58,80,82,73,78,84,32,34,67,72,65,73,78,49,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_first_type
+ type: assert.screen
+ params:
+ contains: "CHAIN1 101"
+ - id: readybasic_ctrl_b_1_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 4C 74 A4"
+ - id: readybasic_ctrl_b_1_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: readybasic_ctrl_b_1
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_launcher_after_readybasic_ctrl_b_1
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ pre_delay_s: 1.0
+ capture_label: chain_launcher_after_rb_ctrl_b_1
+ - id: assert_launcher_bank_after_ctrl_b_1
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "00"
+ - id: reenter_readybasic_1
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
+ - id: capture_readybasic_reentry_1
+ type: screen.capture
+ params:
+ label: chain_readybasic_reentry_1
+ pitch: warm ReadyBASIC entry evidence; bank/vector assertions and typed sentinel prove keyboard liveness
+ - id: assert_readybasic_bank_reentry_1
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "05"
+ - id: readybasic_second_type
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,67,72,65,73,78,50,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_second_type
+ type: assert.screen
+ params:
+ contains: "CHAIN2 101"
+ - id: readybasic_ctrl_b_2_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 4C 74 A4"
+ - id: readybasic_ctrl_b_2_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: readybasic_ctrl_b_2
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_launcher_after_readybasic_ctrl_b_2
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ pre_delay_s: 1.0
+ capture_label: chain_launcher_after_rb_ctrl_b_2
+ - id: launch_reuviewer_from_readybasic_position
+ type: input.sequence
+ params:
+ keys: [17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_reuviewer
+ type: screen.wait_contains
+ params:
+ text: "REU MEMORY"
+ wait_timeout_s: 90
+ capture_label: chain_reuviewer_loaded
+ - id: assert_reuviewer_bank
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "08"
+ - id: stage_readyos_token_status_for_readybasic_reuviewer_chain
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "00 00 00 00 00 07 00 00 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
+ - id: configure_readyos_token_status_dma_for_readybasic_reuviewer_chain
+ type: memory.write
+ params:
+ start: 57090
+ bytes_hex: "3C 03 40 BA 21 18 00"
+ - id: commit_readyos_token_status_for_readybasic_reuviewer_chain
+ type: memory.write
+ params:
+ start: 57089
+ bytes_hex: "90"
+ - id: reuviewer_f2_to_readybasic
+ type: input.sequence
+ params:
+ keys: [137]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.2
+ - id: capture_readybasic_after_reuviewer_f2
+ type: screen.capture
+ params:
+ label: chain_readybasic_after_reuviewer_f2
+ pitch: warm ReadyBASIC entry evidence; bank/vector assertions and typed sentinel prove keyboard liveness
+ - id: assert_readybasic_bank_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "05"
+ - id: assert_chrin_vector_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "08 12"
+ - id: assert_keylog_vector_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "7E C1"
+ - id: assert_keyboard_buffer_empty_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: wait_readybasic_stable_after_reuviewer_f2
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: chain_readybasic_stable_after_reuviewer_f2
+ - id: assert_readybasic_bank_stable_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "05"
+ - id: assert_keyboard_buffer_empty_stable_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: readybasic_type_after_reuviewer_f2
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,67,72,65,73,78,51,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_type_after_reuviewer_f2
+ type: assert.screen
+ params:
+ contains: "CHAIN3 101"
+ - id: readybasic_f2_back_to_reuviewer_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 4C 74 A4"
+ - id: readybasic_f2_back_to_reuviewer_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: readybasic_f2_back_to_reuviewer
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_reuviewer_after_readybasic_f2
+ type: screen.wait_contains
+ params:
+ text: "REU MEMORY"
+ wait_timeout_s: 80
+ pre_delay_s: 1.0
+ capture_label: chain_reuviewer_after_readybasic_f2
+ - id: assert_app_keylog_vector_restored_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "48 EB"
+ - id: assert_app_chrin_vector_restored_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "57 F1"
+ - id: assert_default_input_device_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 153
+ end: 153
+ equals_hex: "00"
+ - id: assert_reuviewer_bank_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "08"
+ - id: assert_keyboard_buffer_empty_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: wait_reuviewer_stable_after_readybasic_f2
+ type: screen.wait_contains
+ params:
+ text: "REU MEMORY"
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: chain_reuviewer_stable_after_readybasic_f2
+ - id: assert_reuviewer_bank_stable_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "08"
+ - id: assert_keyboard_buffer_empty_stable_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: reuviewer_ctrl_b_after_readybasic_f2
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
+ - id: capture_after_reuviewer_ctrl_b_input
+ type: screen.capture
+ params:
+ label: chain_after_reuviewer_ctrl_b_hotkey
+ pitch: capture after resumed REU Viewer Ctrl+B hotkey
+ - id: wait_launcher_after_reuviewer_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ capture_label: chain_launcher_after_reuviewer_ctrl_b
+ - id: assert_launcher_bank_after_reuviewer_ctrl_b
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "00"
+ - id: select_readybasic_after_reuviewer_ctrl_b
+ type: memory.write
+ params:
+ start: 51232
+ bytes_hex: "05"
+ - id: launch_readybasic_after_reuviewer_ctrl_b
+ type: monitor.command
+ params:
+ command: "raw:g c80f"
+ - id: capture_readybasic_after_reuviewer_ctrl_b_reentry
+ type: screen.capture
+ params:
+ label: chain_readybasic_after_reuviewer_ctrl_b_reentry
+ pitch: warm ReadyBASIC entry evidence; bank/vector assertions and typed sentinel prove keyboard liveness
+ - id: readybasic_type_after_reuviewer_ctrl_b_reentry
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,67,72,65,73,78,52,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_type_after_reuviewer_ctrl_b_reentry
+ type: assert.screen
+ params:
+ contains: "CHAIN4 101"
+ - id: readybasic_exit_after_multi_hop_reentry
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: wait_launcher_stable_after_readybasic_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ pre_delay_s: 2.0
+ capture_label: chain_launcher_stable_after_readybasic_exit
+ - id: assert_launcher_bank_after_readybasic_exit
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "00"
+ - id: assert_readybasic_not_auto_reentered_after_exit
+ type: assert.screen_not_contains
+ params:
+ not_contains: "ready."
+ - id: select_readybasic_after_exit_guard
+ type: memory.write
+ params:
+ start: 51232
+ bytes_hex: "05"
+ - id: reenter_readybasic_after_exit_guard
+ type: monitor.command
+ params:
+ command: "raw:g c80f"
+ - id: capture_readybasic_after_exit_guard_reentry
+ type: screen.capture
+ params:
+ label: chain_readybasic_after_exit_guard_reentry
+ pitch: warm ReadyBASIC entry evidence; bank/vector assertions and typed sentinel prove keyboard liveness
+ - id: readybasic_type_after_exit_guard_reentry
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,67,72,65,73,78,53,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_type_after_exit_guard_reentry
+ type: assert.screen
+ params:
+ contains: "CHAIN5 101"
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_reuviewer_f2_chain_probe.regular.yaml b/agentworking/easyflash_full_vice_plans/readybasic_reuviewer_f2_chain_probe.regular.yaml
new file mode 100644
index 0000000..82e8a2f
--- /dev/null
+++ b/agentworking/easyflash_full_vice_plans/readybasic_reuviewer_f2_chain_probe.regular.yaml
@@ -0,0 +1,410 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_reuviewer_f2_chain_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_launcher_initial
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 180
+ capture_label: chain_launcher_initial
+ - id: launch_readybasic_from_launcher
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_initial
+ type: screen.wait_contains
+ params:
+ text: "READYBASIC"
+ wait_timeout_s: 120
+ capture_label: chain_readybasic_initial
+ - id: assert_readybasic_bank_initial
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "05"
+ - id: assert_chrin_vector_initial
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "08 12"
+ - id: assert_keylog_vector_initial
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "7E C1"
+ - id: readybasic_first_type
+ type: input.sequence
+ params:
+ keys: [81,37,61,49,48,49,58,80,82,73,78,84,32,34,67,72,65,73,78,49,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_first_type
+ type: assert.screen
+ params:
+ contains: "CHAIN1 101"
+ - id: readybasic_ctrl_b_1_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 4C 74 A4"
+ - id: readybasic_ctrl_b_1_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: readybasic_ctrl_b_1
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_launcher_after_readybasic_ctrl_b_1
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ pre_delay_s: 1.0
+ capture_label: chain_launcher_after_rb_ctrl_b_1
+ - id: assert_launcher_bank_after_ctrl_b_1
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "00"
+ - id: reenter_readybasic_1
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
+ - id: capture_readybasic_reentry_1
+ type: screen.capture
+ params:
+ label: chain_readybasic_reentry_1
+ pitch: warm ReadyBASIC entry evidence; bank/vector assertions and typed sentinel prove keyboard liveness
+ - id: assert_readybasic_bank_reentry_1
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "05"
+ - id: readybasic_second_type
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,67,72,65,73,78,50,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_second_type
+ type: assert.screen
+ params:
+ contains: "CHAIN2 101"
+ - id: readybasic_ctrl_b_2_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 4C 74 A4"
+ - id: readybasic_ctrl_b_2_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: readybasic_ctrl_b_2
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_launcher_after_readybasic_ctrl_b_2
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ pre_delay_s: 1.0
+ capture_label: chain_launcher_after_rb_ctrl_b_2
+ - id: launch_reuviewer_from_readybasic_position
+ type: input.sequence
+ params:
+ keys: [17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_reuviewer
+ type: screen.wait_contains
+ params:
+ text: "REU MEMORY"
+ wait_timeout_s: 90
+ capture_label: chain_reuviewer_loaded
+ - id: assert_reuviewer_bank
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "08"
+ - id: stage_readyos_token_status_for_readybasic_reuviewer_chain
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "00 00 00 00 00 07 00 00 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
+ - id: configure_readyos_token_status_dma_for_readybasic_reuviewer_chain
+ type: memory.write
+ params:
+ start: 57090
+ bytes_hex: "3C 03 40 BA 21 18 00"
+ - id: commit_readyos_token_status_for_readybasic_reuviewer_chain
+ type: memory.write
+ params:
+ start: 57089
+ bytes_hex: "90"
+ - id: reuviewer_f2_to_readybasic
+ type: input.sequence
+ params:
+ keys: [137]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.2
+ - id: capture_readybasic_after_reuviewer_f2
+ type: screen.capture
+ params:
+ label: chain_readybasic_after_reuviewer_f2
+ pitch: warm ReadyBASIC entry evidence; bank/vector assertions and typed sentinel prove keyboard liveness
+ - id: assert_readybasic_bank_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "05"
+ - id: assert_chrin_vector_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "08 12"
+ - id: assert_keylog_vector_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "7E C1"
+ - id: assert_keyboard_buffer_empty_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: wait_readybasic_stable_after_reuviewer_f2
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: chain_readybasic_stable_after_reuviewer_f2
+ - id: assert_readybasic_bank_stable_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "05"
+ - id: assert_keyboard_buffer_empty_stable_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: readybasic_type_after_reuviewer_f2
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,67,72,65,73,78,51,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_type_after_reuviewer_f2
+ type: assert.screen
+ params:
+ contains: "CHAIN3 101"
+ - id: readybasic_f2_back_to_reuviewer_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 4C 74 A4"
+ - id: readybasic_f2_back_to_reuviewer_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: readybasic_f2_back_to_reuviewer
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_reuviewer_after_readybasic_f2
+ type: screen.wait_contains
+ params:
+ text: "REU MEMORY"
+ wait_timeout_s: 80
+ pre_delay_s: 1.0
+ capture_label: chain_reuviewer_after_readybasic_f2
+ - id: assert_app_keylog_vector_restored_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "48 EB"
+ - id: assert_app_chrin_vector_restored_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "57 F1"
+ - id: assert_default_input_device_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 153
+ end: 153
+ equals_hex: "00"
+ - id: assert_reuviewer_bank_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "08"
+ - id: assert_keyboard_buffer_empty_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: wait_reuviewer_stable_after_readybasic_f2
+ type: screen.wait_contains
+ params:
+ text: "REU MEMORY"
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: chain_reuviewer_stable_after_readybasic_f2
+ - id: assert_reuviewer_bank_stable_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "08"
+ - id: assert_keyboard_buffer_empty_stable_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: reuviewer_ctrl_b_after_readybasic_f2
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
+ - id: capture_after_reuviewer_ctrl_b_input
+ type: screen.capture
+ params:
+ label: chain_after_reuviewer_ctrl_b_hotkey
+ pitch: capture after resumed REU Viewer Ctrl+B hotkey
+ - id: wait_launcher_after_reuviewer_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ capture_label: chain_launcher_after_reuviewer_ctrl_b
+ - id: assert_launcher_bank_after_reuviewer_ctrl_b
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "00"
+ - id: select_readybasic_after_reuviewer_ctrl_b
+ type: memory.write
+ params:
+ start: 51232
+ bytes_hex: "05"
+ - id: launch_readybasic_after_reuviewer_ctrl_b
+ type: monitor.command
+ params:
+ command: "raw:g c80f"
+ - id: capture_readybasic_after_reuviewer_ctrl_b_reentry
+ type: screen.capture
+ params:
+ label: chain_readybasic_after_reuviewer_ctrl_b_reentry
+ pitch: warm ReadyBASIC entry evidence; bank/vector assertions and typed sentinel prove keyboard liveness
+ - id: readybasic_type_after_reuviewer_ctrl_b_reentry
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,67,72,65,73,78,52,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_type_after_reuviewer_ctrl_b_reentry
+ type: assert.screen
+ params:
+ contains: "CHAIN4 101"
+ - id: readybasic_exit_after_multi_hop_reentry
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: wait_launcher_stable_after_readybasic_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ pre_delay_s: 2.0
+ capture_label: chain_launcher_stable_after_readybasic_exit
+ - id: assert_launcher_bank_after_readybasic_exit
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "00"
+ - id: assert_readybasic_not_auto_reentered_after_exit
+ type: assert.screen_not_contains
+ params:
+ not_contains: "ready."
+ - id: select_readybasic_after_exit_guard
+ type: memory.write
+ params:
+ start: 51232
+ bytes_hex: "05"
+ - id: reenter_readybasic_after_exit_guard
+ type: monitor.command
+ params:
+ command: "raw:g c80f"
+ - id: capture_readybasic_after_exit_guard_reentry
+ type: screen.capture
+ params:
+ label: chain_readybasic_after_exit_guard_reentry
+ pitch: warm ReadyBASIC entry evidence; bank/vector assertions and typed sentinel prove keyboard liveness
+ - id: readybasic_type_after_exit_guard_reentry
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,67,72,65,73,78,53,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_type_after_exit_guard_reentry
+ type: assert.screen
+ params:
+ contains: "CHAIN5 101"
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_screen_reu_temp_probe.easyflash.yaml b/agentworking/easyflash_full_vice_plans/readybasic_screen_reu_temp_probe.easyflash.yaml
index 8beadb0..b792099 100644
--- a/agentworking/easyflash_full_vice_plans/readybasic_screen_reu_temp_probe.easyflash.yaml
+++ b/agentworking/easyflash_full_vice_plans/readybasic_screen_reu_temp_probe.easyflash.yaml
@@ -19,7 +19,7 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.4/precog-easyflash/readyos_easyflash.crt"
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
autostart_enabled: false
disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
drive8_enabled: true
@@ -40,7 +40,7 @@ steps:
text: "READY OS"
pre_delay_s: 4
poll_s: 0.5
- wait_timeout_s: 240
+ wait_timeout_s: 420
capture_label: easyflash_readybasic_launcher
- id: easyflash_start_readybasic
type: input.sequence
@@ -51,7 +51,7 @@ steps:
- id: wait_readybasic_prompt
type: screen.wait_contains
params:
- text: "readybasic"
+ text: "READY."
wait_timeout_s: 180
capture_label: scrreu_prompt
- id: dump_initial_ranges
@@ -63,7 +63,7 @@ steps:
- { label: descriptors_1000, start: 0x1000, end: 0x11FF }
- { label: resident_1200, start: 0x1200, end: 0x1BFF }
- { label: command_overlay_a800, start: 0xA800, end: 0xAFFF }
- - { label: reu_alloc_c600, start: 0xC600, end: 0xC6FF }
+ - { label: shim_resident_c600, start: 0xC600, end: 0xC9FF }
- id: load_temp_program
type: input.sequence
params:
@@ -86,6 +86,11 @@ steps:
keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
inter_key_delay_s: 0.03
post_delay_s: 75.0
+ - id: capture_temp_program_progress
+ type: screen.capture
+ params:
+ label: scrreu_progress
+ pitch: screen-backed REU program progress after 30 seconds
- id: assert_done
type: assert.memory
params:
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_screen_reu_temp_probe.regular.yaml b/agentworking/easyflash_full_vice_plans/readybasic_screen_reu_temp_probe.regular.yaml
index a12950e..2ca696d 100644
--- a/agentworking/easyflash_full_vice_plans/readybasic_screen_reu_temp_probe.regular.yaml
+++ b/agentworking/easyflash_full_vice_plans/readybasic_screen_reu_temp_probe.regular.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
@@ -48,7 +48,7 @@ steps:
- { label: descriptors_1000, start: 0x1000, end: 0x11FF }
- { label: resident_1200, start: 0x1200, end: 0x1BFF }
- { label: command_overlay_a800, start: 0xA800, end: 0xAFFF }
- - { label: reu_alloc_c600, start: 0xC600, end: 0xC6FF }
+ - { label: shim_resident_c600, start: 0xC600, end: 0xC9FF }
- id: load_temp_program
type: input.sequence
params:
@@ -71,12 +71,17 @@ steps:
keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
inter_key_delay_s: 0.03
post_delay_s: 30.0
+ - id: capture_temp_program_progress
+ type: screen.capture
+ params:
+ label: scrreu_progress
+ pitch: screen-backed REU program progress after 30 seconds
- id: assert_done
- type: screen.wait_contains
+ type: assert.memory
params:
- text: "RBSCRREU DONE"
- wait_timeout_s: 300
- capture_label: scrreu_done
+ start: 1024
+ end: 1036
+ equals_hex: "52 42 53 43 52 52 45 55 20 44 4F 4E 45"
- id: dump_after_done
type: dump.memory_ranges
params:
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_second_entry_editor_probe.easyflash.yaml b/agentworking/easyflash_full_vice_plans/readybasic_second_entry_editor_probe.easyflash.yaml
index b4b1d33..018bfb2 100644
--- a/agentworking/easyflash_full_vice_plans/readybasic_second_entry_editor_probe.easyflash.yaml
+++ b/agentworking/easyflash_full_vice_plans/readybasic_second_entry_editor_probe.easyflash.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.4/precog-easyflash/readyos_easyflash.crt"
+ cart_crt: "Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
autostart_enabled: false
- disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
+ disk8: "agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
drive8_enabled: true
drive8_type: 1541
drive9_enabled: false
@@ -35,12 +35,16 @@ steps:
params:
kill_stale: true
- id: easyflash_wait_launcher
+ retry:
+ max_attempts: 1
+ backoff_ms: 0
+ jitter: false
type: screen.wait_contains
params:
text: "READY OS"
pre_delay_s: 4
poll_s: 0.5
- wait_timeout_s: 240
+ wait_timeout_s: 420
capture_label: easyflash_readybasic_launcher
- id: easyflash_start_readybasic
type: input.sequence
@@ -104,28 +108,50 @@ steps:
- id: move_readybasic_to_editor_before_setup
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_editor_before_setup
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_before_setup
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_before_setup
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
+ - id: wait_editor_stable_before_setup
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ pre_delay_s: 1.5
+ wait_timeout_s: 30
+ - id: clear_keyboard_before_editor_text_before_setup
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: type_editor_chars_before_setup
type: input.sequence
params:
keys: [80,82,79,66,69,32,76,73,78,69,13]
inter_key_delay_s: 0.035
post_delay_s: 0.6
+ - id: clear_keyboard_before_editor_ctrl_b_before_setup
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: ctrl_b_editor_before_setup
- type: input.sequence
+ type: monitor.command
params:
- keys: [2]
- pre_delay_s: 0
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_before_setup
type: screen.wait_contains
params:
@@ -134,10 +160,19 @@ steps:
- id: move_editor_to_readybasic_before_setup
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_readybasic_before_setup
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_before_setup
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_tour_before_setup
type: screen.wait_contains
params:
@@ -284,7 +319,7 @@ steps:
type: dump.memory_ranges
params:
ranges: &state_ranges
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_text_and_vars_1200, start: 0x1200, end: 0x1800 }
- { label: string_heap_9300, start: 0x9300, end: 0x9600 }
- { label: runtime_state_9600, start: 0x9600, end: 0x9A00 }
@@ -303,28 +338,50 @@ steps:
- id: move_readybasic_to_editor_verify_1
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_editor_verify_1
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_verify_1
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_verify_1
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
+ - id: wait_editor_stable_verify_1
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ pre_delay_s: 1.5
+ wait_timeout_s: 30
+ - id: clear_keyboard_before_editor_text_verify_1
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: type_editor_chars_verify_1
type: input.sequence
params:
keys: [80,82,79,66,69,32,76,73,78,69,13]
inter_key_delay_s: 0.035
post_delay_s: 0.6
+ - id: clear_keyboard_before_editor_ctrl_b_verify_1
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: ctrl_b_editor_verify_1
- type: input.sequence
+ type: monitor.command
params:
- keys: [2]
- pre_delay_s: 0
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_verify_1
type: screen.wait_contains
params:
@@ -333,10 +390,19 @@ steps:
- id: move_editor_to_readybasic_verify_1
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_readybasic_verify_1
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_verify_1
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_tour_verify_1
type: screen.wait_contains
params:
@@ -417,28 +483,50 @@ steps:
- id: move_readybasic_to_editor_verify_2
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_editor_verify_2
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_verify_2
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_verify_2
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
+ - id: wait_editor_stable_verify_2
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ pre_delay_s: 1.5
+ wait_timeout_s: 30
+ - id: clear_keyboard_before_editor_text_verify_2
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: type_editor_chars_verify_2
type: input.sequence
params:
keys: [80,82,79,66,69,32,76,73,78,69,13]
inter_key_delay_s: 0.035
post_delay_s: 0.6
+ - id: clear_keyboard_before_editor_ctrl_b_verify_2
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: ctrl_b_editor_verify_2
- type: input.sequence
+ type: monitor.command
params:
- keys: [2]
- pre_delay_s: 0
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_verify_2
type: screen.wait_contains
params:
@@ -447,10 +535,19 @@ steps:
- id: move_editor_to_readybasic_verify_2
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_readybasic_verify_2
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_verify_2
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_tour_verify_2
type: screen.wait_contains
params:
@@ -531,28 +628,50 @@ steps:
- id: move_readybasic_to_editor_verify_3
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_editor_verify_3
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_verify_3
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_verify_3
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
+ - id: wait_editor_stable_verify_3
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ pre_delay_s: 1.5
+ wait_timeout_s: 30
+ - id: clear_keyboard_before_editor_text_verify_3
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: type_editor_chars_verify_3
type: input.sequence
params:
keys: [80,82,79,66,69,32,76,73,78,69,13]
inter_key_delay_s: 0.035
post_delay_s: 0.6
+ - id: clear_keyboard_before_editor_ctrl_b_verify_3
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: ctrl_b_editor_verify_3
- type: input.sequence
+ type: monitor.command
params:
- keys: [2]
- pre_delay_s: 0
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_verify_3
type: screen.wait_contains
params:
@@ -561,10 +680,19 @@ steps:
- id: move_editor_to_readybasic_verify_3
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_readybasic_verify_3
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_verify_3
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_tour_verify_3
type: screen.wait_contains
params:
@@ -645,28 +773,50 @@ steps:
- id: move_readybasic_to_editor_verify_4
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_editor_verify_4
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_verify_4
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_verify_4
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
+ - id: wait_editor_stable_verify_4
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ pre_delay_s: 1.5
+ wait_timeout_s: 30
+ - id: clear_keyboard_before_editor_text_verify_4
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: type_editor_chars_verify_4
type: input.sequence
params:
keys: [80,82,79,66,69,32,76,73,78,69,13]
inter_key_delay_s: 0.035
post_delay_s: 0.6
+ - id: clear_keyboard_before_editor_ctrl_b_verify_4
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: ctrl_b_editor_verify_4
- type: input.sequence
+ type: monitor.command
params:
- keys: [2]
- pre_delay_s: 0
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_verify_4
type: screen.wait_contains
params:
@@ -675,10 +825,19 @@ steps:
- id: move_editor_to_readybasic_verify_4
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_readybasic_verify_4
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_verify_4
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_tour_verify_4
type: screen.wait_contains
params:
@@ -759,28 +918,50 @@ steps:
- id: move_readybasic_to_editor_verify_5
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_editor_verify_5
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_verify_5
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_verify_5
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
+ - id: wait_editor_stable_verify_5
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ pre_delay_s: 1.5
+ wait_timeout_s: 30
+ - id: clear_keyboard_before_editor_text_verify_5
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: type_editor_chars_verify_5
type: input.sequence
params:
keys: [80,82,79,66,69,32,76,73,78,69,13]
inter_key_delay_s: 0.035
post_delay_s: 0.6
+ - id: clear_keyboard_before_editor_ctrl_b_verify_5
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: ctrl_b_editor_verify_5
- type: input.sequence
+ type: monitor.command
params:
- keys: [2]
- pre_delay_s: 0
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_verify_5
type: screen.wait_contains
params:
@@ -789,10 +970,19 @@ steps:
- id: move_editor_to_readybasic_verify_5
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_readybasic_verify_5
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_verify_5
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_tour_verify_5
type: screen.wait_contains
params:
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_second_entry_editor_probe.regular.yaml b/agentworking/easyflash_full_vice_plans/readybasic_second_entry_editor_probe.regular.yaml
index 69fcf3b..a4de0c6 100644
--- a/agentworking/easyflash_full_vice_plans/readybasic_second_entry_editor_probe.regular.yaml
+++ b/agentworking/easyflash_full_vice_plans/readybasic_second_entry_editor_probe.regular.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
@@ -89,28 +89,50 @@ steps:
- id: move_readybasic_to_editor_before_setup
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_editor_before_setup
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_before_setup
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_before_setup
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
+ - id: wait_editor_stable_before_setup
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ pre_delay_s: 1.5
+ wait_timeout_s: 30
+ - id: clear_keyboard_before_editor_text_before_setup
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: type_editor_chars_before_setup
type: input.sequence
params:
keys: [80,82,79,66,69,32,76,73,78,69,13]
inter_key_delay_s: 0.035
post_delay_s: 0.6
+ - id: clear_keyboard_before_editor_ctrl_b_before_setup
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: ctrl_b_editor_before_setup
- type: input.sequence
+ type: monitor.command
params:
- keys: [2]
- pre_delay_s: 0
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_before_setup
type: screen.wait_contains
params:
@@ -119,10 +141,19 @@ steps:
- id: move_editor_to_readybasic_before_setup
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_readybasic_before_setup
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_before_setup
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_tour_before_setup
type: screen.wait_contains
params:
@@ -269,7 +300,7 @@ steps:
type: dump.memory_ranges
params:
ranges: &state_ranges
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_text_and_vars_1200, start: 0x1200, end: 0x1800 }
- { label: string_heap_9300, start: 0x9300, end: 0x9600 }
- { label: runtime_state_9600, start: 0x9600, end: 0x9A00 }
@@ -288,28 +319,50 @@ steps:
- id: move_readybasic_to_editor_verify_1
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_editor_verify_1
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_verify_1
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_verify_1
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
+ - id: wait_editor_stable_verify_1
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ pre_delay_s: 1.5
+ wait_timeout_s: 30
+ - id: clear_keyboard_before_editor_text_verify_1
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: type_editor_chars_verify_1
type: input.sequence
params:
keys: [80,82,79,66,69,32,76,73,78,69,13]
inter_key_delay_s: 0.035
post_delay_s: 0.6
+ - id: clear_keyboard_before_editor_ctrl_b_verify_1
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: ctrl_b_editor_verify_1
- type: input.sequence
+ type: monitor.command
params:
- keys: [2]
- pre_delay_s: 0
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_verify_1
type: screen.wait_contains
params:
@@ -318,10 +371,19 @@ steps:
- id: move_editor_to_readybasic_verify_1
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_readybasic_verify_1
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_verify_1
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_tour_verify_1
type: screen.wait_contains
params:
@@ -402,28 +464,50 @@ steps:
- id: move_readybasic_to_editor_verify_2
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_editor_verify_2
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_verify_2
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_verify_2
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
+ - id: wait_editor_stable_verify_2
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ pre_delay_s: 1.5
+ wait_timeout_s: 30
+ - id: clear_keyboard_before_editor_text_verify_2
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: type_editor_chars_verify_2
type: input.sequence
params:
keys: [80,82,79,66,69,32,76,73,78,69,13]
inter_key_delay_s: 0.035
post_delay_s: 0.6
+ - id: clear_keyboard_before_editor_ctrl_b_verify_2
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: ctrl_b_editor_verify_2
- type: input.sequence
+ type: monitor.command
params:
- keys: [2]
- pre_delay_s: 0
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_verify_2
type: screen.wait_contains
params:
@@ -432,10 +516,19 @@ steps:
- id: move_editor_to_readybasic_verify_2
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_readybasic_verify_2
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_verify_2
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_tour_verify_2
type: screen.wait_contains
params:
@@ -516,28 +609,50 @@ steps:
- id: move_readybasic_to_editor_verify_3
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_editor_verify_3
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_verify_3
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_verify_3
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
+ - id: wait_editor_stable_verify_3
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ pre_delay_s: 1.5
+ wait_timeout_s: 30
+ - id: clear_keyboard_before_editor_text_verify_3
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: type_editor_chars_verify_3
type: input.sequence
params:
keys: [80,82,79,66,69,32,76,73,78,69,13]
inter_key_delay_s: 0.035
post_delay_s: 0.6
+ - id: clear_keyboard_before_editor_ctrl_b_verify_3
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: ctrl_b_editor_verify_3
- type: input.sequence
+ type: monitor.command
params:
- keys: [2]
- pre_delay_s: 0
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_verify_3
type: screen.wait_contains
params:
@@ -546,10 +661,19 @@ steps:
- id: move_editor_to_readybasic_verify_3
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_readybasic_verify_3
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_verify_3
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_tour_verify_3
type: screen.wait_contains
params:
@@ -630,28 +754,50 @@ steps:
- id: move_readybasic_to_editor_verify_4
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_editor_verify_4
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_verify_4
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_verify_4
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
+ - id: wait_editor_stable_verify_4
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ pre_delay_s: 1.5
+ wait_timeout_s: 30
+ - id: clear_keyboard_before_editor_text_verify_4
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: type_editor_chars_verify_4
type: input.sequence
params:
keys: [80,82,79,66,69,32,76,73,78,69,13]
inter_key_delay_s: 0.035
post_delay_s: 0.6
+ - id: clear_keyboard_before_editor_ctrl_b_verify_4
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: ctrl_b_editor_verify_4
- type: input.sequence
+ type: monitor.command
params:
- keys: [2]
- pre_delay_s: 0
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_verify_4
type: screen.wait_contains
params:
@@ -660,10 +806,19 @@ steps:
- id: move_editor_to_readybasic_verify_4
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_readybasic_verify_4
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_verify_4
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_tour_verify_4
type: screen.wait_contains
params:
@@ -744,28 +899,50 @@ steps:
- id: move_readybasic_to_editor_verify_5
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_editor_verify_5
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_verify_5
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_verify_5
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
+ - id: wait_editor_stable_verify_5
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ pre_delay_s: 1.5
+ wait_timeout_s: 30
+ - id: clear_keyboard_before_editor_text_verify_5
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: type_editor_chars_verify_5
type: input.sequence
params:
keys: [80,82,79,66,69,32,76,73,78,69,13]
inter_key_delay_s: 0.035
post_delay_s: 0.6
+ - id: clear_keyboard_before_editor_ctrl_b_verify_5
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: ctrl_b_editor_verify_5
- type: input.sequence
+ type: monitor.command
params:
- keys: [2]
- pre_delay_s: 0
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_verify_5
type: screen.wait_contains
params:
@@ -774,10 +951,19 @@ steps:
- id: move_editor_to_readybasic_verify_5
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_readybasic_verify_5
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_verify_5
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_tour_verify_5
type: screen.wait_contains
params:
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_state_probe.easyflash.yaml b/agentworking/easyflash_full_vice_plans/readybasic_state_probe.easyflash.yaml
index 64d16f4..c1e5f32 100644
--- a/agentworking/easyflash_full_vice_plans/readybasic_state_probe.easyflash.yaml
+++ b/agentworking/easyflash_full_vice_plans/readybasic_state_probe.easyflash.yaml
@@ -19,7 +19,7 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.4/precog-easyflash/readyos_easyflash.crt"
+ cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
autostart_enabled: false
disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
drive8_enabled: true
@@ -40,7 +40,7 @@ steps:
text: "READY OS"
pre_delay_s: 4
poll_s: 0.5
- wait_timeout_s: 240
+ wait_timeout_s: 420
capture_label: easyflash_readybasic_launcher
- id: easyflash_start_readybasic
type: input.sequence
@@ -51,7 +51,7 @@ steps:
- id: wait_readybasic_prompt
type: screen.wait_contains
params:
- text: "readybasic"
+ text: "READY."
wait_timeout_s: 180
capture_label: readybasic_prompt
- id: dump_initial_state
@@ -92,11 +92,9 @@ steps:
text: "READY OS"
wait_timeout_s: 30
- id: resume_direct_string
- type: input.sequence
+ type: monitor.command
params:
- keys: [13]
- inter_key_delay_s: 0.03
- post_delay_s: 2.0
+ command: "keybuf \\x0d"
- id: wait_prompt_after_direct_string_resume
type: screen.wait_contains
params:
@@ -161,11 +159,9 @@ steps:
text: "READY OS"
wait_timeout_s: 30
- id: resume_multiline
- type: input.sequence
+ type: monitor.command
params:
- keys: [13]
- inter_key_delay_s: 0.03
- post_delay_s: 2.0
+ command: "keybuf \\x0d"
- id: wait_prompt_after_multiline_resume
type: screen.wait_contains
params:
@@ -218,11 +214,9 @@ steps:
text: "READY OS"
wait_timeout_s: 30
- id: resume_after_new
- type: input.sequence
+ type: monitor.command
params:
- keys: [13]
- inter_key_delay_s: 0.03
- post_delay_s: 2.0
+ command: "keybuf \\x0d"
- id: wait_prompt_after_new_resume
type: screen.wait_contains
params:
@@ -267,11 +261,9 @@ steps:
text: "READY OS"
wait_timeout_s: 30
- id: resume_variables
- type: input.sequence
+ type: monitor.command
params:
- keys: [13]
- inter_key_delay_s: 0.03
- post_delay_s: 2.0
+ command: "keybuf \\x0d"
- id: wait_prompt_after_variables_resume
type: screen.wait_contains
params:
@@ -324,11 +316,9 @@ steps:
text: "READY OS"
wait_timeout_s: 30
- id: resume_rb_program
- type: input.sequence
+ type: monitor.command
params:
- keys: [13]
- inter_key_delay_s: 0.03
- post_delay_s: 2.0
+ command: "keybuf \\x0d"
- id: wait_prompt_after_rb_resume
type: screen.wait_contains
params:
diff --git a/agentworking/easyflash_full_vice_plans/readybasic_state_probe.regular.yaml b/agentworking/easyflash_full_vice_plans/readybasic_state_probe.regular.yaml
index c7561af..ca26665 100644
--- a/agentworking/easyflash_full_vice_plans/readybasic_state_probe.regular.yaml
+++ b/agentworking/easyflash_full_vice_plans/readybasic_state_probe.regular.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4h-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
@@ -77,11 +77,9 @@ steps:
text: "READY OS"
wait_timeout_s: 30
- id: resume_direct_string
- type: input.sequence
+ type: monitor.command
params:
- keys: [13]
- inter_key_delay_s: 0.03
- post_delay_s: 2.0
+ command: "keybuf \\x0d"
- id: wait_prompt_after_direct_string_resume
type: screen.wait_contains
params:
@@ -146,11 +144,9 @@ steps:
text: "READY OS"
wait_timeout_s: 30
- id: resume_multiline
- type: input.sequence
+ type: monitor.command
params:
- keys: [13]
- inter_key_delay_s: 0.03
- post_delay_s: 2.0
+ command: "keybuf \\x0d"
- id: wait_prompt_after_multiline_resume
type: screen.wait_contains
params:
@@ -203,11 +199,9 @@ steps:
text: "READY OS"
wait_timeout_s: 30
- id: resume_after_new
- type: input.sequence
+ type: monitor.command
params:
- keys: [13]
- inter_key_delay_s: 0.03
- post_delay_s: 2.0
+ command: "keybuf \\x0d"
- id: wait_prompt_after_new_resume
type: screen.wait_contains
params:
@@ -252,11 +246,9 @@ steps:
text: "READY OS"
wait_timeout_s: 30
- id: resume_variables
- type: input.sequence
+ type: monitor.command
params:
- keys: [13]
- inter_key_delay_s: 0.03
- post_delay_s: 2.0
+ command: "keybuf \\x0d"
- id: wait_prompt_after_variables_resume
type: screen.wait_contains
params:
@@ -309,11 +301,9 @@ steps:
text: "READY OS"
wait_timeout_s: 30
- id: resume_rb_program
- type: input.sequence
+ type: monitor.command
params:
- keys: [13]
- inter_key_delay_s: 0.03
- post_delay_s: 2.0
+ command: "keybuf \\x0d"
- id: wait_prompt_after_rb_resume
type: screen.wait_contains
params:
diff --git a/agentworking/easyflash_full_vice_plans/readyshell_cross_app_resume_probe.easyflash.yaml b/agentworking/easyflash_full_vice_plans/readyshell_cross_app_resume_probe.easyflash.yaml
index eaa3bd0..05c845b 100644
--- a/agentworking/easyflash_full_vice_plans/readyshell_cross_app_resume_probe.easyflash.yaml
+++ b/agentworking/easyflash_full_vice_plans/readyshell_cross_app_resume_probe.easyflash.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- cart_crt: "/Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.4/precog-easyflash/readyos_easyflash.crt"
+ cart_crt: "Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
autostart_enabled: false
- disk8: "/Users/karlprosserpp/dev/c64projects/readyosprecog/agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
+ disk8: "agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
drive8_enabled: true
drive8_type: 1541
drive9_enabled: false
@@ -35,12 +35,16 @@ steps:
params:
kill_stale: true
- id: easyflash_wait_launcher
+ retry:
+ max_attempts: 1
+ backoff_ms: 0
+ jitter: false
type: screen.wait_contains
params:
text: "READY OS"
pre_delay_s: 4
poll_s: 0.5
- wait_timeout_s: 240
+ wait_timeout_s: 420
capture_label: easyflash_editor_launcher
- id: easyflash_start_editor
type: input.sequence
@@ -51,9 +55,14 @@ steps:
- id: wait_editor_initial
type: screen.wait_contains
params:
- text: "editor"
+ text: "EDITOR:"
wait_timeout_s: 180
capture_label: editor_initial
+ - id: clear_keyboard_buffer_before_editor_entry
+ type: memory.write
+ params:
+ start: 198
+ bytes_hex: "00"
- id: editor_touch_1
type: input.sequence
params:
@@ -107,13 +116,28 @@ steps:
- id: move_readybasic_to_editor_1
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_relaunch_1
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ # The binary-monitor key helper can drop a lone RETURN immediately after
+ # ReadyBASIC's EXIT return. VICE's text-monitor keybuf path is deterministic.
+ - id: launch_editor_after_readybasic_1
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
+ - id: capture_after_move_readybasic_to_editor_1
+ type: screen.capture
+ params:
+ label: after_move_readybasic_to_editor_1
- id: wait_editor_after_readybasic_1
type: screen.wait_contains
params:
- text: "editor"
+ text: "EDITOR:"
wait_timeout_s: 60
capture_label: editor_after_readybasic_1
- id: ctrl_b_editor_to_launcher_before_readyshell_1
@@ -199,6 +223,6 @@ steps:
type: dump.memory_ranges
params:
ranges:
- - { label: launcher_shim_c800, start: 0xC800, end: 0xCA00 }
+ - { label: launcher_shim_c600, start: 0xC600, end: 0xCA00 }
- { label: app_work_1000, start: 0x1000, end: 0x1800 }
- { label: upper_app_a000, start: 0xA000, end: 0xC600 }
diff --git a/agentworking/easyflash_full_vice_plans/readyshell_cross_app_resume_probe.regular.yaml b/agentworking/easyflash_full_vice_plans/readyshell_cross_app_resume_probe.regular.yaml
index cc1a63d..6982dab 100644
--- a/agentworking/easyflash_full_vice_plans/readyshell_cross_app_resume_probe.regular.yaml
+++ b/agentworking/easyflash_full_vice_plans/readyshell_cross_app_resume_probe.regular.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
@@ -36,9 +36,14 @@ steps:
- id: wait_editor_initial
type: screen.wait_contains
params:
- text: "editor"
+ text: "EDITOR:"
wait_timeout_s: 180
capture_label: editor_initial
+ - id: clear_keyboard_buffer_before_editor_entry
+ type: memory.write
+ params:
+ start: 198
+ bytes_hex: "00"
- id: editor_touch_1
type: input.sequence
params:
@@ -92,13 +97,28 @@ steps:
- id: move_readybasic_to_editor_1
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_relaunch_1
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ # The binary-monitor key helper can drop a lone RETURN immediately after
+ # ReadyBASIC's EXIT return. VICE's text-monitor keybuf path is deterministic.
+ - id: launch_editor_after_readybasic_1
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
+ - id: capture_after_move_readybasic_to_editor_1
+ type: screen.capture
+ params:
+ label: after_move_readybasic_to_editor_1
- id: wait_editor_after_readybasic_1
type: screen.wait_contains
params:
- text: "editor"
+ text: "EDITOR:"
wait_timeout_s: 60
capture_label: editor_after_readybasic_1
- id: ctrl_b_editor_to_launcher_before_readyshell_1
@@ -184,6 +204,6 @@ steps:
type: dump.memory_ranges
params:
ranges:
- - { label: launcher_shim_c800, start: 0xC800, end: 0xCA00 }
+ - { label: launcher_shim_c600, start: 0xC600, end: 0xCA00 }
- { label: app_work_1000, start: 0x1000, end: 0x1800 }
- { label: upper_app_a000, start: 0xA000, end: 0xC600 }
diff --git a/agentworking/readybasic-gfx-phase1/IMPLEMENTATION_LOG.md b/agentworking/readybasic-gfx-phase1/IMPLEMENTATION_LOG.md
new file mode 100644
index 0000000..c4e87c9
--- /dev/null
+++ b/agentworking/readybasic-gfx-phase1/IMPLEMENTATION_LOG.md
@@ -0,0 +1,36 @@
+# ReadyBASIC Graphics Phase 1 Implementation Log
+
+## 2026-06-15
+
+- Started Phase 1 command-only implementation.
+- Cleaned AGENTWORKING top level by archiving older artifacts.
+- Added built-in graphics descriptors for `GFXCORE`, `GFXPRIM`, `GFXSPR`, and
+ `INPUTEV`.
+- Added command-only signatures for graphics mode strings, graphics surfaces,
+ 3-arg primitives, 5-arg primitives, sprite setup, and no-arg input commands.
+- Implemented Bank D mode setup, clears, immediate plot/point/line/rect/frect,
+ sprite setup/move/color/collision polling, and joystick/keyboard polling.
+- Moved command descriptor lookup under hidden RAM to keep resident code within
+ the `$1200-$2ABF` budget.
+- Added `rbgfx01` through `rbgfx12` BASIC demos and Makefile/profile wiring.
+- Added `build_support/run_readybasic_gfx_phase1_probe.sh`.
+- Updated ReadyBASIC graphics/current/plugin architecture docs.
+- Regenerated the regular D81 profile with the built-in graphics demos present.
+- Regenerated the ReadyBASIC memory report.
+- Added `build_support/run_readybasic_readyos_loaded_apps_suite.sh`, which boots
+ ReadyOS preboot, waits for ReadyBASIC loaded by ReadyOS, then loads/lists/runs
+ `RBTEST1`, `RBPROC1`, and all `RBGFXxx` PRGs from inside ReadyBASIC.
+- Fixed demo programs so they only use existing ReadyBASIC/C64 BASIC syntax:
+ numeric loop variables instead of integer loop variables, and no graphics
+ command immediately after `THEN`.
+- Fixed `GFXMODE` VIC register setup so stack restoration no longer overwrites
+ the intended `$D011`/`$D016` values.
+- Fixed bitmap `GFXCLEAR` screen RAM initialization so plotted foreground pixels
+ are visible in hires and multicolor bitmap modes.
+- Added `SPRROW(N,ROW,B1,B2,B3)` to the `GFXSPR` overlay so BASIC demos can
+ define actual 24-bit hardware sprite rows in Bank D sprite memory.
+- Fixed slot-2 overlay descriptors to copy `GFXSPR`/`INPUTEV` from their real
+ linked payload offsets and use entry offsets relative to slot 2.
+- Added `RBGFX13` plus `build_support/run_readybasic_sprite_steps_demo.sh` and
+ `make readybasic-sprite-steps-vice` for ReadyOS-hosted staged sprite
+ screenshots.
diff --git a/agentworking/readybasic-gfx-phase1/LESSONS.md b/agentworking/readybasic-gfx-phase1/LESSONS.md
new file mode 100644
index 0000000..323545d
--- /dev/null
+++ b/agentworking/readybasic-gfx-phase1/LESSONS.md
@@ -0,0 +1,29 @@
+# ReadyBASIC Graphics Phase 1 Lessons
+
+- Keep graphics state command-owned. Do not alter ReadyBASIC language paths.
+- Bank D graphics must not use `$C000-$C9FF`; ReadyBASIC and ReadyOS own that
+ area for bridge, shared frames, REU metadata, and shim ABI.
+- The existing static checker froze old proof payload sizes, so graphics work
+ must update it to validate ranges and budgets instead of exact legacy sizes.
+- Descriptor lookup does not need BASIC ROM and can live under hidden RAM; this
+ is useful resident-pressure relief without changing language behavior.
+- Phase 1 can expose the REU surface handle ABI before full offscreen drawing,
+ but docs/tests must be explicit that `GFXTARGET(0)` is the implemented draw
+ target and `GFXBLIT(H%)` is currently handle validation.
+- Launcher-cycle hotkey verification can hang at preboot `LOADING LAUNCHER...`
+ even after the default hotkey probe passes. Keep this separated from graphics
+ command verification unless a focused change touches launcher/profile boot.
+- Visual ReadyOS-context screenshots matter for graphics commands. The
+ command-only probe passed before screenshots showed blank output because VIC
+ mode registers were being clobbered after the command handler returned.
+- Keep demos inside the already-supported language surface. C64 BASIC rejects
+ `FOR X%` style loop variables here, and ReadyBASIC intentionally does not
+ add command-after-`THEN` behavior for Phase 1 graphics.
+- Bitmap screen RAM color bytes are part of visibility, not just clearing.
+ Clearing bitmap memory while setting foreground equal to background can make
+ correct plotted pixels look blank.
+- Sprite demos need explicit pattern data. `SPRSET`/`SPRMOVE` prove VIC state,
+ but `SPRROW` makes the pixels visible and auditable from BASIC source.
+- Slot-2 overlay descriptors must describe the linked payload location, not
+ assume every overlay begins at `$B800`. Otherwise absolute references inside
+ the overlay resolve against the wrong runtime address.
diff --git a/agentworking/readybasic-gfx-phase1/STATE.md b/agentworking/readybasic-gfx-phase1/STATE.md
new file mode 100644
index 0000000..7378d65
--- /dev/null
+++ b/agentworking/readybasic-gfx-phase1/STATE.md
@@ -0,0 +1,35 @@
+# ReadyBASIC Graphics Phase 1 State
+
+Objective: implement Phase 1 graphics as ReadyBASIC commands only, without
+changing language/runtime behavior.
+
+Design source: `src/apps/readybasic/READYBASIC_GRAPHICS_COMMAND_DESIGN.md`.
+
+Current status:
+
+- Phase 1 command-only implementation is in place.
+- Old `agentworking` top-level artifacts archived under
+ `agentworking/archive-pre-readybasic-gfx-phase1-20260615/`.
+- `bin/readybasic.prg` builds with Phase 1 graphics command descriptors and
+ built-in payloads.
+- Graphics module payloads are grouped into non-default built-in packs:
+ `GFXCORE`, `GFXPRIM`, `GFXSPR`, and `INPUTEV`.
+- Twelve `rbgfx*.bas` demos exist and compile to `$2AC1` PRGs.
+- Static checker validates graphics modules, Bank D guardrails, and flexible
+ pack budgets while preserving the hard ReadyBASIC memory guards.
+- Current post-Phase-2/CMDPACK2 map: `RESIDENT` `$1200-$2ABA`, `HIDDEN`
+ `$A000-$A7DE`, `LOWPACK` `$A800-$AEFC`, `SLOTPACK1` `$B000-$B474`,
+ `SLOTPACK2` `$B800-$BD14`, `OVL1PACK` `$B800-$BA71`, and `OVL2PACK`
+ `$B800-$B86C`.
+
+Known limits:
+
+- `GFXTARGET(0)` is the implemented draw target. `GFXSURF` creates typed REU
+ handles and `GFXBLIT(H%)` validates them, but offscreen draw/blit is not
+ pixel-complete in Phase 1.
+- `PNT(X,Y,V%)` is the preferred Phase 1 point-read spelling. `POINT` remains
+ registered, but the short alias avoids a BASIC parser/name corner in probes.
+- `LINE` is a simple endpoint stepper, not a full Bresenham implementation.
+- Multicolor bitmap/tile modes set VIC mode/layout state, but primitives are
+ still Phase 1 one-bit/cell-oriented behavior.
+- Input is polling-only; no IRQ sampler was added.
diff --git a/agentworking/readybasic-gfx-phase1/TEST_LOG.md b/agentworking/readybasic-gfx-phase1/TEST_LOG.md
new file mode 100644
index 0000000..64b47cf
--- /dev/null
+++ b/agentworking/readybasic-gfx-phase1/TEST_LOG.md
@@ -0,0 +1,49 @@
+# ReadyBASIC Graphics Phase 1 Test Log
+
+## 2026-06-15
+
+- `make bin/readybasic.prg` passed.
+- `make obj/rbgfx01_modes.prg obj/rbgfx02_hires_plot.prg obj/rbgfx03_hires_lines.prg obj/rbgfx04_rects.prg obj/rbgfx05_point_read.prg obj/rbgfx06_reu_surface.prg obj/rbgfx07_mbitmap.prg obj/rbgfx08_tile.prg obj/rbgfx09_sprites.prg obj/rbgfx10_collision.prg obj/rbgfx11_input.prg obj/rbgfx12_showcase.prg bin/readybasic.prg` passed.
+- `make readybasic-plugin-static-check` passed.
+- `READYBASIC_SKIP_BUILD=1 make readybasic-gfx-phase1-vice` passed.
+ Run dir: `logs/vice_auto_20260615_194952`.
+- Current-image rerun of `READYBASIC_SKIP_BUILD=1 make
+ readybasic-gfx-phase1-vice` passed after the final D81 rebuild.
+ Run dir: `logs/vice_auto_20260615_202122`.
+- `READYBASIC_SKIP_BUILD=1 make readybasic-module-overlay-vice` passed.
+ Run dir: `logs/vice_auto_20260615_195343`.
+- `READYBASIC_SKIP_BUILD=1 make readybasic-plugin-command-vice` passed.
+ Run dir: `logs/vice_auto_20260615_195029`.
+- `READYBASIC_SKIP_BUILD=1 make readybasic-program-vice` passed.
+ Run dir: `logs/vice_auto_20260615_195225`.
+- `READYBASIC_SKIP_BUILD=1 make readybasic-rbtest1-vice` passed.
+ Run dir: `logs/vice_auto_20260615_195328`.
+- `make readybasic-memory-report` passed and regenerated
+ `docs/readybasic_memory_diagrams.html`.
+- `READYBASIC_SKIP_BUILD=1 make readybasic-vice-suites` was run after focused
+ checks. It passed through demo, repeat/label, lifecycle, module overlay,
+ plugin command, program, rbtest1, state, and large-vars probes, then hung in
+ `readybasic-hotkey-vice` launcher-cycle startup waiting for launcher text at
+ `wait_launcher_initial`.
+ Repro run dir: `logs/vice_auto_20260615_201724`.
+- Focused default hotkey probe passed after that hang:
+ `bash build_support/run_readybasic_hotkey_probe.sh`.
+ Run dir: `logs/vice_auto_20260615_201648`.
+- `READYBASIC_SKIP_BUILD=1 make readybasic-readyos-loaded-apps-vice` passed.
+ Run dir: `logs/vice_auto_20260615_205414`.
+ This is the explicit ReadyOS context suite: it boots ReadyOS preboot, waits
+ for ReadyBASIC loaded by ReadyOS, then loads/lists/runs `RBTEST1`, `RBPROC1`,
+ and all `RBGFXxx` PRGs from inside ReadyBASIC with screenshots.
+- The ReadyOS-loaded visual suite caught and validated fixes for:
+ - BASIC demo loop variables using `%` where C64 BASIC syntax rejects them.
+ - Unsupported command-after-`THEN` syntax in `rbgfx08_tile.bas`.
+ - `GFXMODE` clobbering VIC register values while restoring the caller's
+ return address.
+ - Bitmap clears filling screen RAM with an invisible foreground/background
+ color pair.
+- `build_support/run_readybasic_sprite_steps_demo.sh` passed after rebuilding
+ the regular D81 profile.
+ Run dir: `logs/vice_auto_20260615_224423`.
+ This boots ReadyOS preboot with ReadyBASIC as the first app, loads/lists/runs
+ `RBGFX13` inside ReadyBASIC, captures initial sprite placement, movement,
+ recolor, and final completion screenshots, and asserts no BASIC error.
diff --git a/agentworking/readybasic-gfx-phase2/IMPLEMENTATION_LOG.md b/agentworking/readybasic-gfx-phase2/IMPLEMENTATION_LOG.md
new file mode 100644
index 0000000..1d15804
--- /dev/null
+++ b/agentworking/readybasic-gfx-phase2/IMPLEMENTATION_LOG.md
@@ -0,0 +1,26 @@
+# ReadyBASIC Graphics Phase 2 Implementation Log
+
+## 2026-06-15
+
+- Committed completed Phase 1 baseline as `2ddfcb5`.
+- Added `CIRCLE(X,Y,R,C)` and `FCIRCLE(X,Y,R,C)` command descriptors and
+ `GFXPRIM` module bodies.
+- Added `TILE(X,Y,CH,C)` and `CHARAT(X,Y,CH,C)` command descriptors and cell
+ write support for Bank D tile modes plus ordinary text-mode demo output.
+- Added sprite expansion, priority, per-sprite multicolor enable, shared
+ multicolor register, and tokenizer-safe alias descriptors in `GFXSPR`.
+- Added `rbgfx14_phase2_prims.bas`, `rbgfx15_phase2_tiles.bas`, and
+ `rbgfx16_phase2_sprite_ctrl.bas`.
+- Added the Phase 2 demos to the ReadyBASIC demo list and regular D81 developer
+ profiles.
+- Added `build_support/run_readybasic_gfx_phase2_demo.sh`, which boots ReadyOS,
+ waits for ReadyBASIC loaded by ReadyOS, loads/runs Phase 2 demos from inside
+ ReadyBASIC, captures staged screenshots, and asserts no BASIC error.
+- Updated graphics/current/plugin architecture docs with implemented Phase 2
+ commands, aliases, payload sizes, and deferred work.
+- Added `CMDPACK2` at `$6200-$7FFF` and changed `GFXSPR`/`INPUTEV` into true
+ slot-2 replacement overlays. They are stored in the assigned command-code REU
+ bank at `$5000` and `$5800`, respectively, then fetched into `$B800` when
+ called.
+- Updated static guardrails and the HTML memory report generator for sparse
+ built-in overlay storage.
diff --git a/agentworking/readybasic-gfx-phase2/LESSONS.md b/agentworking/readybasic-gfx-phase2/LESSONS.md
new file mode 100644
index 0000000..01a68df
--- /dev/null
+++ b/agentworking/readybasic-gfx-phase2/LESSONS.md
@@ -0,0 +1,20 @@
+# ReadyBASIC Graphics Phase 2 Lessons
+
+- Keep command names token-safe in demo source. PETCAT can split embedded BASIC
+ tokens inside longer names, so visible demos should prefer aliases such as
+ `SPRSIZE`, `SPRMUL`, `SPRMCO`, and `SPRCOL`.
+- Do not hide sprite pixel setup. `rbgfx16` uses `SPRROW` to make the sprite
+ bitmap auditable in BASIC source before testing movement and VIC controls.
+- Split staged demo commands onto separate lines when debugging parser issues.
+ It makes VICE screenshot failures point at the exact command.
+- Slot-2 payload budget is now tighter. `GFXPRIM` is `$0515` bytes and the
+ `GFXSPR` overlay is `$0272` bytes; larger commands should either replace
+ approximations carefully or move into a separate overlay.
+- Do not pack unrelated slot-2 families sequentially in one runtime strip.
+ `GFXPRIM`, `GFXSPR`, and `INPUTEV` should be replacement overlays that each
+ get their own 2KB execution-image budget.
+- Cold-load seed room and runtime execution room are separate constraints.
+ `CMDPACK2` adds storage/stash capacity, but each command family still has to
+ fit in the runtime slot or overlay it is fetched into.
+- ReadyOS-context screenshots are the real proof for graphics work. Direct PRG
+ loads are not representative of ReadyBASIC running under ReadyOS.
diff --git a/agentworking/readybasic-gfx-phase2/STATE.md b/agentworking/readybasic-gfx-phase2/STATE.md
new file mode 100644
index 0000000..e4e9452
--- /dev/null
+++ b/agentworking/readybasic-gfx-phase2/STATE.md
@@ -0,0 +1,36 @@
+# ReadyBASIC Graphics Phase 2 State
+
+Objective: implement Phase 2 graphics as ReadyBASIC commands only, without
+changing language/runtime behavior.
+
+Design source: `src/apps/readybasic/READYBASIC_GRAPHICS_COMMAND_DESIGN.md`.
+
+Current status:
+
+- Phase 1 was committed as `2ddfcb5`.
+- Phase 2 visible command additions are implemented in built-in graphics
+ modules; no external `ZMODLD` step is required.
+- New `GFXPRIM` commands: `CIRCLE`, `FCIRCLE`, `TILE`, and `CHARAT`.
+- New `GFXSPR` commands and aliases: `SPREXPAND`/`SPRSIZE`, `SPRPRI`,
+ `SPRMULTI`/`SPRMUL`, `SPRMCOLOR`/`SPRMCO`, and `SPRCOL`.
+- New demos: `rbgfx14_phase2_prims.bas`, `rbgfx15_phase2_tiles.bas`, and
+ `rbgfx16_phase2_sprite_ctrl.bas`.
+- New VICE automation: `build_support/run_readybasic_gfx_phase2_demo.sh` and
+ `make readybasic-gfx-phase2-vice`.
+- Current map after the replacement-overlay rework: `BASIC_START` remains
+ `$2AC1`, formula free bytes remain `30013`, `RESIDENT` remains `$18BB`
+ / 6331B, and `bin/readybasic.prg` is `28674` bytes because `CMDPACK2`
+ extends the cold-load seed image through `$7FFF`.
+- Runtime slot headroom: slot 0 has 259B free, slot 1 has 907B free,
+ `GFXPRIM` has 747B free, `GFXSPR` has 1422B free, and `INPUTEV` has
+ 1939B free.
+
+Known limits:
+
+- `CIRCLE` is an outline approximation that reuses `LINE`.
+- `FCIRCLE` currently fills the bounding rectangle as a command-path proof.
+- Full REU-backed offscreen drawing/blitting, dirty-rect `GFXSYNC`, retained
+ display lists, sprite-sheet handles, polygon fill, and true circular fill are
+ deferred.
+- `POLY`/`FPOLY` and `SCROLL` are not implemented commands yet, so the Phase 2
+ screenshot automation does not include polygon screenshots.
diff --git a/agentworking/readybasic-gfx-phase2/TEST_LOG.md b/agentworking/readybasic-gfx-phase2/TEST_LOG.md
new file mode 100644
index 0000000..38f9fca
--- /dev/null
+++ b/agentworking/readybasic-gfx-phase2/TEST_LOG.md
@@ -0,0 +1,50 @@
+# ReadyBASIC Graphics Phase 2 Test Log
+
+## 2026-06-15
+
+- `make bin/readybasic.prg obj/rbgfx16_phase2_sprite_ctrl.prg` passed after
+ adding tokenizer-safe sprite aliases.
+- `build_support/run_readybasic_gfx_phase2_demo.sh` passed.
+ Run dir: `logs/vice_auto_20260615_232955`.
+- `READYBASIC_SKIP_BUILD=1 make readybasic-gfx-phase2-vice` passed.
+ Run dir: `logs/vice_auto_20260615_233307`.
+- `make readybasic-plugin-static-check` passed.
+- `build_support/run_readybasic_gfx_phase2_demo.sh` passed after the
+ `CMDPACK2`/replacement-overlay rework.
+ Run dir: `logs/vice_auto_20260616_132309`.
+- The Phase 2 VICE run booted ReadyOS preboot, waited for ReadyBASIC loaded by
+ ReadyOS, then loaded and ran `RBGFX14`, `RBGFX15`, and `RBGFX16` inside
+ ReadyBASIC.
+- Captured screenshots:
+ - `readybasic_gfx_phase2_prompt`
+ - `readybasic_gfx_phase2_list_rbgfx14`
+ - `readybasic_gfx_phase2_primitives`
+ - `readybasic_gfx_phase2_prims_done`
+ - `readybasic_gfx_phase2_tiles`
+ - `readybasic_gfx_phase2_tiles_done`
+ - `readybasic_gfx_phase2_sprite_normal`
+ - `readybasic_gfx_phase2_sprite_expanded`
+ - `readybasic_gfx_phase2_sprite_multi_priority`
+ - `readybasic_gfx_phase2_sprites_done`
+- Earlier failed runs caught PETCAT tokenization collisions in `SPREXPAND`,
+ `SPRMULTI`, and `SPRMCLR`; aliases now keep demo source token-safe.
+- There are no polygon screenshots because `POLY` and `FPOLY` are not
+ implemented Phase 2 commands; they remain documented future/deferred work.
+
+## 2026-06-16
+
+- `make readybasic-plugin-static-check` passed after expanding the static
+ guardrails for `CMDPACK2`, replacement slot-2 overlay run addresses, and
+ fixed code-bank offsets `$5000`/`$5800`.
+- `make readybasic-memory-report` regenerated
+ `docs/readybasic_memory_diagrams.html` with the sparse built-in payload map.
+- `make readybasic-vice-suites` passed after the CMDPACK2/replacement-overlay
+ rework. Final run status was success with no failed or degraded steps.
+ Representative run dirs:
+ - graphics demo: `logs/vice_auto_20260616_132309`
+ - module overlay probe: `logs/vice_auto_20260616_141715`
+ - plugin command probe: `logs/vice_auto_20260616_141814`
+ - cross-app resume probe: `logs/vice_auto_20260616_142612`
+ - second-entry/editor probe: `logs/vice_auto_20260616_142835`
+ - full suite visual verification: `logs/vice_auto_20260616_143027`
+- The module overlay probe retained the ReadyBASIC free-byte assertion.
diff --git a/agentworking/readybasic-gfx-phase3/IMPLEMENTATION_LOG.md b/agentworking/readybasic-gfx-phase3/IMPLEMENTATION_LOG.md
new file mode 100644
index 0000000..be428d5
--- /dev/null
+++ b/agentworking/readybasic-gfx-phase3/IMPLEMENTATION_LOG.md
@@ -0,0 +1,33 @@
+# ReadyBASIC Graphics Phase 3 Implementation Log
+
+## 2026-06-16
+
+- Added linker segment `OVL3PACK` for a third slot-2 replacement overlay.
+- Added `RB_SUBMOD_GFXPOLY = 20` and `RB_CODE_GFXPOLY_OFF = $6000`.
+- Added typed REU point-buffer handle kind `RB_HANDLE_TYPE_POINTBUF = 4`.
+- Added command descriptors for `POLY`, `FPOLY`, `PBUFNEW`, `PBUFSET`,
+ `PBUFFREE`, `POLYH`, and `FPOLYH`.
+- Added the `SIG_POLY` parser signature for BASIC integer-array polygon input.
+- Reused existing numeric signatures for point-buffer handle commands where
+ possible to avoid resident growth.
+- Added `GFXPOLY` body code in `OVL3PACK`, including array point reads, REU
+ point-buffer page fetch/store, outline polygon closure, and conservative
+ filled polygon fan drawing.
+- Extended cold prestash to copy `OVL3PACK` from `CMDPACK2` into assigned
+ code-bank offset `$6000`.
+- Updated static verification to enforce `GFXPOLY` placement, size, submodule
+ id, handle type, and `RB_CODE_GFXPOLY_OFF=$6000`.
+- Updated memory-report generation and regenerated
+ `docs/readybasic_memory_diagrams.html`.
+- Added Phase 3 BASIC demos and ReadyOS/ReadyBASIC VICE automation.
+- Fixed polygon loop state after VICE exposed REU-demo hangs: point count now
+ lives in dedicated copy scratch instead of fields clobbered by line drawing.
+- Kept demo labels neutral so `LIST`/`RUN` automation proves the files without
+ accidentally invoking command parsing from display-only text.
+
+Implementation decision:
+
+- The requested dynamic same-name handle form would have required more resident
+ parser/dispatch code. With `RESIDENT` ending at `$2ABF`, the implementation
+ uses `POLYH` and `FPOLYH` for REU point-buffer handles to preserve the fixed
+ BASIC start/free-byte invariant.
diff --git a/agentworking/readybasic-gfx-phase3/LESSONS.md b/agentworking/readybasic-gfx-phase3/LESSONS.md
new file mode 100644
index 0000000..d6f119c
--- /dev/null
+++ b/agentworking/readybasic-gfx-phase3/LESSONS.md
@@ -0,0 +1,26 @@
+# ReadyBASIC Graphics Phase 3 Lessons
+
+- Resident parser bytes are now the scarcest resource. Preserve
+ `BASIC_START=$2AC1` first, even when that means command spelling is less
+ elegant than the original design.
+- Same-name overloads are expensive in this command spine because lookup returns
+ one descriptor and the parser must distinguish array-base syntax from scalar
+ numeric handle syntax.
+- `GFXPOLY` belongs in its own replacement overlay. Putting polygon bodies into
+ `GFXPRIM` would consume the remaining primitive headroom and make future
+ primitive fixes harder.
+- Document implementation-level approximations plainly. Current filled polygons
+ are convex fan fills; a true scanline fill should be a future overlay-growth
+ task, not silently implied by the command name.
+- ReadyOS-context VICE automation remains the real graphics proof. All Phase 3
+ demos are loaded and run from inside ReadyBASIC after ReadyOS launches it.
+- Demo text should avoid command-looking words in visible strings and even in
+ casual REM text. Existing command hook behavior can scan surprising places, so
+ the Phase 3 demos use neutral labels and done markers.
+- Do not keep polygon loop state in command frame fields reused by primitive
+ drawing. The line worker mutates current-point fields; polygon count and index
+ need separate scratch bytes.
+- Screenshot demos should hold graphics mode with a `GET` loop and let VICE
+ automation press SPACE after capture. Pause-only demos can return to text
+ before the harness captures, especially when command waits are byte-sized or
+ intentionally short.
diff --git a/agentworking/readybasic-gfx-phase3/STATE.md b/agentworking/readybasic-gfx-phase3/STATE.md
new file mode 100644
index 0000000..5b0c465
--- /dev/null
+++ b/agentworking/readybasic-gfx-phase3/STATE.md
@@ -0,0 +1,37 @@
+# ReadyBASIC Graphics Phase 3 State
+
+Objective: implement polygon-first graphics commands as ReadyBASIC commands only,
+without changing ReadyBASIC language behavior, tokenization, control flow, native
+expression rules, `BASIC_START`, or empty BASIC free bytes.
+
+Design source: `src/apps/readybasic/READYBASIC_GRAPHICS_COMMAND_DESIGN.md`.
+
+Current status:
+
+- Phase 3 adds built-in module id `3`, submodule `20`, named `GFXPOLY`.
+- `GFXPOLY` is a slot-2 replacement overlay fetched into `$B800-$BF99`.
+- The overlay is stored in the ReadyBASIC assigned command-code REU bank at
+ offset `$6000`; its current size is `$079A` / 1946B.
+- `BASIC_START` remains `$2AC1`; formula empty BASIC free bytes remain `30013`.
+- Array-backed commands are `POLY(A%(0),COUNT,C)` and
+ `FPOLY(A%(0),COUNT,C)`.
+- REU point-buffer commands are `PBUFNEW(COUNT,H%)`,
+ `PBUFSET(H%,INDEX,X,Y)`, `POLYH(H%,COUNT,C)`, `FPOLYH(H%,COUNT,C)`, and
+ `PBUFFREE(H%)`.
+- Point buffers are typed REU handle type `4` and currently use one heap page,
+ supporting up to 64 zero-based points.
+- New demos are `rbgfx17_poly_array.bas`, `rbgfx18_fpoly_array.bas`,
+ `rbgfx19_poly_reu.bas`, and `rbgfx20_fpoly_reu_showcase.bas`.
+- New automation is `build_support/run_readybasic_gfx_phase3_demo.sh` and
+ `make readybasic-gfx-phase3-vice`.
+
+Known limits:
+
+- Same-name handle overloads `POLY(H%,COUNT,C)` and `FPOLY(H%,COUNT,C)` were
+ not implemented. `POLYH` and `FPOLYH` keep the resident parser small enough to
+ preserve `BASIC_START=$2AC1`.
+- `FPOLY` and `FPOLYH` use a conservative convex fan fill, not a full
+ scanline/concave polygon fill.
+- Polygon line drawing uses the current compact step-toward-endpoint primitive,
+ so uneven slopes are approximate.
+- Tile modes draw/fill through the existing cell-space plotting path.
diff --git a/agentworking/readybasic-gfx-phase3/TEST_LOG.md b/agentworking/readybasic-gfx-phase3/TEST_LOG.md
new file mode 100644
index 0000000..2c4a815
--- /dev/null
+++ b/agentworking/readybasic-gfx-phase3/TEST_LOG.md
@@ -0,0 +1,60 @@
+# ReadyBASIC Graphics Phase 3 Test Log
+
+## 2026-06-16
+
+Planned focused checks:
+
+- `make bin/readybasic.prg`
+- `make readybasic-plugin-static-check`
+- `make readybasic-memory-report`
+- `make readybasic-gfx-phase3-vice`
+- `make readybasic-gfx-phase2-vice`
+- `make readybasic-module-overlay-vice`
+- `make readybasic-plugin-command-vice`
+
+Planned full regression:
+
+- `make readybasic-vice-suites`
+
+Capture labels expected from the Phase 3 VICE demo:
+
+- `readybasic_gfx_phase3_poly_array`
+- `readybasic_gfx_phase3_fpoly_array`
+- `readybasic_gfx_phase3_poly_reu`
+- `readybasic_gfx_phase3_fpoly_reu_showcase`
+
+Completed focused checks so far:
+
+- `make bin/readybasic.prg`: passed.
+- `make readybasic-plugin-static-check`: passed.
+- `make readybasic-memory-report`: passed.
+- `make readybasic-gfx-phase3-vice`: passed, including ReadyOS boot,
+ ReadyBASIC-loaded demos, one `LIST` assertion, `PBUFNEW`/`PBUFFREE` text
+ probe, no BASIC error prompt, and all four screenshot captures.
+- `make readybasic-gfx-phase2-vice`: passed.
+- `make readybasic-module-overlay-vice`: passed.
+- `make readybasic-plugin-command-vice`: passed.
+
+Full regression:
+
+- `make readybasic-vice-suites`: passed.
+
+Relevant VICE run directories:
+
+- Phase 3 polygon screenshots:
+ `/Users/karlprosserpp/dev/c64projects/readyosprecog/logs/vice_auto_20260616_180808`
+- Phase 2 graphics regression:
+ `/Users/karlprosserpp/dev/c64projects/readyosprecog/logs/vice_auto_20260616_172349`
+- Module overlay focused regression:
+ `/Users/karlprosserpp/dev/c64projects/readyosprecog/logs/vice_auto_20260616_172427`
+- Plugin command focused regression:
+ `/Users/karlprosserpp/dev/c64projects/readyosprecog/logs/vice_auto_20260616_172530`
+- Full suite final visual verification:
+ `/Users/karlprosserpp/dev/c64projects/readyosprecog/logs/vice_auto_20260616_175215`
+
+Screenshot capture note:
+
+- The final Phase 3 demos use the proven Phase 2 `GET`/SPACE gate after a
+ short `ZPAUSE(30)`. Earlier pause-only demo captures returned to text before
+ the harness screenshot step, so screenshot demos should hold graphics mode
+ until automation explicitly advances them.
diff --git a/agentworking/readybasic-gfx-phase4/IMPLEMENTATION_LOG.md b/agentworking/readybasic-gfx-phase4/IMPLEMENTATION_LOG.md
new file mode 100644
index 0000000..0eaf994
--- /dev/null
+++ b/agentworking/readybasic-gfx-phase4/IMPLEMENTATION_LOG.md
@@ -0,0 +1,12 @@
+# Implementation Log
+
+- Added linker segments `OVL4PACK` and `OVL5PACK` for built-in slot-2 replacement overlays.
+- Added submodules `GFXDL` and `GFXTILE`, stashed at code-bank offsets `$6800` and `$7000`.
+- Added typed REU handle kinds for display lists, charsets, tilesets, and tilemaps.
+- Implemented `DLMAKE`, `DLCLR`, `DLPLOT`, `DLLINE`, `DLRECT`, `DLFRECT`, and `DLDRAW`.
+- Implemented `CHRMAKE`, `CHRROW`, `CHRUSE`, `TSMAKE`, `TSSET`, `TMMAKE`, `TMSET`, `TMDRAW`, `MCELL`, and `MCBG`.
+- Fixed `TMDRAW` map handle preservation: the first version saved map bank/page in `RF_RECT_BUF`, which overlaps the tileset fetch buffer.
+- Kept constructor command names as `*MAKE` because embedded `NEW` is unsafe under the unchanged BASIC tokenizer path.
+- Added `GFXTGT` as a stored-program-safe descriptor alias for the existing `GFXTARGET` command id/worker after `GFXTARGET(H%)` tokenized badly in a `petcat` demo.
+- Added `rbgfx26_mode_matrix.bas` to exercise immediate primitives across `HIRES`, `MBITMAP`, `TILE`, and `MTILE`.
+- Added `rbgfx27_target_blit.bas` to exercise `GFXSURF`, `GFXTGT`, `GFXSYNC`, `GFXBLIT`, and visible-target restore.
diff --git a/agentworking/readybasic-gfx-phase4/LESSONS.md b/agentworking/readybasic-gfx-phase4/LESSONS.md
new file mode 100644
index 0000000..1ebccdc
--- /dev/null
+++ b/agentworking/readybasic-gfx-phase4/LESSONS.md
@@ -0,0 +1,8 @@
+# Lessons
+
+- At 1MHz, BASIC-side resource construction loops are slow enough that screenshot automation must wait for an explicit program-held graphics frame, not an optimistic fixed delay.
+- Command names containing tokenizable BASIC words are risky without changing the language tokenizer. `DLMAKE`, `CHRMAKE`, `TSMAKE`, and `TMMAKE` are safer than `*NEW`.
+- Even existing names can be unsafe in stored BASIC if they contain tokenizable substrings; `GFXTGT` is the safe demo spelling for `GFXTARGET`.
+- Shared scratch buffers overlap intentionally. Before fetching larger REU chunks, check whether any saved state lives inside the destination range.
+- For speed, retained resources should be compact and REU-backed. BASIC should build handles or load future resource files; command overlays should perform the expensive traversal/copy work.
+- The tilemap command path and the tile/charset display path are separate failure domains. Debugging them separately avoids blaming the REU structure when the visible VIC configuration is the real issue.
diff --git a/agentworking/readybasic-gfx-phase4/STATE.md b/agentworking/readybasic-gfx-phase4/STATE.md
new file mode 100644
index 0000000..d8780d8
--- /dev/null
+++ b/agentworking/readybasic-gfx-phase4/STATE.md
@@ -0,0 +1,7 @@
+# ReadyBASIC Graphics Phase 4 State
+
+- Implemented command-only overlays `GFXDL` and `GFXTILE`.
+- Added retained display-list commands, fixed-format charset/tileset/tilemap handles, explicit multicolor bitmap cell commands, mode-matrix and target/blit demos, and ReadyOS-hosted VICE automation.
+- `BASIC_START` remains `$2AC1`; resident size remains `$18C0`.
+- Latest focused run: `READYBASIC_SKIP_BUILD=1 make readybasic-gfx-phase4-vice` passed with 34/34 steps.
+- Known issue: `TMDRAW` writes expected Bank D screen/color bytes, but the current VICE screenshot is still blank in `GFXMODE("TILE")`; remaining issue is Bank D charset/tile display visibility.
diff --git a/agentworking/readybasic-gfx-phase4/TEST_LOG.md b/agentworking/readybasic-gfx-phase4/TEST_LOG.md
new file mode 100644
index 0000000..09cd53f
--- /dev/null
+++ b/agentworking/readybasic-gfx-phase4/TEST_LOG.md
@@ -0,0 +1,22 @@
+# Test Log
+
+- `make bin/readybasic.prg` passed.
+- `make obj/rbgfx23_dlist.prg obj/rbgfx24_tilemap.prg obj/rbgfx25_mbcells.prg` passed.
+- `make readybasic-plugin-static-check` passed.
+- `make obj/rbgfx26_mode_matrix.prg obj/rbgfx27_target_blit.prg` passed.
+- `READYBASIC_SKIP_BUILD=1 make readybasic-gfx-phase4-vice` passed in ReadyOS-hosted VICE context with 34/34 steps.
+- `make readybasic-vice-suites` passed after the Phase 4 demo/doc updates. The last broad suite stages completed successfully, including:
+ - `readybasic_reuviewer_f2_chain_probe`, 64/64 steps, run directory `/Users/karlprosserpp/dev/c64projects/readyosprecog/logs/vice_auto_20260616_234214`.
+ - `readybasic_cross_app_resume_probe`, 211/211 steps, run directory `/Users/karlprosserpp/dev/c64projects/readyosprecog/logs/vice_auto_20260616_234257`.
+ - `readybasic_second_entry_editor_probe`, 150/150 steps, run directory `/Users/karlprosserpp/dev/c64projects/readyosprecog/logs/vice_auto_20260616_234519`.
+ - `readybasic_full_suite_visual_verification`, 184/184 steps, run directory `/Users/karlprosserpp/dev/c64projects/readyosprecog/logs/vice_auto_20260616_234711`.
+- Screenshot run directory with latest focused pass:
+ `/Users/karlprosserpp/dev/c64projects/readyosprecog/logs/vice_auto_20260616_230724`.
+
+Screenshot observations:
+
+- Display-list demo shows retained plot/line/rect/frect output.
+- Multicolor bitmap cell demo shows visible slot/cell color changes.
+- Mode matrix shows visible `HIRES` and `MBITMAP` primitive coverage, and its final text capture reports `MATRIX 1 1 1 73`, proving `PNT` returned values in all four tested modes.
+- Target/blit demo reports `SURF 6`, `TARGET SURF ERR 0`, `SYNC ERR 0`, `BLIT ERR 0`, and `TARGET VISIBLE ERR 0`.
+- Tilemap demo currently captures a blank blue Bank D tile screen even though a debug pass showed `TMDRAW` wrote screen byte `81`, color byte `2`, and `ERRCODE()` returned `0`.
diff --git a/agentworking/readybasic-gfx-phase5/IMPLEMENTATION_LOG.md b/agentworking/readybasic-gfx-phase5/IMPLEMENTATION_LOG.md
new file mode 100644
index 0000000..a3f75b7
--- /dev/null
+++ b/agentworking/readybasic-gfx-phase5/IMPLEMENTATION_LOG.md
@@ -0,0 +1,18 @@
+# ReadyBASIC Graphics Phase 5 Implementation Log
+
+## 2026-06-17
+
+- Added demos `rbgfx28_tile_visible.bas` through `rbgfx32_convex_poly.bas`.
+- Added `build_support/run_readybasic_gfx_phase5_demo.sh` and Makefile target `readybasic-gfx-phase5-vice`.
+- Added the new demo PRGs to the ReadyBASIC-capable D81 profiles.
+- Fixed the four-character mode parser path:
+ - `TILE` now returns `RB_GFX_MODE_TILE`.
+ - `TEXT` still returns `RB_GFX_MODE_TEXT`.
+- Added command-side mode state storage at `RB_GFX_MODE_STATE`.
+- Updated `gfx_get_mode`, primitive, display-list, and polygon mode checks to use the stored mode state.
+- Seeded simple solid tile glyphs during `GFXCLEAR` for `TILE`/`MTILE` so immediate primitive demos render without requiring custom charset setup.
+- Fixed `DLPLOT` color replay and added an MBITMAP display-list plot path.
+- Fixed `GFXSYNC` and `GFXBLIT` REU DMA memory configuration:
+ - REU surface transfers use `$35` so Bank D RAM and REU registers are both reachable.
+ - General under-ROM command dispatch uses `$36` so command code runs with BASIC ROM hidden and I/O visible.
+
diff --git a/agentworking/readybasic-gfx-phase5/LESSONS.md b/agentworking/readybasic-gfx-phase5/LESSONS.md
new file mode 100644
index 0000000..40c663b
--- /dev/null
+++ b/agentworking/readybasic-gfx-phase5/LESSONS.md
@@ -0,0 +1,10 @@
+# ReadyBASIC Graphics Phase 5 Lessons
+
+- A VICE automation step passing is not enough for graphics work. The screenshot has to be visually inspected or pixel-counted.
+- `GFXMODE("TILE")` was returning text mode because the four-character parser branch checked only the leading `T`. The fix is command parser logic, not ReadyBASIC language behavior.
+- Running overlay code with BASIC ROM hidden is not enough for graphics; VIC/CIA/color/REU paths also need I/O visibility at the right moments.
+- `$36` is appropriate for ordinary under-ROM command execution: BASIC ROM hidden, KERNAL and I/O visible.
+- REU graphics DMA that touches Bank D bitmap RAM should use `$35` while programming/transferring, because it keeps the needed RAM visible without hiding the REU registers.
+- Store graphics mode as command state instead of reverse-engineering it from live VIC/CIA registers on every draw. It is faster and avoids ReadyOS context surprises.
+- Keep demos small, but make them visually unambiguous. Blank-screen tests are not tests.
+
diff --git a/agentworking/readybasic-gfx-phase5/STATE.md b/agentworking/readybasic-gfx-phase5/STATE.md
new file mode 100644
index 0000000..5388d8b
--- /dev/null
+++ b/agentworking/readybasic-gfx-phase5/STATE.md
@@ -0,0 +1,23 @@
+# ReadyBASIC Graphics Phase 5 State
+
+Date: 2026-06-17
+
+Phase 5 is command-only. It keeps BASIC start/free memory and ReadyBASIC language behavior unchanged.
+
+Implemented in this slate:
+
+- Fixed `GFXMODE("TILE")` so it selects Bank D tile mode instead of falling through to `TEXT`.
+- Kept graphics mode in `RB_GFX_MODE_STATE` so command overlays do not need to re-read VIC/CIA mode state.
+- Made under-ROM command overlay calls enter with BASIC ROM hidden and I/O visible.
+- Made `GFXSYNC` snapshot visible Bank D bitmap/screen/color layout into the selected `GFXTGT(H%)` surface.
+- Made `GFXBLIT(H%)` restore typed REU graphics surfaces to visible Bank D.
+- Added visible `TILE`, visible `MTILE`, MBITMAP display-list, sync/blit, and polygon showcase demos.
+- Added `make readybasic-gfx-phase5-vice`.
+
+Current focused screenshot run:
+
+- `logs/vice_auto_20260617_011251`
+
+Final full ReadyBASIC VICE suite:
+
+- `make readybasic-vice-suites`: pass
diff --git a/agentworking/readybasic-gfx-phase5/TEST_LOG.md b/agentworking/readybasic-gfx-phase5/TEST_LOG.md
new file mode 100644
index 0000000..2e2c510
--- /dev/null
+++ b/agentworking/readybasic-gfx-phase5/TEST_LOG.md
@@ -0,0 +1,85 @@
+# ReadyBASIC Graphics Phase 5 Test Log
+
+## Focused Run
+
+Command:
+
+```sh
+make bin/readybasic.prg
+make readybasic-plugin-static-check
+make readybasic-gfx-phase5-vice
+```
+
+Result:
+
+- `make bin/readybasic.prg`: pass
+- `make readybasic-plugin-static-check`: pass
+- `make readybasic-gfx-phase5-vice`: pass
+
+Run directory:
+
+- `logs/vice_auto_20260617_005937`
+- Later focused rerun after the `SPRCOL` phase-1 demo fix and full-suite prep:
+ `logs/vice_auto_20260617_011251`
+
+Key screenshots:
+
+- `readybasic_gfx_phase5_tile_visible.png`
+- `readybasic_gfx_phase5_mtile_visible.png`
+- `readybasic_gfx_phase5_mbitmap_dlist.png`
+- `readybasic_gfx_phase5_sync_source.png`
+- `readybasic_gfx_phase5_sync_cleared.png`
+- `readybasic_gfx_phase5_sync_restored.png`
+- `readybasic_gfx_phase5_convex_poly.png`
+
+PNG sanity counts from the focused run:
+
+- tile visible: 6 colors, 38344 nonblack pixels
+- mtile visible: 5 colors, 38416 nonblack pixels
+- mbitmap dlist: 3 colors, 1310 nonblack pixels
+- sync source: 3 colors, 2009 nonblack pixels
+- sync cleared: 2 colors, 1116 nonblack pixels
+- sync restored: 3 colors, 2009 nonblack pixels
+- convex poly: 3 colors, 12894 nonblack pixels
+
+## Focused Graphics Regression Batch
+
+Command:
+
+```sh
+make readybasic-plugin-static-check readybasic-gfx-phase1-vice readybasic-gfx-phase2-vice readybasic-gfx-phase3-vice readybasic-gfx-mbitmap-vice readybasic-gfx-phase4-vice readybasic-gfx-phase5-vice
+```
+
+Result: pass.
+
+Key run directories:
+
+- Phase 1: `logs/vice_auto_20260617_010936`
+- Phase 2: `logs/vice_auto_20260617_011006`
+- Phase 4: `logs/vice_auto_20260617_011146`
+- Phase 5: `logs/vice_auto_20260617_011251`
+
+## Full ReadyBASIC VICE Suite
+
+Command:
+
+```sh
+make readybasic-vice-suites
+```
+
+Result: pass on the final normal run.
+
+Final run directories observed during the suite:
+
+- `readybasic_demo_suite`: `logs/vice_auto_20260617_015512`
+- `readybasic_repeat_label_probe`: `logs/vice_auto_20260617_020549`
+- `readybasic_lifecycle_probe`: `logs/vice_auto_20260617_020643`
+- `readybasic_plugin_command_probe`: `logs/vice_auto_20260617_020808`
+- `readybasic_program_probe`: `logs/vice_auto_20260617_021011`
+- `readybasic_rbtest1_probe`: `logs/vice_auto_20260617_021120`
+- `readybasic_large_vars_probe`: `logs/vice_auto_20260617_021227`
+- `readybasic_hotkey_launcher_cycle`: `logs/vice_auto_20260617_021311`
+- `readybasic_reuviewer_f2_chain_probe`: `logs/vice_auto_20260617_021513`
+- `readybasic_cross_app_resume_probe`: `logs/vice_auto_20260617_021557`
+- `readybasic_second_entry_editor_probe`: `logs/vice_auto_20260617_021819`
+- `readybasic_full_suite_visual_verification`: `logs/vice_auto_20260617_022010`
diff --git a/agentworking/readybasic-sound-phase1/IMPLEMENTATION_LOG.md b/agentworking/readybasic-sound-phase1/IMPLEMENTATION_LOG.md
new file mode 100644
index 0000000..5b039cf
--- /dev/null
+++ b/agentworking/readybasic-sound-phase1/IMPLEMENTATION_LOG.md
@@ -0,0 +1,13 @@
+# ReadyBASIC Sound Phase 1 Implementation Log
+
+## 2026-06-17
+
+- Added linker segment `SLOT2OVL6` / `OVL6PACK`.
+- Added sound constants for SID register addresses.
+- Added `RB_MODULE_SID=4`, `RB_SUBMOD_SIDCORE=23`, and `RB_CODE_SIDCORE_OFF=$7800`.
+- Added `CMD_SIDCORE` descriptor macro and 16 command descriptors.
+- Extended cold prestash table from five to six built-in overlays.
+- Implemented `SIDCORE` direct SID commands in `OVL6PACK`.
+- Tried a seven-number command parser signature for friendly `VOICE(V,F,W,A,D,S,R)`, but it grew resident code by 31 bytes and overflowed the fixed resident budget.
+- Reworked `VOICE` to the faster packed SID form `VOICE(V,F,W,AD,SR)` using the existing five-number parser signature.
+- Added six human-audible BASIC demos and a ReadyOS/ReadyBASIC VICE automation script.
diff --git a/agentworking/readybasic-sound-phase1/LESSONS.md b/agentworking/readybasic-sound-phase1/LESSONS.md
new file mode 100644
index 0000000..3a482d1
--- /dev/null
+++ b/agentworking/readybasic-sound-phase1/LESSONS.md
@@ -0,0 +1,6 @@
+# ReadyBASIC Sound Phase 1 Lessons
+
+- New command syntax should prefer existing parser signatures unless there is a very strong reason to grow resident code.
+- For SID, packed bytes are not merely a compromise: `AD` and `SR` match the hardware registers and reduce command dispatch/expression overhead at 1 MHz.
+- Sound verification cannot rely on screenshots. The automated suite should prove ReadyOS/ReadyBASIC loading, stored BASIC tokenization, command dispatch, and no BASIC error; human listening remains the real audio validation for this phase.
+- Keep playback blocking in Phase 1. Nonblocking music implies persistent timing state and should be designed as a later poll/IRQ phase.
diff --git a/agentworking/readybasic-sound-phase1/STATE.md b/agentworking/readybasic-sound-phase1/STATE.md
new file mode 100644
index 0000000..b30efb7
--- /dev/null
+++ b/agentworking/readybasic-sound-phase1/STATE.md
@@ -0,0 +1,22 @@
+# ReadyBASIC Sound Phase 1 State
+
+Started: 2026-06-17
+
+Goal: add command-only SID sound support to ReadyBASIC without changing language behavior, BASIC start, or BASIC bytes free.
+
+Current implementation:
+
+- New built-in sound module id `4`.
+- New `SIDCORE` submodule id `23`.
+- New slot-2 overlay `OVL6PACK`, prestashed to the ReadyBASIC code REU bank at `$7800`.
+- Public commands: `SIDCLR`, `SILENCE`, `VOL`, `FREQ`, `NOTE`, `PULSE`, `ADSR`, `ENV`, `WAVE`, `GATE`, `CTRL`, `VOICE`, `FILTER`, `FILT`, `SOUND`, `SND`.
+- `VOICE` intentionally uses the existing five-number parser signature: `VOICE(V,F,W,AD,SR)`.
+- No IRQ music engine, no resident scheduler, no new language features.
+
+Verification status:
+
+- `make bin/readybasic.prg` passes after removing the resident-growing seven-argument parser experiment.
+- `make readybasic-plugin-static-check` passes.
+- `make readybasic-memory-report` passes; BASIC free remains `30013`.
+- `make readybasic-sound-phase1-vice` passes inside ReadyOS-loaded ReadyBASIC.
+- `make readybasic-vice-suites` passes.
diff --git a/agentworking/readybasic-sound-phase1/TEST_LOG.md b/agentworking/readybasic-sound-phase1/TEST_LOG.md
new file mode 100644
index 0000000..abdfad3
--- /dev/null
+++ b/agentworking/readybasic-sound-phase1/TEST_LOG.md
@@ -0,0 +1,34 @@
+# ReadyBASIC Sound Phase 1 Test Log
+
+## 2026-06-17
+
+- `make bin/readybasic.prg`
+ - Initial result: failed; adding a seven-argument `VOICE` parser grew `RESIDENT` by 31 bytes.
+ - Fix: remove the new parser signature and use existing `SIG_LINE` for packed `VOICE(V,F,W,AD,SR)`.
+ - Current result: pass.
+
+- `make obj/rbsnd01_sid_basics.prg obj/rbsnd02_voice_state.prg obj/rbsnd03_notes.prg obj/rbsnd04_filter.prg obj/rbsnd05_voice_batch.prg obj/rbsnd06_three_voice.prg`
+ - Result: pass.
+
+- `make readybasic-plugin-static-check`
+ - Result: pass.
+
+- `make readybasic-memory-report`
+ - Result: pass.
+ - Confirmed `RESIDENT` remains `$1200-$2ABF` and BASIC free memory remains `30013`.
+ - Confirmed `OVL6PACK` / `SIDCORE` uses 526 bytes of a 2KB slot and is stashed at REU code-bank offset `$7800`.
+
+- `make readybasic-sound-phase1-vice`
+ - Result: pass.
+ - ReadyOS booted first, ReadyBASIC was loaded by ReadyOS, and each `rbsndNN` demo was loaded/listed/run inside ReadyBASIC.
+ - Run directory: `logs/vice_auto_20260617_115052`.
+
+- `make readybasic-vice-suites`
+ - Result: pass.
+ - Includes the new sound demo suite and the full ReadyBASIC visual/command verification suite.
+ - Sound suite run directory from full regression: `logs/vice_auto_20260617_121614`.
+ - Full visual verification run directory from full regression: `logs/vice_auto_20260617_121645`.
+
+Human audio note:
+
+- VICE automation proves the demos load, list, run, and complete without BASIC errors in the correct ReadyOS context. It does not prove audible SID output quality; the demos deliberately print what should be heard and pause long enough for human listening.
diff --git a/agentworking/readyos-1kb-shim-skip-bank/DOCUMENTATION_AUDIT.md b/agentworking/readyos-1kb-shim-skip-bank/DOCUMENTATION_AUDIT.md
new file mode 100644
index 0000000..bf63e41
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/DOCUMENTATION_AUDIT.md
@@ -0,0 +1,52 @@
+# Documentation Audit: 1 KB Shim And ReadyOS-at-Skip Contract
+
+## Scope
+
+The audit covers Markdown and HTML under `docs/`, `privatedocs/`, the 0.2.5
+release/SKU tree, application documentation under `src/apps/`, and top-level
+Markdown. The corpus-wide scan examined 196 Markdown/HTML files before this
+evidence file was added.
+
+## Current contract checked
+
+- Active app RAM and snapshot: `$1000-$C5FF` (`$B600`, 46,592 bytes).
+- Full resident shim: `$C600-$C9FF` (1 KB).
+- Shim expansion reserve: `$C600-$C7FF`; stable public ABI: `$C800-$C9FF`.
+- Physical banks below `Skip`: skipped/reserved.
+- Physical `Skip`: combined ReadyOS bank.
+- Physical `Skip+1`: first dynamic allocation candidate.
+- ReadyOS bank `$0000-$B5FF`: launcher snapshot.
+- ReadyOS bank `$B600-$FFFF`: schema v5 and its maps, status, clipboard,
+ hotkeys, registries, catalog, audit, and launcher runtime state.
+- ReadyBASIC custom assembler/linker shape remains below `$C600`.
+- ReadyShell overlay execution remains `$8E00-$C5FF`.
+
+## Classification and preservation
+
+- All 38 HTML documents are explicitly classified as current or preserved
+ historical/design material by `update_documentation_html_status.py`.
+- Historical material was not deleted or silently normalized. Thirty-one
+ retained Markdown/HTML reports carry the current-contract supersession
+ marker while keeping their dated layouts and measurements.
+- Current documents with legitimate uses of strings such as `$B800` (for
+ example, a ReadyBASIC submodule address) were not incorrectly rewritten as
+ though every occurrence described the old app-window size.
+- Generated SKU `help.md`, `helpme.md`, manifests, release README/template, and
+ the special 1 MB Kung Fu Flash 2 budget explanation were regenerated.
+
+## Full shim source copies
+
+`verify_shim_html_source.py` finds every full commented shim listing in the
+HTML corpus and compares its `.byte` directives with
+`src/boot/readyos_shim.inc`. Five listings pass, each containing the same 175
+canonical directives and current schema-v5 token lookup annotations.
+
+## Automated evidence
+
+- `python3 build_support/verify_documentation_contract.py`: PASS.
+- `python3 build_support/update_documentation_html_status.py --check`: PASS,
+ 38 classified HTML documents.
+- `python3 build_support/verify_shim_html_source.py`: PASS, five complete
+ canonical listings.
+- `python3 build_support/annotate_historical_memory_contracts.py`: repeat-safe;
+ a final rerun must report zero newly annotated documents.
diff --git a/agentworking/readyos-1kb-shim-skip-bank/PLAN.md b/agentworking/readyos-1kb-shim-skip-bank/PLAN.md
new file mode 100644
index 0000000..a4dbc22
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/PLAN.md
@@ -0,0 +1,44 @@
+# ReadyOS 1KB Shim / ReadyOS-at-Skip Refactor
+
+Baseline commit: `1644b22` (`Unify ReadyOS bank state and refresh documentation`)
+
+## Required final contract
+
+- The complete resident ReadyOS shim area is `$C600-$C9FF` (`$0400`, 1024 bytes).
+- The existing public jump table and data ABI remains fixed at `$C800-$C9FF`.
+- `$C600-$C7FF` is reserved shim expansion space and is not linked, allocated,
+ snapshotted, or treated as scratch by applications.
+- The app snapshot is `$1000-$C5FF` (`$B600`, 46,592 bytes).
+- Physical `Skip` is the combined ReadyOS bank. With `Skip=0`, physical bank 0
+ is the ReadyOS bank.
+- Physical `Skip+1` is the first dynamic allocation candidate; token 0 resolves
+ directly to physical `Skip`; nonzero tokens resolve through the ReadyOS-bank
+ mapping table.
+- The ReadyOS bank contains the launcher snapshot at `$0000-$B5FF` and schema-v5
+ state at `$B600-$FFFF`.
+- ReadyBASIC preserves its custom assembler/linker shape and does not use
+ `$C600-$C9FF`.
+- ReadyShell retains its `$8E00-$C5FF` overlay ABI.
+- Disk, EasyFlash, and Ultimate DMA launch/switch/resume behavior must agree.
+
+## Verification evidence required
+
+- Before/after linker, code/data/BSS, heap, and full-window headroom reports for
+ every app and both regular/EasyFlash launchers and ReadyShell builds.
+- Exact 1024-byte disk/EasyFlash shim identity and canonical commented source
+ verification, including HTML full-source copies.
+- Static memory, snapshot/resume, ReadyOS-bank schema, dynamic allocation,
+ ReadyBASIC-shape, documentation, and no-deletion gates.
+- All release-profile builds and EasyFlash packing/smoke verification.
+- Full regular and EasyFlash ReadyBASIC suites.
+- ReadyShell host, overlay, cross-app resume, and UI automation suites.
+- Core UI/app switching, hotkey, clipboard, owned-bank, unload, and resume suites.
+- Ultimate 64 UCI/DMA loading and cross-app suites launched through the required
+ Terminal-owned background workflow.
+
+## Safety rules
+
+- Do not delete source, documentation, reports, or release artifacts.
+- Preserve baseline evidence and append test results to `TEST_LOG.md`.
+- Build ReadyOS only through `run.sh`/`run.ps1` and the established aggregate
+ Makefile test targets; never launch a single app directly.
diff --git a/agentworking/readyos-1kb-shim-skip-bank/REQUIREMENTS_AUDIT.md b/agentworking/readyos-1kb-shim-skip-bank/REQUIREMENTS_AUDIT.md
new file mode 100644
index 0000000..3e957f4
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/REQUIREMENTS_AUDIT.md
@@ -0,0 +1,25 @@
+# Requirement-by-Requirement Completion Audit
+
+This checklist is intentionally evidence-based. An item becomes complete only
+after the named final-state evidence exists and has been inspected.
+
+| Requirement | Final evidence | Status |
+|---|---|---|
+| Full resident 1 KB shim at `$C600-$C9FF` | linker configs, boot/EasyFlash images, `verify_readyos_shim.py`, binary identity | proven |
+| `$C600-$C7FF` remains shim headroom, not app RAM | all app linker configs/maps, ReadyBASIC custom layout, memory verifier | proven |
+| Stable public ABI remains `$C800-$C9FF` | canonical shim source and symbol/byte verification | proven |
+| App snapshot is `$1000-$C5FF` / `$B600` | shim opcodes, boot/loaders, app configs, resume verifier | proven |
+| Banks below `Skip` are skipped; physical `Skip` is ReadyOS; `Skip+1` is first dynamic | allocator/control-bank/boot/EasyFlash source plus schema dumps | proven |
+| App/map/status/clipboard/catalog authority is in ReadyOS bank | schema-v5 offsets and callers; launcher/schema UI tests | proven |
+| Disk, EasyFlash, and Ultimate DMA paths agree | regular/EasyFlash suites and Ultimate hardware acceptance | proven |
+| ReadyBASIC custom assembler/linker shape stays compatible and tight | source contract, linker map, shape verifier, full regular/EasyFlash suites | proven |
+| ReadyShell memory and overlay ABI stay tight | map/report, host suite, regular/EasyFlash cross-app suites, Ultimate sequence | proven |
+| Clipboard and app resume state survive switching | regular non-empty clipboard plan plus cross-app suites | proven |
+| All release/SKU builds succeed | final `/bin/bash ./run.sh --build-all` | proven |
+| All VICE UI suites succeed | retained full regular and EasyFlash aggregate manifests plus final targeted clipboard run | proven |
+| Ultimate DMA loading succeeds | editor direct/return, F3 selection, F1 all, manifest, ReadyBASIC, ReadyShell, ReadyIRC | proven |
+| Linker/BSS/heap/overlay/headroom analyzed before and after | JSON/Markdown comparison and regenerated reports | proven |
+| Main, SKU, app, public/private Markdown and HTML are current or visibly historical | documentation verifier, HTML classification, corpus scan | proven |
+| Every full commented HTML shim source matches current source | five-listing byte/directive verifier | proven |
+| No files or retained historical artifacts are deleted | final Git deletion audit and release-artifact restoration | proven |
+| Working changes committed in reviewable scopes | `ced085d`, `561124f`, `eb58efb`, plus this final audit commit | proven |
diff --git a/agentworking/readyos-1kb-shim-skip-bank/TEST_LOG.md b/agentworking/readyos-1kb-shim-skip-bank/TEST_LOG.md
new file mode 100644
index 0000000..b81ffbc
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/TEST_LOG.md
@@ -0,0 +1,163 @@
+# ReadyOS 1KB Shim / ReadyOS-at-Skip Test Log
+
+## Baseline
+
+- Known-good working state committed as `1644b22`.
+- Fresh pre-change linker/headroom report: `headroom_before.json`.
+- Pre-change contract: app snapshot `$1000-$C7FF` (`$B800`), 512-byte shim
+ `$C800-$C9FF`, ReadyOS bank at physical `Skip+1`.
+
+## Implementation and build verification
+
+- `/bin/bash ./run.sh --build-all`: PASS for all release SKUs and EasyFlash.
+- Generated release version: `0.2.5L`.
+- `python3 build_support/verify_readyos_shim.py`: PASS; canonical resident shim is
+ 1024 bytes, disk boot clears `$C600-$C7FF` and installs the `$C800-$C9FF`
+ ABI, and EasyFlash packages the full resident image.
+- `python3 build_support/verify_reu_control_bank.py`: PASS.
+- `python3 build_support/verify_memory_map.py`: PASS; expected warning only for
+ ReadyShell overlay 6 ending at `$C5F4`.
+- `python3 build_support/verify_dynamic_launcher.py`: PASS.
+- `python3 build_support/verify_resume_contract.py`: PASS.
+- `python3 build_support/verify_readybasic_plugin.py`: PASS.
+- `python3 verify.py`: PASS.
+- `python3 build_support/verify_shim_html_source.py`: PASS; all five complete
+ HTML source listings contain the 175 canonical `.byte` directives.
+
+## Host tests
+
+- `python3 build_support/editor_host_smoke.py`: PASS, headroom 12,194 bytes.
+- `python3 build_support/tasklist_host_smoke.py`: PASS, headroom 6,398 bytes.
+- `python3 build_support/simplefiles_host_smoke.py`: PASS.
+- `make readyshell-host-tests`: PASS for parser, VM, C64 overlay VM, REU/value,
+ and serialization tests; compiler warnings are unchanged unused static helpers.
+
+## Regular VICE/UI automation
+
+- Full ReadyBASIC aggregate (26 suites): PASS; manifest
+ `logs/vice_auto_20260802_190250/manifest.json`.
+- ReadyBASIC hotkey, cross-app resume, second-entry Editor return, loaded-apps,
+ and keyboard regression probes: PASS; manifests `...184119`, `...185151`,
+ `...185342`, `...185924`, and `...185052` respectively.
+- Launcher ReadyOS-bank/schema state probe: 28/28 PASS; manifest `...191057`.
+- QuickNotes owned-REU lifecycle before unload: 15/15 PASS; manifest `...191156`.
+- QuickNotes unload/release lifecycle: 17/17 PASS; manifest `...191215`.
+- ReadyShell Editor -> ReadyBASIC -> Editor -> ReadyShell overlay/resume sequence:
+ 33/33 PASS on unchanged retry; manifest `...191608`.
+- The first keyboard attempt timed out and the first ReadyShell attempt dropped
+ its final `EXIT` key. Both partial failures are retained in `logs/`; fresh,
+ unchanged reruns passed and are the manifests cited above.
+
+## EasyFlash/cartridge automation
+
+- `make easyflash-verify`: PASS for layout, static contract, full 1KB shim,
+ schema v5, preload image, and launcher verification.
+- `make easyflash-preload-verify`: PASS.
+- Full ReadyBASIC visual/command/heap/procedure suite: 188/188 PASS; manifest
+ `logs/vice_auto_20260802_204002/manifest.json`.
+- ReadyBASIC second-entry Editor probe: 194/194 PASS; manifest
+ `logs/vice_auto_20260802_203756/manifest.json`.
+- Ten ReadyBASIC <-> Editor switch/resume cycles: 265/265 PASS; manifest
+ `logs/vice_auto_20260802_202538/manifest.json`.
+- ReadyShell Editor -> ReadyBASIC -> Editor -> ReadyShell overlay/resume sequence:
+ 35/35 PASS; manifest `logs/vice_auto_20260802_204753/manifest.json`.
+- ReadyBASIC REUViewer/F2 chain: 70/70 PASS; manifest
+ `logs/vice_auto_20260802_202447/manifest.json`. This found and corrected a
+ stale test-only assumption that the ReadyOS bank was `Skip+1` and that token
+ status lived at the previous schema offset. The probe now derives both values
+ from generated/source configuration.
+- Aggregate EasyFlash plans also passed demo, repeat/label, lifecycle, module,
+ plugin, program, RBTEST1, resume, screen-REU, state, large-variable, F4/F2
+ hotkey, and keyboard coverage. Their passing manifests span `...193240`
+ through `...201921`; all failed cold-start attempts and passing fresh-process
+ retries remain preserved in `logs/`.
+
+## Headroom result
+
+- Detailed before/after data: `headroom_before.json`, `headroom_after.json`, and
+ `headroom_comparison.md` in this directory.
+- Every conventional app gives the reserved lower shim half its intended 512
+ bytes; code/data/BSS are otherwise stable.
+- Tightest conventional application is Dizzy: 1,468-byte heap and 1,580 bytes
+ of raw window headroom.
+- ReadyBASIC retains 1,025 bytes to `$C5FF` in its custom layout.
+- ReadyShell retains its 3,688-byte heap; overlay 6 ends at `$C5F4` and therefore
+ has 11 bytes of overlay-address headroom without consuming that heap.
+
+## Safety audit so far
+
+- The release builder's normal cleanup briefly removed old tracked versioned
+ release files. They were detected immediately and restored from the checkpoint.
+- `git status --short` contains no tracked deletions after restoration.
+- Historical documentation is preserved; stale layouts are explicitly marked as
+ historical rather than removed.
+
+## Final recheck pass
+
+- `make verify`: PASS after the complete source and documentation update. This
+ reran the aggregate memory-map, ONCE/BSS, 1 KB shim, schema-v5, dynamic
+ launcher, resume, ReadyBASIC-shape, and documentation gates.
+- `python3 build_support/verify_documentation_contract.py`: PASS for 14 live
+ contract documents, all retained historical-contract markers, and all 38
+ classified HTML documents. The corpus audit subsequently standardized six
+ more historical Markdown reports; the final count is now 31 historical
+ markers.
+- `python3 build_support/verify_shim_html_source.py`: PASS for five complete
+ commented HTML shim listings, each matching all 175 canonical `.byte`
+ directives.
+- Host checks rerun unchanged: Editor, Tasklist, SimpleFiles, and the complete
+ ReadyShell host suite all PASS.
+- Final report regeneration caught and corrected a generator-level HTML status
+ regression: `readybasic_memory_report.py` and `readyshell_overlay_report.py`
+ now emit their exact current-document banners themselves. The regenerated
+ public/private reports and the 38-document classification gate all PASS.
+- Canonical `/bin/bash ./run.sh --build-all`: PASS with exit code 0 for the
+ complete 0.2.5Y disk-SKU matrix and EasyFlash artifacts. The post-build
+ preservation audit found zero tracked deletions.
+- Regular VICE empty-clipboard return control: 12/12 PASS; manifest
+ `logs/vice_auto_20260802_212333/manifest.json`.
+- Final regular-D81 non-empty clipboard lifecycle: 32/32 PASS with zero degraded
+ steps; manifest `logs/vice_auto_20260802_222311/manifest.json`. Editor copied
+ `CLIPTEST42`, Clipboard Manager reported exactly one item and previewed the
+ text, Editor resumed with its original contents, and paste produced
+ `ZCLIPTEST42`. The run also dumped the complete resident `$C600-$C9FF` shim.
+- Retained failed clipboard diagnostics used either the Ultimate-DMA artifact or
+ an unreliable isolated harness Return injection. The passing plan uses the
+ established queue-clear plus VICE `keybuf` method from the second-entry suite;
+ no ReadyOS source change was needed.
+
+## Ultimate 64 acceptance
+
+- Editor direct DMA launch and return: PASS
+ (`c64u-dma/editor-direct-dma-return/status`).
+- Editor F3 load-selected DMA path: PASS
+ (`c64u-dma/editor-load-selected/status`).
+- F1 load-all followed by ReadyShell overlay execution: PASS on unchanged retry
+ (`c64u-dma-retry/loadall-readyshell-overlay-smoke/status`).
+- F5 manifest load followed by SidetRIS launch: PASS
+ (`c64u-dma-retry2/manifest-sidetris/status`).
+- The first ReadyBASIC load-selected retry remained blank before ReadyOS boot
+ and ended `READYOS_BOOT_FAIL`; it never reached or exercised ReadyBASIC. The
+ failure is retained under `c64u-dma-retry2/readybasic-load-selected/`.
+- ReadyBASIC F3 load-selected DMA path: PASS on an isolated unchanged retry
+ (`c64u-readybasic-retry3/readybasic-load-selected/status`). The run proved
+ launcher DMA readiness, loader completion, `DMA:ON`, and the final
+ ReadyBASIC screen.
+- Editor -> ReadyBASIC -> ReadyShell hardware lifecycle: 30/30 PASS with zero
+ degraded steps; manifest `logs/ultimate_auto_20260802_214758/manifest.json`.
+ The run modified and suspended Editor, launched and exercised ReadyBASIC,
+ returned through the launcher, then loaded ReadyShell and verified `VER`,
+ `LST`, and `CAT` overlay execution before dumping the final app/shim state.
+- Stable-path DMA build for the ReadyIRC suite: PASS via
+ `LAUNCHER_DMA_LOAD=1 /bin/bash ./run.sh --profile precog-d81 --config
+ build_support/c64u_dma_acceptance/precog-d81-dma-valid.ini --build-only`.
+ Artifact `readyos-v0.2.5w-d81.d81` uses `reu_bank_skip=32` and launcher path
+ `/usb1/readyos.d81`.
+- ReadyIRC Ultimate 64 lifecycle: 82/82 PASS with zero degraded steps; manifest
+ `logs/ultimate_auto_20260802_215831/manifest.json`. It covers setup/input
+ validation, lowercase charset, mixed-case network traffic, append/scroll
+ rendering, history stability, `NAMES`, channel switching, live suspend/resume
+ without reconnect, stale-socket reconnect, intentional disconnect, retained
+ settings/channel, and final full-shim dump. The fixture independently passed
+ all protocol assertions: three registrations, exact mixed-case PONG, ordered
+ PART/JOIN, expected NAMES requests, switched-channel PRIVMSG, and two QUITs.
diff --git a/agentworking/readyos-1kb-shim-skip-bank/boot_hang_probe.yaml b/agentworking/readyos-1kb-shim-skip-bank/boot_hang_probe.yaml
new file mode 100644
index 0000000..93a9154
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/boot_hang_probe.yaml
@@ -0,0 +1,60 @@
+version: 1
+kind: vice_task_plan
+plan_id: readyos_runfirst_fixture_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 1
+ backoff_ms: 0
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 90
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: true
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81-preboot.prg"
+ drive8_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_loading_launcher
+ type: screen.wait_contains
+ params:
+ text: "LOADING LAUNCHER"
+ wait_timeout_s: 30
+ - id: delay_during_load
+ type: input.key
+ params:
+ key: 145
+ pre_delay_s: 40
+ - id: capture_stalled_screen
+ type: screen.capture
+ params:
+ label: runfirst_after_40s
+ - id: registers_after_20s
+ type: monitor.command
+ params:
+ command: "r"
+ - id: dump_boot_and_shim
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: kernal_vectors, start: 0x002B, end: 0x0030 }
+ - { label: irq_vectors, start: 0x0314, end: 0x0315 }
+ - { label: boot_code, start: 0x0801, end: 0x0FFF }
+ - { label: launcher_prefix, start: 0x1000, end: 0x11FF }
+ - { label: shim_full, start: 0xC600, end: 0xC9FF }
diff --git a/agentworking/readyos-1kb-shim-skip-bank/c64u-dma-retry/loadall-readyshell-overlay-smoke/status b/agentworking/readyos-1kb-shim-skip-bank/c64u-dma-retry/loadall-readyshell-overlay-smoke/status
new file mode 100644
index 0000000..01ffb35
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/c64u-dma-retry/loadall-readyshell-overlay-smoke/status
@@ -0,0 +1 @@
+READYOS_LOADALL_READYSHELL_OVERLAY_PASS
diff --git a/agentworking/readyos-1kb-shim-skip-bank/c64u-dma-retry/manifest-sidetris/status b/agentworking/readyos-1kb-shim-skip-bank/c64u-dma-retry/manifest-sidetris/status
new file mode 100644
index 0000000..9def559
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/c64u-dma-retry/manifest-sidetris/status
@@ -0,0 +1 @@
+READYOS_MANIFEST_DIALOG_FAIL
diff --git a/agentworking/readyos-1kb-shim-skip-bank/c64u-dma-retry/suite.status b/agentworking/readyos-1kb-shim-skip-bank/c64u-dma-retry/suite.status
new file mode 100644
index 0000000..446853f
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/c64u-dma-retry/suite.status
@@ -0,0 +1 @@
+FAIL rc=1
diff --git a/agentworking/readyos-1kb-shim-skip-bank/c64u-dma-retry2/manifest-sidetris/status b/agentworking/readyos-1kb-shim-skip-bank/c64u-dma-retry2/manifest-sidetris/status
new file mode 100644
index 0000000..084b66d
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/c64u-dma-retry2/manifest-sidetris/status
@@ -0,0 +1 @@
+READYOS_MANIFEST_SIDETRIS_PASS
diff --git a/agentworking/readyos-1kb-shim-skip-bank/c64u-dma-retry2/readybasic-load-selected/status b/agentworking/readyos-1kb-shim-skip-bank/c64u-dma-retry2/readybasic-load-selected/status
new file mode 100644
index 0000000..f914918
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/c64u-dma-retry2/readybasic-load-selected/status
@@ -0,0 +1 @@
+READYOS_BOOT_FAIL
diff --git a/agentworking/readyos-1kb-shim-skip-bank/c64u-dma-retry2/suite.status b/agentworking/readyos-1kb-shim-skip-bank/c64u-dma-retry2/suite.status
new file mode 100644
index 0000000..446853f
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/c64u-dma-retry2/suite.status
@@ -0,0 +1 @@
+FAIL rc=1
diff --git a/agentworking/readyos-1kb-shim-skip-bank/c64u-dma/editor-direct-dma-return/status b/agentworking/readyos-1kb-shim-skip-bank/c64u-dma/editor-direct-dma-return/status
new file mode 100644
index 0000000..a3d6004
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/c64u-dma/editor-direct-dma-return/status
@@ -0,0 +1 @@
+READYOS_EDITOR_DIRECT_DMA_RETURN_PASS
diff --git a/agentworking/readyos-1kb-shim-skip-bank/c64u-dma/editor-load-selected/status b/agentworking/readyos-1kb-shim-skip-bank/c64u-dma/editor-load-selected/status
new file mode 100644
index 0000000..30dcf65
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/c64u-dma/editor-load-selected/status
@@ -0,0 +1 @@
+READYOS_EDITOR_LOAD_SELECTED_PASS
diff --git a/agentworking/readyos-1kb-shim-skip-bank/c64u-dma/loadall-readyshell-overlay-smoke/status b/agentworking/readyos-1kb-shim-skip-bank/c64u-dma/loadall-readyshell-overlay-smoke/status
new file mode 100644
index 0000000..f914918
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/c64u-dma/loadall-readyshell-overlay-smoke/status
@@ -0,0 +1 @@
+READYOS_BOOT_FAIL
diff --git a/agentworking/readyos-1kb-shim-skip-bank/c64u-dma/suite.status b/agentworking/readyos-1kb-shim-skip-bank/c64u-dma/suite.status
new file mode 100644
index 0000000..446853f
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/c64u-dma/suite.status
@@ -0,0 +1 @@
+FAIL rc=1
diff --git a/agentworking/readyos-1kb-shim-skip-bank/c64u-readybasic-retry3/readybasic-load-selected/status b/agentworking/readyos-1kb-shim-skip-bank/c64u-readybasic-retry3/readybasic-load-selected/status
new file mode 100644
index 0000000..3913efc
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/c64u-readybasic-retry3/readybasic-load-selected/status
@@ -0,0 +1 @@
+READYOS_READYBASIC_LOAD_SELECTED_PASS
diff --git a/agentworking/readyos-1kb-shim-skip-bank/c64u-readybasic-retry3/suite.status b/agentworking/readyos-1kb-shim-skip-bank/c64u-readybasic-retry3/suite.status
new file mode 100644
index 0000000..7ef22e9
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/c64u-readybasic-retry3/suite.status
@@ -0,0 +1 @@
+PASS
diff --git a/agentworking/readyos-1kb-shim-skip-bank/c64u-readyirc-w/fixture-status.json b/agentworking/readyos-1kb-shim-skip-bank/c64u-readyirc-w/fixture-status.json
new file mode 100644
index 0000000..d015224
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/c64u-readyirc-w/fixture-status.json
@@ -0,0 +1,94 @@
+{
+ "connections": 3,
+ "registered": 3,
+ "quit_count": 2,
+ "exact_pong": true,
+ "registrations": [
+ {
+ "connection": 1,
+ "nick": "autonick",
+ "user": "autonick",
+ "channel": "#readyostest"
+ },
+ {
+ "connection": 2,
+ "nick": "autonick",
+ "user": "autonick",
+ "channel": "#secondtest"
+ },
+ {
+ "connection": 3,
+ "nick": "autonick",
+ "user": "autonick",
+ "channel": "#secondtest"
+ }
+ ],
+ "part_channels": [
+ "#readyostest"
+ ],
+ "join_switches": [
+ "#secondtest"
+ ],
+ "channel_commands": [
+ "part #readyostest",
+ "join #secondtest"
+ ],
+ "names_requests": [
+ "#readyostest",
+ "#longnames"
+ ],
+ "privmsg_targets": [
+ "#readyostest",
+ "#readyostest",
+ "#readyostest",
+ "#readyostest",
+ "#readyostest",
+ "#readyostest",
+ "#readyostest",
+ "#secondtest",
+ "#secondtest",
+ "#secondtest"
+ ],
+ "events": [
+ "connection 1 parted #readyostest",
+ "connection 1 tx :autonick!user@fixture PART #readyostest :changing channel",
+ "connection 1 rx JOIN #secondtest",
+ "connection 1 switched join #secondtest",
+ "connection 1 tx :autonick!user@fixture JOIN :#secondtest",
+ "connection 1 tx :SwitchBot!user@fixture PRIVMSG #secondtest :JOINED NEW CHANNEL",
+ "connection 1 rx PRIVMSG #secondtest :afterjoin",
+ "connection 1 tx :EchoBot!user@fixture PRIVMSG #secondtest :ECHO MIXED AFTERJOIN",
+ "connection 1 rx PRIVMSG #secondtest :queuewhileaway",
+ "connection 1 tx :QueueBot!user@fixture PRIVMSG #secondtest :QUEUED WHILE SUSPENDED",
+ "connection 1 rx PRIVMSG #secondtest :dropwhileaway",
+ "connection 1 forced close",
+ "connection 1 closed",
+ "connection 2 accepted",
+ "connection 2 rx NICK autonick",
+ "connection 2 rx USER autonick * 0 :autonick",
+ "connection 2 rx JOIN #secondtest",
+ "connection 2 registered nick=autonick",
+ "connection 2 tx :Fixture.Server 001 autonick :WELCOME MIXED CASE",
+ "connection 2 tx :UpperNick!user@fixture PRIVMSG #secondtest :CONNECTION 2 MIXED CASE WELCOME",
+ "connection 2 tx PING :MiXeDToken",
+ "connection 2 rx PONG :MiXeDToken",
+ "exact mixed-case pong received",
+ "connection 2 rx QUIT :READYIRC DISCONNECT",
+ "connection 2 quit received",
+ "connection 2 closed",
+ "connection 3 accepted",
+ "connection 3 rx NICK autonick",
+ "connection 3 rx USER autonick * 0 :autonick",
+ "connection 3 rx JOIN #secondtest",
+ "connection 3 registered nick=autonick",
+ "connection 3 tx :Fixture.Server 001 autonick :WELCOME MIXED CASE",
+ "connection 3 tx :UpperNick!user@fixture PRIVMSG #secondtest :CONNECTION 3 MIXED CASE WELCOME",
+ "connection 3 tx PING :MiXeDToken",
+ "connection 3 rx PONG :MiXeDToken",
+ "exact mixed-case pong received",
+ "connection 3 rx QUIT :READYIRC DISCONNECT",
+ "connection 3 quit received",
+ "connection 3 closed",
+ "fixture stopped"
+ ]
+}
diff --git a/agentworking/readyos-1kb-shim-skip-bank/c64u-readyirc-w/post-suite-clean-boot/status b/agentworking/readyos-1kb-shim-skip-bank/c64u-readyirc-w/post-suite-clean-boot/status
new file mode 100644
index 0000000..406f98d
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/c64u-readyirc-w/post-suite-clean-boot/status
@@ -0,0 +1 @@
+READYOS_BOOT_PASS
diff --git a/agentworking/readyos-1kb-shim-skip-bank/c64u-readyirc-w/post-suite-reu-clear/status b/agentworking/readyos-1kb-shim-skip-bank/c64u-readyirc-w/post-suite-reu-clear/status
new file mode 100644
index 0000000..4cbc2fc
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/c64u-readyirc-w/post-suite-reu-clear/status
@@ -0,0 +1 @@
+READYOS_CLEAR_REU_ONLY_OK
diff --git a/agentworking/readyos-1kb-shim-skip-bank/c64u-readyirc-w/reu-clear-preflight/status b/agentworking/readyos-1kb-shim-skip-bank/c64u-readyirc-w/reu-clear-preflight/status
new file mode 100644
index 0000000..4cbc2fc
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/c64u-readyirc-w/reu-clear-preflight/status
@@ -0,0 +1 @@
+READYOS_CLEAR_REU_ONLY_OK
diff --git a/agentworking/readyos-1kb-shim-skip-bank/c64u-readyirc-w/suite.status b/agentworking/readyos-1kb-shim-skip-bank/c64u-readyirc-w/suite.status
new file mode 100644
index 0000000..7ef22e9
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/c64u-readyirc-w/suite.status
@@ -0,0 +1 @@
+PASS
diff --git a/agentworking/readyos-1kb-shim-skip-bank/c64u-readyshell/reu-clear/status b/agentworking/readyos-1kb-shim-skip-bank/c64u-readyshell/reu-clear/status
new file mode 100644
index 0000000..4cbc2fc
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/c64u-readyshell/reu-clear/status
@@ -0,0 +1 @@
+READYOS_CLEAR_REU_ONLY_OK
diff --git a/agentworking/readyos-1kb-shim-skip-bank/c64u-readyshell/suite.status b/agentworking/readyos-1kb-shim-skip-bank/c64u-readyshell/suite.status
new file mode 100644
index 0000000..7ef22e9
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/c64u-readyshell/suite.status
@@ -0,0 +1 @@
+PASS
diff --git a/agentworking/readyos-1kb-shim-skip-bank/c64u_dma_unique.ini b/agentworking/readyos-1kb-shim-skip-bank/c64u_dma_unique.ini
new file mode 100644
index 0000000..45eaa0f
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/c64u_dma_unique.ini
@@ -0,0 +1,72 @@
+[system]
+variant_name=precog d81
+variant_boot_name=precog d81
+reu_bank_skip=32
+
+[launcher]
+load_all_to_reu=0
+runappfirst=
+c64u_image_path=/usb1/r1k250802a.d81
+
+[apps]
+8:editor:editor:1
+text editor with clipboard
+
+8:readyshell:readyshell (beta):2:rsovl+
+command shell poc scaffold
+rsparser@0:0000,rsvm@0:3800,rsdrvilst@0:7000,rsldv@1:0000,rsstv@0:a800,rsfops@1:3800,rscat@1:7000,rscopy@1:a800,rsedit@2:0000
+
+8:simplefiles:simple files
+dual pane file manager and seq viewer
+
+8:clipmgr:clipboard
+manage clipboard items
+
+8:readybasic:ready basic (alpha):3:rbcore+
+scoped basic v2 bridge poc
+rbcore,rbcode
+
+8:cal26:calendar 26
+calendar for 2026 with appointments
+
+8:tasklist:task list
+outliner with notes and search
+
+8:reuviewer:reu viewer
+view reu memory usage
+
+8:sysinfo:system info
+system, reu, and ultimate status
+
+8:quicknotes:quicknotes
+reu-backed note editor
+
+8:calcplus:calc plus
+keyboard-first expression calculator
+
+8:hexview:hex viewer
+browse memory in hex format
+
+8:simplecells:simple cells (alpha)
+spreadsheet with formulas and colors
+
+8:game2048:2048 game
+2048 tile puzzle
+
+8:deminer:deminer
+minesweeper-style puzzle
+
+8:dizzy:dizzy kanban
+fizzy inspired kanban app
+
+8:readyirc:readyirc
+ultimate tcp irc client
+
+8:ucitest:uci tester
+ultimate command interface lab
+
+8:rirc-rrnet:readyirc rrnet
+rr-net tcp irc client
+
+8:readme:read.me
+readyos, ultimate buddy, precog poc os
diff --git a/agentworking/readyos-1kb-shim-skip-bank/clipboard_cross_app_regular.yaml b/agentworking/readyos-1kb-shim-skip-bank/clipboard_cross_app_regular.yaml
new file mode 100644
index 0000000..272cc4a
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/clipboard_cross_app_regular.yaml
@@ -0,0 +1,127 @@
+version: 1
+kind: vice_task_plan
+plan_id: clipboard_cross_app_readyos_bank
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy: { max_attempts: 2, backoff_ms: 250, jitter: false }
+ timeouts: { launch_s: 45, step_s: 180, read_s: 2 }
+ artifact_policy: { capture_screen: true, capture_state: true, capture_dump: false }
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5y-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5y-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5y-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params: { kill_stale: true }
+ - id: wait_launcher_initial
+ type: screen.wait_contains
+ params: { text: "READY OS", wait_timeout_s: 180, capture_on_success: true, capture_label: clip_launcher_initial }
+ - id: launch_editor
+ type: input.sequence
+ params: { keys: [19,17,17,13], inter_key_delay_s: 0.08, post_delay_s: 2.0 }
+ - id: wait_editor
+ type: screen.wait_contains
+ params: { text: "F1:CPY", wait_timeout_s: 90, capture_on_success: true, capture_label: clip_editor_initial }
+ - id: type_clipboard_source
+ type: input.sequence
+ params: { keys: [67,76,73,80,84,69,83,84,52,50], inter_key_delay_s: 0.05, post_delay_s: 0.5 }
+ - id: assert_clipboard_source
+ type: assert.screen
+ params: { contains: "CLIPTEST42" }
+ - id: copy_current_line
+ type: input.sequence
+ params: { keys: [133], inter_key_delay_s: 0.05, post_delay_s: 0.8 }
+ - id: return_editor_to_launcher
+ type: input.sequence
+ params: { keys: [2], inter_key_delay_s: 0.05, post_delay_s: 1.0 }
+ - id: wait_launcher_after_copy
+ type: screen.wait_contains
+ params: { text: "READY OS", wait_timeout_s: 45, capture_on_success: true, capture_label: clip_launcher_after_copy }
+ - id: launch_clipboard_manager
+ type: input.sequence
+ params: { keys: [19,17,17,17,17,17,13], inter_key_delay_s: 0.08, post_delay_s: 2.0 }
+ - id: wait_clipboard_manager
+ type: screen.wait_contains
+ params: { text: "CLIPBOARD MANAGER", wait_timeout_s: 90, capture_on_success: true, capture_label: clip_manager }
+ - id: assert_clipboard_count
+ type: assert.screen
+ params: { contains: "ITEMS: 1" }
+ - id: assert_clipboard_preview
+ type: assert.screen
+ params: { contains: "CLIPTEST42" }
+ - id: return_clipboard_manager_to_launcher
+ type: input.sequence
+ params: { keys: [2], inter_key_delay_s: 0.05, post_delay_s: 1.0 }
+ - id: capture_after_manager_return
+ type: screen.capture
+ params: { label: clip_after_manager_return, note: Diagnostic capture immediately after Clipboard Manager CTRL+B. }
+ - id: regs_after_manager_return
+ type: monitor.command
+ params: { command: "r" }
+ - id: dump_after_manager_return
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: shim_hot_state_c820, start: 0xC820, end: 0xC83F }
+ - { label: app_entry_1000, start: 0x1000, end: 0x107F }
+ - id: dump_reu_after_manager_return
+ type: dump.reu
+ params: { stage_tag: clipboard_after_manager_return, mode: sampled }
+ - id: wait_launcher_after_manager
+ type: screen.wait_contains
+ params: { text: "READY OS", pre_delay_s: 15.0, wait_timeout_s: 45, capture_on_success: true, capture_label: clip_launcher_after_manager }
+ - id: move_launcher_to_editor
+ type: input.sequence
+ params: { keys: [145,145,145], inter_key_delay_s: 0.5, post_delay_s: 2.0 }
+ - id: capture_editor_selected_for_resume
+ type: assert.screen
+ params: { contains: "TEXT EDITOR WITH CLIPBOARD" }
+ - id: clear_keyboard_before_editor_resume
+ type: memory.write
+ params: { start: 0x00C6, bytes_hex: "00" }
+ - id: resume_editor
+ type: monitor.command
+ params: { command: "keybuf \\x0d" }
+ - id: capture_after_editor_resume_request
+ type: screen.capture
+ params: { label: clip_after_editor_resume_request, note: Diagnostic capture after selecting the loaded Editor snapshot. }
+ - id: regs_after_editor_resume_request
+ type: monitor.command
+ params: { command: "r" }
+ - id: dump_after_editor_resume_request
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: shim_hot_state_after_editor_resume, start: 0xC820, end: 0xC83F }
+ - { label: app_entry_after_editor_resume, start: 0x1000, end: 0x107F }
+ - id: wait_editor_resumed
+ type: screen.wait_contains
+ params: { text: "F1:CPY", wait_timeout_s: 90, capture_on_success: true, capture_label: clip_editor_resumed }
+ - id: assert_editor_resume_text
+ type: assert.screen
+ params: { contains: "CLIPTEST42" }
+ - id: create_paste_target
+ type: input.sequence
+ params: { keys: [13,90,134], inter_key_delay_s: 0.08, post_delay_s: 1.0 }
+ - id: assert_cross_app_paste
+ type: assert.screen
+ params: { contains: "ZCLIPTEST42" }
+ - id: dump_resident_shim
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: shim_full_c600, start: 0xC600, end: 0xC9FF }
+ - { label: shim_lower_reserve_c600, start: 0xC600, end: 0xC7FF }
+ - id: regs_final
+ type: monitor.command
+ params: { command: "r" }
diff --git a/agentworking/readyos-1kb-shim-skip-bank/clipmgr_empty_return_regular.yaml b/agentworking/readyos-1kb-shim-skip-bank/clipmgr_empty_return_regular.yaml
new file mode 100644
index 0000000..c43bb99
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/clipmgr_empty_return_regular.yaml
@@ -0,0 +1,64 @@
+version: 1
+kind: vice_task_plan
+plan_id: clipmgr_empty_return_control
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy: { max_attempts: 2, backoff_ms: 250, jitter: false }
+ timeouts: { launch_s: 45, step_s: 180, read_s: 2 }
+ artifact_policy: { capture_screen: true, capture_state: true, capture_dump: false }
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5u-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5u-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5u-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params: { kill_stale: true }
+ - id: wait_launcher_initial
+ type: screen.wait_contains
+ params: { text: "READY OS", wait_timeout_s: 180, capture_on_success: true, capture_label: empty_clip_launcher }
+ - id: launch_clipboard_manager
+ type: input.sequence
+ params: { keys: [19,17,17,17,17,17,13], inter_key_delay_s: 0.08, post_delay_s: 2.0 }
+ - id: wait_clipboard_manager
+ type: screen.wait_contains
+ params: { text: "CLIPBOARD MANAGER", wait_timeout_s: 90, capture_on_success: true, capture_label: empty_clip_manager }
+ - id: assert_clipboard_empty
+ type: assert.screen
+ params: { contains: "CLIPBOARD IS EMPTY" }
+ - id: regs_before_return
+ type: monitor.command
+ params: { command: "r" }
+ - id: return_clipboard_manager_to_launcher
+ type: input.sequence
+ params: { keys: [2], inter_key_delay_s: 0.05, post_delay_s: 1.0 }
+ - id: capture_after_return_key
+ type: screen.capture
+ params: { label: empty_clip_after_return_key, note: Diagnostic capture after injected Ctrl+B byte. }
+ - id: regs_after_return_key
+ type: monitor.command
+ params: { command: "r" }
+ - id: dump_after_return_key
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: cc65_zp, start: 0x0002, end: 0x001B }
+ - { label: cc65_stack_tail, start: 0xC580, end: 0xC5FF }
+ - { label: keyboard_state, start: 0x00C5, end: 0x00C6 }
+ - { label: shim_hot_state, start: 0xC820, end: 0xC83F }
+ - { label: app_entry_after_return, start: 0x1000, end: 0x107F }
+ - id: dump_reu_after_return_key
+ type: dump.reu
+ params: { stage_tag: empty_clip_after_return_key, mode: sampled }
+ - id: wait_launcher_after_manager
+ type: screen.wait_contains
+ params: { text: "READY OS", wait_timeout_s: 45, capture_on_success: true, capture_label: empty_clip_launcher_after }
diff --git a/agentworking/readyos-1kb-shim-skip-bank/headroom_after.json b/agentworking/readyos-1kb-shim-skip-bank/headroom_after.json
new file mode 100644
index 0000000..5b1f2b5
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/headroom_after.json
@@ -0,0 +1,1242 @@
+{
+ "app_window_end": "0xC5FF",
+ "app_window_start": "0x1000",
+ "maps": [
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 4738,
+ "bss_bytes": 2509,
+ "code_ro_init_bytes": 39295,
+ "data_bytes": 50,
+ "heap_capacity": 4626,
+ "heap_end": "0xC58F",
+ "heap_start": "0xB37E",
+ "main_segment_total": 41854,
+ "map": "obj/launcher.map",
+ "name": "launcher",
+ "runtime_end": "0xB37D",
+ "segments": {
+ "BSS": {
+ "end": "0xB37D",
+ "size": 2509,
+ "start": "0xA9B1"
+ },
+ "CODE": {
+ "end": "0xA39D",
+ "size": 37739,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0xA96E",
+ "size": 50,
+ "start": "0xA93D"
+ },
+ "INIT": {
+ "end": "0xA98A",
+ "size": 28,
+ "start": "0xA96F"
+ },
+ "ONCE": {
+ "end": "0xA9B0",
+ "size": 38,
+ "start": "0xA98B"
+ },
+ "RODATA": {
+ "end": "0xA93C",
+ "size": 1439,
+ "start": "0xA39E"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 12194,
+ "bss_bytes": 9880,
+ "code_ro_init_bytes": 24384,
+ "data_bytes": 134,
+ "heap_capacity": 12082,
+ "heap_end": "0xC58F",
+ "heap_start": "0x965E",
+ "main_segment_total": 34398,
+ "map": "obj/editor.map",
+ "name": "editor",
+ "runtime_end": "0x965D",
+ "segments": {
+ "BSS": {
+ "end": "0x965D",
+ "size": 9880,
+ "start": "0x6FC6"
+ },
+ "CODE": {
+ "end": "0x6BBF",
+ "size": 23437,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x6F83",
+ "size": 134,
+ "start": "0x6EFE"
+ },
+ "INIT": {
+ "end": "0x6F9F",
+ "size": 28,
+ "start": "0x6F84"
+ },
+ "ONCE": {
+ "end": "0x6FC5",
+ "size": 38,
+ "start": "0x6FA0"
+ },
+ "RODATA": {
+ "end": "0x6EFD",
+ "size": 830,
+ "start": "0x6BC0"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 9292,
+ "bss_bytes": 6047,
+ "code_ro_init_bytes": 31031,
+ "data_bytes": 222,
+ "heap_capacity": 9180,
+ "heap_end": "0xC58F",
+ "heap_start": "0xA1B4",
+ "main_segment_total": 37300,
+ "map": "obj/quicknotes.map",
+ "name": "quicknotes",
+ "runtime_end": "0xA1B3",
+ "segments": {
+ "BSS": {
+ "end": "0xA1B3",
+ "size": 6047,
+ "start": "0x8A15"
+ },
+ "CODE": {
+ "end": "0x853F",
+ "size": 29965,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x89D2",
+ "size": 222,
+ "start": "0x88F5"
+ },
+ "INIT": {
+ "end": "0x89EE",
+ "size": 28,
+ "start": "0x89D3"
+ },
+ "ONCE": {
+ "end": "0x8A14",
+ "size": 38,
+ "start": "0x89EF"
+ },
+ "RODATA": {
+ "end": "0x88F4",
+ "size": 949,
+ "start": "0x8540"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 7750,
+ "bss_bytes": 1321,
+ "code_ro_init_bytes": 37363,
+ "data_bytes": 158,
+ "heap_capacity": 7638,
+ "heap_end": "0xC58F",
+ "heap_start": "0xA7BA",
+ "main_segment_total": 38842,
+ "map": "obj/calcplus.map",
+ "name": "calcplus",
+ "runtime_end": "0xA7B9",
+ "segments": {
+ "BSS": {
+ "end": "0xA7B9",
+ "size": 1321,
+ "start": "0xA291"
+ },
+ "CODE": {
+ "end": "0x9D1B",
+ "size": 36073,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0xA24E",
+ "size": 158,
+ "start": "0xA1B1"
+ },
+ "INIT": {
+ "end": "0xA26A",
+ "size": 28,
+ "start": "0xA24F"
+ },
+ "ONCE": {
+ "end": "0xA290",
+ "size": 38,
+ "start": "0xA26B"
+ },
+ "RODATA": {
+ "end": "0xA1B0",
+ "size": 1173,
+ "start": "0x9D1C"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 33652,
+ "bss_bytes": 101,
+ "code_ro_init_bytes": 12793,
+ "data_bytes": 46,
+ "heap_capacity": 33540,
+ "heap_end": "0xC58F",
+ "heap_start": "0x428C",
+ "main_segment_total": 12940,
+ "map": "obj/hexview.map",
+ "name": "hexview",
+ "runtime_end": "0x428B",
+ "segments": {
+ "BSS": {
+ "end": "0x428B",
+ "size": 101,
+ "start": "0x4227"
+ },
+ "CODE": {
+ "end": "0x3FC4",
+ "size": 12178,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x41E4",
+ "size": 46,
+ "start": "0x41B7"
+ },
+ "INIT": {
+ "end": "0x4200",
+ "size": 28,
+ "start": "0x41E5"
+ },
+ "ONCE": {
+ "end": "0x4226",
+ "size": 38,
+ "start": "0x4201"
+ },
+ "RODATA": {
+ "end": "0x41B6",
+ "size": 498,
+ "start": "0x3FC5"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 14637,
+ "bss_bytes": 1062,
+ "code_ro_init_bytes": 30847,
+ "data_bytes": 46,
+ "heap_capacity": 14524,
+ "heap_end": "0xC58F",
+ "heap_start": "0x8CD4",
+ "main_segment_total": 31955,
+ "map": "obj/clipmgr.map",
+ "name": "clipmgr",
+ "runtime_end": "0x8CD2",
+ "segments": {
+ "BSS": {
+ "end": "0x8CD2",
+ "size": 1062,
+ "start": "0x88AD"
+ },
+ "CODE": {
+ "end": "0x84F2",
+ "size": 29888,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x886A",
+ "size": 46,
+ "start": "0x883D"
+ },
+ "INIT": {
+ "end": "0x8886",
+ "size": 28,
+ "start": "0x886B"
+ },
+ "ONCE": {
+ "end": "0x88AC",
+ "size": 38,
+ "start": "0x8887"
+ },
+ "RODATA": {
+ "end": "0x883C",
+ "size": 842,
+ "start": "0x84F3"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 31220,
+ "bss_bytes": 221,
+ "code_ro_init_bytes": 15105,
+ "data_bytes": 46,
+ "heap_capacity": 31108,
+ "heap_end": "0xC58F",
+ "heap_start": "0x4C0C",
+ "main_segment_total": 15372,
+ "map": "obj/reuviewer.map",
+ "name": "reuviewer",
+ "runtime_end": "0x4C0B",
+ "segments": {
+ "BSS": {
+ "end": "0x4C0B",
+ "size": 221,
+ "start": "0x4B2F"
+ },
+ "CODE": {
+ "end": "0x4967",
+ "size": 14645,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x4AEC",
+ "size": 46,
+ "start": "0x4ABF"
+ },
+ "INIT": {
+ "end": "0x4B08",
+ "size": 28,
+ "start": "0x4AED"
+ },
+ "ONCE": {
+ "end": "0x4B2E",
+ "size": 38,
+ "start": "0x4B09"
+ },
+ "RODATA": {
+ "end": "0x4ABE",
+ "size": 343,
+ "start": "0x4968"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 30084,
+ "bss_bytes": 277,
+ "code_ro_init_bytes": 16184,
+ "data_bytes": 47,
+ "heap_capacity": 29972,
+ "heap_end": "0xC58F",
+ "heap_start": "0x507C",
+ "main_segment_total": 16508,
+ "map": "obj/sysinfo.map",
+ "name": "sysinfo",
+ "runtime_end": "0x507B",
+ "segments": {
+ "BSS": {
+ "end": "0x507B",
+ "size": 277,
+ "start": "0x4F67"
+ },
+ "CODE": {
+ "end": "0x4ACD",
+ "size": 15003,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x4F24",
+ "size": 47,
+ "start": "0x4EF6"
+ },
+ "INIT": {
+ "end": "0x4F40",
+ "size": 28,
+ "start": "0x4F25"
+ },
+ "ONCE": {
+ "end": "0x4F66",
+ "size": 38,
+ "start": "0x4F41"
+ },
+ "RODATA": {
+ "end": "0x4EF5",
+ "size": 1064,
+ "start": "0x4ACE"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 6398,
+ "bss_bytes": 8927,
+ "code_ro_init_bytes": 31116,
+ "data_bytes": 151,
+ "heap_capacity": 6286,
+ "heap_end": "0xC58F",
+ "heap_start": "0xAD02",
+ "main_segment_total": 40194,
+ "map": "obj/tasklist.map",
+ "name": "tasklist",
+ "runtime_end": "0xAD01",
+ "segments": {
+ "BSS": {
+ "end": "0xAD01",
+ "size": 8927,
+ "start": "0x8A23"
+ },
+ "CODE": {
+ "end": "0x8614",
+ "size": 30178,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x89E0",
+ "size": 151,
+ "start": "0x894A"
+ },
+ "INIT": {
+ "end": "0x89FC",
+ "size": 28,
+ "start": "0x89E1"
+ },
+ "ONCE": {
+ "end": "0x8A22",
+ "size": 38,
+ "start": "0x89FD"
+ },
+ "RODATA": {
+ "end": "0x8949",
+ "size": 821,
+ "start": "0x8615"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 12440,
+ "bss_bytes": 4397,
+ "code_ro_init_bytes": 29693,
+ "data_bytes": 62,
+ "heap_capacity": 12328,
+ "heap_end": "0xC58F",
+ "heap_start": "0x9568",
+ "main_segment_total": 34152,
+ "map": "obj/simplefiles.map",
+ "name": "simplefiles",
+ "runtime_end": "0x9567",
+ "segments": {
+ "BSS": {
+ "end": "0x9567",
+ "size": 4397,
+ "start": "0x843B"
+ },
+ "CODE": {
+ "end": "0x7EED",
+ "size": 28347,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x83F8",
+ "size": 62,
+ "start": "0x83BB"
+ },
+ "INIT": {
+ "end": "0x8414",
+ "size": 28,
+ "start": "0x83F9"
+ },
+ "ONCE": {
+ "end": "0x843A",
+ "size": 38,
+ "start": "0x8415"
+ },
+ "RODATA": {
+ "end": "0x83BA",
+ "size": 1229,
+ "start": "0x7EEE"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 9500,
+ "bss_bytes": 2142,
+ "code_ro_init_bytes": 34712,
+ "data_bytes": 238,
+ "heap_capacity": 9388,
+ "heap_end": "0xC58F",
+ "heap_start": "0xA0E4",
+ "main_segment_total": 37092,
+ "map": "obj/simplecells.map",
+ "name": "simplecells",
+ "runtime_end": "0xA0E3",
+ "segments": {
+ "BSS": {
+ "end": "0xA0E3",
+ "size": 2142,
+ "start": "0x9886"
+ },
+ "CODE": {
+ "end": "0x909B",
+ "size": 32873,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x9843",
+ "size": 238,
+ "start": "0x9756"
+ },
+ "INIT": {
+ "end": "0x985F",
+ "size": 28,
+ "start": "0x9844"
+ },
+ "ONCE": {
+ "end": "0x9885",
+ "size": 38,
+ "start": "0x9860"
+ },
+ "RODATA": {
+ "end": "0x9755",
+ "size": 1722,
+ "start": "0x909C"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 28505,
+ "bss_bytes": 1203,
+ "code_ro_init_bytes": 16838,
+ "data_bytes": 46,
+ "heap_capacity": 28392,
+ "heap_end": "0xC58F",
+ "heap_start": "0x56A8",
+ "main_segment_total": 18087,
+ "map": "obj/game2048.map",
+ "name": "game2048",
+ "runtime_end": "0x56A6",
+ "segments": {
+ "BSS": {
+ "end": "0x56A6",
+ "size": 1203,
+ "start": "0x51F4"
+ },
+ "CODE": {
+ "end": "0x5053",
+ "size": 16417,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x51B1",
+ "size": 46,
+ "start": "0x5184"
+ },
+ "INIT": {
+ "end": "0x51CD",
+ "size": 28,
+ "start": "0x51B2"
+ },
+ "ONCE": {
+ "end": "0x51F3",
+ "size": 38,
+ "start": "0x51CE"
+ },
+ "RODATA": {
+ "end": "0x5183",
+ "size": 304,
+ "start": "0x5054"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 22092,
+ "bss_bytes": 4276,
+ "code_ro_init_bytes": 20178,
+ "data_bytes": 46,
+ "heap_capacity": 21980,
+ "heap_end": "0xC58F",
+ "heap_start": "0x6FB4",
+ "main_segment_total": 24500,
+ "map": "obj/deminer.map",
+ "name": "deminer",
+ "runtime_end": "0x6FB3",
+ "segments": {
+ "BSS": {
+ "end": "0x6FB3",
+ "size": 4276,
+ "start": "0x5F00"
+ },
+ "CODE": {
+ "end": "0x5BA4",
+ "size": 19314,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x5EBD",
+ "size": 46,
+ "start": "0x5E90"
+ },
+ "INIT": {
+ "end": "0x5ED9",
+ "size": 28,
+ "start": "0x5EBE"
+ },
+ "ONCE": {
+ "end": "0x5EFF",
+ "size": 38,
+ "start": "0x5EDA"
+ },
+ "RODATA": {
+ "end": "0x5E8F",
+ "size": 747,
+ "start": "0x5BA5"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 30141,
+ "bss_bytes": 908,
+ "code_ro_init_bytes": 15457,
+ "data_bytes": 86,
+ "heap_capacity": 30028,
+ "heap_end": "0xC58F",
+ "heap_start": "0x5044",
+ "main_segment_total": 16451,
+ "map": "obj/sidetris.map",
+ "name": "sidetris",
+ "runtime_end": "0x5042",
+ "segments": {
+ "BSS": {
+ "end": "0x5042",
+ "size": 908,
+ "start": "0x4CB7"
+ },
+ "CODE": {
+ "end": "0x481B",
+ "size": 14313,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x4C74",
+ "size": 86,
+ "start": "0x4C1F"
+ },
+ "INIT": {
+ "end": "0x4C90",
+ "size": 28,
+ "start": "0x4C75"
+ },
+ "ONCE": {
+ "end": "0x4CB6",
+ "size": 38,
+ "start": "0x4C91"
+ },
+ "RODATA": {
+ "end": "0x4C1E",
+ "size": 1027,
+ "start": "0x481C"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 9173,
+ "bss_bytes": 4803,
+ "code_ro_init_bytes": 32292,
+ "data_bytes": 324,
+ "heap_capacity": 9060,
+ "heap_end": "0xC58F",
+ "heap_start": "0xA22C",
+ "main_segment_total": 37419,
+ "map": "obj/cal26.map",
+ "name": "cal26",
+ "runtime_end": "0xA22A",
+ "segments": {
+ "BSS": {
+ "end": "0xA22A",
+ "size": 4803,
+ "start": "0x8F68"
+ },
+ "CODE": {
+ "end": "0x8694",
+ "size": 30306,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x8F25",
+ "size": 324,
+ "start": "0x8DE2"
+ },
+ "INIT": {
+ "end": "0x8F41",
+ "size": 28,
+ "start": "0x8F26"
+ },
+ "ONCE": {
+ "end": "0x8F67",
+ "size": 38,
+ "start": "0x8F42"
+ },
+ "RODATA": {
+ "end": "0x8DE1",
+ "size": 1869,
+ "start": "0x8695"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 1580,
+ "bss_bytes": 6327,
+ "code_ro_init_bytes": 38553,
+ "data_bytes": 132,
+ "heap_capacity": 1468,
+ "heap_end": "0xC58F",
+ "heap_start": "0xBFD4",
+ "main_segment_total": 45012,
+ "map": "obj/dizzy.map",
+ "name": "dizzy",
+ "runtime_end": "0xBFD3",
+ "segments": {
+ "BSS": {
+ "end": "0xBFD3",
+ "size": 6327,
+ "start": "0xA71D"
+ },
+ "CODE": {
+ "end": "0xA18D",
+ "size": 37211,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0xA6DA",
+ "size": 132,
+ "start": "0xA657"
+ },
+ "INIT": {
+ "end": "0xA6F6",
+ "size": 28,
+ "start": "0xA6DB"
+ },
+ "ONCE": {
+ "end": "0xA71C",
+ "size": 38,
+ "start": "0xA6F7"
+ },
+ "RODATA": {
+ "end": "0xA656",
+ "size": 1225,
+ "start": "0xA18E"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 19312,
+ "bss_bytes": 5351,
+ "code_ro_init_bytes": 21882,
+ "data_bytes": 47,
+ "heap_capacity": 19200,
+ "heap_end": "0xC58F",
+ "heap_start": "0x7A90",
+ "main_segment_total": 27280,
+ "map": "obj/readyirc.map",
+ "name": "readyirc",
+ "runtime_end": "0x7A8F",
+ "segments": {
+ "BSS": {
+ "end": "0x7A8F",
+ "size": 5351,
+ "start": "0x65A9"
+ },
+ "CODE": {
+ "end": "0x619B",
+ "size": 20841,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x6566",
+ "size": 47,
+ "start": "0x6538"
+ },
+ "INIT": {
+ "end": "0x6582",
+ "size": 28,
+ "start": "0x6567"
+ },
+ "ONCE": {
+ "end": "0x65A8",
+ "size": 38,
+ "start": "0x6583"
+ },
+ "RODATA": {
+ "end": "0x6537",
+ "size": 924,
+ "start": "0x619C"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 18178,
+ "bss_bytes": 6909,
+ "code_ro_init_bytes": 21278,
+ "data_bytes": 227,
+ "heap_capacity": 18066,
+ "heap_end": "0xC58F",
+ "heap_start": "0x7EFE",
+ "main_segment_total": 28414,
+ "map": "obj/rirc-rrnet.map",
+ "name": "rirc-rrnet",
+ "runtime_end": "0x7EFD",
+ "segments": {
+ "BSS": {
+ "end": "0x7EFD",
+ "size": 6909,
+ "start": "0x6401"
+ },
+ "CODE": {
+ "end": "0x5FFD",
+ "size": 20427,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x63BE",
+ "size": 227,
+ "start": "0x62DC"
+ },
+ "INIT": {
+ "end": "0x63DA",
+ "size": 28,
+ "start": "0x63BF"
+ },
+ "ONCE": {
+ "end": "0x6400",
+ "size": 38,
+ "start": "0x63DB"
+ },
+ "RODATA": {
+ "end": "0x62DB",
+ "size": 734,
+ "start": "0x5FFE"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 1025,
+ "bss_bytes": 0,
+ "code_ro_init_bytes": 9290,
+ "data_bytes": 0,
+ "main_segment_total": 2954,
+ "map": "obj/readybasic.map",
+ "name": "readybasic",
+ "runtime_end": "0xC1FE",
+ "segments": {
+ "BRIDGE": {
+ "end": "0xC1FE",
+ "size": 511,
+ "start": "0xC000"
+ },
+ "ENTRY": {
+ "end": "0x11FF",
+ "size": 512,
+ "start": "0x1000"
+ },
+ "HIDDEN": {
+ "end": "0xA78A",
+ "size": 1931,
+ "start": "0xA000"
+ }
+ }
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 21293,
+ "bss_bytes": 2708,
+ "code_ro_init_bytes": 22520,
+ "data_bytes": 71,
+ "heap_capacity": 21180,
+ "heap_end": "0xC58F",
+ "heap_start": "0x72D4",
+ "main_segment_total": 25299,
+ "map": "obj/ucitest.map",
+ "name": "ucitest",
+ "runtime_end": "0x72D2",
+ "segments": {
+ "BSS": {
+ "end": "0x72D2",
+ "size": 2708,
+ "start": "0x683F"
+ },
+ "CODE": {
+ "end": "0x5933",
+ "size": 18689,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x67FC",
+ "size": 71,
+ "start": "0x67B6"
+ },
+ "INIT": {
+ "end": "0x6818",
+ "size": 28,
+ "start": "0x67FD"
+ },
+ "ONCE": {
+ "end": "0x683E",
+ "size": 38,
+ "start": "0x6819"
+ },
+ "RODATA": {
+ "end": "0x67B5",
+ "size": 3714,
+ "start": "0x5934"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 22393,
+ "bss_bytes": 48,
+ "code_ro_init_bytes": 24105,
+ "data_bytes": 46,
+ "heap_capacity": 22280,
+ "heap_end": "0xC58F",
+ "heap_start": "0x6E88",
+ "main_segment_total": 24199,
+ "map": "obj/readme.map",
+ "name": "readme",
+ "runtime_end": "0x6E86",
+ "segments": {
+ "BSS": {
+ "end": "0x6E86",
+ "size": 48,
+ "start": "0x6E57"
+ },
+ "CODE": {
+ "end": "0x392E",
+ "size": 10492,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x6E14",
+ "size": 46,
+ "start": "0x6DE7"
+ },
+ "INIT": {
+ "end": "0x6E30",
+ "size": 28,
+ "start": "0x6E15"
+ },
+ "ONCE": {
+ "end": "0x6E56",
+ "size": 38,
+ "start": "0x6E31"
+ },
+ "RODATA": {
+ "end": "0x6DE6",
+ "size": 13496,
+ "start": "0x392F"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 18027,
+ "bss_bytes": 426,
+ "code_ro_init_bytes": 28069,
+ "data_bytes": 70,
+ "heap_capacity": 3688,
+ "main_segment_total": 28565,
+ "map": "obj/readyshell.map",
+ "name": "readyshell",
+ "readyshell": {
+ "heap_end": "0x8DFD",
+ "heap_size": 3688,
+ "heap_start": "0x7F96",
+ "himem": "0xC600",
+ "overlay_loadaddr": "0x8DFE",
+ "overlay_start": "0x8E00",
+ "overlay_window": 14336
+ },
+ "runtime_end": "0x7F94",
+ "segments": {
+ "BSS": {
+ "end": "0x7F94",
+ "size": 426,
+ "start": "0x7DEB"
+ },
+ "CODE": {
+ "end": "0x795E",
+ "size": 26924,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x7D96",
+ "size": 70,
+ "start": "0x7D51"
+ },
+ "INIT": {
+ "end": "0x7DB2",
+ "size": 28,
+ "start": "0x7D97"
+ },
+ "ONCE": {
+ "end": "0x7DEA",
+ "size": 56,
+ "start": "0x7DB3"
+ },
+ "RODATA": {
+ "end": "0x7D50",
+ "size": 1010,
+ "start": "0x795F"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ }
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 17637,
+ "bss_bytes": 1978,
+ "code_ro_init_bytes": 26927,
+ "data_bytes": 50,
+ "heap_capacity": 17524,
+ "heap_end": "0xC58F",
+ "heap_start": "0x811C",
+ "main_segment_total": 28955,
+ "map": "obj/launcher_easyflash.map",
+ "name": "launcher_easyflash",
+ "runtime_end": "0x811A",
+ "segments": {
+ "BSS": {
+ "end": "0x811A",
+ "size": 1978,
+ "start": "0x7961"
+ },
+ "CODE": {
+ "end": "0x70A7",
+ "size": 24693,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x791E",
+ "size": 50,
+ "start": "0x78ED"
+ },
+ "INIT": {
+ "end": "0x793A",
+ "size": 28,
+ "start": "0x791F"
+ },
+ "ONCE": {
+ "end": "0x7960",
+ "size": 38,
+ "start": "0x793B"
+ },
+ "RODATA": {
+ "end": "0x78EC",
+ "size": 2117,
+ "start": "0x70A8"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 18129,
+ "bss_bytes": 426,
+ "code_ro_init_bytes": 27967,
+ "data_bytes": 70,
+ "heap_capacity": 3790,
+ "main_segment_total": 28463,
+ "map": "obj/readyshell_easyflash.map",
+ "name": "readyshell_easyflash",
+ "readyshell": {
+ "heap_end": "0x8DFD",
+ "heap_size": 3790,
+ "heap_start": "0x7F30",
+ "himem": "0xC600",
+ "overlay_loadaddr": "0x8DFE",
+ "overlay_start": "0x8E00",
+ "overlay_window": 14336
+ },
+ "runtime_end": "0x7F2E",
+ "segments": {
+ "BSS": {
+ "end": "0x7F2E",
+ "size": 426,
+ "start": "0x7D85"
+ },
+ "CODE": {
+ "end": "0x78F8",
+ "size": 26822,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x7D30",
+ "size": 70,
+ "start": "0x7CEB"
+ },
+ "INIT": {
+ "end": "0x7D4C",
+ "size": 28,
+ "start": "0x7D31"
+ },
+ "ONCE": {
+ "end": "0x7D84",
+ "size": 56,
+ "start": "0x7D4D"
+ },
+ "RODATA": {
+ "end": "0x7CEA",
+ "size": 1010,
+ "start": "0x78F9"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ }
+ }
+ ]
+}
diff --git a/agentworking/readyos-1kb-shim-skip-bank/headroom_before.json b/agentworking/readyos-1kb-shim-skip-bank/headroom_before.json
new file mode 100644
index 0000000..f4b64ba
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/headroom_before.json
@@ -0,0 +1,1242 @@
+{
+ "app_window_end": "0xC7FF",
+ "app_window_start": "0x1000",
+ "maps": [
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 5244,
+ "bss_bytes": 2509,
+ "code_ro_init_bytes": 39301,
+ "data_bytes": 50,
+ "heap_capacity": 5132,
+ "heap_end": "0xC78F",
+ "heap_start": "0xB384",
+ "main_segment_total": 41860,
+ "map": "obj/launcher.map",
+ "name": "launcher",
+ "runtime_end": "0xB383",
+ "segments": {
+ "BSS": {
+ "end": "0xB383",
+ "size": 2509,
+ "start": "0xA9B7"
+ },
+ "CODE": {
+ "end": "0xA3A3",
+ "size": 37745,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0xA974",
+ "size": 50,
+ "start": "0xA943"
+ },
+ "INIT": {
+ "end": "0xA990",
+ "size": 28,
+ "start": "0xA975"
+ },
+ "ONCE": {
+ "end": "0xA9B6",
+ "size": 38,
+ "start": "0xA991"
+ },
+ "RODATA": {
+ "end": "0xA942",
+ "size": 1439,
+ "start": "0xA3A4"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 12706,
+ "bss_bytes": 9880,
+ "code_ro_init_bytes": 24384,
+ "data_bytes": 134,
+ "heap_capacity": 12594,
+ "heap_end": "0xC78F",
+ "heap_start": "0x965E",
+ "main_segment_total": 34398,
+ "map": "obj/editor.map",
+ "name": "editor",
+ "runtime_end": "0x965D",
+ "segments": {
+ "BSS": {
+ "end": "0x965D",
+ "size": 9880,
+ "start": "0x6FC6"
+ },
+ "CODE": {
+ "end": "0x6BBF",
+ "size": 23437,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x6F83",
+ "size": 134,
+ "start": "0x6EFE"
+ },
+ "INIT": {
+ "end": "0x6F9F",
+ "size": 28,
+ "start": "0x6F84"
+ },
+ "ONCE": {
+ "end": "0x6FC5",
+ "size": 38,
+ "start": "0x6FA0"
+ },
+ "RODATA": {
+ "end": "0x6EFD",
+ "size": 830,
+ "start": "0x6BC0"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 9804,
+ "bss_bytes": 6047,
+ "code_ro_init_bytes": 31031,
+ "data_bytes": 222,
+ "heap_capacity": 9692,
+ "heap_end": "0xC78F",
+ "heap_start": "0xA1B4",
+ "main_segment_total": 37300,
+ "map": "obj/quicknotes.map",
+ "name": "quicknotes",
+ "runtime_end": "0xA1B3",
+ "segments": {
+ "BSS": {
+ "end": "0xA1B3",
+ "size": 6047,
+ "start": "0x8A15"
+ },
+ "CODE": {
+ "end": "0x853F",
+ "size": 29965,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x89D2",
+ "size": 222,
+ "start": "0x88F5"
+ },
+ "INIT": {
+ "end": "0x89EE",
+ "size": 28,
+ "start": "0x89D3"
+ },
+ "ONCE": {
+ "end": "0x8A14",
+ "size": 38,
+ "start": "0x89EF"
+ },
+ "RODATA": {
+ "end": "0x88F4",
+ "size": 949,
+ "start": "0x8540"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 8262,
+ "bss_bytes": 1321,
+ "code_ro_init_bytes": 37363,
+ "data_bytes": 158,
+ "heap_capacity": 8150,
+ "heap_end": "0xC78F",
+ "heap_start": "0xA7BA",
+ "main_segment_total": 38842,
+ "map": "obj/calcplus.map",
+ "name": "calcplus",
+ "runtime_end": "0xA7B9",
+ "segments": {
+ "BSS": {
+ "end": "0xA7B9",
+ "size": 1321,
+ "start": "0xA291"
+ },
+ "CODE": {
+ "end": "0x9D1B",
+ "size": 36073,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0xA24E",
+ "size": 158,
+ "start": "0xA1B1"
+ },
+ "INIT": {
+ "end": "0xA26A",
+ "size": 28,
+ "start": "0xA24F"
+ },
+ "ONCE": {
+ "end": "0xA290",
+ "size": 38,
+ "start": "0xA26B"
+ },
+ "RODATA": {
+ "end": "0xA1B0",
+ "size": 1173,
+ "start": "0x9D1C"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 34164,
+ "bss_bytes": 101,
+ "code_ro_init_bytes": 12793,
+ "data_bytes": 46,
+ "heap_capacity": 34052,
+ "heap_end": "0xC78F",
+ "heap_start": "0x428C",
+ "main_segment_total": 12940,
+ "map": "obj/hexview.map",
+ "name": "hexview",
+ "runtime_end": "0x428B",
+ "segments": {
+ "BSS": {
+ "end": "0x428B",
+ "size": 101,
+ "start": "0x4227"
+ },
+ "CODE": {
+ "end": "0x3FC4",
+ "size": 12178,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x41E4",
+ "size": 46,
+ "start": "0x41B7"
+ },
+ "INIT": {
+ "end": "0x4200",
+ "size": 28,
+ "start": "0x41E5"
+ },
+ "ONCE": {
+ "end": "0x4226",
+ "size": 38,
+ "start": "0x4201"
+ },
+ "RODATA": {
+ "end": "0x41B6",
+ "size": 498,
+ "start": "0x3FC5"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 15149,
+ "bss_bytes": 1062,
+ "code_ro_init_bytes": 30847,
+ "data_bytes": 46,
+ "heap_capacity": 15036,
+ "heap_end": "0xC78F",
+ "heap_start": "0x8CD4",
+ "main_segment_total": 31955,
+ "map": "obj/clipmgr.map",
+ "name": "clipmgr",
+ "runtime_end": "0x8CD2",
+ "segments": {
+ "BSS": {
+ "end": "0x8CD2",
+ "size": 1062,
+ "start": "0x88AD"
+ },
+ "CODE": {
+ "end": "0x84F2",
+ "size": 29888,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x886A",
+ "size": 46,
+ "start": "0x883D"
+ },
+ "INIT": {
+ "end": "0x8886",
+ "size": 28,
+ "start": "0x886B"
+ },
+ "ONCE": {
+ "end": "0x88AC",
+ "size": 38,
+ "start": "0x8887"
+ },
+ "RODATA": {
+ "end": "0x883C",
+ "size": 842,
+ "start": "0x84F3"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 31728,
+ "bss_bytes": 221,
+ "code_ro_init_bytes": 15109,
+ "data_bytes": 46,
+ "heap_capacity": 31616,
+ "heap_end": "0xC78F",
+ "heap_start": "0x4C10",
+ "main_segment_total": 15376,
+ "map": "obj/reuviewer.map",
+ "name": "reuviewer",
+ "runtime_end": "0x4C0F",
+ "segments": {
+ "BSS": {
+ "end": "0x4C0F",
+ "size": 221,
+ "start": "0x4B33"
+ },
+ "CODE": {
+ "end": "0x496B",
+ "size": 14649,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x4AF0",
+ "size": 46,
+ "start": "0x4AC3"
+ },
+ "INIT": {
+ "end": "0x4B0C",
+ "size": 28,
+ "start": "0x4AF1"
+ },
+ "ONCE": {
+ "end": "0x4B32",
+ "size": 38,
+ "start": "0x4B0D"
+ },
+ "RODATA": {
+ "end": "0x4AC2",
+ "size": 343,
+ "start": "0x496C"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 30596,
+ "bss_bytes": 277,
+ "code_ro_init_bytes": 16184,
+ "data_bytes": 47,
+ "heap_capacity": 30484,
+ "heap_end": "0xC78F",
+ "heap_start": "0x507C",
+ "main_segment_total": 16508,
+ "map": "obj/sysinfo.map",
+ "name": "sysinfo",
+ "runtime_end": "0x507B",
+ "segments": {
+ "BSS": {
+ "end": "0x507B",
+ "size": 277,
+ "start": "0x4F67"
+ },
+ "CODE": {
+ "end": "0x4ACD",
+ "size": 15003,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x4F24",
+ "size": 47,
+ "start": "0x4EF6"
+ },
+ "INIT": {
+ "end": "0x4F40",
+ "size": 28,
+ "start": "0x4F25"
+ },
+ "ONCE": {
+ "end": "0x4F66",
+ "size": 38,
+ "start": "0x4F41"
+ },
+ "RODATA": {
+ "end": "0x4EF5",
+ "size": 1064,
+ "start": "0x4ACE"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 6910,
+ "bss_bytes": 8927,
+ "code_ro_init_bytes": 31116,
+ "data_bytes": 151,
+ "heap_capacity": 6798,
+ "heap_end": "0xC78F",
+ "heap_start": "0xAD02",
+ "main_segment_total": 40194,
+ "map": "obj/tasklist.map",
+ "name": "tasklist",
+ "runtime_end": "0xAD01",
+ "segments": {
+ "BSS": {
+ "end": "0xAD01",
+ "size": 8927,
+ "start": "0x8A23"
+ },
+ "CODE": {
+ "end": "0x8614",
+ "size": 30178,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x89E0",
+ "size": 151,
+ "start": "0x894A"
+ },
+ "INIT": {
+ "end": "0x89FC",
+ "size": 28,
+ "start": "0x89E1"
+ },
+ "ONCE": {
+ "end": "0x8A22",
+ "size": 38,
+ "start": "0x89FD"
+ },
+ "RODATA": {
+ "end": "0x8949",
+ "size": 821,
+ "start": "0x8615"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 12952,
+ "bss_bytes": 4397,
+ "code_ro_init_bytes": 29693,
+ "data_bytes": 62,
+ "heap_capacity": 12840,
+ "heap_end": "0xC78F",
+ "heap_start": "0x9568",
+ "main_segment_total": 34152,
+ "map": "obj/simplefiles.map",
+ "name": "simplefiles",
+ "runtime_end": "0x9567",
+ "segments": {
+ "BSS": {
+ "end": "0x9567",
+ "size": 4397,
+ "start": "0x843B"
+ },
+ "CODE": {
+ "end": "0x7EED",
+ "size": 28347,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x83F8",
+ "size": 62,
+ "start": "0x83BB"
+ },
+ "INIT": {
+ "end": "0x8414",
+ "size": 28,
+ "start": "0x83F9"
+ },
+ "ONCE": {
+ "end": "0x843A",
+ "size": 38,
+ "start": "0x8415"
+ },
+ "RODATA": {
+ "end": "0x83BA",
+ "size": 1229,
+ "start": "0x7EEE"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 10012,
+ "bss_bytes": 2142,
+ "code_ro_init_bytes": 34712,
+ "data_bytes": 238,
+ "heap_capacity": 9900,
+ "heap_end": "0xC78F",
+ "heap_start": "0xA0E4",
+ "main_segment_total": 37092,
+ "map": "obj/simplecells.map",
+ "name": "simplecells",
+ "runtime_end": "0xA0E3",
+ "segments": {
+ "BSS": {
+ "end": "0xA0E3",
+ "size": 2142,
+ "start": "0x9886"
+ },
+ "CODE": {
+ "end": "0x909B",
+ "size": 32873,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x9843",
+ "size": 238,
+ "start": "0x9756"
+ },
+ "INIT": {
+ "end": "0x985F",
+ "size": 28,
+ "start": "0x9844"
+ },
+ "ONCE": {
+ "end": "0x9885",
+ "size": 38,
+ "start": "0x9860"
+ },
+ "RODATA": {
+ "end": "0x9755",
+ "size": 1722,
+ "start": "0x909C"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 29017,
+ "bss_bytes": 1203,
+ "code_ro_init_bytes": 16838,
+ "data_bytes": 46,
+ "heap_capacity": 28904,
+ "heap_end": "0xC78F",
+ "heap_start": "0x56A8",
+ "main_segment_total": 18087,
+ "map": "obj/game2048.map",
+ "name": "game2048",
+ "runtime_end": "0x56A6",
+ "segments": {
+ "BSS": {
+ "end": "0x56A6",
+ "size": 1203,
+ "start": "0x51F4"
+ },
+ "CODE": {
+ "end": "0x5053",
+ "size": 16417,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x51B1",
+ "size": 46,
+ "start": "0x5184"
+ },
+ "INIT": {
+ "end": "0x51CD",
+ "size": 28,
+ "start": "0x51B2"
+ },
+ "ONCE": {
+ "end": "0x51F3",
+ "size": 38,
+ "start": "0x51CE"
+ },
+ "RODATA": {
+ "end": "0x5183",
+ "size": 304,
+ "start": "0x5054"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 22604,
+ "bss_bytes": 4276,
+ "code_ro_init_bytes": 20178,
+ "data_bytes": 46,
+ "heap_capacity": 22492,
+ "heap_end": "0xC78F",
+ "heap_start": "0x6FB4",
+ "main_segment_total": 24500,
+ "map": "obj/deminer.map",
+ "name": "deminer",
+ "runtime_end": "0x6FB3",
+ "segments": {
+ "BSS": {
+ "end": "0x6FB3",
+ "size": 4276,
+ "start": "0x5F00"
+ },
+ "CODE": {
+ "end": "0x5BA4",
+ "size": 19314,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x5EBD",
+ "size": 46,
+ "start": "0x5E90"
+ },
+ "INIT": {
+ "end": "0x5ED9",
+ "size": 28,
+ "start": "0x5EBE"
+ },
+ "ONCE": {
+ "end": "0x5EFF",
+ "size": 38,
+ "start": "0x5EDA"
+ },
+ "RODATA": {
+ "end": "0x5E8F",
+ "size": 747,
+ "start": "0x5BA5"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 30653,
+ "bss_bytes": 908,
+ "code_ro_init_bytes": 15457,
+ "data_bytes": 86,
+ "heap_capacity": 30540,
+ "heap_end": "0xC78F",
+ "heap_start": "0x5044",
+ "main_segment_total": 16451,
+ "map": "obj/sidetris.map",
+ "name": "sidetris",
+ "runtime_end": "0x5042",
+ "segments": {
+ "BSS": {
+ "end": "0x5042",
+ "size": 908,
+ "start": "0x4CB7"
+ },
+ "CODE": {
+ "end": "0x481B",
+ "size": 14313,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x4C74",
+ "size": 86,
+ "start": "0x4C1F"
+ },
+ "INIT": {
+ "end": "0x4C90",
+ "size": 28,
+ "start": "0x4C75"
+ },
+ "ONCE": {
+ "end": "0x4CB6",
+ "size": 38,
+ "start": "0x4C91"
+ },
+ "RODATA": {
+ "end": "0x4C1E",
+ "size": 1027,
+ "start": "0x481C"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 9685,
+ "bss_bytes": 4803,
+ "code_ro_init_bytes": 32292,
+ "data_bytes": 324,
+ "heap_capacity": 9572,
+ "heap_end": "0xC78F",
+ "heap_start": "0xA22C",
+ "main_segment_total": 37419,
+ "map": "obj/cal26.map",
+ "name": "cal26",
+ "runtime_end": "0xA22A",
+ "segments": {
+ "BSS": {
+ "end": "0xA22A",
+ "size": 4803,
+ "start": "0x8F68"
+ },
+ "CODE": {
+ "end": "0x8694",
+ "size": 30306,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x8F25",
+ "size": 324,
+ "start": "0x8DE2"
+ },
+ "INIT": {
+ "end": "0x8F41",
+ "size": 28,
+ "start": "0x8F26"
+ },
+ "ONCE": {
+ "end": "0x8F67",
+ "size": 38,
+ "start": "0x8F42"
+ },
+ "RODATA": {
+ "end": "0x8DE1",
+ "size": 1869,
+ "start": "0x8695"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 2092,
+ "bss_bytes": 6327,
+ "code_ro_init_bytes": 38553,
+ "data_bytes": 132,
+ "heap_capacity": 1980,
+ "heap_end": "0xC78F",
+ "heap_start": "0xBFD4",
+ "main_segment_total": 45012,
+ "map": "obj/dizzy.map",
+ "name": "dizzy",
+ "runtime_end": "0xBFD3",
+ "segments": {
+ "BSS": {
+ "end": "0xBFD3",
+ "size": 6327,
+ "start": "0xA71D"
+ },
+ "CODE": {
+ "end": "0xA18D",
+ "size": 37211,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0xA6DA",
+ "size": 132,
+ "start": "0xA657"
+ },
+ "INIT": {
+ "end": "0xA6F6",
+ "size": 28,
+ "start": "0xA6DB"
+ },
+ "ONCE": {
+ "end": "0xA71C",
+ "size": 38,
+ "start": "0xA6F7"
+ },
+ "RODATA": {
+ "end": "0xA656",
+ "size": 1225,
+ "start": "0xA18E"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 19824,
+ "bss_bytes": 5351,
+ "code_ro_init_bytes": 21882,
+ "data_bytes": 47,
+ "heap_capacity": 19712,
+ "heap_end": "0xC78F",
+ "heap_start": "0x7A90",
+ "main_segment_total": 27280,
+ "map": "obj/readyirc.map",
+ "name": "readyirc",
+ "runtime_end": "0x7A8F",
+ "segments": {
+ "BSS": {
+ "end": "0x7A8F",
+ "size": 5351,
+ "start": "0x65A9"
+ },
+ "CODE": {
+ "end": "0x619B",
+ "size": 20841,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x6566",
+ "size": 47,
+ "start": "0x6538"
+ },
+ "INIT": {
+ "end": "0x6582",
+ "size": 28,
+ "start": "0x6567"
+ },
+ "ONCE": {
+ "end": "0x65A8",
+ "size": 38,
+ "start": "0x6583"
+ },
+ "RODATA": {
+ "end": "0x6537",
+ "size": 924,
+ "start": "0x619C"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 18690,
+ "bss_bytes": 6909,
+ "code_ro_init_bytes": 21278,
+ "data_bytes": 227,
+ "heap_capacity": 18578,
+ "heap_end": "0xC78F",
+ "heap_start": "0x7EFE",
+ "main_segment_total": 28414,
+ "map": "obj/rirc-rrnet.map",
+ "name": "rirc-rrnet",
+ "runtime_end": "0x7EFD",
+ "segments": {
+ "BSS": {
+ "end": "0x7EFD",
+ "size": 6909,
+ "start": "0x6401"
+ },
+ "CODE": {
+ "end": "0x5FFD",
+ "size": 20427,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x63BE",
+ "size": 227,
+ "start": "0x62DC"
+ },
+ "INIT": {
+ "end": "0x63DA",
+ "size": 28,
+ "start": "0x63BF"
+ },
+ "ONCE": {
+ "end": "0x6400",
+ "size": 38,
+ "start": "0x63DB"
+ },
+ "RODATA": {
+ "end": "0x62DB",
+ "size": 734,
+ "start": "0x5FFE"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 1537,
+ "bss_bytes": 0,
+ "code_ro_init_bytes": 9290,
+ "data_bytes": 0,
+ "main_segment_total": 2954,
+ "map": "obj/readybasic.map",
+ "name": "readybasic",
+ "runtime_end": "0xC1FE",
+ "segments": {
+ "BRIDGE": {
+ "end": "0xC1FE",
+ "size": 511,
+ "start": "0xC000"
+ },
+ "ENTRY": {
+ "end": "0x11FF",
+ "size": 512,
+ "start": "0x1000"
+ },
+ "HIDDEN": {
+ "end": "0xA78A",
+ "size": 1931,
+ "start": "0xA000"
+ }
+ }
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 21805,
+ "bss_bytes": 2708,
+ "code_ro_init_bytes": 22520,
+ "data_bytes": 71,
+ "heap_capacity": 21692,
+ "heap_end": "0xC78F",
+ "heap_start": "0x72D4",
+ "main_segment_total": 25299,
+ "map": "obj/ucitest.map",
+ "name": "ucitest",
+ "runtime_end": "0x72D2",
+ "segments": {
+ "BSS": {
+ "end": "0x72D2",
+ "size": 2708,
+ "start": "0x683F"
+ },
+ "CODE": {
+ "end": "0x5933",
+ "size": 18689,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x67FC",
+ "size": 71,
+ "start": "0x67B6"
+ },
+ "INIT": {
+ "end": "0x6818",
+ "size": 28,
+ "start": "0x67FD"
+ },
+ "ONCE": {
+ "end": "0x683E",
+ "size": 38,
+ "start": "0x6819"
+ },
+ "RODATA": {
+ "end": "0x67B5",
+ "size": 3714,
+ "start": "0x5934"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 22905,
+ "bss_bytes": 48,
+ "code_ro_init_bytes": 24105,
+ "data_bytes": 46,
+ "heap_capacity": 22792,
+ "heap_end": "0xC78F",
+ "heap_start": "0x6E88",
+ "main_segment_total": 24199,
+ "map": "obj/readme.map",
+ "name": "readme",
+ "runtime_end": "0x6E86",
+ "segments": {
+ "BSS": {
+ "end": "0x6E86",
+ "size": 48,
+ "start": "0x6E57"
+ },
+ "CODE": {
+ "end": "0x392E",
+ "size": 10492,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x6E14",
+ "size": 46,
+ "start": "0x6DE7"
+ },
+ "INIT": {
+ "end": "0x6E30",
+ "size": 28,
+ "start": "0x6E15"
+ },
+ "ONCE": {
+ "end": "0x6E56",
+ "size": 38,
+ "start": "0x6E31"
+ },
+ "RODATA": {
+ "end": "0x6DE6",
+ "size": 13496,
+ "start": "0x392F"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 18539,
+ "bss_bytes": 426,
+ "code_ro_init_bytes": 28069,
+ "data_bytes": 70,
+ "heap_capacity": 3688,
+ "main_segment_total": 28565,
+ "map": "obj/readyshell.map",
+ "name": "readyshell",
+ "readyshell": {
+ "heap_end": "0x8DFD",
+ "heap_size": 3688,
+ "heap_start": "0x7F96",
+ "himem": "0xC600",
+ "overlay_loadaddr": "0x8DFE",
+ "overlay_start": "0x8E00",
+ "overlay_window": 14336
+ },
+ "runtime_end": "0x7F94",
+ "segments": {
+ "BSS": {
+ "end": "0x7F94",
+ "size": 426,
+ "start": "0x7DEB"
+ },
+ "CODE": {
+ "end": "0x795E",
+ "size": 26924,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x7D96",
+ "size": 70,
+ "start": "0x7D51"
+ },
+ "INIT": {
+ "end": "0x7DB2",
+ "size": 28,
+ "start": "0x7D97"
+ },
+ "ONCE": {
+ "end": "0x7DEA",
+ "size": 56,
+ "start": "0x7DB3"
+ },
+ "RODATA": {
+ "end": "0x7D50",
+ "size": 1010,
+ "start": "0x795F"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ }
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 18143,
+ "bss_bytes": 1978,
+ "code_ro_init_bytes": 26933,
+ "data_bytes": 50,
+ "heap_capacity": 18030,
+ "heap_end": "0xC78F",
+ "heap_start": "0x8122",
+ "main_segment_total": 28961,
+ "map": "obj/launcher_easyflash.map",
+ "name": "launcher_easyflash",
+ "runtime_end": "0x8120",
+ "segments": {
+ "BSS": {
+ "end": "0x8120",
+ "size": 1978,
+ "start": "0x7967"
+ },
+ "CODE": {
+ "end": "0x70AD",
+ "size": 24699,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x7924",
+ "size": 50,
+ "start": "0x78F3"
+ },
+ "INIT": {
+ "end": "0x7940",
+ "size": 28,
+ "start": "0x7925"
+ },
+ "ONCE": {
+ "end": "0x7966",
+ "size": 38,
+ "start": "0x7941"
+ },
+ "RODATA": {
+ "end": "0x78F2",
+ "size": 2117,
+ "start": "0x70AE"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 18641,
+ "bss_bytes": 426,
+ "code_ro_init_bytes": 27967,
+ "data_bytes": 70,
+ "heap_capacity": 3790,
+ "main_segment_total": 28463,
+ "map": "obj/readyshell_easyflash.map",
+ "name": "readyshell_easyflash",
+ "readyshell": {
+ "heap_end": "0x8DFD",
+ "heap_size": 3790,
+ "heap_start": "0x7F30",
+ "himem": "0xC600",
+ "overlay_loadaddr": "0x8DFE",
+ "overlay_start": "0x8E00",
+ "overlay_window": 14336
+ },
+ "runtime_end": "0x7F2E",
+ "segments": {
+ "BSS": {
+ "end": "0x7F2E",
+ "size": 426,
+ "start": "0x7D85"
+ },
+ "CODE": {
+ "end": "0x78F8",
+ "size": 26822,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x7D30",
+ "size": 70,
+ "start": "0x7CEB"
+ },
+ "INIT": {
+ "end": "0x7D4C",
+ "size": 28,
+ "start": "0x7D31"
+ },
+ "ONCE": {
+ "end": "0x7D84",
+ "size": 56,
+ "start": "0x7D4D"
+ },
+ "RODATA": {
+ "end": "0x7CEA",
+ "size": 1010,
+ "start": "0x78F9"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ }
+ }
+ ]
+}
diff --git a/agentworking/readyos-1kb-shim-skip-bank/headroom_comparison.md b/agentworking/readyos-1kb-shim-skip-bank/headroom_comparison.md
new file mode 100644
index 0000000..fc3a327
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/headroom_comparison.md
@@ -0,0 +1,35 @@
+# ReadyOS Bank Refactor Memory Comparison
+
+Generated from linker maps before and after the schema-v5 ReadyOS-bank refactor.
+Positive headroom/heap deltas mean more free C64 RAM; negative code/data/BSS deltas mean smaller linked segments.
+
+| App/map | Code/RO/init before | after | delta | Data before | after | delta | BSS before | after | delta | Heap before | after | delta | Window headroom before | after | delta |
+| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
+| launcher | 39301 | 39295 | -6 | 50 | 50 | 0 | 2509 | 2509 | 0 | 5132 | 4626 | -506 | 5244 | 4738 | -506 |
+| editor | 24384 | 24384 | 0 | 134 | 134 | 0 | 9880 | 9880 | 0 | 12594 | 12082 | -512 | 12706 | 12194 | -512 |
+| quicknotes | 31031 | 31031 | 0 | 222 | 222 | 0 | 6047 | 6047 | 0 | 9692 | 9180 | -512 | 9804 | 9292 | -512 |
+| calcplus | 37363 | 37363 | 0 | 158 | 158 | 0 | 1321 | 1321 | 0 | 8150 | 7638 | -512 | 8262 | 7750 | -512 |
+| hexview | 12793 | 12793 | 0 | 46 | 46 | 0 | 101 | 101 | 0 | 34052 | 33540 | -512 | 34164 | 33652 | -512 |
+| clipmgr | 30847 | 30847 | 0 | 46 | 46 | 0 | 1062 | 1062 | 0 | 15036 | 14524 | -512 | 15149 | 14637 | -512 |
+| reuviewer | 15109 | 15105 | -4 | 46 | 46 | 0 | 221 | 221 | 0 | 31616 | 31108 | -508 | 31728 | 31220 | -508 |
+| sysinfo | 16184 | 16184 | 0 | 47 | 47 | 0 | 277 | 277 | 0 | 30484 | 29972 | -512 | 30596 | 30084 | -512 |
+| tasklist | 31116 | 31116 | 0 | 151 | 151 | 0 | 8927 | 8927 | 0 | 6798 | 6286 | -512 | 6910 | 6398 | -512 |
+| simplefiles | 29693 | 29693 | 0 | 62 | 62 | 0 | 4397 | 4397 | 0 | 12840 | 12328 | -512 | 12952 | 12440 | -512 |
+| simplecells | 34712 | 34712 | 0 | 238 | 238 | 0 | 2142 | 2142 | 0 | 9900 | 9388 | -512 | 10012 | 9500 | -512 |
+| game2048 | 16838 | 16838 | 0 | 46 | 46 | 0 | 1203 | 1203 | 0 | 28904 | 28392 | -512 | 29017 | 28505 | -512 |
+| deminer | 20178 | 20178 | 0 | 46 | 46 | 0 | 4276 | 4276 | 0 | 22492 | 21980 | -512 | 22604 | 22092 | -512 |
+| sidetris | 15457 | 15457 | 0 | 86 | 86 | 0 | 908 | 908 | 0 | 30540 | 30028 | -512 | 30653 | 30141 | -512 |
+| cal26 | 32292 | 32292 | 0 | 324 | 324 | 0 | 4803 | 4803 | 0 | 9572 | 9060 | -512 | 9685 | 9173 | -512 |
+| dizzy | 38553 | 38553 | 0 | 132 | 132 | 0 | 6327 | 6327 | 0 | 1980 | 1468 | -512 | 2092 | 1580 | -512 |
+| readyirc | 21882 | 21882 | 0 | 47 | 47 | 0 | 5351 | 5351 | 0 | 19712 | 19200 | -512 | 19824 | 19312 | -512 |
+| rirc-rrnet | 21278 | 21278 | 0 | 227 | 227 | 0 | 6909 | 6909 | 0 | 18578 | 18066 | -512 | 18690 | 18178 | -512 |
+| readybasic | 9290 | 9290 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | — | — | — | 1537 | 1025 | -512 |
+| ucitest | 22520 | 22520 | 0 | 71 | 71 | 0 | 2708 | 2708 | 0 | 21692 | 21180 | -512 | 21805 | 21293 | -512 |
+| readme | 24105 | 24105 | 0 | 46 | 46 | 0 | 48 | 48 | 0 | 22792 | 22280 | -512 | 22905 | 22393 | -512 |
+| readyshell | 28069 | 28069 | 0 | 70 | 70 | 0 | 426 | 426 | 0 | 3688 | 3688 | 0 | 18539 | 18027 | -512 |
+| launcher_easyflash | 26933 | 26927 | -6 | 50 | 50 | 0 | 1978 | 1978 | 0 | 18030 | 17524 | -506 | 18143 | 17637 | -506 |
+| readyshell_easyflash | 27967 | 27967 | 0 | 70 | 70 | 0 | 426 | 426 | 0 | 3790 | 3790 | 0 | 18641 | 18129 | -512 |
+
+Before snapshot end: `0xC7FF`. After snapshot end: `0xC5FF`.
+ReadyBASIC has no conventional cc65 BSS/heap: its custom assembler/linker budget is enforced separately by `verify_readybasic_plugin.py`.
+ReadyShell heap is bounded by its unchanged overlay load address; the full snapshot ends at `$C5FF` before the 1 KB resident shim.
diff --git a/agentworking/readyos-1kb-shim-skip-bank/reuviewer_fix_easyflash.yaml b/agentworking/readyos-1kb-shim-skip-bank/reuviewer_fix_easyflash.yaml
new file mode 100644
index 0000000..7888cf3
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/reuviewer_fix_easyflash.yaml
@@ -0,0 +1,413 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_reuviewer_f2_chain_probe_easyflash
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ cart_crt: "Releases/0.2.5/precog-easyflash/readyos_easyflash.crt"
+ autostart_enabled: false
+ disk8: "agentworking/easyflash_full_vice_plans/readyos_data.easyflash-vice.d64"
+ drive8_enabled: true
+ drive8_type: 1541
+ drive9_enabled: false
+ true_drive: true
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_launcher_initial
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ pre_delay_s: 4
+ poll_s: 0.5
+ wait_timeout_s: 420
+ capture_label: chain_launcher_initial
+ - id: launch_readybasic_from_launcher
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_initial
+ type: screen.wait_contains
+ params:
+ text: "READY."
+ wait_timeout_s: 120
+ capture_label: chain_readybasic_initial
+ - id: assert_readybasic_bank_initial
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "05"
+ - id: assert_chrin_vector_initial
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "08 12"
+ - id: assert_keylog_vector_initial
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "7E C1"
+ - id: readybasic_first_type
+ type: input.sequence
+ params:
+ keys: [81,37,61,49,48,49,58,80,82,73,78,84,32,34,67,72,65,73,78,49,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_first_type
+ type: assert.screen
+ params:
+ contains: "CHAIN1 101"
+ - id: readybasic_ctrl_b_1_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 4C 74 A4"
+ - id: readybasic_ctrl_b_1_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: readybasic_ctrl_b_1
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_launcher_after_readybasic_ctrl_b_1
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ pre_delay_s: 1.0
+ capture_label: chain_launcher_after_rb_ctrl_b_1
+ - id: assert_launcher_bank_after_ctrl_b_1
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "00"
+ - id: reenter_readybasic_1
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
+ - id: capture_readybasic_reentry_1
+ type: screen.capture
+ params:
+ label: chain_readybasic_reentry_1
+ pitch: warm ReadyBASIC entry evidence; bank/vector assertions and typed sentinel prove keyboard liveness
+ - id: assert_readybasic_bank_reentry_1
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "05"
+ - id: readybasic_second_type
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,67,72,65,73,78,50,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_second_type
+ type: assert.screen
+ params:
+ contains: "CHAIN2 101"
+ - id: readybasic_ctrl_b_2_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 4C 74 A4"
+ - id: readybasic_ctrl_b_2_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: readybasic_ctrl_b_2
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_launcher_after_readybasic_ctrl_b_2
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ pre_delay_s: 1.0
+ capture_label: chain_launcher_after_rb_ctrl_b_2
+ - id: launch_reuviewer_from_readybasic_position
+ type: input.sequence
+ params:
+ keys: [17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_reuviewer
+ type: screen.wait_contains
+ params:
+ text: "REU MEMORY"
+ wait_timeout_s: 90
+ capture_label: chain_reuviewer_loaded
+ - id: assert_reuviewer_bank
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "08"
+ - id: stage_readyos_token_status_for_readybasic_reuviewer_chain
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "00 00 00 00 00 07 00 00 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
+ - id: configure_readyos_token_status_dma_for_readybasic_reuviewer_chain
+ type: memory.write
+ params:
+ start: 57090
+ bytes_hex: "3C 03 40 B8 20 18 00"
+ - id: commit_readyos_token_status_for_readybasic_reuviewer_chain
+ type: memory.write
+ params:
+ start: 57089
+ bytes_hex: "90"
+ - id: reuviewer_f2_to_readybasic
+ type: input.sequence
+ params:
+ keys: [137]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.2
+ - id: capture_readybasic_after_reuviewer_f2
+ type: screen.capture
+ params:
+ label: chain_readybasic_after_reuviewer_f2
+ pitch: warm ReadyBASIC entry evidence; bank/vector assertions and typed sentinel prove keyboard liveness
+ - id: assert_readybasic_bank_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "05"
+ - id: assert_chrin_vector_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "08 12"
+ - id: assert_keylog_vector_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "7E C1"
+ - id: assert_keyboard_buffer_empty_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: wait_readybasic_stable_after_reuviewer_f2
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: chain_readybasic_stable_after_reuviewer_f2
+ - id: assert_readybasic_bank_stable_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "05"
+ - id: assert_keyboard_buffer_empty_stable_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: readybasic_type_after_reuviewer_f2
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,67,72,65,73,78,51,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_type_after_reuviewer_f2
+ type: assert.screen
+ params:
+ contains: "CHAIN3 101"
+ - id: readybasic_f2_back_to_reuviewer_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 4C 74 A4"
+ - id: readybasic_f2_back_to_reuviewer_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: readybasic_f2_back_to_reuviewer
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_reuviewer_after_readybasic_f2
+ type: screen.wait_contains
+ params:
+ text: "REU MEMORY"
+ wait_timeout_s: 80
+ pre_delay_s: 1.0
+ capture_label: chain_reuviewer_after_readybasic_f2
+ - id: assert_app_keylog_vector_restored_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "48 EB"
+ - id: assert_app_chrin_vector_restored_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "57 F1"
+ - id: assert_default_input_device_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 153
+ end: 153
+ equals_hex: "00"
+ - id: assert_reuviewer_bank_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "08"
+ - id: assert_keyboard_buffer_empty_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: wait_reuviewer_stable_after_readybasic_f2
+ type: screen.wait_contains
+ params:
+ text: "REU MEMORY"
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: chain_reuviewer_stable_after_readybasic_f2
+ - id: assert_reuviewer_bank_stable_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "08"
+ - id: assert_keyboard_buffer_empty_stable_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: reuviewer_ctrl_b_after_readybasic_f2
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
+ - id: capture_after_reuviewer_ctrl_b_input
+ type: screen.capture
+ params:
+ label: chain_after_reuviewer_ctrl_b_hotkey
+ pitch: capture after resumed REU Viewer Ctrl+B hotkey
+ - id: wait_launcher_after_reuviewer_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ capture_label: chain_launcher_after_reuviewer_ctrl_b
+ - id: assert_launcher_bank_after_reuviewer_ctrl_b
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "00"
+ - id: select_readybasic_after_reuviewer_ctrl_b
+ type: memory.write
+ params:
+ start: 51232
+ bytes_hex: "05"
+ - id: launch_readybasic_after_reuviewer_ctrl_b
+ type: monitor.command
+ params:
+ command: "raw:g c80f"
+ - id: capture_readybasic_after_reuviewer_ctrl_b_reentry
+ type: screen.capture
+ params:
+ label: chain_readybasic_after_reuviewer_ctrl_b_reentry
+ pitch: warm ReadyBASIC entry evidence; bank/vector assertions and typed sentinel prove keyboard liveness
+ - id: readybasic_type_after_reuviewer_ctrl_b_reentry
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,67,72,65,73,78,52,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_type_after_reuviewer_ctrl_b_reentry
+ type: assert.screen
+ params:
+ contains: "CHAIN4 101"
+ - id: readybasic_exit_after_multi_hop_reentry
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: wait_launcher_stable_after_readybasic_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ pre_delay_s: 2.0
+ capture_label: chain_launcher_stable_after_readybasic_exit
+ - id: assert_launcher_bank_after_readybasic_exit
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "00"
+ - id: assert_readybasic_not_auto_reentered_after_exit
+ type: assert.screen_not_contains
+ params:
+ not_contains: "ready."
+ - id: select_readybasic_after_exit_guard
+ type: memory.write
+ params:
+ start: 51232
+ bytes_hex: "05"
+ - id: reenter_readybasic_after_exit_guard
+ type: monitor.command
+ params:
+ command: "raw:g c80f"
+ - id: capture_readybasic_after_exit_guard_reentry
+ type: screen.capture
+ params:
+ label: chain_readybasic_after_exit_guard_reentry
+ pitch: warm ReadyBASIC entry evidence; bank/vector assertions and typed sentinel prove keyboard liveness
+ - id: readybasic_type_after_exit_guard_reentry
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,67,72,65,73,78,53,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_type_after_exit_guard_reentry
+ type: assert.screen
+ params:
+ contains: "CHAIN5 101"
diff --git a/agentworking/readyos-1kb-shim-skip-bank/reuviewer_fix_regular.yaml b/agentworking/readyos-1kb-shim-skip-bank/reuviewer_fix_regular.yaml
new file mode 100644
index 0000000..4d819d4
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/reuviewer_fix_regular.yaml
@@ -0,0 +1,410 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_reuviewer_f2_chain_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5t-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_launcher_initial
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 180
+ capture_label: chain_launcher_initial
+ - id: launch_readybasic_from_launcher
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_readybasic_initial
+ type: screen.wait_contains
+ params:
+ text: "READYBASIC"
+ wait_timeout_s: 120
+ capture_label: chain_readybasic_initial
+ - id: assert_readybasic_bank_initial
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "05"
+ - id: assert_chrin_vector_initial
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "08 12"
+ - id: assert_keylog_vector_initial
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "7E C1"
+ - id: readybasic_first_type
+ type: input.sequence
+ params:
+ keys: [81,37,61,49,48,49,58,80,82,73,78,84,32,34,67,72,65,73,78,49,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_first_type
+ type: assert.screen
+ params:
+ contains: "CHAIN1 101"
+ - id: readybasic_ctrl_b_1_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 4C 74 A4"
+ - id: readybasic_ctrl_b_1_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: readybasic_ctrl_b_1
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_launcher_after_readybasic_ctrl_b_1
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ pre_delay_s: 1.0
+ capture_label: chain_launcher_after_rb_ctrl_b_1
+ - id: assert_launcher_bank_after_ctrl_b_1
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "00"
+ - id: reenter_readybasic_1
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
+ - id: capture_readybasic_reentry_1
+ type: screen.capture
+ params:
+ label: chain_readybasic_reentry_1
+ pitch: warm ReadyBASIC entry evidence; bank/vector assertions and typed sentinel prove keyboard liveness
+ - id: assert_readybasic_bank_reentry_1
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "05"
+ - id: readybasic_second_type
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,67,72,65,73,78,50,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_second_type
+ type: assert.screen
+ params:
+ contains: "CHAIN2 101"
+ - id: readybasic_ctrl_b_2_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 4C 74 A4"
+ - id: readybasic_ctrl_b_2_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: readybasic_ctrl_b_2
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_launcher_after_readybasic_ctrl_b_2
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ pre_delay_s: 1.0
+ capture_label: chain_launcher_after_rb_ctrl_b_2
+ - id: launch_reuviewer_from_readybasic_position
+ type: input.sequence
+ params:
+ keys: [17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_reuviewer
+ type: screen.wait_contains
+ params:
+ text: "REU MEMORY"
+ wait_timeout_s: 90
+ capture_label: chain_reuviewer_loaded
+ - id: assert_reuviewer_bank
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "08"
+ - id: stage_readyos_token_status_for_readybasic_reuviewer_chain
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "00 00 00 00 00 07 00 00 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
+ - id: configure_readyos_token_status_dma_for_readybasic_reuviewer_chain
+ type: memory.write
+ params:
+ start: 57090
+ bytes_hex: "3C 03 40 B8 20 18 00"
+ - id: commit_readyos_token_status_for_readybasic_reuviewer_chain
+ type: memory.write
+ params:
+ start: 57089
+ bytes_hex: "90"
+ - id: reuviewer_f2_to_readybasic
+ type: input.sequence
+ params:
+ keys: [137]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.2
+ - id: capture_readybasic_after_reuviewer_f2
+ type: screen.capture
+ params:
+ label: chain_readybasic_after_reuviewer_f2
+ pitch: warm ReadyBASIC entry evidence; bank/vector assertions and typed sentinel prove keyboard liveness
+ - id: assert_readybasic_bank_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "05"
+ - id: assert_chrin_vector_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "08 12"
+ - id: assert_keylog_vector_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "7E C1"
+ - id: assert_keyboard_buffer_empty_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: wait_readybasic_stable_after_reuviewer_f2
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: chain_readybasic_stable_after_reuviewer_f2
+ - id: assert_readybasic_bank_stable_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "05"
+ - id: assert_keyboard_buffer_empty_stable_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: readybasic_type_after_reuviewer_f2
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,67,72,65,73,78,51,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_type_after_reuviewer_f2
+ type: assert.screen
+ params:
+ contains: "CHAIN3 101"
+ - id: readybasic_f2_back_to_reuviewer_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 4C 74 A4"
+ - id: readybasic_f2_back_to_reuviewer_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: readybasic_f2_back_to_reuviewer
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_reuviewer_after_readybasic_f2
+ type: screen.wait_contains
+ params:
+ text: "REU MEMORY"
+ wait_timeout_s: 80
+ pre_delay_s: 1.0
+ capture_label: chain_reuviewer_after_readybasic_f2
+ - id: assert_app_keylog_vector_restored_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "48 EB"
+ - id: assert_app_chrin_vector_restored_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "57 F1"
+ - id: assert_default_input_device_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 153
+ end: 153
+ equals_hex: "00"
+ - id: assert_reuviewer_bank_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "08"
+ - id: assert_keyboard_buffer_empty_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: wait_reuviewer_stable_after_readybasic_f2
+ type: screen.wait_contains
+ params:
+ text: "REU MEMORY"
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: chain_reuviewer_stable_after_readybasic_f2
+ - id: assert_reuviewer_bank_stable_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "08"
+ - id: assert_keyboard_buffer_empty_stable_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: reuviewer_ctrl_b_after_readybasic_f2
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
+ - id: capture_after_reuviewer_ctrl_b_input
+ type: screen.capture
+ params:
+ label: chain_after_reuviewer_ctrl_b_hotkey
+ pitch: capture after resumed REU Viewer Ctrl+B hotkey
+ - id: wait_launcher_after_reuviewer_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ capture_label: chain_launcher_after_reuviewer_ctrl_b
+ - id: assert_launcher_bank_after_reuviewer_ctrl_b
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "00"
+ - id: select_readybasic_after_reuviewer_ctrl_b
+ type: memory.write
+ params:
+ start: 51232
+ bytes_hex: "05"
+ - id: launch_readybasic_after_reuviewer_ctrl_b
+ type: monitor.command
+ params:
+ command: "raw:g c80f"
+ - id: capture_readybasic_after_reuviewer_ctrl_b_reentry
+ type: screen.capture
+ params:
+ label: chain_readybasic_after_reuviewer_ctrl_b_reentry
+ pitch: warm ReadyBASIC entry evidence; bank/vector assertions and typed sentinel prove keyboard liveness
+ - id: readybasic_type_after_reuviewer_ctrl_b_reentry
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,67,72,65,73,78,52,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_type_after_reuviewer_ctrl_b_reentry
+ type: assert.screen
+ params:
+ contains: "CHAIN4 101"
+ - id: readybasic_exit_after_multi_hop_reentry
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: wait_launcher_stable_after_readybasic_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ pre_delay_s: 2.0
+ capture_label: chain_launcher_stable_after_readybasic_exit
+ - id: assert_launcher_bank_after_readybasic_exit
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "00"
+ - id: assert_readybasic_not_auto_reentered_after_exit
+ type: assert.screen_not_contains
+ params:
+ not_contains: "ready."
+ - id: select_readybasic_after_exit_guard
+ type: memory.write
+ params:
+ start: 51232
+ bytes_hex: "05"
+ - id: reenter_readybasic_after_exit_guard
+ type: monitor.command
+ params:
+ command: "raw:g c80f"
+ - id: capture_readybasic_after_exit_guard_reentry
+ type: screen.capture
+ params:
+ label: chain_readybasic_after_exit_guard_reentry
+ pitch: warm ReadyBASIC entry evidence; bank/vector assertions and typed sentinel prove keyboard liveness
+ - id: readybasic_type_after_exit_guard_reentry
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,67,72,65,73,78,53,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_type_after_exit_guard_reentry
+ type: assert.screen
+ params:
+ contains: "CHAIN5 101"
diff --git a/agentworking/readyos-1kb-shim-skip-bank/run_c64u_dma_acceptance_retry2_terminal.sh b/agentworking/readyos-1kb-shim-skip-bank/run_c64u_dma_acceptance_retry2_terminal.sh
new file mode 100644
index 0000000..e2aaf08
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/run_c64u_dma_acceptance_retry2_terminal.sh
@@ -0,0 +1,65 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+repo="/Users/karlprosserpp/dev/c64projects/readyosprecog"
+d81="$repo/Releases/0.2.5/precog-d81/readyos-v0.2.5u-d81.d81"
+remote_name="r1k250802a.d81"
+root="$repo/agentworking/readyos-1kb-shim-skip-bank/c64u-dma-retry2"
+suite_status="$root/suite.status"
+suite_log="$root/suite.log"
+
+mkdir -p "$root"
+if [[ -e "$suite_status" || -e "$suite_log" ]]; then
+ printf 'refusing to overwrite retained retry2 suite artifacts: %s\n' "$root" >&2
+ exit 1
+fi
+printf '%s\n' RUNNING > "$suite_status"
+: > "$suite_log"
+
+on_exit() {
+ rc=$?
+ if [[ "$rc" -ne 0 ]]; then
+ printf 'FAIL rc=%s\n' "$rc" > "$suite_status"
+ fi
+}
+trap on_exit EXIT
+
+run_action() {
+ action="$1"
+ expected="$2"
+ out="$root/$action"
+ if [[ -e "$out" ]]; then
+ printf 'refusing to overwrite retained action artifacts: %s\n' "$out" >&2
+ return 1
+ fi
+ mkdir -p "$out"
+ printf 'START %s %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$action" | tee -a "$suite_log"
+ C64U_HOST="${C64U_HOST:-10.0.0.79}" \
+ C64U_REMOTE_DIR=USB1 \
+ C64U_SKIP_UPLOAD=1 \
+ C64U_MACHINE_REBOOT=1 \
+ READYOS_CLEAR_REU=1 \
+ READYOS_CLEAR_REU_BANKS=256 \
+ READYOS_EXPECT_DMA=1 \
+ READYOS_EXPECT_DMA_READY=1 \
+ READYOS_FAIL_ON_DISK_LOADING_WHEN_DMA=1 \
+ READYOS_BOOT_INITIAL_WAIT_S=90 \
+ READYOS_QUIET_AFTER_MANIFEST_OPEN_S=120 \
+ READYOS_MANIFEST_DIALOG_WAIT_S=240 \
+ READYOS_BOOT_ACTION="$action" \
+ /bin/bash "$repo/build_support/run_readyos_boot_c64u_rest.sh" \
+ "$d81" "$remote_name" "$out" >> "$suite_log" 2>&1
+ actual="$(tr -d '\r\n' < "$out/status")"
+ if [[ "$actual" != "$expected" ]]; then
+ printf 'STATUS MISMATCH %s expected=%s actual=%s\n' \
+ "$action" "$expected" "$actual" | tee -a "$suite_log"
+ return 1
+ fi
+ printf 'PASS %s %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$action" | tee -a "$suite_log"
+}
+
+run_action manifest-sidetris READYOS_MANIFEST_SIDETRIS_PASS
+run_action readybasic-load-selected READYOS_READYBASIC_LOAD_SELECTED_PASS
+
+printf '%s\n' PASS > "$suite_status"
+printf 'SUITE PASS %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" | tee -a "$suite_log"
diff --git a/agentworking/readyos-1kb-shim-skip-bank/run_c64u_dma_acceptance_retry_terminal.sh b/agentworking/readyos-1kb-shim-skip-bank/run_c64u_dma_acceptance_retry_terminal.sh
new file mode 100644
index 0000000..12d2265
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/run_c64u_dma_acceptance_retry_terminal.sh
@@ -0,0 +1,60 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+repo="/Users/karlprosserpp/dev/c64projects/readyosprecog"
+d81="$repo/Releases/0.2.5/precog-d81/readyos-v0.2.5u-d81.d81"
+remote_name="r1k250802a.d81"
+root="$repo/agentworking/readyos-1kb-shim-skip-bank/c64u-dma-retry"
+suite_status="$root/suite.status"
+suite_log="$root/suite.log"
+
+mkdir -p "$root"
+: > "$suite_log"
+printf '%s\n' RUNNING > "$suite_status"
+
+on_exit() {
+ rc=$?
+ if [ "$rc" -ne 0 ]; then
+ printf 'FAIL rc=%s\n' "$rc" > "$suite_status"
+ fi
+}
+trap on_exit EXIT
+
+run_action() {
+ action="$1"
+ expected="$2"
+ out="$root/$action"
+ if [ -e "$out" ]; then
+ printf 'refusing to overwrite retained retry artifacts: %s\n' "$out" >&2
+ return 1
+ fi
+ mkdir -p "$out"
+ printf 'START %s %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$action" | tee -a "$suite_log"
+ C64U_HOST="${C64U_HOST:-10.0.0.79}" \
+ C64U_REMOTE_DIR=USB1 \
+ C64U_SKIP_UPLOAD=1 \
+ C64U_MACHINE_REBOOT=1 \
+ READYOS_CLEAR_REU=1 \
+ READYOS_CLEAR_REU_BANKS=256 \
+ READYOS_EXPECT_DMA=1 \
+ READYOS_EXPECT_DMA_READY=1 \
+ READYOS_FAIL_ON_DISK_LOADING_WHEN_DMA=1 \
+ READYOS_BOOT_INITIAL_WAIT_S=90 \
+ READYOS_BOOT_ACTION="$action" \
+ /bin/bash "$repo/build_support/run_readyos_boot_c64u_rest.sh" \
+ "$d81" "$remote_name" "$out" >> "$suite_log" 2>&1
+ actual="$(tr -d '\r\n' < "$out/status")"
+ if [ "$actual" != "$expected" ]; then
+ printf 'STATUS MISMATCH %s expected=%s actual=%s\n' \
+ "$action" "$expected" "$actual" | tee -a "$suite_log"
+ return 1
+ fi
+ printf 'PASS %s %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$action" | tee -a "$suite_log"
+}
+
+run_action loadall-readyshell-overlay-smoke READYOS_LOADALL_READYSHELL_OVERLAY_PASS
+run_action manifest-sidetris READYOS_MANIFEST_SIDETRIS_PASS
+run_action readybasic-load-selected READYOS_READYBASIC_LOAD_SELECTED_PASS
+
+printf '%s\n' PASS > "$suite_status"
+printf 'SUITE PASS %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" | tee -a "$suite_log"
diff --git a/agentworking/readyos-1kb-shim-skip-bank/run_c64u_dma_acceptance_terminal.sh b/agentworking/readyos-1kb-shim-skip-bank/run_c64u_dma_acceptance_terminal.sh
new file mode 100644
index 0000000..b53697e
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/run_c64u_dma_acceptance_terminal.sh
@@ -0,0 +1,60 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+repo="/Users/karlprosserpp/dev/c64projects/readyosprecog"
+d81="$repo/Releases/0.2.5/precog-d81/readyos-v0.2.5u-d81.d81"
+remote_name="r1k250802a.d81"
+root="$repo/agentworking/readyos-1kb-shim-skip-bank/c64u-dma"
+suite_status="$root/suite.status"
+suite_log="$root/suite.log"
+
+mkdir -p "$root"
+: > "$suite_log"
+printf '%s\n' RUNNING > "$suite_status"
+
+on_exit() {
+ rc=$?
+ if [ "$rc" -ne 0 ]; then
+ printf 'FAIL rc=%s\n' "$rc" > "$suite_status"
+ fi
+}
+trap on_exit EXIT
+
+run_action() {
+ action="$1"
+ expected="$2"
+ skip_upload="$3"
+ out="$root/$action"
+ rm -rf "$out"
+ mkdir -p "$out"
+ printf 'START %s %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$action" | tee -a "$suite_log"
+ C64U_HOST="${C64U_HOST:-10.0.0.79}" \
+ C64U_REMOTE_DIR=USB1 \
+ C64U_SKIP_UPLOAD="$skip_upload" \
+ C64U_MACHINE_REBOOT=1 \
+ READYOS_CLEAR_REU=1 \
+ READYOS_CLEAR_REU_BANKS=256 \
+ READYOS_EXPECT_DMA=1 \
+ READYOS_EXPECT_DMA_READY=1 \
+ READYOS_FAIL_ON_DISK_LOADING_WHEN_DMA=1 \
+ READYOS_BOOT_INITIAL_WAIT_S=90 \
+ READYOS_BOOT_ACTION="$action" \
+ /bin/bash "$repo/build_support/run_readyos_boot_c64u_rest.sh" \
+ "$d81" "$remote_name" "$out" >> "$suite_log" 2>&1
+ actual="$(tr -d '\r\n' < "$out/status")"
+ if [ "$actual" != "$expected" ]; then
+ printf 'STATUS MISMATCH %s expected=%s actual=%s\n' \
+ "$action" "$expected" "$actual" | tee -a "$suite_log"
+ return 1
+ fi
+ printf 'PASS %s %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$action" | tee -a "$suite_log"
+}
+
+run_action editor-direct-dma-return READYOS_EDITOR_DIRECT_DMA_RETURN_PASS 0
+run_action editor-load-selected READYOS_EDITOR_LOAD_SELECTED_PASS 1
+run_action loadall-readyshell-overlay-smoke READYOS_LOADALL_READYSHELL_OVERLAY_PASS 1
+run_action manifest-sidetris READYOS_MANIFEST_SIDETRIS_PASS 1
+run_action readybasic-load-selected READYOS_READYBASIC_LOAD_SELECTED_PASS 1
+
+printf '%s\n' PASS > "$suite_status"
+printf 'SUITE PASS %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" | tee -a "$suite_log"
diff --git a/agentworking/readyos-1kb-shim-skip-bank/run_c64u_readybasic_retry3_terminal.sh b/agentworking/readyos-1kb-shim-skip-bank/run_c64u_readybasic_retry3_terminal.sh
new file mode 100644
index 0000000..b23ce43
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/run_c64u_readybasic_retry3_terminal.sh
@@ -0,0 +1,51 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+repo="/Users/karlprosserpp/dev/c64projects/readyosprecog"
+d81="$repo/Releases/0.2.5/precog-d81/readyos-v0.2.5u-d81.d81"
+remote_name="r1k250802a.d81"
+root="$repo/agentworking/readyos-1kb-shim-skip-bank/c64u-readybasic-retry3"
+status="$root/suite.status"
+log="$root/suite.log"
+out="$root/readybasic-load-selected"
+
+mkdir -p "$root"
+if [[ -e "$status" || -e "$log" || -e "$out" ]]; then
+ printf 'refusing to overwrite retained retry3 artifacts: %s\n' "$root" >&2
+ exit 1
+fi
+printf '%s\n' RUNNING > "$status"
+: > "$log"
+mkdir -p "$out"
+
+on_exit() {
+ rc=$?
+ if [[ "$rc" -ne 0 ]]; then
+ printf 'FAIL rc=%s\n' "$rc" > "$status"
+ fi
+}
+trap on_exit EXIT
+
+C64U_HOST="${C64U_HOST:-10.0.0.79}" \
+C64U_REMOTE_DIR=USB1 \
+C64U_SKIP_UPLOAD=1 \
+C64U_MACHINE_REBOOT=1 \
+READYOS_CLEAR_REU=1 \
+READYOS_CLEAR_REU_BANKS=256 \
+READYOS_EXPECT_DMA=1 \
+READYOS_EXPECT_DMA_READY=1 \
+READYOS_FAIL_ON_DISK_LOADING_WHEN_DMA=1 \
+READYOS_BOOT_INITIAL_WAIT_S=120 \
+READYOS_BOOT_ACTION=readybasic-load-selected \
+ /bin/bash "$repo/build_support/run_readyos_boot_c64u_rest.sh" \
+ "$d81" "$remote_name" "$out" >> "$log" 2>&1
+
+actual="$(tr -d '\r\n' < "$out/status")"
+if [[ "$actual" != READYOS_READYBASIC_LOAD_SELECTED_PASS ]]; then
+ printf 'STATUS MISMATCH expected=%s actual=%s\n' \
+ READYOS_READYBASIC_LOAD_SELECTED_PASS "$actual" >> "$log"
+ exit 1
+fi
+
+printf '%s\n' PASS > "$status"
+printf 'SUITE PASS %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$log"
diff --git a/agentworking/readyos-1kb-shim-skip-bank/run_c64u_readyirc_w_terminal.sh b/agentworking/readyos-1kb-shim-skip-bank/run_c64u_readyirc_w_terminal.sh
new file mode 100644
index 0000000..f162a92
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/run_c64u_readyirc_w_terminal.sh
@@ -0,0 +1,37 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+repo="/Users/karlprosserpp/dev/c64projects/readyosprecog"
+d81="$repo/Releases/0.2.5/precog-d81/readyos-v0.2.5w-d81.d81"
+root="$repo/agentworking/readyos-1kb-shim-skip-bank/c64u-readyirc-w"
+status="$root/suite.status"
+log="$root/suite.log"
+
+if [[ ! -f "$d81" ]]; then
+ printf 'missing DMA-enabled ReadyIRC test image: %s\n' "$d81" >&2
+ exit 1
+fi
+if [[ -e "$root" ]]; then
+ printf 'refusing to overwrite retained ReadyIRC artifacts: %s\n' "$root" >&2
+ exit 1
+fi
+mkdir -p "$root"
+printf '%s\n' RUNNING > "$status"
+: > "$log"
+
+on_exit() {
+ rc=$?
+ if [[ "$rc" -ne 0 ]]; then
+ printf 'FAIL rc=%s\n' "$rc" > "$status"
+ fi
+}
+trap on_exit EXIT
+
+READYIRC_C64U_SKIP_BUILD=1 \
+READYIRC_C64U_D81="$d81" \
+READYIRC_C64U_OUT_DIR="$root" \
+ /bin/bash "$repo/build_support/run_readyirc_c64u_suite.sh" \
+ >> "$log" 2>&1
+
+printf '%s\n' PASS > "$status"
+printf 'SUITE PASS %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$log"
diff --git a/agentworking/readyos-1kb-shim-skip-bank/run_c64u_readyshell_acceptance_terminal.sh b/agentworking/readyos-1kb-shim-skip-bank/run_c64u_readyshell_acceptance_terminal.sh
new file mode 100644
index 0000000..0d32177
--- /dev/null
+++ b/agentworking/readyos-1kb-shim-skip-bank/run_c64u_readyshell_acceptance_terminal.sh
@@ -0,0 +1,44 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+repo="/Users/karlprosserpp/dev/c64projects/readyosprecog"
+d81="$repo/Releases/0.2.5/precog-d81/readyos-v0.2.5u-d81.d81"
+root="$repo/agentworking/readyos-1kb-shim-skip-bank/c64u-readyshell"
+status="$root/suite.status"
+
+mkdir -p "$root"
+printf '%s\n' RUNNING > "$status"
+
+on_exit() {
+ rc=$?
+ if [ "$rc" -ne 0 ]; then
+ printf 'FAIL rc=%s\n' "$rc" > "$status"
+ fi
+}
+trap on_exit EXIT
+
+# The prior generic acceptance leaves the uniquely named D81 mounted. Clear all
+# physical REU banks without replacing or remounting that image.
+C64U_HOST="${C64U_HOST:-10.0.0.79}" \
+C64U_SKIP_UPLOAD=1 \
+C64U_SKIP_CONFIG=1 \
+READYOS_CLEAR_REU=1 \
+READYOS_CLEAR_REU_BANKS=256 \
+READYOS_CLEAR_REU_ONLY=1 \
+ /bin/bash "$repo/build_support/run_readyos_boot_c64u_rest.sh" \
+ "$d81" r1k250802a.d81 "$root/reu-clear" > "$root/reu-clear.log" 2>&1
+
+READYSHELL_C64U_SKIP_BUILD=1 \
+READYSHELL_C64U_D81="$d81" \
+C64U_HOST="${C64U_HOST:-10.0.0.79}" \
+C64U_REMOTE_ROOT=USB1 \
+C64U_REMOTE_D81=r1k250802a.d81 \
+C64U_IMAGE_PATH_CONFIG=/usb1/r1k250802a.d81 \
+READYSHELL_C64U_PREMOUNT_REST=0 \
+READYSHELL_C64U_ASSUME_MOUNTED=1 \
+READYSHELL_C64U_PLAN="$root/readyshell_cross_app_resume_c64u.generated.yaml" \
+READYSHELL_C64U_CONFIG_SRC="$root/readyshell_cross_app_resume_c64u.generated.ini" \
+ /bin/bash "$repo/build_support/run_readyshell_cross_app_resume_c64u.sh" \
+ > "$root/run.log" 2>&1
+
+printf '%s\n' PASS > "$status"
diff --git a/agentworking/readyos-bank-refactor/IMPLEMENTATION_LOG.md b/agentworking/readyos-bank-refactor/IMPLEMENTATION_LOG.md
new file mode 100644
index 0000000..0ed88ca
--- /dev/null
+++ b/agentworking/readyos-bank-refactor/IMPLEMENTATION_LOG.md
@@ -0,0 +1,94 @@
+# ReadyOS Bank Refactor Implementation Log
+
+> **Historical checkpoint, superseded 2026-08-02.** Entries below intentionally
+> preserve the prior `$B800` snapshot, 512-byte shim, and `Skip+1` ReadyOS-bank
+> implementation history. Current authority is the 1 KB shim, `$B600`
+> snapshot, ReadyOS bank at `Skip`, and dynamic pool at `Skip+1`.
+
+## 2026-08-01 - baseline and architecture lock
+
+- Preserved the dirty worktree and ran baseline builds/tests in an isolated
+ source copy.
+- Confirmed the current split:
+ - physical `Skip`: schema-v4 global/control bank;
+ - physical `Skip+1`: launcher snapshot;
+ - `$C600-$C6FF`: resident physical allocation/type table;
+ - `$C700`: resident magic and additional shared state;
+ - `$C836-$C838`: 24-bit loaded snapshot bitmap;
+ - `$C83B`: configured skip value used by arithmetic mapping.
+- Locked the replacement: `Skip+1` becomes the combined launcher/metadata
+ ReadyOS bank, `Skip` becomes allocatable, and token mappings become explicit.
+
+## 2026-08-01 - schema v5 implementation and documentation
+
+- Expanded every normal app snapshot to `$1000-$C7FF` (`$B800`) and moved the
+ resume tail to `$B800-$FFFF` (`$4800`).
+- Implemented the combined physical `Skip+1` ReadyOS bank and direct REU access
+ for mapping, status, allocation types, clipboard metadata, hotkeys, app and
+ resource registries, dependency lines, catalog text, audit, and runtime data.
+- Reworked the exact 512-byte shim to resolve nonzero tokens through `$B940`
+ and commit loaded/resumable status through `$BA40`; token 0 resolves directly
+ to the ReadyOS bank stored at `$C83B`.
+- Updated launcher, EasyFlash, ReadyShell, ReadyBASIC, REU Viewer, owned
+ allocation, TUI, clipboard, and resume users. Retired monolithic micromodule
+ sources remain in-tree but are compile-disabled and labeled.
+- Removed the obsolete EasyFlash shim-bitmap writer. EasyFlash loader-only
+ overlay metadata and debug staging now use `$CB20-$CB83`, outside the app
+ snapshot and shim, before authoritative data is committed to REU.
+- Added exhaustive Markdown/HTML status classification, canonical shim-source
+ appendix synchronization, and exact HTML byte verification.
+- `/bin/bash ./run.sh --build-all` passed for build `0.2.5D`, including all disk
+ profiles, 1MB KFF2, and EasyFlash after the final loader cleanup.
+
+## 2026-08-02 - runtime hardening and micromodule size lock
+
+- Fixed the launcher catalog scratch-pointer lifetime: token/snapshot
+ publication can reuse the catalog scratch area, so the filename is now
+ acquired only after allocation and reacquired for DMA fallback.
+- Restored launcher selection only after the ReadyOS-bank registry has been
+ reconstructed and bounds-checked. Token 0 warm state remains a compact
+ 128-byte UI payload at ReadyOS-bank offset `$FE40`.
+- Replaced duplicated TUI ReadyOS-byte DMA code in full REU clients with the
+ two six-byte tail-jump entry points in `tui_readyos_alias.s`. The unique
+ basename is intentional: an earlier same-basename `.c`/`.s` pair allowed
+ GNU Make to regenerate and remove the assembler as an intermediate.
+- Retained the safe C adapter and the lightweight standalone implementation as
+ documented, compile-selected alternatives. Full REU clients use the alias;
+ SysInfo and UCITest use the standalone no-BSS implementation.
+- The final linker-map comparison records 87-88 bytes recovered per relevant
+ full client. Launcher heap/headroom is now 5,132/5,244 bytes; ReadyShell
+ heap/full-window headroom is 3,688/18,539 bytes after the obsolete RAM debug
+ mirror was also removed.
+- Hardened launcher and ReadyShell cross-app automation by clearing the KERNAL
+ keyboard count and using VICE text-monitor `keybuf` for the lone RETURN that
+ the binary-monitor helper could drop after a dump or app return.
+- Retired five unused preload trace stores to app RAM `$C007-$C00C` and made
+ reserved ABI entry `$C812` jump to the safe `$C9FF` `RTS`. The shim stays
+ exactly 512 bytes and now has 129 verifier-enforced zero code-padding bytes,
+ including a new 42-byte contiguous run at `$C8B6-$C8DF`.
+- Removed ReadyShell's duplicate `$C7A0-$C7DF` / `$C7F0` diagnostic ring. Ring
+ contents and head now exist only in the loader-assigned ReadyShell state
+ bank; small live cursor/availability variables remain in BSS. This recovered
+ another 96 bytes of regular ReadyShell resident heap without changing BSS.
+
+## 2026-08-02 - aggregate completion and documentation lock
+
+- Expanded the ReadyBASIC aggregate to cover all 26 maintained runtime suites,
+ including screen-REU temporary storage, every graphics/sprite/sound phase,
+ loaded-app behavior, and the final visual verification suite.
+- Replaced remaining post-transition combined navigation/RETURN sequences with
+ deterministic keyboard-buffer or direct logical-token actions where the
+ harness had observable dropped-key races.
+- Updated the ReuViewer F2-chain harness for the schema-v5 source of truth: it
+ stages a 24-byte status image and DMA-writes it to ReadyOS-bank `$BA40`.
+ This both preserves the two-app chain scenario on all-preloaded EasyFlash and
+ proves the retired shim bitmap is no longer consulted.
+- Regenerated ReadyBASIC spatial memory diagrams and public/private ReadyShell
+ overlay inventories, rebuilt current Markdown-derived HTML, synchronized all
+ complete commented shim sources, and reclassified/verified every HTML file.
+- The retained memory comparison records per-app CODE/RO/init, DATA, BSS, heap,
+ and full-window headroom before and after. ReadyBASIC is explicitly treated
+ as a custom-assembler shape, not assigned fictional cc65 BSS/heap figures.
+- Completed every regular and EasyFlash runtime suite, all release builds,
+ static verifiers, host tests, HTML checks, whitespace checks, and the final
+ no-deletion audit.
diff --git a/agentworking/readyos-bank-refactor/STATE.md b/agentworking/readyos-bank-refactor/STATE.md
new file mode 100644
index 0000000..f0bebe6
--- /dev/null
+++ b/agentworking/readyos-bank-refactor/STATE.md
@@ -0,0 +1,75 @@
+# ReadyOS Bank Refactor State
+
+> **Historical checkpoint, superseded 2026-08-02.** This retained audit proves
+> the earlier 512-byte-shim/`Skip+1` design. The current contract reserves the
+> full 1 KB `$C600-$C9FF` shim, snapshots `$1000-$C5FF` (`$B600`), places the
+> ReadyOS bank at physical `Skip`, and begins dynamic allocation at `Skip+1`.
+> See `agentworking/readyos-1kb-shim-skip-bank/PLAN.md` and
+> `privatedocs/top_level_md/MEMORY_MAP.md`.
+
+This is the retained implementation audit for the refactor that makes physical
+REU bank `Skip+1` the ReadyOS bank and removes the `$C600-$C7FF` resident
+metadata mirror.
+
+## Required end state
+
+- `Skip+1` is the single authoritative ReadyOS metadata bank.
+- Launcher state and the ReadyOS schema share that bank.
+- App snapshots cover `$1000-$C7FF` (`$B800` bytes).
+- The shim remains exactly `$0200` bytes at `$C800-$C9FF`.
+- App/micromodule code does not retain a second allocation, loaded-app, token,
+ resource, or clipboard metadata source in C64 RAM.
+- ReadyBASIC's custom assembler consumes generated ABI constants and verifies
+ the ReadyBASIC binary shape it depends upon.
+- No tracked or untracked file that existed at the start of the refactor is
+ deleted.
+
+## Starting worktree
+
+- 1,396 tracked files.
+- The tree was already dirty with documentation, generated binaries, generated
+ version files, and schema-v4 documentation work.
+- Three tracked release artifacts were already deleted and must be restored,
+ while their untracked `0.2.5d` replacements must also be preserved:
+ - `Releases/0.2.5/precog-d81/readyos-v0.2.5y-d81-boot.prg`
+ - `Releases/0.2.5/precog-d81/readyos-v0.2.5y-d81-preboot.prg`
+ - `Releases/0.2.5/precog-d81/readyos-v0.2.5y-d81.d81`
+
+## Baseline verification
+
+- `/bin/bash ./run.sh --build-all`: passed in an isolated source copy.
+- Shim verifier: passed; canonical image is exactly 512 bytes.
+- Resume verifier: passed for the old `$B600/$4A00` contract.
+- Schema-v4 control-bank verifier: passed.
+- Dynamic-launcher verifier: passed, but its coverage of tokens above 23 is too
+ weak and will be strengthened.
+- All 16 regular ReadyBASIC aggregate suites ultimately passed.
+- One plugin-command run stalled while boot displayed `LOADING LAUNCHER...`;
+ the clean rerun passed all 119 steps.
+- One 212-step cross-app run stopped at cycle 6 because the keyboard buffer did
+ not drain; the clean rerun passed all 212 steps and all ten state checks.
+
+## Known baseline-report gap
+
+`report_app_headroom.py` currently reports only 19 maps and omits built apps
+including Simple Cells, SIDetris, and UCITest. ReadyBASIC also needs a custom
+segment report rather than the ordinary cc65 total. The reporter must discover
+the complete built map set before post-refactor size claims are accepted.
+
+## Final state — complete
+
+- The schema-v5 ReadyOS bank at physical `Skip+1` is authoritative for bank
+ types, explicit token-to-physical mappings, token status, app/resource
+ registries, clipboard metadata, hotkeys, catalog strings, audit data, and
+ runtime state. Physical `Skip` is the first dynamic allocation candidate.
+- App snapshots are `$1000-$C7FF` (`$B800`); the resident shim remains exactly
+ 512 bytes at `$C800-$C9FF`. `$C836-$C838` are reserved retired bytes.
+- Every discovered app map is present in the before/after report, including
+ Simple Cells, SIDetris, UCITest, ReadyBASIC, both launchers, and both
+ ReadyShell builds. ReadyBASIC's non-cc65 shape is separately enforced.
+- All regular-D81 suites, all 19 EasyFlash plans, focused launcher/QuickNotes/
+ ReadyShell probes, EasyFlash smoke, ReadyShell host tests, every release SKU,
+ schema/resume/memory/shim verifiers, and HTML/source checks passed.
+- All tracked release artifacts removed by versioned builds were restored.
+ Final `git diff --diff-filter=D` is empty; no source, documentation, tracked
+ generated artifact, or pre-existing untracked file was deleted.
diff --git a/agentworking/readyos-bank-refactor/TEST_LOG.md b/agentworking/readyos-bank-refactor/TEST_LOG.md
new file mode 100644
index 0000000..0d87ebf
--- /dev/null
+++ b/agentworking/readyos-bank-refactor/TEST_LOG.md
@@ -0,0 +1,111 @@
+# ReadyOS Bank Refactor Test Log
+
+## Pre-change baseline
+
+| Gate | Result |
+|---|---|
+| All release-profile and EasyFlash builds | Pass |
+| 512-byte shim verification | Pass |
+| Old resume-contract verification | Pass |
+| Schema-v4 control-bank verification | Pass |
+| ReadyBASIC aggregate suite | Pass after two clean reruns for baseline flakes |
+| ReadyBASIC ten-cycle cross-app state preservation | Pass, 212/212 |
+
+Post-change results will be appended here with exact commands, manifests, first
+failing step, and rerun classification.
+
+## Post-change build and static gates
+
+| Command / gate | Result |
+|---|---|
+| `/bin/bash ./run.sh --build-all` (final EasyFlash cleanup, build `0.2.5D`) | Pass, exit 0 |
+| `verify_readyos_shim.py --check-easyflash-bin` | Pass; exact 512-byte disk/EasyFlash shim |
+| resume, schema-v5, dynamic-launcher, memory-map, ReadyBASIC shape verifiers | Pass before final full rebuild; repeat pending below |
+| HTML classification and canonical full-shim-source verifier | Pass; 34 HTML documents classified, 5 full listings byte-exact |
+| `python3 verify.py --profile precog-d81` | Pass; `ALL CHECKS PASSED` after updating obsolete schema-v4/C64-mirror assertions |
+| `make easyflash-smoke` | Pass; loader preload markers, launcher entry/UI, persisted 16 MiB REU image, schema-v5 header, ReadyOS bank type, and every EasyFlash token mapping/status verified |
+
+## EasyFlash smoke hardening findings
+
+- An initial monitor-only schema fetch did not execute because EasyFlash owns
+ the `$DFxx` I/O window while monitor-injected code is active. The gate now
+ persists VICE's raw REU image and verifies physical `Skip+1` directly.
+- That stronger check found the binary magic was `D2 C3 C2 35`, because cc65
+ target-character translation had been applied to C character literals.
+ `REUCB_MAGIC0..3` now use explicit ASCII ABI bytes `52 43 42 35`; the rebuilt
+ EasyFlash smoke passes with the corrected on-REU header.
+
+## Focused post-change runtime probes
+
+| Command / manifest | Result |
+|---|---|
+| `make launcher-reu-state-vice`, `logs/vice_auto_20260802_003232` | Pass before final micromodule optimization |
+| `make quicknotes-owned-reu-vice`, `logs/vice_auto_20260802_004417` and `...004436` | Pass both legs; owned bank visible before unload and free afterward |
+| `make readyshell-cross-app-resume-vice`, `logs/vice_auto_20260802_010521` | Pass, 33/33, no degraded steps; Editor/ReadyShell/ReadyBASIC switching and resume state stable |
+| `LAUNCHER_REU_STATE_SKIP_BUILD=1 make launcher-reu-state-vice`, `logs/vice_auto_20260802_013756` | Pass, 28/28 on final exact assembly alias; unload invalidation, reload, relaunch, and ReadyBASIC stability print verified |
+
+The first final-alias launcher attempt exposed a dropped lone RETURN after the
+reload/dump sequence, not a runtime-state failure: cold launch, exit, unload,
+reload, and the launcher screen had all passed. The probe now uses the same
+deterministic text-monitor key-buffer path as the cross-app suite; the complete
+rerun passed without degraded steps.
+
+## Final static gate before aggregate suites
+
+The schema-v5 control-bank verifier, dynamic launcher verifier, resume-contract
+verifier, exact 512-byte shim verifier (including the then-current 104 zero
+padding bytes), and
+full memory-map verifier all passed against the final unique-name assembly
+adapter build. Aggregate runtime results follow below.
+
+## Final regular-D81 aggregate
+
+All 26 targets in `make readybasic-vice-suites` passed without degraded steps.
+This includes demo, repeat/labels, lifecycle, module overlay, plugin commands,
+program/rbtest1, minimal and large-variable resume, screen-REU temporary data,
+state, hotkeys, keyboard regression, ReuViewer F2 chain, ten-cycle cross-app
+resume, second-entry Editor, graphics phases 1-5, multicolor bitmap, sprites,
+sound, loaded-app coverage, and the 186-step visual suite. Salient manifests:
+
+- ten-cycle cross-app: `logs/vice_auto_20260802_024131`, 263/263;
+- second-entry Editor: `logs/vice_auto_20260802_024615`, 192/192;
+- loaded apps: `logs/vice_auto_20260802_025157`, 215/215;
+- full visual suite: `logs/vice_auto_20260802_025522`, 186/186.
+
+Focused final probes also passed: launcher state 28/28 at
+`logs/vice_auto_20260802_014929`; QuickNotes ownership/unload 15/15 and 17/17
+at `...030335` and `...030355`; ReadyShell cross-app 33/33 at `...030440`.
+
+## Final EasyFlash aggregate
+
+All 19 generated EasyFlash plans passed without degraded steps. Salient
+manifests are:
+
+- ten-cycle cross-app: `logs/vice_auto_20260802_031224`, 265/265;
+- demo: `logs/vice_auto_20260802_031419`, 80/80;
+- full visual: `logs/vice_auto_20260802_032629`, 188/188;
+- plugin commands: `logs/vice_auto_20260802_033724`, 123/123;
+- authoritative ReadyOS-status F2 chain:
+ `logs/vice_auto_20260802_035055`, 70/70;
+- second-entry Editor: `logs/vice_auto_20260802_035317`, 194/194;
+- state: `logs/vice_auto_20260802_035511`, 59/59;
+- ReadyShell cross-app: `logs/vice_auto_20260802_035555`, 35/35.
+
+The F2-chain harness was corrected to DMA its constrained token-status image
+to ReadyOS-bank `$BA40`; writing the retired `$C836-$C838` bytes correctly has
+no effect after this refactor. Deterministic direct-token re-entry replaced two
+launcher-selection assumptions. The corrected run passed both F2 directions,
+vector restoration, keyboard drainage, resume state, and exit suppression.
+
+## Final build, documentation, and deletion gates
+
+| Command / gate | Result |
+|---|---|
+| `/bin/bash ./run.sh --build-all` (`0.2.5I`) | Pass, all disk SKUs, KFF2, and EasyFlash |
+| `make verify` (subsequent verification build `0.2.5J`) | Pass |
+| `verify_readyos_shim.py --check-easyflash-bin` | Pass; 512 bytes; SHA-256 `7e34e228b6553b84bc47431d9938e3c53a9cc7c060f4cb26960f1b24f137e2a3` |
+| `make readyshell-host-tests` | Pass |
+| ReadyBASIC and ReadyShell memory-report regeneration | Pass |
+| HTML status/source verification | Pass; 38 classified HTML files and 5 full shim listings (175 canonical directives each) |
+| `git diff --check` | Pass |
+| tracked deletion audit | Pass; zero deleted paths after restoring version-pruned release artifacts |
diff --git a/agentworking/readyos-bank-refactor/headroom_after.json b/agentworking/readyos-bank-refactor/headroom_after.json
new file mode 100644
index 0000000..ab193e0
--- /dev/null
+++ b/agentworking/readyos-bank-refactor/headroom_after.json
@@ -0,0 +1,1242 @@
+{
+ "app_window_end": "0xC7FF",
+ "app_window_start": "0x1000",
+ "maps": [
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 5070,
+ "bss_bytes": 2621,
+ "code_ro_init_bytes": 39363,
+ "data_bytes": 50,
+ "heap_capacity": 4958,
+ "heap_end": "0xC78F",
+ "heap_start": "0xB432",
+ "main_segment_total": 42034,
+ "map": "obj/launcher.map",
+ "name": "launcher",
+ "runtime_end": "0xB431",
+ "segments": {
+ "BSS": {
+ "end": "0xB431",
+ "size": 2621,
+ "start": "0xA9F5"
+ },
+ "CODE": {
+ "end": "0xA3E1",
+ "size": 37807,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0xA9B2",
+ "size": 50,
+ "start": "0xA981"
+ },
+ "INIT": {
+ "end": "0xA9CE",
+ "size": 28,
+ "start": "0xA9B3"
+ },
+ "ONCE": {
+ "end": "0xA9F4",
+ "size": 38,
+ "start": "0xA9CF"
+ },
+ "RODATA": {
+ "end": "0xA980",
+ "size": 1439,
+ "start": "0xA3E2"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 12619,
+ "bss_bytes": 9880,
+ "code_ro_init_bytes": 24471,
+ "data_bytes": 134,
+ "heap_capacity": 12506,
+ "heap_end": "0xC78F",
+ "heap_start": "0x96B6",
+ "main_segment_total": 34485,
+ "map": "obj/editor.map",
+ "name": "editor",
+ "runtime_end": "0x96B4",
+ "segments": {
+ "BSS": {
+ "end": "0x96B4",
+ "size": 9880,
+ "start": "0x701D"
+ },
+ "CODE": {
+ "end": "0x6C16",
+ "size": 23524,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x6FDA",
+ "size": 134,
+ "start": "0x6F55"
+ },
+ "INIT": {
+ "end": "0x6FF6",
+ "size": 28,
+ "start": "0x6FDB"
+ },
+ "ONCE": {
+ "end": "0x701C",
+ "size": 38,
+ "start": "0x6FF7"
+ },
+ "RODATA": {
+ "end": "0x6F54",
+ "size": 830,
+ "start": "0x6C17"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 9717,
+ "bss_bytes": 6047,
+ "code_ro_init_bytes": 31118,
+ "data_bytes": 222,
+ "heap_capacity": 9604,
+ "heap_end": "0xC78F",
+ "heap_start": "0xA20C",
+ "main_segment_total": 37387,
+ "map": "obj/quicknotes.map",
+ "name": "quicknotes",
+ "runtime_end": "0xA20A",
+ "segments": {
+ "BSS": {
+ "end": "0xA20A",
+ "size": 6047,
+ "start": "0x8A6C"
+ },
+ "CODE": {
+ "end": "0x8596",
+ "size": 30052,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x8A29",
+ "size": 222,
+ "start": "0x894C"
+ },
+ "INIT": {
+ "end": "0x8A45",
+ "size": 28,
+ "start": "0x8A2A"
+ },
+ "ONCE": {
+ "end": "0x8A6B",
+ "size": 38,
+ "start": "0x8A46"
+ },
+ "RODATA": {
+ "end": "0x894B",
+ "size": 949,
+ "start": "0x8597"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 8139,
+ "bss_bytes": 1321,
+ "code_ro_init_bytes": 37486,
+ "data_bytes": 158,
+ "heap_capacity": 8026,
+ "heap_end": "0xC78F",
+ "heap_start": "0xA836",
+ "main_segment_total": 38965,
+ "map": "obj/calcplus.map",
+ "name": "calcplus",
+ "runtime_end": "0xA834",
+ "segments": {
+ "BSS": {
+ "end": "0xA834",
+ "size": 1321,
+ "start": "0xA30C"
+ },
+ "CODE": {
+ "end": "0x9D96",
+ "size": 36196,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0xA2C9",
+ "size": 158,
+ "start": "0xA22C"
+ },
+ "INIT": {
+ "end": "0xA2E5",
+ "size": 28,
+ "start": "0xA2CA"
+ },
+ "ONCE": {
+ "end": "0xA30B",
+ "size": 38,
+ "start": "0xA2E6"
+ },
+ "RODATA": {
+ "end": "0xA22B",
+ "size": 1173,
+ "start": "0x9D97"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 34041,
+ "bss_bytes": 101,
+ "code_ro_init_bytes": 12916,
+ "data_bytes": 46,
+ "heap_capacity": 33928,
+ "heap_end": "0xC78F",
+ "heap_start": "0x4308",
+ "main_segment_total": 13063,
+ "map": "obj/hexview.map",
+ "name": "hexview",
+ "runtime_end": "0x4306",
+ "segments": {
+ "BSS": {
+ "end": "0x4306",
+ "size": 101,
+ "start": "0x42A2"
+ },
+ "CODE": {
+ "end": "0x403F",
+ "size": 12301,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x425F",
+ "size": 46,
+ "start": "0x4232"
+ },
+ "INIT": {
+ "end": "0x427B",
+ "size": 28,
+ "start": "0x4260"
+ },
+ "ONCE": {
+ "end": "0x42A1",
+ "size": 38,
+ "start": "0x427C"
+ },
+ "RODATA": {
+ "end": "0x4231",
+ "size": 498,
+ "start": "0x4040"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 15026,
+ "bss_bytes": 1062,
+ "code_ro_init_bytes": 30970,
+ "data_bytes": 46,
+ "heap_capacity": 14914,
+ "heap_end": "0xC78F",
+ "heap_start": "0x8D4E",
+ "main_segment_total": 32078,
+ "map": "obj/clipmgr.map",
+ "name": "clipmgr",
+ "runtime_end": "0x8D4D",
+ "segments": {
+ "BSS": {
+ "end": "0x8D4D",
+ "size": 1062,
+ "start": "0x8928"
+ },
+ "CODE": {
+ "end": "0x856D",
+ "size": 30011,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x88E5",
+ "size": 46,
+ "start": "0x88B8"
+ },
+ "INIT": {
+ "end": "0x8901",
+ "size": 28,
+ "start": "0x88E6"
+ },
+ "ONCE": {
+ "end": "0x8927",
+ "size": 38,
+ "start": "0x8902"
+ },
+ "RODATA": {
+ "end": "0x88B7",
+ "size": 842,
+ "start": "0x856E"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 31605,
+ "bss_bytes": 221,
+ "code_ro_init_bytes": 15232,
+ "data_bytes": 46,
+ "heap_capacity": 31492,
+ "heap_end": "0xC78F",
+ "heap_start": "0x4C8C",
+ "main_segment_total": 15499,
+ "map": "obj/reuviewer.map",
+ "name": "reuviewer",
+ "runtime_end": "0x4C8A",
+ "segments": {
+ "BSS": {
+ "end": "0x4C8A",
+ "size": 221,
+ "start": "0x4BAE"
+ },
+ "CODE": {
+ "end": "0x49E6",
+ "size": 14772,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x4B6B",
+ "size": 46,
+ "start": "0x4B3E"
+ },
+ "INIT": {
+ "end": "0x4B87",
+ "size": 28,
+ "start": "0x4B6C"
+ },
+ "ONCE": {
+ "end": "0x4BAD",
+ "size": 38,
+ "start": "0x4B88"
+ },
+ "RODATA": {
+ "end": "0x4B3D",
+ "size": 343,
+ "start": "0x49E7"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 30596,
+ "bss_bytes": 277,
+ "code_ro_init_bytes": 16184,
+ "data_bytes": 47,
+ "heap_capacity": 30484,
+ "heap_end": "0xC78F",
+ "heap_start": "0x507C",
+ "main_segment_total": 16508,
+ "map": "obj/sysinfo.map",
+ "name": "sysinfo",
+ "runtime_end": "0x507B",
+ "segments": {
+ "BSS": {
+ "end": "0x507B",
+ "size": 277,
+ "start": "0x4F67"
+ },
+ "CODE": {
+ "end": "0x4ACD",
+ "size": 15003,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x4F24",
+ "size": 47,
+ "start": "0x4EF6"
+ },
+ "INIT": {
+ "end": "0x4F40",
+ "size": 28,
+ "start": "0x4F25"
+ },
+ "ONCE": {
+ "end": "0x4F66",
+ "size": 38,
+ "start": "0x4F41"
+ },
+ "RODATA": {
+ "end": "0x4EF5",
+ "size": 1064,
+ "start": "0x4ACE"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 6823,
+ "bss_bytes": 8927,
+ "code_ro_init_bytes": 31203,
+ "data_bytes": 151,
+ "heap_capacity": 6710,
+ "heap_end": "0xC78F",
+ "heap_start": "0xAD5A",
+ "main_segment_total": 40281,
+ "map": "obj/tasklist.map",
+ "name": "tasklist",
+ "runtime_end": "0xAD58",
+ "segments": {
+ "BSS": {
+ "end": "0xAD58",
+ "size": 8927,
+ "start": "0x8A7A"
+ },
+ "CODE": {
+ "end": "0x866B",
+ "size": 30265,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x8A37",
+ "size": 151,
+ "start": "0x89A1"
+ },
+ "INIT": {
+ "end": "0x8A53",
+ "size": 28,
+ "start": "0x8A38"
+ },
+ "ONCE": {
+ "end": "0x8A79",
+ "size": 38,
+ "start": "0x8A54"
+ },
+ "RODATA": {
+ "end": "0x89A0",
+ "size": 821,
+ "start": "0x866C"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 12865,
+ "bss_bytes": 4397,
+ "code_ro_init_bytes": 29780,
+ "data_bytes": 62,
+ "heap_capacity": 12752,
+ "heap_end": "0xC78F",
+ "heap_start": "0x95C0",
+ "main_segment_total": 34239,
+ "map": "obj/simplefiles.map",
+ "name": "simplefiles",
+ "runtime_end": "0x95BE",
+ "segments": {
+ "BSS": {
+ "end": "0x95BE",
+ "size": 4397,
+ "start": "0x8492"
+ },
+ "CODE": {
+ "end": "0x7F44",
+ "size": 28434,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x844F",
+ "size": 62,
+ "start": "0x8412"
+ },
+ "INIT": {
+ "end": "0x846B",
+ "size": 28,
+ "start": "0x8450"
+ },
+ "ONCE": {
+ "end": "0x8491",
+ "size": 38,
+ "start": "0x846C"
+ },
+ "RODATA": {
+ "end": "0x8411",
+ "size": 1229,
+ "start": "0x7F45"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 9925,
+ "bss_bytes": 2142,
+ "code_ro_init_bytes": 34799,
+ "data_bytes": 238,
+ "heap_capacity": 9812,
+ "heap_end": "0xC78F",
+ "heap_start": "0xA13C",
+ "main_segment_total": 37179,
+ "map": "obj/simplecells.map",
+ "name": "simplecells",
+ "runtime_end": "0xA13A",
+ "segments": {
+ "BSS": {
+ "end": "0xA13A",
+ "size": 2142,
+ "start": "0x98DD"
+ },
+ "CODE": {
+ "end": "0x90F2",
+ "size": 32960,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x989A",
+ "size": 238,
+ "start": "0x97AD"
+ },
+ "INIT": {
+ "end": "0x98B6",
+ "size": 28,
+ "start": "0x989B"
+ },
+ "ONCE": {
+ "end": "0x98DC",
+ "size": 38,
+ "start": "0x98B7"
+ },
+ "RODATA": {
+ "end": "0x97AC",
+ "size": 1722,
+ "start": "0x90F3"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 28894,
+ "bss_bytes": 1203,
+ "code_ro_init_bytes": 16961,
+ "data_bytes": 46,
+ "heap_capacity": 28782,
+ "heap_end": "0xC78F",
+ "heap_start": "0x5722",
+ "main_segment_total": 18210,
+ "map": "obj/game2048.map",
+ "name": "game2048",
+ "runtime_end": "0x5721",
+ "segments": {
+ "BSS": {
+ "end": "0x5721",
+ "size": 1203,
+ "start": "0x526F"
+ },
+ "CODE": {
+ "end": "0x50CE",
+ "size": 16540,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x522C",
+ "size": 46,
+ "start": "0x51FF"
+ },
+ "INIT": {
+ "end": "0x5248",
+ "size": 28,
+ "start": "0x522D"
+ },
+ "ONCE": {
+ "end": "0x526E",
+ "size": 38,
+ "start": "0x5249"
+ },
+ "RODATA": {
+ "end": "0x51FE",
+ "size": 304,
+ "start": "0x50CF"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 22481,
+ "bss_bytes": 4276,
+ "code_ro_init_bytes": 20301,
+ "data_bytes": 46,
+ "heap_capacity": 22368,
+ "heap_end": "0xC78F",
+ "heap_start": "0x7030",
+ "main_segment_total": 24623,
+ "map": "obj/deminer.map",
+ "name": "deminer",
+ "runtime_end": "0x702E",
+ "segments": {
+ "BSS": {
+ "end": "0x702E",
+ "size": 4276,
+ "start": "0x5F7B"
+ },
+ "CODE": {
+ "end": "0x5C1F",
+ "size": 19437,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x5F38",
+ "size": 46,
+ "start": "0x5F0B"
+ },
+ "INIT": {
+ "end": "0x5F54",
+ "size": 28,
+ "start": "0x5F39"
+ },
+ "ONCE": {
+ "end": "0x5F7A",
+ "size": 38,
+ "start": "0x5F55"
+ },
+ "RODATA": {
+ "end": "0x5F0A",
+ "size": 747,
+ "start": "0x5C20"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 30566,
+ "bss_bytes": 908,
+ "code_ro_init_bytes": 15544,
+ "data_bytes": 86,
+ "heap_capacity": 30454,
+ "heap_end": "0xC78F",
+ "heap_start": "0x509A",
+ "main_segment_total": 16538,
+ "map": "obj/sidetris.map",
+ "name": "sidetris",
+ "runtime_end": "0x5099",
+ "segments": {
+ "BSS": {
+ "end": "0x5099",
+ "size": 908,
+ "start": "0x4D0E"
+ },
+ "CODE": {
+ "end": "0x4872",
+ "size": 14400,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x4CCB",
+ "size": 86,
+ "start": "0x4C76"
+ },
+ "INIT": {
+ "end": "0x4CE7",
+ "size": 28,
+ "start": "0x4CCC"
+ },
+ "ONCE": {
+ "end": "0x4D0D",
+ "size": 38,
+ "start": "0x4CE8"
+ },
+ "RODATA": {
+ "end": "0x4C75",
+ "size": 1027,
+ "start": "0x4873"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 9598,
+ "bss_bytes": 4803,
+ "code_ro_init_bytes": 32379,
+ "data_bytes": 324,
+ "heap_capacity": 9486,
+ "heap_end": "0xC78F",
+ "heap_start": "0xA282",
+ "main_segment_total": 37506,
+ "map": "obj/cal26.map",
+ "name": "cal26",
+ "runtime_end": "0xA281",
+ "segments": {
+ "BSS": {
+ "end": "0xA281",
+ "size": 4803,
+ "start": "0x8FBF"
+ },
+ "CODE": {
+ "end": "0x86EB",
+ "size": 30393,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x8F7C",
+ "size": 324,
+ "start": "0x8E39"
+ },
+ "INIT": {
+ "end": "0x8F98",
+ "size": 28,
+ "start": "0x8F7D"
+ },
+ "ONCE": {
+ "end": "0x8FBE",
+ "size": 38,
+ "start": "0x8F99"
+ },
+ "RODATA": {
+ "end": "0x8E38",
+ "size": 1869,
+ "start": "0x86EC"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 1969,
+ "bss_bytes": 6327,
+ "code_ro_init_bytes": 38676,
+ "data_bytes": 132,
+ "heap_capacity": 1856,
+ "heap_end": "0xC78F",
+ "heap_start": "0xC050",
+ "main_segment_total": 45135,
+ "map": "obj/dizzy.map",
+ "name": "dizzy",
+ "runtime_end": "0xC04E",
+ "segments": {
+ "BSS": {
+ "end": "0xC04E",
+ "size": 6327,
+ "start": "0xA798"
+ },
+ "CODE": {
+ "end": "0xA208",
+ "size": 37334,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0xA755",
+ "size": 132,
+ "start": "0xA6D2"
+ },
+ "INIT": {
+ "end": "0xA771",
+ "size": 28,
+ "start": "0xA756"
+ },
+ "ONCE": {
+ "end": "0xA797",
+ "size": 38,
+ "start": "0xA772"
+ },
+ "RODATA": {
+ "end": "0xA6D1",
+ "size": 1225,
+ "start": "0xA209"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 19737,
+ "bss_bytes": 5351,
+ "code_ro_init_bytes": 21969,
+ "data_bytes": 47,
+ "heap_capacity": 19624,
+ "heap_end": "0xC78F",
+ "heap_start": "0x7AE8",
+ "main_segment_total": 27367,
+ "map": "obj/readyirc.map",
+ "name": "readyirc",
+ "runtime_end": "0x7AE6",
+ "segments": {
+ "BSS": {
+ "end": "0x7AE6",
+ "size": 5351,
+ "start": "0x6600"
+ },
+ "CODE": {
+ "end": "0x61F2",
+ "size": 20928,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x65BD",
+ "size": 47,
+ "start": "0x658F"
+ },
+ "INIT": {
+ "end": "0x65D9",
+ "size": 28,
+ "start": "0x65BE"
+ },
+ "ONCE": {
+ "end": "0x65FF",
+ "size": 38,
+ "start": "0x65DA"
+ },
+ "RODATA": {
+ "end": "0x658E",
+ "size": 924,
+ "start": "0x61F3"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 18603,
+ "bss_bytes": 6909,
+ "code_ro_init_bytes": 21365,
+ "data_bytes": 227,
+ "heap_capacity": 18490,
+ "heap_end": "0xC78F",
+ "heap_start": "0x7F56",
+ "main_segment_total": 28501,
+ "map": "obj/rirc-rrnet.map",
+ "name": "rirc-rrnet",
+ "runtime_end": "0x7F54",
+ "segments": {
+ "BSS": {
+ "end": "0x7F54",
+ "size": 6909,
+ "start": "0x6458"
+ },
+ "CODE": {
+ "end": "0x6054",
+ "size": 20514,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x6415",
+ "size": 227,
+ "start": "0x6333"
+ },
+ "INIT": {
+ "end": "0x6431",
+ "size": 28,
+ "start": "0x6416"
+ },
+ "ONCE": {
+ "end": "0x6457",
+ "size": 38,
+ "start": "0x6432"
+ },
+ "RODATA": {
+ "end": "0x6332",
+ "size": 734,
+ "start": "0x6055"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 1537,
+ "bss_bytes": 0,
+ "code_ro_init_bytes": 9290,
+ "data_bytes": 0,
+ "main_segment_total": 2954,
+ "map": "obj/readybasic.map",
+ "name": "readybasic",
+ "runtime_end": "0xC1FE",
+ "segments": {
+ "BRIDGE": {
+ "end": "0xC1FE",
+ "size": 511,
+ "start": "0xC000"
+ },
+ "ENTRY": {
+ "end": "0x11FF",
+ "size": 512,
+ "start": "0x1000"
+ },
+ "HIDDEN": {
+ "end": "0xA78A",
+ "size": 1931,
+ "start": "0xA000"
+ }
+ }
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 21805,
+ "bss_bytes": 2708,
+ "code_ro_init_bytes": 22520,
+ "data_bytes": 71,
+ "heap_capacity": 21692,
+ "heap_end": "0xC78F",
+ "heap_start": "0x72D4",
+ "main_segment_total": 25299,
+ "map": "obj/ucitest.map",
+ "name": "ucitest",
+ "runtime_end": "0x72D2",
+ "segments": {
+ "BSS": {
+ "end": "0x72D2",
+ "size": 2708,
+ "start": "0x683F"
+ },
+ "CODE": {
+ "end": "0x5933",
+ "size": 18689,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x67FC",
+ "size": 71,
+ "start": "0x67B6"
+ },
+ "INIT": {
+ "end": "0x6818",
+ "size": 28,
+ "start": "0x67FD"
+ },
+ "ONCE": {
+ "end": "0x683E",
+ "size": 38,
+ "start": "0x6819"
+ },
+ "RODATA": {
+ "end": "0x67B5",
+ "size": 3714,
+ "start": "0x5934"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 22782,
+ "bss_bytes": 48,
+ "code_ro_init_bytes": 24228,
+ "data_bytes": 46,
+ "heap_capacity": 22670,
+ "heap_end": "0xC78F",
+ "heap_start": "0x6F02",
+ "main_segment_total": 24322,
+ "map": "obj/readme.map",
+ "name": "readme",
+ "runtime_end": "0x6F01",
+ "segments": {
+ "BSS": {
+ "end": "0x6F01",
+ "size": 48,
+ "start": "0x6ED2"
+ },
+ "CODE": {
+ "end": "0x39A9",
+ "size": 10615,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x6E8F",
+ "size": 46,
+ "start": "0x6E62"
+ },
+ "INIT": {
+ "end": "0x6EAB",
+ "size": 28,
+ "start": "0x6E90"
+ },
+ "ONCE": {
+ "end": "0x6ED1",
+ "size": 38,
+ "start": "0x6EAC"
+ },
+ "RODATA": {
+ "end": "0x6E61",
+ "size": 13496,
+ "start": "0x39AA"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 18356,
+ "bss_bytes": 426,
+ "code_ro_init_bytes": 28251,
+ "data_bytes": 71,
+ "heap_capacity": 3506,
+ "main_segment_total": 28748,
+ "map": "obj/readyshell.map",
+ "name": "readyshell",
+ "readyshell": {
+ "heap_end": "0x8DFD",
+ "heap_size": 3506,
+ "heap_start": "0x804C",
+ "himem": "0xC600",
+ "overlay_loadaddr": "0x8DFE",
+ "overlay_start": "0x8E00",
+ "overlay_window": 14336
+ },
+ "runtime_end": "0x804B",
+ "segments": {
+ "BSS": {
+ "end": "0x804B",
+ "size": 426,
+ "start": "0x7EA2"
+ },
+ "CODE": {
+ "end": "0x7A14",
+ "size": 27106,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x7E4D",
+ "size": 71,
+ "start": "0x7E07"
+ },
+ "INIT": {
+ "end": "0x7E69",
+ "size": 28,
+ "start": "0x7E4E"
+ },
+ "ONCE": {
+ "end": "0x7EA1",
+ "size": 56,
+ "start": "0x7E6A"
+ },
+ "RODATA": {
+ "end": "0x7E06",
+ "size": 1010,
+ "start": "0x7A15"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ }
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 17969,
+ "bss_bytes": 2090,
+ "code_ro_init_bytes": 26995,
+ "data_bytes": 50,
+ "heap_capacity": 17856,
+ "heap_end": "0xC78F",
+ "heap_start": "0x81D0",
+ "main_segment_total": 29135,
+ "map": "obj/launcher_easyflash.map",
+ "name": "launcher_easyflash",
+ "runtime_end": "0x81CE",
+ "segments": {
+ "BSS": {
+ "end": "0x81CE",
+ "size": 2090,
+ "start": "0x79A5"
+ },
+ "CODE": {
+ "end": "0x70EB",
+ "size": 24761,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x7962",
+ "size": 50,
+ "start": "0x7931"
+ },
+ "INIT": {
+ "end": "0x797E",
+ "size": 28,
+ "start": "0x7963"
+ },
+ "ONCE": {
+ "end": "0x79A4",
+ "size": 38,
+ "start": "0x797F"
+ },
+ "RODATA": {
+ "end": "0x7930",
+ "size": 2117,
+ "start": "0x70EC"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 18458,
+ "bss_bytes": 426,
+ "code_ro_init_bytes": 28149,
+ "data_bytes": 71,
+ "heap_capacity": 3608,
+ "main_segment_total": 28646,
+ "map": "obj/readyshell_easyflash.map",
+ "name": "readyshell_easyflash",
+ "readyshell": {
+ "heap_end": "0x8DFD",
+ "heap_size": 3608,
+ "heap_start": "0x7FE6",
+ "himem": "0xC600",
+ "overlay_loadaddr": "0x8DFE",
+ "overlay_start": "0x8E00",
+ "overlay_window": 14336
+ },
+ "runtime_end": "0x7FE5",
+ "segments": {
+ "BSS": {
+ "end": "0x7FE5",
+ "size": 426,
+ "start": "0x7E3C"
+ },
+ "CODE": {
+ "end": "0x79AE",
+ "size": 27004,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x7DE7",
+ "size": 71,
+ "start": "0x7DA1"
+ },
+ "INIT": {
+ "end": "0x7E03",
+ "size": 28,
+ "start": "0x7DE8"
+ },
+ "ONCE": {
+ "end": "0x7E3B",
+ "size": 56,
+ "start": "0x7E04"
+ },
+ "RODATA": {
+ "end": "0x7DA0",
+ "size": 1010,
+ "start": "0x79AF"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ }
+ }
+ ]
+}
diff --git a/agentworking/readyos-bank-refactor/headroom_before.json b/agentworking/readyos-bank-refactor/headroom_before.json
new file mode 100644
index 0000000..805469a
--- /dev/null
+++ b/agentworking/readyos-bank-refactor/headroom_before.json
@@ -0,0 +1,1242 @@
+{
+ "app_window_end": "0xC5FF",
+ "app_window_start": "0x1000",
+ "maps": [
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 4414,
+ "bss_bytes": 2421,
+ "code_ro_init_bytes": 39707,
+ "data_bytes": 50,
+ "heap_capacity": 4302,
+ "heap_end": "0xC58F",
+ "heap_start": "0xB4C2",
+ "main_segment_total": 42178,
+ "map": "obj/launcher.map",
+ "name": "launcher",
+ "runtime_end": "0xB4C1",
+ "segments": {
+ "BSS": {
+ "end": "0xB4C1",
+ "size": 2421,
+ "start": "0xAB4D"
+ },
+ "CODE": {
+ "end": "0xA539",
+ "size": 38151,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0xAB0A",
+ "size": 50,
+ "start": "0xAAD9"
+ },
+ "INIT": {
+ "end": "0xAB26",
+ "size": 28,
+ "start": "0xAB0B"
+ },
+ "ONCE": {
+ "end": "0xAB4C",
+ "size": 38,
+ "start": "0xAB27"
+ },
+ "RODATA": {
+ "end": "0xAAD8",
+ "size": 1439,
+ "start": "0xA53A"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 12045,
+ "bss_bytes": 9880,
+ "code_ro_init_bytes": 24533,
+ "data_bytes": 134,
+ "heap_capacity": 11932,
+ "heap_end": "0xC58F",
+ "heap_start": "0x96F4",
+ "main_segment_total": 34547,
+ "map": "obj/editor.map",
+ "name": "editor",
+ "runtime_end": "0x96F2",
+ "segments": {
+ "BSS": {
+ "end": "0x96F2",
+ "size": 9880,
+ "start": "0x705B"
+ },
+ "CODE": {
+ "end": "0x6C54",
+ "size": 23586,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x7018",
+ "size": 134,
+ "start": "0x6F93"
+ },
+ "INIT": {
+ "end": "0x7034",
+ "size": 28,
+ "start": "0x7019"
+ },
+ "ONCE": {
+ "end": "0x705A",
+ "size": 38,
+ "start": "0x7035"
+ },
+ "RODATA": {
+ "end": "0x6F92",
+ "size": 830,
+ "start": "0x6C55"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 9164,
+ "bss_bytes": 6047,
+ "code_ro_init_bytes": 31159,
+ "data_bytes": 222,
+ "heap_capacity": 9052,
+ "heap_end": "0xC58F",
+ "heap_start": "0xA234",
+ "main_segment_total": 37428,
+ "map": "obj/quicknotes.map",
+ "name": "quicknotes",
+ "runtime_end": "0xA233",
+ "segments": {
+ "BSS": {
+ "end": "0xA233",
+ "size": 6047,
+ "start": "0x8A95"
+ },
+ "CODE": {
+ "end": "0x85BF",
+ "size": 30093,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x8A52",
+ "size": 222,
+ "start": "0x8975"
+ },
+ "INIT": {
+ "end": "0x8A6E",
+ "size": 28,
+ "start": "0x8A53"
+ },
+ "ONCE": {
+ "end": "0x8A94",
+ "size": 38,
+ "start": "0x8A6F"
+ },
+ "RODATA": {
+ "end": "0x8974",
+ "size": 949,
+ "start": "0x85C0"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 7266,
+ "bss_bytes": 1321,
+ "code_ro_init_bytes": 37847,
+ "data_bytes": 158,
+ "heap_capacity": 7154,
+ "heap_end": "0xC58F",
+ "heap_start": "0xA99E",
+ "main_segment_total": 39326,
+ "map": "obj/calcplus.map",
+ "name": "calcplus",
+ "runtime_end": "0xA99D",
+ "segments": {
+ "BSS": {
+ "end": "0xA99D",
+ "size": 1321,
+ "start": "0xA475"
+ },
+ "CODE": {
+ "end": "0x9EFF",
+ "size": 36557,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0xA432",
+ "size": 158,
+ "start": "0xA395"
+ },
+ "INIT": {
+ "end": "0xA44E",
+ "size": 28,
+ "start": "0xA433"
+ },
+ "ONCE": {
+ "end": "0xA474",
+ "size": 38,
+ "start": "0xA44F"
+ },
+ "RODATA": {
+ "end": "0xA394",
+ "size": 1173,
+ "start": "0x9F00"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 32950,
+ "bss_bytes": 101,
+ "code_ro_init_bytes": 13495,
+ "data_bytes": 46,
+ "heap_capacity": 32838,
+ "heap_end": "0xC58F",
+ "heap_start": "0x454A",
+ "main_segment_total": 13642,
+ "map": "obj/hexview.map",
+ "name": "hexview",
+ "runtime_end": "0x4549",
+ "segments": {
+ "BSS": {
+ "end": "0x4549",
+ "size": 101,
+ "start": "0x44E5"
+ },
+ "CODE": {
+ "end": "0x4282",
+ "size": 12880,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x44A2",
+ "size": 46,
+ "start": "0x4475"
+ },
+ "INIT": {
+ "end": "0x44BE",
+ "size": 28,
+ "start": "0x44A3"
+ },
+ "ONCE": {
+ "end": "0x44E4",
+ "size": 38,
+ "start": "0x44BF"
+ },
+ "RODATA": {
+ "end": "0x4474",
+ "size": 498,
+ "start": "0x4283"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 14112,
+ "bss_bytes": 1062,
+ "code_ro_init_bytes": 31372,
+ "data_bytes": 46,
+ "heap_capacity": 14000,
+ "heap_end": "0xC58F",
+ "heap_start": "0x8EE0",
+ "main_segment_total": 32480,
+ "map": "obj/clipmgr.map",
+ "name": "clipmgr",
+ "runtime_end": "0x8EDF",
+ "segments": {
+ "BSS": {
+ "end": "0x8EDF",
+ "size": 1062,
+ "start": "0x8ABA"
+ },
+ "CODE": {
+ "end": "0x86FF",
+ "size": 30413,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x8A77",
+ "size": 46,
+ "start": "0x8A4A"
+ },
+ "INIT": {
+ "end": "0x8A93",
+ "size": 28,
+ "start": "0x8A78"
+ },
+ "ONCE": {
+ "end": "0x8AB9",
+ "size": 38,
+ "start": "0x8A94"
+ },
+ "RODATA": {
+ "end": "0x8A49",
+ "size": 842,
+ "start": "0x8700"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 29454,
+ "bss_bytes": 229,
+ "code_ro_init_bytes": 16863,
+ "data_bytes": 46,
+ "heap_capacity": 29342,
+ "heap_end": "0xC58F",
+ "heap_start": "0x52F2",
+ "main_segment_total": 17138,
+ "map": "obj/reuviewer.map",
+ "name": "reuviewer",
+ "runtime_end": "0x52F1",
+ "segments": {
+ "BSS": {
+ "end": "0x52F1",
+ "size": 229,
+ "start": "0x520D"
+ },
+ "CODE": {
+ "end": "0x5043",
+ "size": 16401,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x51CA",
+ "size": 46,
+ "start": "0x519D"
+ },
+ "INIT": {
+ "end": "0x51E6",
+ "size": 28,
+ "start": "0x51CB"
+ },
+ "ONCE": {
+ "end": "0x520C",
+ "size": 38,
+ "start": "0x51E7"
+ },
+ "RODATA": {
+ "end": "0x519C",
+ "size": 345,
+ "start": "0x5044"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 30021,
+ "bss_bytes": 277,
+ "code_ro_init_bytes": 16247,
+ "data_bytes": 47,
+ "heap_capacity": 29908,
+ "heap_end": "0xC58F",
+ "heap_start": "0x50BC",
+ "main_segment_total": 16571,
+ "map": "obj/sysinfo.map",
+ "name": "sysinfo",
+ "runtime_end": "0x50BA",
+ "segments": {
+ "BSS": {
+ "end": "0x50BA",
+ "size": 277,
+ "start": "0x4FA6"
+ },
+ "CODE": {
+ "end": "0x4B0C",
+ "size": 15066,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x4F63",
+ "size": 47,
+ "start": "0x4F35"
+ },
+ "INIT": {
+ "end": "0x4F7F",
+ "size": 28,
+ "start": "0x4F64"
+ },
+ "ONCE": {
+ "end": "0x4FA5",
+ "size": 38,
+ "start": "0x4F80"
+ },
+ "RODATA": {
+ "end": "0x4F34",
+ "size": 1064,
+ "start": "0x4B0D"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 6402,
+ "bss_bytes": 8927,
+ "code_ro_init_bytes": 31112,
+ "data_bytes": 151,
+ "heap_capacity": 6290,
+ "heap_end": "0xC58F",
+ "heap_start": "0xACFE",
+ "main_segment_total": 40190,
+ "map": "obj/tasklist.map",
+ "name": "tasklist",
+ "runtime_end": "0xACFD",
+ "segments": {
+ "BSS": {
+ "end": "0xACFD",
+ "size": 8927,
+ "start": "0x8A1F"
+ },
+ "CODE": {
+ "end": "0x8610",
+ "size": 30174,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x89DC",
+ "size": 151,
+ "start": "0x8946"
+ },
+ "INIT": {
+ "end": "0x89F8",
+ "size": 28,
+ "start": "0x89DD"
+ },
+ "ONCE": {
+ "end": "0x8A1E",
+ "size": 38,
+ "start": "0x89F9"
+ },
+ "RODATA": {
+ "end": "0x8945",
+ "size": 821,
+ "start": "0x8611"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 12636,
+ "bss_bytes": 4397,
+ "code_ro_init_bytes": 29497,
+ "data_bytes": 62,
+ "heap_capacity": 12524,
+ "heap_end": "0xC58F",
+ "heap_start": "0x94A4",
+ "main_segment_total": 33956,
+ "map": "obj/simplefiles.map",
+ "name": "simplefiles",
+ "runtime_end": "0x94A3",
+ "segments": {
+ "BSS": {
+ "end": "0x94A3",
+ "size": 4397,
+ "start": "0x8377"
+ },
+ "CODE": {
+ "end": "0x7E29",
+ "size": 28151,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x8334",
+ "size": 62,
+ "start": "0x82F7"
+ },
+ "INIT": {
+ "end": "0x8350",
+ "size": 28,
+ "start": "0x8335"
+ },
+ "ONCE": {
+ "end": "0x8376",
+ "size": 38,
+ "start": "0x8351"
+ },
+ "RODATA": {
+ "end": "0x82F6",
+ "size": 1229,
+ "start": "0x7E2A"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 9407,
+ "bss_bytes": 2142,
+ "code_ro_init_bytes": 34805,
+ "data_bytes": 238,
+ "heap_capacity": 9294,
+ "heap_end": "0xC58F",
+ "heap_start": "0xA142",
+ "main_segment_total": 37185,
+ "map": "obj/simplecells.map",
+ "name": "simplecells",
+ "runtime_end": "0xA140",
+ "segments": {
+ "BSS": {
+ "end": "0xA140",
+ "size": 2142,
+ "start": "0x98E3"
+ },
+ "CODE": {
+ "end": "0x90F8",
+ "size": 32966,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x98A0",
+ "size": 238,
+ "start": "0x97B3"
+ },
+ "INIT": {
+ "end": "0x98BC",
+ "size": 28,
+ "start": "0x98A1"
+ },
+ "ONCE": {
+ "end": "0x98E2",
+ "size": 38,
+ "start": "0x98BD"
+ },
+ "RODATA": {
+ "end": "0x97B2",
+ "size": 1722,
+ "start": "0x90F9"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 28580,
+ "bss_bytes": 1203,
+ "code_ro_init_bytes": 16763,
+ "data_bytes": 46,
+ "heap_capacity": 28468,
+ "heap_end": "0xC58F",
+ "heap_start": "0x565C",
+ "main_segment_total": 18012,
+ "map": "obj/game2048.map",
+ "name": "game2048",
+ "runtime_end": "0x565B",
+ "segments": {
+ "BSS": {
+ "end": "0x565B",
+ "size": 1203,
+ "start": "0x51A9"
+ },
+ "CODE": {
+ "end": "0x5008",
+ "size": 16342,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x5166",
+ "size": 46,
+ "start": "0x5139"
+ },
+ "INIT": {
+ "end": "0x5182",
+ "size": 28,
+ "start": "0x5167"
+ },
+ "ONCE": {
+ "end": "0x51A8",
+ "size": 38,
+ "start": "0x5183"
+ },
+ "RODATA": {
+ "end": "0x5138",
+ "size": 304,
+ "start": "0x5009"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 22167,
+ "bss_bytes": 4276,
+ "code_ro_init_bytes": 20103,
+ "data_bytes": 46,
+ "heap_capacity": 22054,
+ "heap_end": "0xC58F",
+ "heap_start": "0x6F6A",
+ "main_segment_total": 24425,
+ "map": "obj/deminer.map",
+ "name": "deminer",
+ "runtime_end": "0x6F68",
+ "segments": {
+ "BSS": {
+ "end": "0x6F68",
+ "size": 4276,
+ "start": "0x5EB5"
+ },
+ "CODE": {
+ "end": "0x5B59",
+ "size": 19239,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x5E72",
+ "size": 46,
+ "start": "0x5E45"
+ },
+ "INIT": {
+ "end": "0x5E8E",
+ "size": 28,
+ "start": "0x5E73"
+ },
+ "ONCE": {
+ "end": "0x5EB4",
+ "size": 38,
+ "start": "0x5E8F"
+ },
+ "RODATA": {
+ "end": "0x5E44",
+ "size": 747,
+ "start": "0x5B5A"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 30286,
+ "bss_bytes": 908,
+ "code_ro_init_bytes": 15312,
+ "data_bytes": 86,
+ "heap_capacity": 30174,
+ "heap_end": "0xC58F",
+ "heap_start": "0x4FB2",
+ "main_segment_total": 16306,
+ "map": "obj/sidetris.map",
+ "name": "sidetris",
+ "runtime_end": "0x4FB1",
+ "segments": {
+ "BSS": {
+ "end": "0x4FB1",
+ "size": 908,
+ "start": "0x4C26"
+ },
+ "CODE": {
+ "end": "0x478A",
+ "size": 14168,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x4BE3",
+ "size": 86,
+ "start": "0x4B8E"
+ },
+ "INIT": {
+ "end": "0x4BFF",
+ "size": 28,
+ "start": "0x4BE4"
+ },
+ "ONCE": {
+ "end": "0x4C25",
+ "size": 38,
+ "start": "0x4C00"
+ },
+ "RODATA": {
+ "end": "0x4B8D",
+ "size": 1027,
+ "start": "0x478B"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 9084,
+ "bss_bytes": 4803,
+ "code_ro_init_bytes": 32381,
+ "data_bytes": 324,
+ "heap_capacity": 8972,
+ "heap_end": "0xC58F",
+ "heap_start": "0xA284",
+ "main_segment_total": 37508,
+ "map": "obj/cal26.map",
+ "name": "cal26",
+ "runtime_end": "0xA283",
+ "segments": {
+ "BSS": {
+ "end": "0xA283",
+ "size": 4803,
+ "start": "0x8FC1"
+ },
+ "CODE": {
+ "end": "0x86ED",
+ "size": 30395,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x8F7E",
+ "size": 324,
+ "start": "0x8E3B"
+ },
+ "INIT": {
+ "end": "0x8F9A",
+ "size": 28,
+ "start": "0x8F7F"
+ },
+ "ONCE": {
+ "end": "0x8FC0",
+ "size": 38,
+ "start": "0x8F9B"
+ },
+ "RODATA": {
+ "end": "0x8E3A",
+ "size": 1869,
+ "start": "0x86EE"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 1834,
+ "bss_bytes": 6327,
+ "code_ro_init_bytes": 38299,
+ "data_bytes": 132,
+ "heap_capacity": 1722,
+ "heap_end": "0xC58F",
+ "heap_start": "0xBED6",
+ "main_segment_total": 44758,
+ "map": "obj/dizzy.map",
+ "name": "dizzy",
+ "runtime_end": "0xBED5",
+ "segments": {
+ "BSS": {
+ "end": "0xBED5",
+ "size": 6327,
+ "start": "0xA61F"
+ },
+ "CODE": {
+ "end": "0xA08F",
+ "size": 36957,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0xA5DC",
+ "size": 132,
+ "start": "0xA559"
+ },
+ "INIT": {
+ "end": "0xA5F8",
+ "size": 28,
+ "start": "0xA5DD"
+ },
+ "ONCE": {
+ "end": "0xA61E",
+ "size": 38,
+ "start": "0xA5F9"
+ },
+ "RODATA": {
+ "end": "0xA558",
+ "size": 1225,
+ "start": "0xA090"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 19005,
+ "bss_bytes": 5351,
+ "code_ro_init_bytes": 22189,
+ "data_bytes": 47,
+ "heap_capacity": 18892,
+ "heap_end": "0xC58F",
+ "heap_start": "0x7BC4",
+ "main_segment_total": 27587,
+ "map": "obj/readyirc.map",
+ "name": "readyirc",
+ "runtime_end": "0x7BC2",
+ "segments": {
+ "BSS": {
+ "end": "0x7BC2",
+ "size": 5351,
+ "start": "0x66DC"
+ },
+ "CODE": {
+ "end": "0x62CE",
+ "size": 21148,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x6699",
+ "size": 47,
+ "start": "0x666B"
+ },
+ "INIT": {
+ "end": "0x66B5",
+ "size": 28,
+ "start": "0x669A"
+ },
+ "ONCE": {
+ "end": "0x66DB",
+ "size": 38,
+ "start": "0x66B6"
+ },
+ "RODATA": {
+ "end": "0x666A",
+ "size": 924,
+ "start": "0x62CF"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 17871,
+ "bss_bytes": 6909,
+ "code_ro_init_bytes": 21585,
+ "data_bytes": 227,
+ "heap_capacity": 17758,
+ "heap_end": "0xC58F",
+ "heap_start": "0x8032",
+ "main_segment_total": 28721,
+ "map": "obj/rirc-rrnet.map",
+ "name": "rirc-rrnet",
+ "runtime_end": "0x8030",
+ "segments": {
+ "BSS": {
+ "end": "0x8030",
+ "size": 6909,
+ "start": "0x6534"
+ },
+ "CODE": {
+ "end": "0x6130",
+ "size": 20734,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x64F1",
+ "size": 227,
+ "start": "0x640F"
+ },
+ "INIT": {
+ "end": "0x650D",
+ "size": 28,
+ "start": "0x64F2"
+ },
+ "ONCE": {
+ "end": "0x6533",
+ "size": 38,
+ "start": "0x650E"
+ },
+ "RODATA": {
+ "end": "0x640E",
+ "size": 734,
+ "start": "0x6131"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 1025,
+ "bss_bytes": 0,
+ "code_ro_init_bytes": 9390,
+ "data_bytes": 0,
+ "main_segment_total": 3054,
+ "map": "obj/readybasic.map",
+ "name": "readybasic",
+ "runtime_end": "0xC1FE",
+ "segments": {
+ "BRIDGE": {
+ "end": "0xC1FE",
+ "size": 511,
+ "start": "0xC000"
+ },
+ "ENTRY": {
+ "end": "0x11FF",
+ "size": 512,
+ "start": "0x1000"
+ },
+ "HIDDEN": {
+ "end": "0xA7EE",
+ "size": 2031,
+ "start": "0xA000"
+ }
+ }
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 21230,
+ "bss_bytes": 2708,
+ "code_ro_init_bytes": 22583,
+ "data_bytes": 71,
+ "heap_capacity": 21118,
+ "heap_end": "0xC58F",
+ "heap_start": "0x7312",
+ "main_segment_total": 25362,
+ "map": "obj/ucitest.map",
+ "name": "ucitest",
+ "runtime_end": "0x7311",
+ "segments": {
+ "BSS": {
+ "end": "0x7311",
+ "size": 2708,
+ "start": "0x687E"
+ },
+ "CODE": {
+ "end": "0x5972",
+ "size": 18752,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x683B",
+ "size": 71,
+ "start": "0x67F5"
+ },
+ "INIT": {
+ "end": "0x6857",
+ "size": 28,
+ "start": "0x683C"
+ },
+ "ONCE": {
+ "end": "0x687D",
+ "size": 38,
+ "start": "0x6858"
+ },
+ "RODATA": {
+ "end": "0x67F4",
+ "size": 3714,
+ "start": "0x5973"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 22468,
+ "bss_bytes": 48,
+ "code_ro_init_bytes": 24030,
+ "data_bytes": 46,
+ "heap_capacity": 22356,
+ "heap_end": "0xC58F",
+ "heap_start": "0x6E3C",
+ "main_segment_total": 24124,
+ "map": "obj/readme.map",
+ "name": "readme",
+ "runtime_end": "0x6E3B",
+ "segments": {
+ "BSS": {
+ "end": "0x6E3B",
+ "size": 48,
+ "start": "0x6E0C"
+ },
+ "CODE": {
+ "end": "0x38E3",
+ "size": 10417,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x6DC9",
+ "size": 46,
+ "start": "0x6D9C"
+ },
+ "INIT": {
+ "end": "0x6DE5",
+ "size": 28,
+ "start": "0x6DCA"
+ },
+ "ONCE": {
+ "end": "0x6E0B",
+ "size": 38,
+ "start": "0x6DE6"
+ },
+ "RODATA": {
+ "end": "0x6D9B",
+ "size": 13496,
+ "start": "0x38E4"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 18185,
+ "bss_bytes": 426,
+ "code_ro_init_bytes": 27910,
+ "data_bytes": 71,
+ "heap_capacity": 3846,
+ "main_segment_total": 28407,
+ "map": "obj/readyshell.map",
+ "name": "readyshell",
+ "readyshell": {
+ "heap_end": "0x8DFD",
+ "heap_size": 3846,
+ "heap_start": "0x7EF8",
+ "himem": "0xC600",
+ "overlay_loadaddr": "0x8DFE",
+ "overlay_start": "0x8E00",
+ "overlay_window": 14336
+ },
+ "runtime_end": "0x7EF6",
+ "segments": {
+ "BSS": {
+ "end": "0x7EF6",
+ "size": 426,
+ "start": "0x7D4D"
+ },
+ "CODE": {
+ "end": "0x78BF",
+ "size": 26765,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x7CF8",
+ "size": 71,
+ "start": "0x7CB2"
+ },
+ "INIT": {
+ "end": "0x7D14",
+ "size": 28,
+ "start": "0x7CF9"
+ },
+ "ONCE": {
+ "end": "0x7D4C",
+ "size": 56,
+ "start": "0x7D15"
+ },
+ "RODATA": {
+ "end": "0x7CB1",
+ "size": 1010,
+ "start": "0x78C0"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ }
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 17635,
+ "bss_bytes": 1890,
+ "code_ro_init_bytes": 27017,
+ "data_bytes": 50,
+ "heap_capacity": 17522,
+ "heap_end": "0xC58F",
+ "heap_start": "0x811E",
+ "main_segment_total": 28957,
+ "map": "obj/launcher_easyflash.map",
+ "name": "launcher_easyflash",
+ "runtime_end": "0x811C",
+ "segments": {
+ "BSS": {
+ "end": "0x811C",
+ "size": 1890,
+ "start": "0x79BB"
+ },
+ "CODE": {
+ "end": "0x7116",
+ "size": 24804,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x7978",
+ "size": 50,
+ "start": "0x7947"
+ },
+ "INIT": {
+ "end": "0x7994",
+ "size": 28,
+ "start": "0x7979"
+ },
+ "ONCE": {
+ "end": "0x79BA",
+ "size": 38,
+ "start": "0x7995"
+ },
+ "RODATA": {
+ "end": "0x7946",
+ "size": 2096,
+ "start": "0x7117"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC5FF",
+ "app_window_headroom": 18287,
+ "bss_bytes": 426,
+ "code_ro_init_bytes": 27808,
+ "data_bytes": 71,
+ "heap_capacity": 3948,
+ "main_segment_total": 28305,
+ "map": "obj/readyshell_easyflash.map",
+ "name": "readyshell_easyflash",
+ "readyshell": {
+ "heap_end": "0x8DFD",
+ "heap_size": 3948,
+ "heap_start": "0x7E92",
+ "himem": "0xC600",
+ "overlay_loadaddr": "0x8DFE",
+ "overlay_start": "0x8E00",
+ "overlay_window": 14336
+ },
+ "runtime_end": "0x7E90",
+ "segments": {
+ "BSS": {
+ "end": "0x7E90",
+ "size": 426,
+ "start": "0x7CE7"
+ },
+ "CODE": {
+ "end": "0x7859",
+ "size": 26663,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x7C92",
+ "size": 71,
+ "start": "0x7C4C"
+ },
+ "INIT": {
+ "end": "0x7CAE",
+ "size": 28,
+ "start": "0x7C93"
+ },
+ "ONCE": {
+ "end": "0x7CE6",
+ "size": 56,
+ "start": "0x7CAF"
+ },
+ "RODATA": {
+ "end": "0x7C4B",
+ "size": 1010,
+ "start": "0x785A"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ }
+ }
+ ]
+}
diff --git a/agentworking/readyos-bank-refactor/headroom_comparison.md b/agentworking/readyos-bank-refactor/headroom_comparison.md
new file mode 100644
index 0000000..987fa39
--- /dev/null
+++ b/agentworking/readyos-bank-refactor/headroom_comparison.md
@@ -0,0 +1,35 @@
+# ReadyOS Bank Refactor Memory Comparison
+
+Generated from linker maps before and after the schema-v5 ReadyOS-bank refactor.
+Positive headroom/heap deltas mean more free C64 RAM; negative code/data/BSS deltas mean smaller linked segments.
+
+| App/map | Code/RO/init before | after | delta | Data before | after | delta | BSS before | after | delta | Heap before | after | delta | Window headroom before | after | delta |
+| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
+| launcher | 39707 | 39301 | -406 | 50 | 50 | 0 | 2421 | 2509 | 88 | 4302 | 5132 | 830 | 4414 | 5244 | 830 |
+| editor | 24533 | 24384 | -149 | 134 | 134 | 0 | 9880 | 9880 | 0 | 11932 | 12594 | 662 | 12045 | 12706 | 661 |
+| quicknotes | 31159 | 31031 | -128 | 222 | 222 | 0 | 6047 | 6047 | 0 | 9052 | 9692 | 640 | 9164 | 9804 | 640 |
+| calcplus | 37847 | 37363 | -484 | 158 | 158 | 0 | 1321 | 1321 | 0 | 7154 | 8150 | 996 | 7266 | 8262 | 996 |
+| hexview | 13495 | 12793 | -702 | 46 | 46 | 0 | 101 | 101 | 0 | 32838 | 34052 | 1214 | 32950 | 34164 | 1214 |
+| clipmgr | 31372 | 30847 | -525 | 46 | 46 | 0 | 1062 | 1062 | 0 | 14000 | 15036 | 1036 | 14112 | 15149 | 1037 |
+| reuviewer | 16863 | 15109 | -1754 | 46 | 46 | 0 | 229 | 221 | -8 | 29342 | 31616 | 2274 | 29454 | 31728 | 2274 |
+| sysinfo | 16247 | 16184 | -63 | 47 | 47 | 0 | 277 | 277 | 0 | 29908 | 30484 | 576 | 30021 | 30596 | 575 |
+| tasklist | 31112 | 31116 | 4 | 151 | 151 | 0 | 8927 | 8927 | 0 | 6290 | 6798 | 508 | 6402 | 6910 | 508 |
+| simplefiles | 29497 | 29693 | 196 | 62 | 62 | 0 | 4397 | 4397 | 0 | 12524 | 12840 | 316 | 12636 | 12952 | 316 |
+| simplecells | 34805 | 34712 | -93 | 238 | 238 | 0 | 2142 | 2142 | 0 | 9294 | 9900 | 606 | 9407 | 10012 | 605 |
+| game2048 | 16763 | 16838 | 75 | 46 | 46 | 0 | 1203 | 1203 | 0 | 28468 | 28904 | 436 | 28580 | 29017 | 437 |
+| deminer | 20103 | 20178 | 75 | 46 | 46 | 0 | 4276 | 4276 | 0 | 22054 | 22492 | 438 | 22167 | 22604 | 437 |
+| sidetris | 15312 | 15457 | 145 | 86 | 86 | 0 | 908 | 908 | 0 | 30174 | 30540 | 366 | 30286 | 30653 | 367 |
+| cal26 | 32381 | 32292 | -89 | 324 | 324 | 0 | 4803 | 4803 | 0 | 8972 | 9572 | 600 | 9084 | 9685 | 601 |
+| dizzy | 38299 | 38553 | 254 | 132 | 132 | 0 | 6327 | 6327 | 0 | 1722 | 1980 | 258 | 1834 | 2092 | 258 |
+| readyirc | 22189 | 21882 | -307 | 47 | 47 | 0 | 5351 | 5351 | 0 | 18892 | 19712 | 820 | 19005 | 19824 | 819 |
+| rirc-rrnet | 21585 | 21278 | -307 | 227 | 227 | 0 | 6909 | 6909 | 0 | 17758 | 18578 | 820 | 17871 | 18690 | 819 |
+| readybasic | 9390 | 9290 | -100 | 0 | 0 | 0 | 0 | 0 | 0 | — | — | — | 1025 | 1537 | 512 |
+| ucitest | 22583 | 22520 | -63 | 71 | 71 | 0 | 2708 | 2708 | 0 | 21118 | 21692 | 574 | 21230 | 21805 | 575 |
+| readme | 24030 | 24105 | 75 | 46 | 46 | 0 | 48 | 48 | 0 | 22356 | 22792 | 436 | 22468 | 22905 | 437 |
+| readyshell | 27910 | 28069 | 159 | 71 | 70 | -1 | 426 | 426 | 0 | 3846 | 3688 | -158 | 18185 | 18539 | 354 |
+| launcher_easyflash | 27017 | 27043 | 26 | 50 | 50 | 0 | 1890 | 1978 | 88 | 17522 | 17920 | 398 | 17635 | 18033 | 398 |
+| readyshell_easyflash | 27808 | 28149 | 341 | 71 | 71 | 0 | 426 | 426 | 0 | 3948 | 3608 | -340 | 18287 | 18458 | 171 |
+
+Before snapshot end: `0xC5FF`. After snapshot end: `0xC7FF`.
+ReadyBASIC has no conventional cc65 BSS/heap: its custom assembler/linker budget is enforced separately by `verify_readybasic_plugin.py`.
+ReadyShell heap is bounded by its unchanged overlay load address, while its full snapshot headroom includes the new app-private `$C600-$C7FF` tail.
diff --git a/agentworking/readyos-bank-refactor/headroom_comparison_optimized.md b/agentworking/readyos-bank-refactor/headroom_comparison_optimized.md
new file mode 100644
index 0000000..75041f2
--- /dev/null
+++ b/agentworking/readyos-bank-refactor/headroom_comparison_optimized.md
@@ -0,0 +1,35 @@
+# ReadyOS Bank Refactor Memory Comparison
+
+Generated from linker maps before and after the schema-v5 ReadyOS-bank refactor.
+Positive headroom/heap deltas mean more free C64 RAM; negative code/data/BSS deltas mean smaller linked segments.
+
+| App/map | Code/RO/init before | after | delta | Data before | after | delta | BSS before | after | delta | Heap before | after | delta | Window headroom before | after | delta |
+| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
+| launcher | 39707 | 39325 | -382 | 50 | 50 | 0 | 2421 | 2509 | 88 | 4302 | 5108 | 806 | 4414 | 5220 | 806 |
+| editor | 24533 | 24408 | -125 | 134 | 134 | 0 | 9880 | 9880 | 0 | 11932 | 12570 | 638 | 12045 | 12682 | 637 |
+| quicknotes | 31159 | 31055 | -104 | 222 | 222 | 0 | 6047 | 6047 | 0 | 9052 | 9668 | 616 | 9164 | 9780 | 616 |
+| calcplus | 37847 | 37397 | -450 | 158 | 158 | 0 | 1321 | 1321 | 0 | 7154 | 8116 | 962 | 7266 | 8228 | 962 |
+| hexview | 13495 | 12827 | -668 | 46 | 46 | 0 | 101 | 101 | 0 | 32838 | 34018 | 1180 | 32950 | 34130 | 1180 |
+| clipmgr | 31372 | 30881 | -491 | 46 | 46 | 0 | 1062 | 1062 | 0 | 14000 | 15002 | 1002 | 14112 | 15115 | 1003 |
+| reuviewer | 16863 | 15143 | -1720 | 46 | 46 | 0 | 229 | 221 | -8 | 29342 | 31582 | 2240 | 29454 | 31694 | 2240 |
+| sysinfo | 16247 | 16184 | -63 | 47 | 47 | 0 | 277 | 277 | 0 | 29908 | 30484 | 576 | 30021 | 30596 | 575 |
+| tasklist | 31112 | 31140 | 28 | 151 | 151 | 0 | 8927 | 8927 | 0 | 6290 | 6774 | 484 | 6402 | 6886 | 484 |
+| simplefiles | 29497 | 29717 | 220 | 62 | 62 | 0 | 4397 | 4397 | 0 | 12524 | 12816 | 292 | 12636 | 12928 | 292 |
+| simplecells | 34805 | 34736 | -69 | 238 | 238 | 0 | 2142 | 2142 | 0 | 9294 | 9876 | 582 | 9407 | 9988 | 581 |
+| game2048 | 16763 | 16872 | 109 | 46 | 46 | 0 | 1203 | 1203 | 0 | 28468 | 28870 | 402 | 28580 | 28983 | 403 |
+| deminer | 20103 | 20212 | 109 | 46 | 46 | 0 | 4276 | 4276 | 0 | 22054 | 22458 | 404 | 22167 | 22570 | 403 |
+| sidetris | 15312 | 15481 | 169 | 86 | 86 | 0 | 908 | 908 | 0 | 30174 | 30516 | 342 | 30286 | 30629 | 343 |
+| cal26 | 32381 | 32316 | -65 | 324 | 324 | 0 | 4803 | 4803 | 0 | 8972 | 9548 | 576 | 9084 | 9661 | 577 |
+| dizzy | 38299 | 38587 | 288 | 132 | 132 | 0 | 6327 | 6327 | 0 | 1722 | 1946 | 224 | 1834 | 2058 | 224 |
+| readyirc | 22189 | 21906 | -283 | 47 | 47 | 0 | 5351 | 5351 | 0 | 18892 | 19688 | 796 | 19005 | 19800 | 795 |
+| rirc-rrnet | 21585 | 21302 | -283 | 227 | 227 | 0 | 6909 | 6909 | 0 | 17758 | 18554 | 796 | 17871 | 18666 | 795 |
+| readybasic | 9390 | 9290 | -100 | 0 | 0 | 0 | 0 | 0 | 0 | — | — | — | 1025 | 1537 | 512 |
+| ucitest | 22583 | 22520 | -63 | 71 | 71 | 0 | 2708 | 2708 | 0 | 21118 | 21692 | 574 | 21230 | 21805 | 575 |
+| readme | 24030 | 24139 | 109 | 46 | 46 | 0 | 48 | 48 | 0 | 22356 | 22758 | 402 | 22468 | 22871 | 403 |
+| readyshell | 27910 | 28188 | 278 | 71 | 71 | 0 | 426 | 426 | 0 | 3846 | 3568 | -278 | 18185 | 18419 | 234 |
+| launcher_easyflash | 27017 | 27043 | 26 | 50 | 50 | 0 | 1890 | 1978 | 88 | 17522 | 17920 | 398 | 17635 | 18033 | 398 |
+| readyshell_easyflash | 27808 | 28149 | 341 | 71 | 71 | 0 | 426 | 426 | 0 | 3948 | 3608 | -340 | 18287 | 18458 | 171 |
+
+Before snapshot end: `0xC5FF`. After snapshot end: `0xC7FF`.
+ReadyBASIC has no conventional cc65 BSS/heap: its custom assembler/linker budget is enforced separately by `verify_readybasic_plugin.py`.
+ReadyShell heap is bounded by its unchanged overlay load address, while its full snapshot headroom includes the new app-private `$C600-$C7FF` tail.
diff --git a/agentworking/readyos-bank-refactor/headroom_current_final.json b/agentworking/readyos-bank-refactor/headroom_current_final.json
new file mode 100644
index 0000000..cd429f9
--- /dev/null
+++ b/agentworking/readyos-bank-refactor/headroom_current_final.json
@@ -0,0 +1,1242 @@
+{
+ "app_window_end": "0xC7FF",
+ "app_window_start": "0x1000",
+ "maps": [
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 5244,
+ "bss_bytes": 2509,
+ "code_ro_init_bytes": 39301,
+ "data_bytes": 50,
+ "heap_capacity": 5132,
+ "heap_end": "0xC78F",
+ "heap_start": "0xB384",
+ "main_segment_total": 41860,
+ "map": "obj/launcher.map",
+ "name": "launcher",
+ "runtime_end": "0xB383",
+ "segments": {
+ "BSS": {
+ "end": "0xB383",
+ "size": 2509,
+ "start": "0xA9B7"
+ },
+ "CODE": {
+ "end": "0xA3A3",
+ "size": 37745,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0xA974",
+ "size": 50,
+ "start": "0xA943"
+ },
+ "INIT": {
+ "end": "0xA990",
+ "size": 28,
+ "start": "0xA975"
+ },
+ "ONCE": {
+ "end": "0xA9B6",
+ "size": 38,
+ "start": "0xA991"
+ },
+ "RODATA": {
+ "end": "0xA942",
+ "size": 1439,
+ "start": "0xA3A4"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 12706,
+ "bss_bytes": 9880,
+ "code_ro_init_bytes": 24384,
+ "data_bytes": 134,
+ "heap_capacity": 12594,
+ "heap_end": "0xC78F",
+ "heap_start": "0x965E",
+ "main_segment_total": 34398,
+ "map": "obj/editor.map",
+ "name": "editor",
+ "runtime_end": "0x965D",
+ "segments": {
+ "BSS": {
+ "end": "0x965D",
+ "size": 9880,
+ "start": "0x6FC6"
+ },
+ "CODE": {
+ "end": "0x6BBF",
+ "size": 23437,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x6F83",
+ "size": 134,
+ "start": "0x6EFE"
+ },
+ "INIT": {
+ "end": "0x6F9F",
+ "size": 28,
+ "start": "0x6F84"
+ },
+ "ONCE": {
+ "end": "0x6FC5",
+ "size": 38,
+ "start": "0x6FA0"
+ },
+ "RODATA": {
+ "end": "0x6EFD",
+ "size": 830,
+ "start": "0x6BC0"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 9804,
+ "bss_bytes": 6047,
+ "code_ro_init_bytes": 31031,
+ "data_bytes": 222,
+ "heap_capacity": 9692,
+ "heap_end": "0xC78F",
+ "heap_start": "0xA1B4",
+ "main_segment_total": 37300,
+ "map": "obj/quicknotes.map",
+ "name": "quicknotes",
+ "runtime_end": "0xA1B3",
+ "segments": {
+ "BSS": {
+ "end": "0xA1B3",
+ "size": 6047,
+ "start": "0x8A15"
+ },
+ "CODE": {
+ "end": "0x853F",
+ "size": 29965,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x89D2",
+ "size": 222,
+ "start": "0x88F5"
+ },
+ "INIT": {
+ "end": "0x89EE",
+ "size": 28,
+ "start": "0x89D3"
+ },
+ "ONCE": {
+ "end": "0x8A14",
+ "size": 38,
+ "start": "0x89EF"
+ },
+ "RODATA": {
+ "end": "0x88F4",
+ "size": 949,
+ "start": "0x8540"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 8262,
+ "bss_bytes": 1321,
+ "code_ro_init_bytes": 37363,
+ "data_bytes": 158,
+ "heap_capacity": 8150,
+ "heap_end": "0xC78F",
+ "heap_start": "0xA7BA",
+ "main_segment_total": 38842,
+ "map": "obj/calcplus.map",
+ "name": "calcplus",
+ "runtime_end": "0xA7B9",
+ "segments": {
+ "BSS": {
+ "end": "0xA7B9",
+ "size": 1321,
+ "start": "0xA291"
+ },
+ "CODE": {
+ "end": "0x9D1B",
+ "size": 36073,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0xA24E",
+ "size": 158,
+ "start": "0xA1B1"
+ },
+ "INIT": {
+ "end": "0xA26A",
+ "size": 28,
+ "start": "0xA24F"
+ },
+ "ONCE": {
+ "end": "0xA290",
+ "size": 38,
+ "start": "0xA26B"
+ },
+ "RODATA": {
+ "end": "0xA1B0",
+ "size": 1173,
+ "start": "0x9D1C"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 34164,
+ "bss_bytes": 101,
+ "code_ro_init_bytes": 12793,
+ "data_bytes": 46,
+ "heap_capacity": 34052,
+ "heap_end": "0xC78F",
+ "heap_start": "0x428C",
+ "main_segment_total": 12940,
+ "map": "obj/hexview.map",
+ "name": "hexview",
+ "runtime_end": "0x428B",
+ "segments": {
+ "BSS": {
+ "end": "0x428B",
+ "size": 101,
+ "start": "0x4227"
+ },
+ "CODE": {
+ "end": "0x3FC4",
+ "size": 12178,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x41E4",
+ "size": 46,
+ "start": "0x41B7"
+ },
+ "INIT": {
+ "end": "0x4200",
+ "size": 28,
+ "start": "0x41E5"
+ },
+ "ONCE": {
+ "end": "0x4226",
+ "size": 38,
+ "start": "0x4201"
+ },
+ "RODATA": {
+ "end": "0x41B6",
+ "size": 498,
+ "start": "0x3FC5"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 15149,
+ "bss_bytes": 1062,
+ "code_ro_init_bytes": 30847,
+ "data_bytes": 46,
+ "heap_capacity": 15036,
+ "heap_end": "0xC78F",
+ "heap_start": "0x8CD4",
+ "main_segment_total": 31955,
+ "map": "obj/clipmgr.map",
+ "name": "clipmgr",
+ "runtime_end": "0x8CD2",
+ "segments": {
+ "BSS": {
+ "end": "0x8CD2",
+ "size": 1062,
+ "start": "0x88AD"
+ },
+ "CODE": {
+ "end": "0x84F2",
+ "size": 29888,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x886A",
+ "size": 46,
+ "start": "0x883D"
+ },
+ "INIT": {
+ "end": "0x8886",
+ "size": 28,
+ "start": "0x886B"
+ },
+ "ONCE": {
+ "end": "0x88AC",
+ "size": 38,
+ "start": "0x8887"
+ },
+ "RODATA": {
+ "end": "0x883C",
+ "size": 842,
+ "start": "0x84F3"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 31728,
+ "bss_bytes": 221,
+ "code_ro_init_bytes": 15109,
+ "data_bytes": 46,
+ "heap_capacity": 31616,
+ "heap_end": "0xC78F",
+ "heap_start": "0x4C10",
+ "main_segment_total": 15376,
+ "map": "obj/reuviewer.map",
+ "name": "reuviewer",
+ "runtime_end": "0x4C0F",
+ "segments": {
+ "BSS": {
+ "end": "0x4C0F",
+ "size": 221,
+ "start": "0x4B33"
+ },
+ "CODE": {
+ "end": "0x496B",
+ "size": 14649,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x4AF0",
+ "size": 46,
+ "start": "0x4AC3"
+ },
+ "INIT": {
+ "end": "0x4B0C",
+ "size": 28,
+ "start": "0x4AF1"
+ },
+ "ONCE": {
+ "end": "0x4B32",
+ "size": 38,
+ "start": "0x4B0D"
+ },
+ "RODATA": {
+ "end": "0x4AC2",
+ "size": 343,
+ "start": "0x496C"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 30596,
+ "bss_bytes": 277,
+ "code_ro_init_bytes": 16184,
+ "data_bytes": 47,
+ "heap_capacity": 30484,
+ "heap_end": "0xC78F",
+ "heap_start": "0x507C",
+ "main_segment_total": 16508,
+ "map": "obj/sysinfo.map",
+ "name": "sysinfo",
+ "runtime_end": "0x507B",
+ "segments": {
+ "BSS": {
+ "end": "0x507B",
+ "size": 277,
+ "start": "0x4F67"
+ },
+ "CODE": {
+ "end": "0x4ACD",
+ "size": 15003,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x4F24",
+ "size": 47,
+ "start": "0x4EF6"
+ },
+ "INIT": {
+ "end": "0x4F40",
+ "size": 28,
+ "start": "0x4F25"
+ },
+ "ONCE": {
+ "end": "0x4F66",
+ "size": 38,
+ "start": "0x4F41"
+ },
+ "RODATA": {
+ "end": "0x4EF5",
+ "size": 1064,
+ "start": "0x4ACE"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 6910,
+ "bss_bytes": 8927,
+ "code_ro_init_bytes": 31116,
+ "data_bytes": 151,
+ "heap_capacity": 6798,
+ "heap_end": "0xC78F",
+ "heap_start": "0xAD02",
+ "main_segment_total": 40194,
+ "map": "obj/tasklist.map",
+ "name": "tasklist",
+ "runtime_end": "0xAD01",
+ "segments": {
+ "BSS": {
+ "end": "0xAD01",
+ "size": 8927,
+ "start": "0x8A23"
+ },
+ "CODE": {
+ "end": "0x8614",
+ "size": 30178,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x89E0",
+ "size": 151,
+ "start": "0x894A"
+ },
+ "INIT": {
+ "end": "0x89FC",
+ "size": 28,
+ "start": "0x89E1"
+ },
+ "ONCE": {
+ "end": "0x8A22",
+ "size": 38,
+ "start": "0x89FD"
+ },
+ "RODATA": {
+ "end": "0x8949",
+ "size": 821,
+ "start": "0x8615"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 12952,
+ "bss_bytes": 4397,
+ "code_ro_init_bytes": 29693,
+ "data_bytes": 62,
+ "heap_capacity": 12840,
+ "heap_end": "0xC78F",
+ "heap_start": "0x9568",
+ "main_segment_total": 34152,
+ "map": "obj/simplefiles.map",
+ "name": "simplefiles",
+ "runtime_end": "0x9567",
+ "segments": {
+ "BSS": {
+ "end": "0x9567",
+ "size": 4397,
+ "start": "0x843B"
+ },
+ "CODE": {
+ "end": "0x7EED",
+ "size": 28347,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x83F8",
+ "size": 62,
+ "start": "0x83BB"
+ },
+ "INIT": {
+ "end": "0x8414",
+ "size": 28,
+ "start": "0x83F9"
+ },
+ "ONCE": {
+ "end": "0x843A",
+ "size": 38,
+ "start": "0x8415"
+ },
+ "RODATA": {
+ "end": "0x83BA",
+ "size": 1229,
+ "start": "0x7EEE"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 10012,
+ "bss_bytes": 2142,
+ "code_ro_init_bytes": 34712,
+ "data_bytes": 238,
+ "heap_capacity": 9900,
+ "heap_end": "0xC78F",
+ "heap_start": "0xA0E4",
+ "main_segment_total": 37092,
+ "map": "obj/simplecells.map",
+ "name": "simplecells",
+ "runtime_end": "0xA0E3",
+ "segments": {
+ "BSS": {
+ "end": "0xA0E3",
+ "size": 2142,
+ "start": "0x9886"
+ },
+ "CODE": {
+ "end": "0x909B",
+ "size": 32873,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x9843",
+ "size": 238,
+ "start": "0x9756"
+ },
+ "INIT": {
+ "end": "0x985F",
+ "size": 28,
+ "start": "0x9844"
+ },
+ "ONCE": {
+ "end": "0x9885",
+ "size": 38,
+ "start": "0x9860"
+ },
+ "RODATA": {
+ "end": "0x9755",
+ "size": 1722,
+ "start": "0x909C"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 29017,
+ "bss_bytes": 1203,
+ "code_ro_init_bytes": 16838,
+ "data_bytes": 46,
+ "heap_capacity": 28904,
+ "heap_end": "0xC78F",
+ "heap_start": "0x56A8",
+ "main_segment_total": 18087,
+ "map": "obj/game2048.map",
+ "name": "game2048",
+ "runtime_end": "0x56A6",
+ "segments": {
+ "BSS": {
+ "end": "0x56A6",
+ "size": 1203,
+ "start": "0x51F4"
+ },
+ "CODE": {
+ "end": "0x5053",
+ "size": 16417,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x51B1",
+ "size": 46,
+ "start": "0x5184"
+ },
+ "INIT": {
+ "end": "0x51CD",
+ "size": 28,
+ "start": "0x51B2"
+ },
+ "ONCE": {
+ "end": "0x51F3",
+ "size": 38,
+ "start": "0x51CE"
+ },
+ "RODATA": {
+ "end": "0x5183",
+ "size": 304,
+ "start": "0x5054"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 22604,
+ "bss_bytes": 4276,
+ "code_ro_init_bytes": 20178,
+ "data_bytes": 46,
+ "heap_capacity": 22492,
+ "heap_end": "0xC78F",
+ "heap_start": "0x6FB4",
+ "main_segment_total": 24500,
+ "map": "obj/deminer.map",
+ "name": "deminer",
+ "runtime_end": "0x6FB3",
+ "segments": {
+ "BSS": {
+ "end": "0x6FB3",
+ "size": 4276,
+ "start": "0x5F00"
+ },
+ "CODE": {
+ "end": "0x5BA4",
+ "size": 19314,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x5EBD",
+ "size": 46,
+ "start": "0x5E90"
+ },
+ "INIT": {
+ "end": "0x5ED9",
+ "size": 28,
+ "start": "0x5EBE"
+ },
+ "ONCE": {
+ "end": "0x5EFF",
+ "size": 38,
+ "start": "0x5EDA"
+ },
+ "RODATA": {
+ "end": "0x5E8F",
+ "size": 747,
+ "start": "0x5BA5"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 30653,
+ "bss_bytes": 908,
+ "code_ro_init_bytes": 15457,
+ "data_bytes": 86,
+ "heap_capacity": 30540,
+ "heap_end": "0xC78F",
+ "heap_start": "0x5044",
+ "main_segment_total": 16451,
+ "map": "obj/sidetris.map",
+ "name": "sidetris",
+ "runtime_end": "0x5042",
+ "segments": {
+ "BSS": {
+ "end": "0x5042",
+ "size": 908,
+ "start": "0x4CB7"
+ },
+ "CODE": {
+ "end": "0x481B",
+ "size": 14313,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x4C74",
+ "size": 86,
+ "start": "0x4C1F"
+ },
+ "INIT": {
+ "end": "0x4C90",
+ "size": 28,
+ "start": "0x4C75"
+ },
+ "ONCE": {
+ "end": "0x4CB6",
+ "size": 38,
+ "start": "0x4C91"
+ },
+ "RODATA": {
+ "end": "0x4C1E",
+ "size": 1027,
+ "start": "0x481C"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 9685,
+ "bss_bytes": 4803,
+ "code_ro_init_bytes": 32292,
+ "data_bytes": 324,
+ "heap_capacity": 9572,
+ "heap_end": "0xC78F",
+ "heap_start": "0xA22C",
+ "main_segment_total": 37419,
+ "map": "obj/cal26.map",
+ "name": "cal26",
+ "runtime_end": "0xA22A",
+ "segments": {
+ "BSS": {
+ "end": "0xA22A",
+ "size": 4803,
+ "start": "0x8F68"
+ },
+ "CODE": {
+ "end": "0x8694",
+ "size": 30306,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x8F25",
+ "size": 324,
+ "start": "0x8DE2"
+ },
+ "INIT": {
+ "end": "0x8F41",
+ "size": 28,
+ "start": "0x8F26"
+ },
+ "ONCE": {
+ "end": "0x8F67",
+ "size": 38,
+ "start": "0x8F42"
+ },
+ "RODATA": {
+ "end": "0x8DE1",
+ "size": 1869,
+ "start": "0x8695"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 2092,
+ "bss_bytes": 6327,
+ "code_ro_init_bytes": 38553,
+ "data_bytes": 132,
+ "heap_capacity": 1980,
+ "heap_end": "0xC78F",
+ "heap_start": "0xBFD4",
+ "main_segment_total": 45012,
+ "map": "obj/dizzy.map",
+ "name": "dizzy",
+ "runtime_end": "0xBFD3",
+ "segments": {
+ "BSS": {
+ "end": "0xBFD3",
+ "size": 6327,
+ "start": "0xA71D"
+ },
+ "CODE": {
+ "end": "0xA18D",
+ "size": 37211,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0xA6DA",
+ "size": 132,
+ "start": "0xA657"
+ },
+ "INIT": {
+ "end": "0xA6F6",
+ "size": 28,
+ "start": "0xA6DB"
+ },
+ "ONCE": {
+ "end": "0xA71C",
+ "size": 38,
+ "start": "0xA6F7"
+ },
+ "RODATA": {
+ "end": "0xA656",
+ "size": 1225,
+ "start": "0xA18E"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 19824,
+ "bss_bytes": 5351,
+ "code_ro_init_bytes": 21882,
+ "data_bytes": 47,
+ "heap_capacity": 19712,
+ "heap_end": "0xC78F",
+ "heap_start": "0x7A90",
+ "main_segment_total": 27280,
+ "map": "obj/readyirc.map",
+ "name": "readyirc",
+ "runtime_end": "0x7A8F",
+ "segments": {
+ "BSS": {
+ "end": "0x7A8F",
+ "size": 5351,
+ "start": "0x65A9"
+ },
+ "CODE": {
+ "end": "0x619B",
+ "size": 20841,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x6566",
+ "size": 47,
+ "start": "0x6538"
+ },
+ "INIT": {
+ "end": "0x6582",
+ "size": 28,
+ "start": "0x6567"
+ },
+ "ONCE": {
+ "end": "0x65A8",
+ "size": 38,
+ "start": "0x6583"
+ },
+ "RODATA": {
+ "end": "0x6537",
+ "size": 924,
+ "start": "0x619C"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 18690,
+ "bss_bytes": 6909,
+ "code_ro_init_bytes": 21278,
+ "data_bytes": 227,
+ "heap_capacity": 18578,
+ "heap_end": "0xC78F",
+ "heap_start": "0x7EFE",
+ "main_segment_total": 28414,
+ "map": "obj/rirc-rrnet.map",
+ "name": "rirc-rrnet",
+ "runtime_end": "0x7EFD",
+ "segments": {
+ "BSS": {
+ "end": "0x7EFD",
+ "size": 6909,
+ "start": "0x6401"
+ },
+ "CODE": {
+ "end": "0x5FFD",
+ "size": 20427,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x63BE",
+ "size": 227,
+ "start": "0x62DC"
+ },
+ "INIT": {
+ "end": "0x63DA",
+ "size": 28,
+ "start": "0x63BF"
+ },
+ "ONCE": {
+ "end": "0x6400",
+ "size": 38,
+ "start": "0x63DB"
+ },
+ "RODATA": {
+ "end": "0x62DB",
+ "size": 734,
+ "start": "0x5FFE"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 1537,
+ "bss_bytes": 0,
+ "code_ro_init_bytes": 9290,
+ "data_bytes": 0,
+ "main_segment_total": 2954,
+ "map": "obj/readybasic.map",
+ "name": "readybasic",
+ "runtime_end": "0xC1FE",
+ "segments": {
+ "BRIDGE": {
+ "end": "0xC1FE",
+ "size": 511,
+ "start": "0xC000"
+ },
+ "ENTRY": {
+ "end": "0x11FF",
+ "size": 512,
+ "start": "0x1000"
+ },
+ "HIDDEN": {
+ "end": "0xA78A",
+ "size": 1931,
+ "start": "0xA000"
+ }
+ }
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 21805,
+ "bss_bytes": 2708,
+ "code_ro_init_bytes": 22520,
+ "data_bytes": 71,
+ "heap_capacity": 21692,
+ "heap_end": "0xC78F",
+ "heap_start": "0x72D4",
+ "main_segment_total": 25299,
+ "map": "obj/ucitest.map",
+ "name": "ucitest",
+ "runtime_end": "0x72D2",
+ "segments": {
+ "BSS": {
+ "end": "0x72D2",
+ "size": 2708,
+ "start": "0x683F"
+ },
+ "CODE": {
+ "end": "0x5933",
+ "size": 18689,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x67FC",
+ "size": 71,
+ "start": "0x67B6"
+ },
+ "INIT": {
+ "end": "0x6818",
+ "size": 28,
+ "start": "0x67FD"
+ },
+ "ONCE": {
+ "end": "0x683E",
+ "size": 38,
+ "start": "0x6819"
+ },
+ "RODATA": {
+ "end": "0x67B5",
+ "size": 3714,
+ "start": "0x5934"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 22905,
+ "bss_bytes": 48,
+ "code_ro_init_bytes": 24105,
+ "data_bytes": 46,
+ "heap_capacity": 22792,
+ "heap_end": "0xC78F",
+ "heap_start": "0x6E88",
+ "main_segment_total": 24199,
+ "map": "obj/readme.map",
+ "name": "readme",
+ "runtime_end": "0x6E86",
+ "segments": {
+ "BSS": {
+ "end": "0x6E86",
+ "size": 48,
+ "start": "0x6E57"
+ },
+ "CODE": {
+ "end": "0x392E",
+ "size": 10492,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x6E14",
+ "size": 46,
+ "start": "0x6DE7"
+ },
+ "INIT": {
+ "end": "0x6E30",
+ "size": 28,
+ "start": "0x6E15"
+ },
+ "ONCE": {
+ "end": "0x6E56",
+ "size": 38,
+ "start": "0x6E31"
+ },
+ "RODATA": {
+ "end": "0x6DE6",
+ "size": 13496,
+ "start": "0x392F"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 18539,
+ "bss_bytes": 426,
+ "code_ro_init_bytes": 28069,
+ "data_bytes": 70,
+ "heap_capacity": 3688,
+ "main_segment_total": 28565,
+ "map": "obj/readyshell.map",
+ "name": "readyshell",
+ "readyshell": {
+ "heap_end": "0x8DFD",
+ "heap_size": 3688,
+ "heap_start": "0x7F96",
+ "himem": "0xC600",
+ "overlay_loadaddr": "0x8DFE",
+ "overlay_start": "0x8E00",
+ "overlay_window": 14336
+ },
+ "runtime_end": "0x7F94",
+ "segments": {
+ "BSS": {
+ "end": "0x7F94",
+ "size": 426,
+ "start": "0x7DEB"
+ },
+ "CODE": {
+ "end": "0x795E",
+ "size": 26924,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x7D96",
+ "size": 70,
+ "start": "0x7D51"
+ },
+ "INIT": {
+ "end": "0x7DB2",
+ "size": 28,
+ "start": "0x7D97"
+ },
+ "ONCE": {
+ "end": "0x7DEA",
+ "size": 56,
+ "start": "0x7DB3"
+ },
+ "RODATA": {
+ "end": "0x7D50",
+ "size": 1010,
+ "start": "0x795F"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ }
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 18033,
+ "bss_bytes": 1978,
+ "code_ro_init_bytes": 27043,
+ "data_bytes": 50,
+ "heap_capacity": 17920,
+ "heap_end": "0xC78F",
+ "heap_start": "0x8190",
+ "main_segment_total": 29071,
+ "map": "obj/launcher_easyflash.map",
+ "name": "launcher_easyflash",
+ "runtime_end": "0x818E",
+ "segments": {
+ "BSS": {
+ "end": "0x818E",
+ "size": 1978,
+ "start": "0x79D5"
+ },
+ "CODE": {
+ "end": "0x711B",
+ "size": 24809,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x7992",
+ "size": 50,
+ "start": "0x7961"
+ },
+ "INIT": {
+ "end": "0x79AE",
+ "size": 28,
+ "start": "0x7993"
+ },
+ "ONCE": {
+ "end": "0x79D4",
+ "size": 38,
+ "start": "0x79AF"
+ },
+ "RODATA": {
+ "end": "0x7960",
+ "size": 2117,
+ "start": "0x711C"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 18458,
+ "bss_bytes": 426,
+ "code_ro_init_bytes": 28149,
+ "data_bytes": 71,
+ "heap_capacity": 3608,
+ "main_segment_total": 28646,
+ "map": "obj/readyshell_easyflash.map",
+ "name": "readyshell_easyflash",
+ "readyshell": {
+ "heap_end": "0x8DFD",
+ "heap_size": 3608,
+ "heap_start": "0x7FE6",
+ "himem": "0xC600",
+ "overlay_loadaddr": "0x8DFE",
+ "overlay_start": "0x8E00",
+ "overlay_window": 14336
+ },
+ "runtime_end": "0x7FE5",
+ "segments": {
+ "BSS": {
+ "end": "0x7FE5",
+ "size": 426,
+ "start": "0x7E3C"
+ },
+ "CODE": {
+ "end": "0x79AE",
+ "size": 27004,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x7DE7",
+ "size": 71,
+ "start": "0x7DA1"
+ },
+ "INIT": {
+ "end": "0x7E03",
+ "size": 28,
+ "start": "0x7DE8"
+ },
+ "ONCE": {
+ "end": "0x7E3B",
+ "size": 56,
+ "start": "0x7E04"
+ },
+ "RODATA": {
+ "end": "0x7DA0",
+ "size": 1010,
+ "start": "0x79AF"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ }
+ }
+ ]
+}
diff --git a/agentworking/readyos-bank-refactor/headroom_current_final.txt b/agentworking/readyos-bank-refactor/headroom_current_final.txt
new file mode 100644
index 0000000..cd429f9
--- /dev/null
+++ b/agentworking/readyos-bank-refactor/headroom_current_final.txt
@@ -0,0 +1,1242 @@
+{
+ "app_window_end": "0xC7FF",
+ "app_window_start": "0x1000",
+ "maps": [
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 5244,
+ "bss_bytes": 2509,
+ "code_ro_init_bytes": 39301,
+ "data_bytes": 50,
+ "heap_capacity": 5132,
+ "heap_end": "0xC78F",
+ "heap_start": "0xB384",
+ "main_segment_total": 41860,
+ "map": "obj/launcher.map",
+ "name": "launcher",
+ "runtime_end": "0xB383",
+ "segments": {
+ "BSS": {
+ "end": "0xB383",
+ "size": 2509,
+ "start": "0xA9B7"
+ },
+ "CODE": {
+ "end": "0xA3A3",
+ "size": 37745,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0xA974",
+ "size": 50,
+ "start": "0xA943"
+ },
+ "INIT": {
+ "end": "0xA990",
+ "size": 28,
+ "start": "0xA975"
+ },
+ "ONCE": {
+ "end": "0xA9B6",
+ "size": 38,
+ "start": "0xA991"
+ },
+ "RODATA": {
+ "end": "0xA942",
+ "size": 1439,
+ "start": "0xA3A4"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 12706,
+ "bss_bytes": 9880,
+ "code_ro_init_bytes": 24384,
+ "data_bytes": 134,
+ "heap_capacity": 12594,
+ "heap_end": "0xC78F",
+ "heap_start": "0x965E",
+ "main_segment_total": 34398,
+ "map": "obj/editor.map",
+ "name": "editor",
+ "runtime_end": "0x965D",
+ "segments": {
+ "BSS": {
+ "end": "0x965D",
+ "size": 9880,
+ "start": "0x6FC6"
+ },
+ "CODE": {
+ "end": "0x6BBF",
+ "size": 23437,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x6F83",
+ "size": 134,
+ "start": "0x6EFE"
+ },
+ "INIT": {
+ "end": "0x6F9F",
+ "size": 28,
+ "start": "0x6F84"
+ },
+ "ONCE": {
+ "end": "0x6FC5",
+ "size": 38,
+ "start": "0x6FA0"
+ },
+ "RODATA": {
+ "end": "0x6EFD",
+ "size": 830,
+ "start": "0x6BC0"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 9804,
+ "bss_bytes": 6047,
+ "code_ro_init_bytes": 31031,
+ "data_bytes": 222,
+ "heap_capacity": 9692,
+ "heap_end": "0xC78F",
+ "heap_start": "0xA1B4",
+ "main_segment_total": 37300,
+ "map": "obj/quicknotes.map",
+ "name": "quicknotes",
+ "runtime_end": "0xA1B3",
+ "segments": {
+ "BSS": {
+ "end": "0xA1B3",
+ "size": 6047,
+ "start": "0x8A15"
+ },
+ "CODE": {
+ "end": "0x853F",
+ "size": 29965,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x89D2",
+ "size": 222,
+ "start": "0x88F5"
+ },
+ "INIT": {
+ "end": "0x89EE",
+ "size": 28,
+ "start": "0x89D3"
+ },
+ "ONCE": {
+ "end": "0x8A14",
+ "size": 38,
+ "start": "0x89EF"
+ },
+ "RODATA": {
+ "end": "0x88F4",
+ "size": 949,
+ "start": "0x8540"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 8262,
+ "bss_bytes": 1321,
+ "code_ro_init_bytes": 37363,
+ "data_bytes": 158,
+ "heap_capacity": 8150,
+ "heap_end": "0xC78F",
+ "heap_start": "0xA7BA",
+ "main_segment_total": 38842,
+ "map": "obj/calcplus.map",
+ "name": "calcplus",
+ "runtime_end": "0xA7B9",
+ "segments": {
+ "BSS": {
+ "end": "0xA7B9",
+ "size": 1321,
+ "start": "0xA291"
+ },
+ "CODE": {
+ "end": "0x9D1B",
+ "size": 36073,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0xA24E",
+ "size": 158,
+ "start": "0xA1B1"
+ },
+ "INIT": {
+ "end": "0xA26A",
+ "size": 28,
+ "start": "0xA24F"
+ },
+ "ONCE": {
+ "end": "0xA290",
+ "size": 38,
+ "start": "0xA26B"
+ },
+ "RODATA": {
+ "end": "0xA1B0",
+ "size": 1173,
+ "start": "0x9D1C"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 34164,
+ "bss_bytes": 101,
+ "code_ro_init_bytes": 12793,
+ "data_bytes": 46,
+ "heap_capacity": 34052,
+ "heap_end": "0xC78F",
+ "heap_start": "0x428C",
+ "main_segment_total": 12940,
+ "map": "obj/hexview.map",
+ "name": "hexview",
+ "runtime_end": "0x428B",
+ "segments": {
+ "BSS": {
+ "end": "0x428B",
+ "size": 101,
+ "start": "0x4227"
+ },
+ "CODE": {
+ "end": "0x3FC4",
+ "size": 12178,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x41E4",
+ "size": 46,
+ "start": "0x41B7"
+ },
+ "INIT": {
+ "end": "0x4200",
+ "size": 28,
+ "start": "0x41E5"
+ },
+ "ONCE": {
+ "end": "0x4226",
+ "size": 38,
+ "start": "0x4201"
+ },
+ "RODATA": {
+ "end": "0x41B6",
+ "size": 498,
+ "start": "0x3FC5"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 15149,
+ "bss_bytes": 1062,
+ "code_ro_init_bytes": 30847,
+ "data_bytes": 46,
+ "heap_capacity": 15036,
+ "heap_end": "0xC78F",
+ "heap_start": "0x8CD4",
+ "main_segment_total": 31955,
+ "map": "obj/clipmgr.map",
+ "name": "clipmgr",
+ "runtime_end": "0x8CD2",
+ "segments": {
+ "BSS": {
+ "end": "0x8CD2",
+ "size": 1062,
+ "start": "0x88AD"
+ },
+ "CODE": {
+ "end": "0x84F2",
+ "size": 29888,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x886A",
+ "size": 46,
+ "start": "0x883D"
+ },
+ "INIT": {
+ "end": "0x8886",
+ "size": 28,
+ "start": "0x886B"
+ },
+ "ONCE": {
+ "end": "0x88AC",
+ "size": 38,
+ "start": "0x8887"
+ },
+ "RODATA": {
+ "end": "0x883C",
+ "size": 842,
+ "start": "0x84F3"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 31728,
+ "bss_bytes": 221,
+ "code_ro_init_bytes": 15109,
+ "data_bytes": 46,
+ "heap_capacity": 31616,
+ "heap_end": "0xC78F",
+ "heap_start": "0x4C10",
+ "main_segment_total": 15376,
+ "map": "obj/reuviewer.map",
+ "name": "reuviewer",
+ "runtime_end": "0x4C0F",
+ "segments": {
+ "BSS": {
+ "end": "0x4C0F",
+ "size": 221,
+ "start": "0x4B33"
+ },
+ "CODE": {
+ "end": "0x496B",
+ "size": 14649,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x4AF0",
+ "size": 46,
+ "start": "0x4AC3"
+ },
+ "INIT": {
+ "end": "0x4B0C",
+ "size": 28,
+ "start": "0x4AF1"
+ },
+ "ONCE": {
+ "end": "0x4B32",
+ "size": 38,
+ "start": "0x4B0D"
+ },
+ "RODATA": {
+ "end": "0x4AC2",
+ "size": 343,
+ "start": "0x496C"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 30596,
+ "bss_bytes": 277,
+ "code_ro_init_bytes": 16184,
+ "data_bytes": 47,
+ "heap_capacity": 30484,
+ "heap_end": "0xC78F",
+ "heap_start": "0x507C",
+ "main_segment_total": 16508,
+ "map": "obj/sysinfo.map",
+ "name": "sysinfo",
+ "runtime_end": "0x507B",
+ "segments": {
+ "BSS": {
+ "end": "0x507B",
+ "size": 277,
+ "start": "0x4F67"
+ },
+ "CODE": {
+ "end": "0x4ACD",
+ "size": 15003,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x4F24",
+ "size": 47,
+ "start": "0x4EF6"
+ },
+ "INIT": {
+ "end": "0x4F40",
+ "size": 28,
+ "start": "0x4F25"
+ },
+ "ONCE": {
+ "end": "0x4F66",
+ "size": 38,
+ "start": "0x4F41"
+ },
+ "RODATA": {
+ "end": "0x4EF5",
+ "size": 1064,
+ "start": "0x4ACE"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 6910,
+ "bss_bytes": 8927,
+ "code_ro_init_bytes": 31116,
+ "data_bytes": 151,
+ "heap_capacity": 6798,
+ "heap_end": "0xC78F",
+ "heap_start": "0xAD02",
+ "main_segment_total": 40194,
+ "map": "obj/tasklist.map",
+ "name": "tasklist",
+ "runtime_end": "0xAD01",
+ "segments": {
+ "BSS": {
+ "end": "0xAD01",
+ "size": 8927,
+ "start": "0x8A23"
+ },
+ "CODE": {
+ "end": "0x8614",
+ "size": 30178,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x89E0",
+ "size": 151,
+ "start": "0x894A"
+ },
+ "INIT": {
+ "end": "0x89FC",
+ "size": 28,
+ "start": "0x89E1"
+ },
+ "ONCE": {
+ "end": "0x8A22",
+ "size": 38,
+ "start": "0x89FD"
+ },
+ "RODATA": {
+ "end": "0x8949",
+ "size": 821,
+ "start": "0x8615"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 12952,
+ "bss_bytes": 4397,
+ "code_ro_init_bytes": 29693,
+ "data_bytes": 62,
+ "heap_capacity": 12840,
+ "heap_end": "0xC78F",
+ "heap_start": "0x9568",
+ "main_segment_total": 34152,
+ "map": "obj/simplefiles.map",
+ "name": "simplefiles",
+ "runtime_end": "0x9567",
+ "segments": {
+ "BSS": {
+ "end": "0x9567",
+ "size": 4397,
+ "start": "0x843B"
+ },
+ "CODE": {
+ "end": "0x7EED",
+ "size": 28347,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x83F8",
+ "size": 62,
+ "start": "0x83BB"
+ },
+ "INIT": {
+ "end": "0x8414",
+ "size": 28,
+ "start": "0x83F9"
+ },
+ "ONCE": {
+ "end": "0x843A",
+ "size": 38,
+ "start": "0x8415"
+ },
+ "RODATA": {
+ "end": "0x83BA",
+ "size": 1229,
+ "start": "0x7EEE"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 10012,
+ "bss_bytes": 2142,
+ "code_ro_init_bytes": 34712,
+ "data_bytes": 238,
+ "heap_capacity": 9900,
+ "heap_end": "0xC78F",
+ "heap_start": "0xA0E4",
+ "main_segment_total": 37092,
+ "map": "obj/simplecells.map",
+ "name": "simplecells",
+ "runtime_end": "0xA0E3",
+ "segments": {
+ "BSS": {
+ "end": "0xA0E3",
+ "size": 2142,
+ "start": "0x9886"
+ },
+ "CODE": {
+ "end": "0x909B",
+ "size": 32873,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x9843",
+ "size": 238,
+ "start": "0x9756"
+ },
+ "INIT": {
+ "end": "0x985F",
+ "size": 28,
+ "start": "0x9844"
+ },
+ "ONCE": {
+ "end": "0x9885",
+ "size": 38,
+ "start": "0x9860"
+ },
+ "RODATA": {
+ "end": "0x9755",
+ "size": 1722,
+ "start": "0x909C"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 29017,
+ "bss_bytes": 1203,
+ "code_ro_init_bytes": 16838,
+ "data_bytes": 46,
+ "heap_capacity": 28904,
+ "heap_end": "0xC78F",
+ "heap_start": "0x56A8",
+ "main_segment_total": 18087,
+ "map": "obj/game2048.map",
+ "name": "game2048",
+ "runtime_end": "0x56A6",
+ "segments": {
+ "BSS": {
+ "end": "0x56A6",
+ "size": 1203,
+ "start": "0x51F4"
+ },
+ "CODE": {
+ "end": "0x5053",
+ "size": 16417,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x51B1",
+ "size": 46,
+ "start": "0x5184"
+ },
+ "INIT": {
+ "end": "0x51CD",
+ "size": 28,
+ "start": "0x51B2"
+ },
+ "ONCE": {
+ "end": "0x51F3",
+ "size": 38,
+ "start": "0x51CE"
+ },
+ "RODATA": {
+ "end": "0x5183",
+ "size": 304,
+ "start": "0x5054"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 22604,
+ "bss_bytes": 4276,
+ "code_ro_init_bytes": 20178,
+ "data_bytes": 46,
+ "heap_capacity": 22492,
+ "heap_end": "0xC78F",
+ "heap_start": "0x6FB4",
+ "main_segment_total": 24500,
+ "map": "obj/deminer.map",
+ "name": "deminer",
+ "runtime_end": "0x6FB3",
+ "segments": {
+ "BSS": {
+ "end": "0x6FB3",
+ "size": 4276,
+ "start": "0x5F00"
+ },
+ "CODE": {
+ "end": "0x5BA4",
+ "size": 19314,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x5EBD",
+ "size": 46,
+ "start": "0x5E90"
+ },
+ "INIT": {
+ "end": "0x5ED9",
+ "size": 28,
+ "start": "0x5EBE"
+ },
+ "ONCE": {
+ "end": "0x5EFF",
+ "size": 38,
+ "start": "0x5EDA"
+ },
+ "RODATA": {
+ "end": "0x5E8F",
+ "size": 747,
+ "start": "0x5BA5"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 30653,
+ "bss_bytes": 908,
+ "code_ro_init_bytes": 15457,
+ "data_bytes": 86,
+ "heap_capacity": 30540,
+ "heap_end": "0xC78F",
+ "heap_start": "0x5044",
+ "main_segment_total": 16451,
+ "map": "obj/sidetris.map",
+ "name": "sidetris",
+ "runtime_end": "0x5042",
+ "segments": {
+ "BSS": {
+ "end": "0x5042",
+ "size": 908,
+ "start": "0x4CB7"
+ },
+ "CODE": {
+ "end": "0x481B",
+ "size": 14313,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x4C74",
+ "size": 86,
+ "start": "0x4C1F"
+ },
+ "INIT": {
+ "end": "0x4C90",
+ "size": 28,
+ "start": "0x4C75"
+ },
+ "ONCE": {
+ "end": "0x4CB6",
+ "size": 38,
+ "start": "0x4C91"
+ },
+ "RODATA": {
+ "end": "0x4C1E",
+ "size": 1027,
+ "start": "0x481C"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 9685,
+ "bss_bytes": 4803,
+ "code_ro_init_bytes": 32292,
+ "data_bytes": 324,
+ "heap_capacity": 9572,
+ "heap_end": "0xC78F",
+ "heap_start": "0xA22C",
+ "main_segment_total": 37419,
+ "map": "obj/cal26.map",
+ "name": "cal26",
+ "runtime_end": "0xA22A",
+ "segments": {
+ "BSS": {
+ "end": "0xA22A",
+ "size": 4803,
+ "start": "0x8F68"
+ },
+ "CODE": {
+ "end": "0x8694",
+ "size": 30306,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x8F25",
+ "size": 324,
+ "start": "0x8DE2"
+ },
+ "INIT": {
+ "end": "0x8F41",
+ "size": 28,
+ "start": "0x8F26"
+ },
+ "ONCE": {
+ "end": "0x8F67",
+ "size": 38,
+ "start": "0x8F42"
+ },
+ "RODATA": {
+ "end": "0x8DE1",
+ "size": 1869,
+ "start": "0x8695"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 2092,
+ "bss_bytes": 6327,
+ "code_ro_init_bytes": 38553,
+ "data_bytes": 132,
+ "heap_capacity": 1980,
+ "heap_end": "0xC78F",
+ "heap_start": "0xBFD4",
+ "main_segment_total": 45012,
+ "map": "obj/dizzy.map",
+ "name": "dizzy",
+ "runtime_end": "0xBFD3",
+ "segments": {
+ "BSS": {
+ "end": "0xBFD3",
+ "size": 6327,
+ "start": "0xA71D"
+ },
+ "CODE": {
+ "end": "0xA18D",
+ "size": 37211,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0xA6DA",
+ "size": 132,
+ "start": "0xA657"
+ },
+ "INIT": {
+ "end": "0xA6F6",
+ "size": 28,
+ "start": "0xA6DB"
+ },
+ "ONCE": {
+ "end": "0xA71C",
+ "size": 38,
+ "start": "0xA6F7"
+ },
+ "RODATA": {
+ "end": "0xA656",
+ "size": 1225,
+ "start": "0xA18E"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 19824,
+ "bss_bytes": 5351,
+ "code_ro_init_bytes": 21882,
+ "data_bytes": 47,
+ "heap_capacity": 19712,
+ "heap_end": "0xC78F",
+ "heap_start": "0x7A90",
+ "main_segment_total": 27280,
+ "map": "obj/readyirc.map",
+ "name": "readyirc",
+ "runtime_end": "0x7A8F",
+ "segments": {
+ "BSS": {
+ "end": "0x7A8F",
+ "size": 5351,
+ "start": "0x65A9"
+ },
+ "CODE": {
+ "end": "0x619B",
+ "size": 20841,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x6566",
+ "size": 47,
+ "start": "0x6538"
+ },
+ "INIT": {
+ "end": "0x6582",
+ "size": 28,
+ "start": "0x6567"
+ },
+ "ONCE": {
+ "end": "0x65A8",
+ "size": 38,
+ "start": "0x6583"
+ },
+ "RODATA": {
+ "end": "0x6537",
+ "size": 924,
+ "start": "0x619C"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 18690,
+ "bss_bytes": 6909,
+ "code_ro_init_bytes": 21278,
+ "data_bytes": 227,
+ "heap_capacity": 18578,
+ "heap_end": "0xC78F",
+ "heap_start": "0x7EFE",
+ "main_segment_total": 28414,
+ "map": "obj/rirc-rrnet.map",
+ "name": "rirc-rrnet",
+ "runtime_end": "0x7EFD",
+ "segments": {
+ "BSS": {
+ "end": "0x7EFD",
+ "size": 6909,
+ "start": "0x6401"
+ },
+ "CODE": {
+ "end": "0x5FFD",
+ "size": 20427,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x63BE",
+ "size": 227,
+ "start": "0x62DC"
+ },
+ "INIT": {
+ "end": "0x63DA",
+ "size": 28,
+ "start": "0x63BF"
+ },
+ "ONCE": {
+ "end": "0x6400",
+ "size": 38,
+ "start": "0x63DB"
+ },
+ "RODATA": {
+ "end": "0x62DB",
+ "size": 734,
+ "start": "0x5FFE"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 1537,
+ "bss_bytes": 0,
+ "code_ro_init_bytes": 9290,
+ "data_bytes": 0,
+ "main_segment_total": 2954,
+ "map": "obj/readybasic.map",
+ "name": "readybasic",
+ "runtime_end": "0xC1FE",
+ "segments": {
+ "BRIDGE": {
+ "end": "0xC1FE",
+ "size": 511,
+ "start": "0xC000"
+ },
+ "ENTRY": {
+ "end": "0x11FF",
+ "size": 512,
+ "start": "0x1000"
+ },
+ "HIDDEN": {
+ "end": "0xA78A",
+ "size": 1931,
+ "start": "0xA000"
+ }
+ }
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 21805,
+ "bss_bytes": 2708,
+ "code_ro_init_bytes": 22520,
+ "data_bytes": 71,
+ "heap_capacity": 21692,
+ "heap_end": "0xC78F",
+ "heap_start": "0x72D4",
+ "main_segment_total": 25299,
+ "map": "obj/ucitest.map",
+ "name": "ucitest",
+ "runtime_end": "0x72D2",
+ "segments": {
+ "BSS": {
+ "end": "0x72D2",
+ "size": 2708,
+ "start": "0x683F"
+ },
+ "CODE": {
+ "end": "0x5933",
+ "size": 18689,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x67FC",
+ "size": 71,
+ "start": "0x67B6"
+ },
+ "INIT": {
+ "end": "0x6818",
+ "size": 28,
+ "start": "0x67FD"
+ },
+ "ONCE": {
+ "end": "0x683E",
+ "size": 38,
+ "start": "0x6819"
+ },
+ "RODATA": {
+ "end": "0x67B5",
+ "size": 3714,
+ "start": "0x5934"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 22905,
+ "bss_bytes": 48,
+ "code_ro_init_bytes": 24105,
+ "data_bytes": 46,
+ "heap_capacity": 22792,
+ "heap_end": "0xC78F",
+ "heap_start": "0x6E88",
+ "main_segment_total": 24199,
+ "map": "obj/readme.map",
+ "name": "readme",
+ "runtime_end": "0x6E86",
+ "segments": {
+ "BSS": {
+ "end": "0x6E86",
+ "size": 48,
+ "start": "0x6E57"
+ },
+ "CODE": {
+ "end": "0x392E",
+ "size": 10492,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x6E14",
+ "size": 46,
+ "start": "0x6DE7"
+ },
+ "INIT": {
+ "end": "0x6E30",
+ "size": 28,
+ "start": "0x6E15"
+ },
+ "ONCE": {
+ "end": "0x6E56",
+ "size": 38,
+ "start": "0x6E31"
+ },
+ "RODATA": {
+ "end": "0x6DE6",
+ "size": 13496,
+ "start": "0x392F"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 18539,
+ "bss_bytes": 426,
+ "code_ro_init_bytes": 28069,
+ "data_bytes": 70,
+ "heap_capacity": 3688,
+ "main_segment_total": 28565,
+ "map": "obj/readyshell.map",
+ "name": "readyshell",
+ "readyshell": {
+ "heap_end": "0x8DFD",
+ "heap_size": 3688,
+ "heap_start": "0x7F96",
+ "himem": "0xC600",
+ "overlay_loadaddr": "0x8DFE",
+ "overlay_start": "0x8E00",
+ "overlay_window": 14336
+ },
+ "runtime_end": "0x7F94",
+ "segments": {
+ "BSS": {
+ "end": "0x7F94",
+ "size": 426,
+ "start": "0x7DEB"
+ },
+ "CODE": {
+ "end": "0x795E",
+ "size": 26924,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x7D96",
+ "size": 70,
+ "start": "0x7D51"
+ },
+ "INIT": {
+ "end": "0x7DB2",
+ "size": 28,
+ "start": "0x7D97"
+ },
+ "ONCE": {
+ "end": "0x7DEA",
+ "size": 56,
+ "start": "0x7DB3"
+ },
+ "RODATA": {
+ "end": "0x7D50",
+ "size": 1010,
+ "start": "0x795F"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ }
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 18033,
+ "bss_bytes": 1978,
+ "code_ro_init_bytes": 27043,
+ "data_bytes": 50,
+ "heap_capacity": 17920,
+ "heap_end": "0xC78F",
+ "heap_start": "0x8190",
+ "main_segment_total": 29071,
+ "map": "obj/launcher_easyflash.map",
+ "name": "launcher_easyflash",
+ "runtime_end": "0x818E",
+ "segments": {
+ "BSS": {
+ "end": "0x818E",
+ "size": 1978,
+ "start": "0x79D5"
+ },
+ "CODE": {
+ "end": "0x711B",
+ "size": 24809,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x7992",
+ "size": 50,
+ "start": "0x7961"
+ },
+ "INIT": {
+ "end": "0x79AE",
+ "size": 28,
+ "start": "0x7993"
+ },
+ "ONCE": {
+ "end": "0x79D4",
+ "size": 38,
+ "start": "0x79AF"
+ },
+ "RODATA": {
+ "end": "0x7960",
+ "size": 2117,
+ "start": "0x711C"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 18458,
+ "bss_bytes": 426,
+ "code_ro_init_bytes": 28149,
+ "data_bytes": 71,
+ "heap_capacity": 3608,
+ "main_segment_total": 28646,
+ "map": "obj/readyshell_easyflash.map",
+ "name": "readyshell_easyflash",
+ "readyshell": {
+ "heap_end": "0x8DFD",
+ "heap_size": 3608,
+ "heap_start": "0x7FE6",
+ "himem": "0xC600",
+ "overlay_loadaddr": "0x8DFE",
+ "overlay_start": "0x8E00",
+ "overlay_window": 14336
+ },
+ "runtime_end": "0x7FE5",
+ "segments": {
+ "BSS": {
+ "end": "0x7FE5",
+ "size": 426,
+ "start": "0x7E3C"
+ },
+ "CODE": {
+ "end": "0x79AE",
+ "size": 27004,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x7DE7",
+ "size": 71,
+ "start": "0x7DA1"
+ },
+ "INIT": {
+ "end": "0x7E03",
+ "size": 28,
+ "start": "0x7DE8"
+ },
+ "ONCE": {
+ "end": "0x7E3B",
+ "size": 56,
+ "start": "0x7E04"
+ },
+ "RODATA": {
+ "end": "0x7DA0",
+ "size": 1010,
+ "start": "0x79AF"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ }
+ }
+ ]
+}
diff --git a/agentworking/readyos-bank-refactor/headroom_current_optimized.json b/agentworking/readyos-bank-refactor/headroom_current_optimized.json
new file mode 100644
index 0000000..5727816
--- /dev/null
+++ b/agentworking/readyos-bank-refactor/headroom_current_optimized.json
@@ -0,0 +1,1242 @@
+{
+ "app_window_end": "0xC7FF",
+ "app_window_start": "0x1000",
+ "maps": [
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 5220,
+ "bss_bytes": 2509,
+ "code_ro_init_bytes": 39325,
+ "data_bytes": 50,
+ "heap_capacity": 5108,
+ "heap_end": "0xC78F",
+ "heap_start": "0xB39C",
+ "main_segment_total": 41884,
+ "map": "obj/launcher.map",
+ "name": "launcher",
+ "runtime_end": "0xB39B",
+ "segments": {
+ "BSS": {
+ "end": "0xB39B",
+ "size": 2509,
+ "start": "0xA9CF"
+ },
+ "CODE": {
+ "end": "0xA3BB",
+ "size": 37769,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0xA98C",
+ "size": 50,
+ "start": "0xA95B"
+ },
+ "INIT": {
+ "end": "0xA9A8",
+ "size": 28,
+ "start": "0xA98D"
+ },
+ "ONCE": {
+ "end": "0xA9CE",
+ "size": 38,
+ "start": "0xA9A9"
+ },
+ "RODATA": {
+ "end": "0xA95A",
+ "size": 1439,
+ "start": "0xA3BC"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 12682,
+ "bss_bytes": 9880,
+ "code_ro_init_bytes": 24408,
+ "data_bytes": 134,
+ "heap_capacity": 12570,
+ "heap_end": "0xC78F",
+ "heap_start": "0x9676",
+ "main_segment_total": 34422,
+ "map": "obj/editor.map",
+ "name": "editor",
+ "runtime_end": "0x9675",
+ "segments": {
+ "BSS": {
+ "end": "0x9675",
+ "size": 9880,
+ "start": "0x6FDE"
+ },
+ "CODE": {
+ "end": "0x6BD7",
+ "size": 23461,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x6F9B",
+ "size": 134,
+ "start": "0x6F16"
+ },
+ "INIT": {
+ "end": "0x6FB7",
+ "size": 28,
+ "start": "0x6F9C"
+ },
+ "ONCE": {
+ "end": "0x6FDD",
+ "size": 38,
+ "start": "0x6FB8"
+ },
+ "RODATA": {
+ "end": "0x6F15",
+ "size": 830,
+ "start": "0x6BD8"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 9780,
+ "bss_bytes": 6047,
+ "code_ro_init_bytes": 31055,
+ "data_bytes": 222,
+ "heap_capacity": 9668,
+ "heap_end": "0xC78F",
+ "heap_start": "0xA1CC",
+ "main_segment_total": 37324,
+ "map": "obj/quicknotes.map",
+ "name": "quicknotes",
+ "runtime_end": "0xA1CB",
+ "segments": {
+ "BSS": {
+ "end": "0xA1CB",
+ "size": 6047,
+ "start": "0x8A2D"
+ },
+ "CODE": {
+ "end": "0x8557",
+ "size": 29989,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x89EA",
+ "size": 222,
+ "start": "0x890D"
+ },
+ "INIT": {
+ "end": "0x8A06",
+ "size": 28,
+ "start": "0x89EB"
+ },
+ "ONCE": {
+ "end": "0x8A2C",
+ "size": 38,
+ "start": "0x8A07"
+ },
+ "RODATA": {
+ "end": "0x890C",
+ "size": 949,
+ "start": "0x8558"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 8228,
+ "bss_bytes": 1321,
+ "code_ro_init_bytes": 37397,
+ "data_bytes": 158,
+ "heap_capacity": 8116,
+ "heap_end": "0xC78F",
+ "heap_start": "0xA7DC",
+ "main_segment_total": 38876,
+ "map": "obj/calcplus.map",
+ "name": "calcplus",
+ "runtime_end": "0xA7DB",
+ "segments": {
+ "BSS": {
+ "end": "0xA7DB",
+ "size": 1321,
+ "start": "0xA2B3"
+ },
+ "CODE": {
+ "end": "0x9D3D",
+ "size": 36107,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0xA270",
+ "size": 158,
+ "start": "0xA1D3"
+ },
+ "INIT": {
+ "end": "0xA28C",
+ "size": 28,
+ "start": "0xA271"
+ },
+ "ONCE": {
+ "end": "0xA2B2",
+ "size": 38,
+ "start": "0xA28D"
+ },
+ "RODATA": {
+ "end": "0xA1D2",
+ "size": 1173,
+ "start": "0x9D3E"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 34130,
+ "bss_bytes": 101,
+ "code_ro_init_bytes": 12827,
+ "data_bytes": 46,
+ "heap_capacity": 34018,
+ "heap_end": "0xC78F",
+ "heap_start": "0x42AE",
+ "main_segment_total": 12974,
+ "map": "obj/hexview.map",
+ "name": "hexview",
+ "runtime_end": "0x42AD",
+ "segments": {
+ "BSS": {
+ "end": "0x42AD",
+ "size": 101,
+ "start": "0x4249"
+ },
+ "CODE": {
+ "end": "0x3FE6",
+ "size": 12212,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x4206",
+ "size": 46,
+ "start": "0x41D9"
+ },
+ "INIT": {
+ "end": "0x4222",
+ "size": 28,
+ "start": "0x4207"
+ },
+ "ONCE": {
+ "end": "0x4248",
+ "size": 38,
+ "start": "0x4223"
+ },
+ "RODATA": {
+ "end": "0x41D8",
+ "size": 498,
+ "start": "0x3FE7"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 15115,
+ "bss_bytes": 1062,
+ "code_ro_init_bytes": 30881,
+ "data_bytes": 46,
+ "heap_capacity": 15002,
+ "heap_end": "0xC78F",
+ "heap_start": "0x8CF6",
+ "main_segment_total": 31989,
+ "map": "obj/clipmgr.map",
+ "name": "clipmgr",
+ "runtime_end": "0x8CF4",
+ "segments": {
+ "BSS": {
+ "end": "0x8CF4",
+ "size": 1062,
+ "start": "0x88CF"
+ },
+ "CODE": {
+ "end": "0x8514",
+ "size": 29922,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x888C",
+ "size": 46,
+ "start": "0x885F"
+ },
+ "INIT": {
+ "end": "0x88A8",
+ "size": 28,
+ "start": "0x888D"
+ },
+ "ONCE": {
+ "end": "0x88CE",
+ "size": 38,
+ "start": "0x88A9"
+ },
+ "RODATA": {
+ "end": "0x885E",
+ "size": 842,
+ "start": "0x8515"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 31694,
+ "bss_bytes": 221,
+ "code_ro_init_bytes": 15143,
+ "data_bytes": 46,
+ "heap_capacity": 31582,
+ "heap_end": "0xC78F",
+ "heap_start": "0x4C32",
+ "main_segment_total": 15410,
+ "map": "obj/reuviewer.map",
+ "name": "reuviewer",
+ "runtime_end": "0x4C31",
+ "segments": {
+ "BSS": {
+ "end": "0x4C31",
+ "size": 221,
+ "start": "0x4B55"
+ },
+ "CODE": {
+ "end": "0x498D",
+ "size": 14683,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x4B12",
+ "size": 46,
+ "start": "0x4AE5"
+ },
+ "INIT": {
+ "end": "0x4B2E",
+ "size": 28,
+ "start": "0x4B13"
+ },
+ "ONCE": {
+ "end": "0x4B54",
+ "size": 38,
+ "start": "0x4B2F"
+ },
+ "RODATA": {
+ "end": "0x4AE4",
+ "size": 343,
+ "start": "0x498E"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 30596,
+ "bss_bytes": 277,
+ "code_ro_init_bytes": 16184,
+ "data_bytes": 47,
+ "heap_capacity": 30484,
+ "heap_end": "0xC78F",
+ "heap_start": "0x507C",
+ "main_segment_total": 16508,
+ "map": "obj/sysinfo.map",
+ "name": "sysinfo",
+ "runtime_end": "0x507B",
+ "segments": {
+ "BSS": {
+ "end": "0x507B",
+ "size": 277,
+ "start": "0x4F67"
+ },
+ "CODE": {
+ "end": "0x4ACD",
+ "size": 15003,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x4F24",
+ "size": 47,
+ "start": "0x4EF6"
+ },
+ "INIT": {
+ "end": "0x4F40",
+ "size": 28,
+ "start": "0x4F25"
+ },
+ "ONCE": {
+ "end": "0x4F66",
+ "size": 38,
+ "start": "0x4F41"
+ },
+ "RODATA": {
+ "end": "0x4EF5",
+ "size": 1064,
+ "start": "0x4ACE"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 6886,
+ "bss_bytes": 8927,
+ "code_ro_init_bytes": 31140,
+ "data_bytes": 151,
+ "heap_capacity": 6774,
+ "heap_end": "0xC78F",
+ "heap_start": "0xAD1A",
+ "main_segment_total": 40218,
+ "map": "obj/tasklist.map",
+ "name": "tasklist",
+ "runtime_end": "0xAD19",
+ "segments": {
+ "BSS": {
+ "end": "0xAD19",
+ "size": 8927,
+ "start": "0x8A3B"
+ },
+ "CODE": {
+ "end": "0x862C",
+ "size": 30202,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x89F8",
+ "size": 151,
+ "start": "0x8962"
+ },
+ "INIT": {
+ "end": "0x8A14",
+ "size": 28,
+ "start": "0x89F9"
+ },
+ "ONCE": {
+ "end": "0x8A3A",
+ "size": 38,
+ "start": "0x8A15"
+ },
+ "RODATA": {
+ "end": "0x8961",
+ "size": 821,
+ "start": "0x862D"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 12928,
+ "bss_bytes": 4397,
+ "code_ro_init_bytes": 29717,
+ "data_bytes": 62,
+ "heap_capacity": 12816,
+ "heap_end": "0xC78F",
+ "heap_start": "0x9580",
+ "main_segment_total": 34176,
+ "map": "obj/simplefiles.map",
+ "name": "simplefiles",
+ "runtime_end": "0x957F",
+ "segments": {
+ "BSS": {
+ "end": "0x957F",
+ "size": 4397,
+ "start": "0x8453"
+ },
+ "CODE": {
+ "end": "0x7F05",
+ "size": 28371,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x8410",
+ "size": 62,
+ "start": "0x83D3"
+ },
+ "INIT": {
+ "end": "0x842C",
+ "size": 28,
+ "start": "0x8411"
+ },
+ "ONCE": {
+ "end": "0x8452",
+ "size": 38,
+ "start": "0x842D"
+ },
+ "RODATA": {
+ "end": "0x83D2",
+ "size": 1229,
+ "start": "0x7F06"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 9988,
+ "bss_bytes": 2142,
+ "code_ro_init_bytes": 34736,
+ "data_bytes": 238,
+ "heap_capacity": 9876,
+ "heap_end": "0xC78F",
+ "heap_start": "0xA0FC",
+ "main_segment_total": 37116,
+ "map": "obj/simplecells.map",
+ "name": "simplecells",
+ "runtime_end": "0xA0FB",
+ "segments": {
+ "BSS": {
+ "end": "0xA0FB",
+ "size": 2142,
+ "start": "0x989E"
+ },
+ "CODE": {
+ "end": "0x90B3",
+ "size": 32897,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x985B",
+ "size": 238,
+ "start": "0x976E"
+ },
+ "INIT": {
+ "end": "0x9877",
+ "size": 28,
+ "start": "0x985C"
+ },
+ "ONCE": {
+ "end": "0x989D",
+ "size": 38,
+ "start": "0x9878"
+ },
+ "RODATA": {
+ "end": "0x976D",
+ "size": 1722,
+ "start": "0x90B4"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 28983,
+ "bss_bytes": 1203,
+ "code_ro_init_bytes": 16872,
+ "data_bytes": 46,
+ "heap_capacity": 28870,
+ "heap_end": "0xC78F",
+ "heap_start": "0x56CA",
+ "main_segment_total": 18121,
+ "map": "obj/game2048.map",
+ "name": "game2048",
+ "runtime_end": "0x56C8",
+ "segments": {
+ "BSS": {
+ "end": "0x56C8",
+ "size": 1203,
+ "start": "0x5216"
+ },
+ "CODE": {
+ "end": "0x5075",
+ "size": 16451,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x51D3",
+ "size": 46,
+ "start": "0x51A6"
+ },
+ "INIT": {
+ "end": "0x51EF",
+ "size": 28,
+ "start": "0x51D4"
+ },
+ "ONCE": {
+ "end": "0x5215",
+ "size": 38,
+ "start": "0x51F0"
+ },
+ "RODATA": {
+ "end": "0x51A5",
+ "size": 304,
+ "start": "0x5076"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 22570,
+ "bss_bytes": 4276,
+ "code_ro_init_bytes": 20212,
+ "data_bytes": 46,
+ "heap_capacity": 22458,
+ "heap_end": "0xC78F",
+ "heap_start": "0x6FD6",
+ "main_segment_total": 24534,
+ "map": "obj/deminer.map",
+ "name": "deminer",
+ "runtime_end": "0x6FD5",
+ "segments": {
+ "BSS": {
+ "end": "0x6FD5",
+ "size": 4276,
+ "start": "0x5F22"
+ },
+ "CODE": {
+ "end": "0x5BC6",
+ "size": 19348,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x5EDF",
+ "size": 46,
+ "start": "0x5EB2"
+ },
+ "INIT": {
+ "end": "0x5EFB",
+ "size": 28,
+ "start": "0x5EE0"
+ },
+ "ONCE": {
+ "end": "0x5F21",
+ "size": 38,
+ "start": "0x5EFC"
+ },
+ "RODATA": {
+ "end": "0x5EB1",
+ "size": 747,
+ "start": "0x5BC7"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 30629,
+ "bss_bytes": 908,
+ "code_ro_init_bytes": 15481,
+ "data_bytes": 86,
+ "heap_capacity": 30516,
+ "heap_end": "0xC78F",
+ "heap_start": "0x505C",
+ "main_segment_total": 16475,
+ "map": "obj/sidetris.map",
+ "name": "sidetris",
+ "runtime_end": "0x505A",
+ "segments": {
+ "BSS": {
+ "end": "0x505A",
+ "size": 908,
+ "start": "0x4CCF"
+ },
+ "CODE": {
+ "end": "0x4833",
+ "size": 14337,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x4C8C",
+ "size": 86,
+ "start": "0x4C37"
+ },
+ "INIT": {
+ "end": "0x4CA8",
+ "size": 28,
+ "start": "0x4C8D"
+ },
+ "ONCE": {
+ "end": "0x4CCE",
+ "size": 38,
+ "start": "0x4CA9"
+ },
+ "RODATA": {
+ "end": "0x4C36",
+ "size": 1027,
+ "start": "0x4834"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 9661,
+ "bss_bytes": 4803,
+ "code_ro_init_bytes": 32316,
+ "data_bytes": 324,
+ "heap_capacity": 9548,
+ "heap_end": "0xC78F",
+ "heap_start": "0xA244",
+ "main_segment_total": 37443,
+ "map": "obj/cal26.map",
+ "name": "cal26",
+ "runtime_end": "0xA242",
+ "segments": {
+ "BSS": {
+ "end": "0xA242",
+ "size": 4803,
+ "start": "0x8F80"
+ },
+ "CODE": {
+ "end": "0x86AC",
+ "size": 30330,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x8F3D",
+ "size": 324,
+ "start": "0x8DFA"
+ },
+ "INIT": {
+ "end": "0x8F59",
+ "size": 28,
+ "start": "0x8F3E"
+ },
+ "ONCE": {
+ "end": "0x8F7F",
+ "size": 38,
+ "start": "0x8F5A"
+ },
+ "RODATA": {
+ "end": "0x8DF9",
+ "size": 1869,
+ "start": "0x86AD"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 2058,
+ "bss_bytes": 6327,
+ "code_ro_init_bytes": 38587,
+ "data_bytes": 132,
+ "heap_capacity": 1946,
+ "heap_end": "0xC78F",
+ "heap_start": "0xBFF6",
+ "main_segment_total": 45046,
+ "map": "obj/dizzy.map",
+ "name": "dizzy",
+ "runtime_end": "0xBFF5",
+ "segments": {
+ "BSS": {
+ "end": "0xBFF5",
+ "size": 6327,
+ "start": "0xA73F"
+ },
+ "CODE": {
+ "end": "0xA1AF",
+ "size": 37245,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0xA6FC",
+ "size": 132,
+ "start": "0xA679"
+ },
+ "INIT": {
+ "end": "0xA718",
+ "size": 28,
+ "start": "0xA6FD"
+ },
+ "ONCE": {
+ "end": "0xA73E",
+ "size": 38,
+ "start": "0xA719"
+ },
+ "RODATA": {
+ "end": "0xA678",
+ "size": 1225,
+ "start": "0xA1B0"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 19800,
+ "bss_bytes": 5351,
+ "code_ro_init_bytes": 21906,
+ "data_bytes": 47,
+ "heap_capacity": 19688,
+ "heap_end": "0xC78F",
+ "heap_start": "0x7AA8",
+ "main_segment_total": 27304,
+ "map": "obj/readyirc.map",
+ "name": "readyirc",
+ "runtime_end": "0x7AA7",
+ "segments": {
+ "BSS": {
+ "end": "0x7AA7",
+ "size": 5351,
+ "start": "0x65C1"
+ },
+ "CODE": {
+ "end": "0x61B3",
+ "size": 20865,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x657E",
+ "size": 47,
+ "start": "0x6550"
+ },
+ "INIT": {
+ "end": "0x659A",
+ "size": 28,
+ "start": "0x657F"
+ },
+ "ONCE": {
+ "end": "0x65C0",
+ "size": 38,
+ "start": "0x659B"
+ },
+ "RODATA": {
+ "end": "0x654F",
+ "size": 924,
+ "start": "0x61B4"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 18666,
+ "bss_bytes": 6909,
+ "code_ro_init_bytes": 21302,
+ "data_bytes": 227,
+ "heap_capacity": 18554,
+ "heap_end": "0xC78F",
+ "heap_start": "0x7F16",
+ "main_segment_total": 28438,
+ "map": "obj/rirc-rrnet.map",
+ "name": "rirc-rrnet",
+ "runtime_end": "0x7F15",
+ "segments": {
+ "BSS": {
+ "end": "0x7F15",
+ "size": 6909,
+ "start": "0x6419"
+ },
+ "CODE": {
+ "end": "0x6015",
+ "size": 20451,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x63D6",
+ "size": 227,
+ "start": "0x62F4"
+ },
+ "INIT": {
+ "end": "0x63F2",
+ "size": 28,
+ "start": "0x63D7"
+ },
+ "ONCE": {
+ "end": "0x6418",
+ "size": 38,
+ "start": "0x63F3"
+ },
+ "RODATA": {
+ "end": "0x62F3",
+ "size": 734,
+ "start": "0x6016"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 1537,
+ "bss_bytes": 0,
+ "code_ro_init_bytes": 9290,
+ "data_bytes": 0,
+ "main_segment_total": 2954,
+ "map": "obj/readybasic.map",
+ "name": "readybasic",
+ "runtime_end": "0xC1FE",
+ "segments": {
+ "BRIDGE": {
+ "end": "0xC1FE",
+ "size": 511,
+ "start": "0xC000"
+ },
+ "ENTRY": {
+ "end": "0x11FF",
+ "size": 512,
+ "start": "0x1000"
+ },
+ "HIDDEN": {
+ "end": "0xA78A",
+ "size": 1931,
+ "start": "0xA000"
+ }
+ }
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 21805,
+ "bss_bytes": 2708,
+ "code_ro_init_bytes": 22520,
+ "data_bytes": 71,
+ "heap_capacity": 21692,
+ "heap_end": "0xC78F",
+ "heap_start": "0x72D4",
+ "main_segment_total": 25299,
+ "map": "obj/ucitest.map",
+ "name": "ucitest",
+ "runtime_end": "0x72D2",
+ "segments": {
+ "BSS": {
+ "end": "0x72D2",
+ "size": 2708,
+ "start": "0x683F"
+ },
+ "CODE": {
+ "end": "0x5933",
+ "size": 18689,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x67FC",
+ "size": 71,
+ "start": "0x67B6"
+ },
+ "INIT": {
+ "end": "0x6818",
+ "size": 28,
+ "start": "0x67FD"
+ },
+ "ONCE": {
+ "end": "0x683E",
+ "size": 38,
+ "start": "0x6819"
+ },
+ "RODATA": {
+ "end": "0x67B5",
+ "size": 3714,
+ "start": "0x5934"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 22871,
+ "bss_bytes": 48,
+ "code_ro_init_bytes": 24139,
+ "data_bytes": 46,
+ "heap_capacity": 22758,
+ "heap_end": "0xC78F",
+ "heap_start": "0x6EAA",
+ "main_segment_total": 24233,
+ "map": "obj/readme.map",
+ "name": "readme",
+ "runtime_end": "0x6EA8",
+ "segments": {
+ "BSS": {
+ "end": "0x6EA8",
+ "size": 48,
+ "start": "0x6E79"
+ },
+ "CODE": {
+ "end": "0x3950",
+ "size": 10526,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x6E36",
+ "size": 46,
+ "start": "0x6E09"
+ },
+ "INIT": {
+ "end": "0x6E52",
+ "size": 28,
+ "start": "0x6E37"
+ },
+ "ONCE": {
+ "end": "0x6E78",
+ "size": 38,
+ "start": "0x6E53"
+ },
+ "RODATA": {
+ "end": "0x6E08",
+ "size": 13496,
+ "start": "0x3951"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 18419,
+ "bss_bytes": 426,
+ "code_ro_init_bytes": 28188,
+ "data_bytes": 71,
+ "heap_capacity": 3568,
+ "main_segment_total": 28685,
+ "map": "obj/readyshell.map",
+ "name": "readyshell",
+ "readyshell": {
+ "heap_end": "0x8DFD",
+ "heap_size": 3568,
+ "heap_start": "0x800E",
+ "himem": "0xC600",
+ "overlay_loadaddr": "0x8DFE",
+ "overlay_start": "0x8E00",
+ "overlay_window": 14336
+ },
+ "runtime_end": "0x800C",
+ "segments": {
+ "BSS": {
+ "end": "0x800C",
+ "size": 426,
+ "start": "0x7E63"
+ },
+ "CODE": {
+ "end": "0x79D5",
+ "size": 27043,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x7E0E",
+ "size": 71,
+ "start": "0x7DC8"
+ },
+ "INIT": {
+ "end": "0x7E2A",
+ "size": 28,
+ "start": "0x7E0F"
+ },
+ "ONCE": {
+ "end": "0x7E62",
+ "size": 56,
+ "start": "0x7E2B"
+ },
+ "RODATA": {
+ "end": "0x7DC7",
+ "size": 1010,
+ "start": "0x79D6"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ }
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 18033,
+ "bss_bytes": 1978,
+ "code_ro_init_bytes": 27043,
+ "data_bytes": 50,
+ "heap_capacity": 17920,
+ "heap_end": "0xC78F",
+ "heap_start": "0x8190",
+ "main_segment_total": 29071,
+ "map": "obj/launcher_easyflash.map",
+ "name": "launcher_easyflash",
+ "runtime_end": "0x818E",
+ "segments": {
+ "BSS": {
+ "end": "0x818E",
+ "size": 1978,
+ "start": "0x79D5"
+ },
+ "CODE": {
+ "end": "0x711B",
+ "size": 24809,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x7992",
+ "size": 50,
+ "start": "0x7961"
+ },
+ "INIT": {
+ "end": "0x79AE",
+ "size": 28,
+ "start": "0x7993"
+ },
+ "ONCE": {
+ "end": "0x79D4",
+ "size": 38,
+ "start": "0x79AF"
+ },
+ "RODATA": {
+ "end": "0x7960",
+ "size": 2117,
+ "start": "0x711C"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ },
+ "stack_reserve": 112
+ },
+ {
+ "app_window_end": "0xC7FF",
+ "app_window_headroom": 18458,
+ "bss_bytes": 426,
+ "code_ro_init_bytes": 28149,
+ "data_bytes": 71,
+ "heap_capacity": 3608,
+ "main_segment_total": 28646,
+ "map": "obj/readyshell_easyflash.map",
+ "name": "readyshell_easyflash",
+ "readyshell": {
+ "heap_end": "0x8DFD",
+ "heap_size": 3608,
+ "heap_start": "0x7FE6",
+ "himem": "0xC600",
+ "overlay_loadaddr": "0x8DFE",
+ "overlay_start": "0x8E00",
+ "overlay_window": 14336
+ },
+ "runtime_end": "0x7FE5",
+ "segments": {
+ "BSS": {
+ "end": "0x7FE5",
+ "size": 426,
+ "start": "0x7E3C"
+ },
+ "CODE": {
+ "end": "0x79AE",
+ "size": 27004,
+ "start": "0x1033"
+ },
+ "DATA": {
+ "end": "0x7DE7",
+ "size": 71,
+ "start": "0x7DA1"
+ },
+ "INIT": {
+ "end": "0x7E03",
+ "size": 28,
+ "start": "0x7DE8"
+ },
+ "ONCE": {
+ "end": "0x7E3B",
+ "size": 56,
+ "start": "0x7E04"
+ },
+ "RODATA": {
+ "end": "0x7DA0",
+ "size": 1010,
+ "start": "0x79AF"
+ },
+ "STARTUP": {
+ "end": "0x1032",
+ "size": 51,
+ "start": "0x1000"
+ }
+ }
+ }
+ ]
+}
diff --git a/agentworking/readyos-bank-refactor/regular-preload-debug-drive9.d81 b/agentworking/readyos-bank-refactor/regular-preload-debug-drive9.d81
new file mode 100644
index 0000000..356c19f
Binary files /dev/null and b/agentworking/readyos-bank-refactor/regular-preload-debug-drive9.d81 differ
diff --git a/agentworking/readyos-bank-refactor/regular-preload-debug.mon b/agentworking/readyos-bank-refactor/regular-preload-debug.mon
new file mode 100644
index 0000000..1eed923
--- /dev/null
+++ b/agentworking/readyos-bank-refactor/regular-preload-debug.mon
@@ -0,0 +1,16 @@
+break $6c4f
+x
+m $c800 $c83f
+> $df02 00 04 00 00 20 40 00
+> $df01 91
+m $0400 $043f
+> $df02 00 04 40 b8 20 40 00
+> $df01 91
+m $0400 $043f
+> $df02 00 04 00 00 21 40 00
+> $df01 91
+m $0400 $043f
+> $df02 00 04 40 b8 21 40 00
+> $df01 91
+m $0400 $043f
+q
diff --git a/agentworking/readyos-bank-refactor/regular-preload-debug.reu b/agentworking/readyos-bank-refactor/regular-preload-debug.reu
new file mode 100644
index 0000000..ece1779
Binary files /dev/null and b/agentworking/readyos-bank-refactor/regular-preload-debug.reu differ
diff --git a/bin/boot.prg b/bin/boot.prg
index 6278438..7031154 100644
Binary files a/bin/boot.prg and b/bin/boot.prg differ
diff --git a/bin/boot_easyflash_roml.bin b/bin/boot_easyflash_roml.bin
index 77957c0..79a3f9c 100644
Binary files a/bin/boot_easyflash_roml.bin and b/bin/boot_easyflash_roml.bin differ
diff --git a/bin/cal26.prg b/bin/cal26.prg
index ef0282c..772467f 100644
Binary files a/bin/cal26.prg and b/bin/cal26.prg differ
diff --git a/bin/calcplus.prg b/bin/calcplus.prg
index 8f68363..ae6749a 100644
Binary files a/bin/calcplus.prg and b/bin/calcplus.prg differ
diff --git a/bin/clipmgr.prg b/bin/clipmgr.prg
index fb96aec..4d9194c 100644
Binary files a/bin/clipmgr.prg and b/bin/clipmgr.prg differ
diff --git a/bin/deminer.prg b/bin/deminer.prg
index 0bde87d..f442865 100644
Binary files a/bin/deminer.prg and b/bin/deminer.prg differ
diff --git a/bin/dizzy.prg b/bin/dizzy.prg
index 067e17a..c15b9cf 100644
Binary files a/bin/dizzy.prg and b/bin/dizzy.prg differ
diff --git a/bin/easyflash_shim.bin b/bin/easyflash_shim.bin
index 2a845be..52935a9 100644
Binary files a/bin/easyflash_shim.bin and b/bin/easyflash_shim.bin differ
diff --git a/bin/editor.prg b/bin/editor.prg
index f00d7f9..79552a5 100644
Binary files a/bin/editor.prg and b/bin/editor.prg differ
diff --git a/bin/game2048.prg b/bin/game2048.prg
index 1049005..b04e48d 100644
Binary files a/bin/game2048.prg and b/bin/game2048.prg differ
diff --git a/bin/hexview.prg b/bin/hexview.prg
index e164aa6..080969d 100644
Binary files a/bin/hexview.prg and b/bin/hexview.prg differ
diff --git a/bin/launcher.prg b/bin/launcher.prg
index a87c899..e588569 100644
Binary files a/bin/launcher.prg and b/bin/launcher.prg differ
diff --git a/bin/launcher_easyflash.prg b/bin/launcher_easyflash.prg
index 6304198..313b790 100644
Binary files a/bin/launcher_easyflash.prg and b/bin/launcher_easyflash.prg differ
diff --git a/bin/quicknotes.prg b/bin/quicknotes.prg
index 90e02de..134c2e5 100644
Binary files a/bin/quicknotes.prg and b/bin/quicknotes.prg differ
diff --git a/bin/readme.prg b/bin/readme.prg
index 266ed11..dfd953e 100644
Binary files a/bin/readme.prg and b/bin/readme.prg differ
diff --git a/bin/readybasic.prg b/bin/readybasic.prg
index 5abc38e..2b55f35 100644
Binary files a/bin/readybasic.prg and b/bin/readybasic.prg differ
diff --git a/bin/readyirc.prg b/bin/readyirc.prg
index 4ceb211..3606ed4 100644
Binary files a/bin/readyirc.prg and b/bin/readyirc.prg differ
diff --git a/bin/readyshell.prg b/bin/readyshell.prg
index ced4da9..6648150 100644
Binary files a/bin/readyshell.prg and b/bin/readyshell.prg differ
diff --git a/bin/readyshell_easyflash.prg b/bin/readyshell_easyflash.prg
index 589bfb2..3d5d567 100644
Binary files a/bin/readyshell_easyflash.prg and b/bin/readyshell_easyflash.prg differ
diff --git a/bin/reuviewer.prg b/bin/reuviewer.prg
index ccaaa6e..41d9111 100644
Binary files a/bin/reuviewer.prg and b/bin/reuviewer.prg differ
diff --git a/bin/rirc-rrnet.prg b/bin/rirc-rrnet.prg
index 5e4f42b..5931bb4 100644
Binary files a/bin/rirc-rrnet.prg and b/bin/rirc-rrnet.prg differ
diff --git a/bin/rscat.prg b/bin/rscat.prg
index cbd62b8..e347b1f 100644
Binary files a/bin/rscat.prg and b/bin/rscat.prg differ
diff --git a/bin/rscopy.prg b/bin/rscopy.prg
index 26d64d0..082d84d 100644
Binary files a/bin/rscopy.prg and b/bin/rscopy.prg differ
diff --git a/bin/rsdrvilst.prg b/bin/rsdrvilst.prg
index 8f89310..553a981 100644
Binary files a/bin/rsdrvilst.prg and b/bin/rsdrvilst.prg differ
diff --git a/bin/rsedit.prg b/bin/rsedit.prg
index d65f76b..05169ff 100644
Binary files a/bin/rsedit.prg and b/bin/rsedit.prg differ
diff --git a/bin/rsfops.prg b/bin/rsfops.prg
index 2028fd5..c6695b2 100644
Binary files a/bin/rsfops.prg and b/bin/rsfops.prg differ
diff --git a/bin/rsldv.prg b/bin/rsldv.prg
index 7345d80..2fbd4ac 100644
Binary files a/bin/rsldv.prg and b/bin/rsldv.prg differ
diff --git a/bin/rsparser.prg b/bin/rsparser.prg
index 886bb5c..b3fd728 100644
Binary files a/bin/rsparser.prg and b/bin/rsparser.prg differ
diff --git a/bin/rsstv.prg b/bin/rsstv.prg
index a348b6d..d5d78b1 100644
Binary files a/bin/rsstv.prg and b/bin/rsstv.prg differ
diff --git a/bin/rsvm.prg b/bin/rsvm.prg
index c572899..efdc27a 100644
Binary files a/bin/rsvm.prg and b/bin/rsvm.prg differ
diff --git a/bin/sidetris.prg b/bin/sidetris.prg
index 9eb212b..01c50b1 100644
Binary files a/bin/sidetris.prg and b/bin/sidetris.prg differ
diff --git a/bin/simplecells.prg b/bin/simplecells.prg
index c115418..65d4582 100644
Binary files a/bin/simplecells.prg and b/bin/simplecells.prg differ
diff --git a/bin/simplefiles.prg b/bin/simplefiles.prg
index 1320636..97d0b43 100644
Binary files a/bin/simplefiles.prg and b/bin/simplefiles.prg differ
diff --git a/bin/sysinfo.prg b/bin/sysinfo.prg
index cf4d33d..76275b3 100644
Binary files a/bin/sysinfo.prg and b/bin/sysinfo.prg differ
diff --git a/bin/tasklist.prg b/bin/tasklist.prg
index 20e8fc4..013f26f 100644
Binary files a/bin/tasklist.prg and b/bin/tasklist.prg differ
diff --git a/bin/ucitest.prg b/bin/ucitest.prg
index 6decb30..58e0967 100644
Binary files a/bin/ucitest.prg and b/bin/ucitest.prg differ
diff --git a/build/uci_dma_probe/readback/probe.prg b/build/uci_dma_probe/readback/probe.prg
new file mode 100644
index 0000000..52eb98c
Binary files /dev/null and b/build/uci_dma_probe/readback/probe.prg differ
diff --git a/build/uci_dma_probe/readback/udma1.prg b/build/uci_dma_probe/readback/udma1.prg
new file mode 100644
index 0000000..c7825b7
Binary files /dev/null and b/build/uci_dma_probe/readback/udma1.prg differ
diff --git a/build/uci_dma_probe/readback/udma2.prg b/build/uci_dma_probe/readback/udma2.prg
new file mode 100644
index 0000000..0848ea6
Binary files /dev/null and b/build/uci_dma_probe/readback/udma2.prg differ
diff --git a/build/uci_dma_probe/readback/udma3.prg b/build/uci_dma_probe/readback/udma3.prg
new file mode 100644
index 0000000..678f32f
Binary files /dev/null and b/build/uci_dma_probe/readback/udma3.prg differ
diff --git a/build/uci_dma_probe/readback_d64/probe.prg b/build/uci_dma_probe/readback_d64/probe.prg
new file mode 100644
index 0000000..660849e
Binary files /dev/null and b/build/uci_dma_probe/readback_d64/probe.prg differ
diff --git a/build/uci_dma_probe/readback_d64/udma1.prg b/build/uci_dma_probe/readback_d64/udma1.prg
new file mode 100644
index 0000000..c7825b7
Binary files /dev/null and b/build/uci_dma_probe/readback_d64/udma1.prg differ
diff --git a/build/uci_dma_probe/uci_dma_probe.d64 b/build/uci_dma_probe/uci_dma_probe.d64
new file mode 100644
index 0000000..bd182b9
Binary files /dev/null and b/build/uci_dma_probe/uci_dma_probe.d64 differ
diff --git a/build/uci_dma_probe/uci_dma_probe.d81 b/build/uci_dma_probe/uci_dma_probe.d81
new file mode 100644
index 0000000..cefc870
Binary files /dev/null and b/build/uci_dma_probe/uci_dma_probe.d81 differ
diff --git a/build/uci_dma_probe/uci_dma_probe.prg b/build/uci_dma_probe/uci_dma_probe.prg
new file mode 100644
index 0000000..52eb98c
Binary files /dev/null and b/build/uci_dma_probe/uci_dma_probe.prg differ
diff --git a/build/uci_dma_probe/udma1.prg b/build/uci_dma_probe/udma1.prg
new file mode 100644
index 0000000..c7825b7
Binary files /dev/null and b/build/uci_dma_probe/udma1.prg differ
diff --git a/build/uci_dma_probe/udma2.prg b/build/uci_dma_probe/udma2.prg
new file mode 100644
index 0000000..0848ea6
Binary files /dev/null and b/build/uci_dma_probe/udma2.prg differ
diff --git a/build/uci_dma_probe/udma3.prg b/build/uci_dma_probe/udma3.prg
new file mode 100644
index 0000000..678f32f
Binary files /dev/null and b/build/uci_dma_probe/udma3.prg differ
diff --git a/build/uci_timing/apps_cfg_petscii.seq b/build/uci_timing/apps_cfg_petscii.seq
new file mode 100644
index 0000000..fbb41ef
--- /dev/null
+++ b/build/uci_timing/apps_cfg_petscii.seq
@@ -0,0 +1 @@
+[SYSTEM]
VARIANT_NAME=PRECOG D81
VARIANT_BOOT_NAME=PRECOG D81
REU_BANK_SKIP=32
[LAUNCHER]
LOAD_ALL_TO_REU=0
RUNAPPFIRST=
C64U_IMAGE_PATH=/USB1/READYOS.D81
[APPS]
8:EDITOR:EDITOR:1
TEXT EDITOR WITH CLIPBOARD
8:READYSHELL:READYSHELL (BETA):2:RSOVL+
COMMAND SHELL POC SCAFFOLD
RSPARSER@0:0000,RSVM@0:3800,RSDRVILST@0:7000,RSLDV@1:0000,RSSTV@0:A800,RSFOPS@1:3800,RSCAT@1:7000,RSCOPY@1:A800,RSEDIT@2:0000
8:SIMPLEFILES:SIMPLE FILES
DUAL PANE FILE MANAGER AND SEQ VIEWER
8:CLIPMGR:CLIPBOARD
MANAGE CLIPBOARD ITEMS
8:READYBASIC:READY BASIC (ALPHA):3:RBCORE+
SCOPED BASIC V2 BRIDGE POC
RBCORE,RBCODE
8:CAL26:CALENDAR 26
CALENDAR FOR 2026 WITH APPOINTMENTS
8:TASKLIST:TASK LIST
OUTLINER WITH NOTES AND SEARCH
8:REUVIEWER:REU VIEWER
VIEW REU MEMORY USAGE
8:SYSINFO:SYSTEM INFO
SYSTEM, REU, AND ULTIMATE STATUS
8:QUICKNOTES:QUICKNOTES
REU-BACKED NOTE EDITOR
8:CALCPLUS:CALC PLUS
KEYBOARD-FIRST EXPRESSION CALCULATOR
8:HEXVIEW:HEX VIEWER
BROWSE MEMORY IN HEX FORMAT
8:SIMPLECELLS:SIMPLE CELLS (ALPHA)
SPREADSHEET WITH FORMULAS AND COLORS
8:GAME2048:2048 GAME
2048 TILE PUZZLE
8:DEMINER:DEMINER
MINESWEEPER-STYLE PUZZLE
8:DIZZY:DIZZY KANBAN
FIZZY INSPIRED KANBAN APP
8:READYIRC:READYIRC
ULTIMATE TCP IRC CLIENT
8:UCITEST:UCI TESTER
ULTIMATE COMMAND INTERFACE LAB
8:RIRC-RRNET:READYIRC RRNET
RR-NET TCP IRC CLIENT
8:README:READ.ME
READYOS, ULTIMATE BUDDY, PRECOG POC OS
\ No newline at end of file
diff --git a/build/uci_timing/files_to_write.txt b/build/uci_timing/files_to_write.txt
new file mode 100644
index 0000000..c76ae55
--- /dev/null
+++ b/build/uci_timing/files_to_write.txt
@@ -0,0 +1,29 @@
+/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/editor.prg editor
+/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/readyshell.prg readyshell
+/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/rsparser.prg rsparser
+/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/rsvm.prg rsvm
+/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/rsdrvilst.prg rsdrvilst
+/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/rsldv.prg rsldv
+/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/rsstv.prg rsstv
+/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/rsfops.prg rsfops
+/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/rscat.prg rscat
+/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/rscopy.prg rscopy
+/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/rsedit.prg rsedit
+/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/simplefiles.prg simplefiles
+/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/clipmgr.prg clipmgr
+/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/readybasic.prg readybasic
+/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/cal26.prg cal26
+/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/tasklist.prg tasklist
+/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/reuviewer.prg reuviewer
+/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/sysinfo.prg sysinfo
+/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/quicknotes.prg quicknotes
+/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/calcplus.prg calcplus
+/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/hexview.prg hexview
+/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/simplecells.prg simplecells
+/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/game2048.prg game2048
+/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/deminer.prg deminer
+/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/dizzy.prg dizzy
+/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/readyirc.prg readyirc
+/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/ucitest.prg ucitest
+/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/rirc-rrnet.prg rirc-rrnet
+/Users/karlprosserpp/dev/c64projects/readyosprecog/bin/readme.prg readme
diff --git a/build/uci_timing/latest_1mhz_fast_raw_result.json b/build/uci_timing/latest_1mhz_fast_raw_result.json
new file mode 100644
index 0000000..5260230
--- /dev/null
+++ b/build/uci_timing/latest_1mhz_fast_raw_result.json
@@ -0,0 +1,96 @@
+{
+ "avg_header_tax_ms": 0,
+ "dir_probe": {
+ "data_len": 0,
+ "data_prefix_hex": "00000000",
+ "status_len": 0,
+ "status_prefix": ""
+ },
+ "done": 1,
+ "dump": "/private/tmp/uci_timing_probe_c64u_rest_capture/probe_results_3000.bin",
+ "failures": 0,
+ "first_failure": {
+ "debug_status0": 0,
+ "debug_status1": 0,
+ "item": 0,
+ "launcher_error": 0,
+ "name": ""
+ },
+ "header_tax_ms": 0,
+ "items": 29,
+ "loaded_kb": 607,
+ "max_load_ms": 3350,
+ "max_load_name": "editor",
+ "phases_ms": {
+ "first_load": 3350,
+ "subsequent_loads": 30383
+ },
+ "raw_phase_ticks": {
+ "first_load": 201,
+ "subsequent_loads": 1823
+ },
+ "raw_stage_ticks": {
+ "cd_dir": 22,
+ "cd_image": 22,
+ "cd_root": 20,
+ "close": 567,
+ "detect": 0,
+ "drvinfo": 19,
+ "file_info": 0,
+ "identify": 20,
+ "load_reu": 701,
+ "mount": 31,
+ "open": 620,
+ "read_header": 0,
+ "seek_payload": 0
+ },
+ "raw_subsequent_stage_ticks": {
+ "cd_dir": 0,
+ "cd_image": 0,
+ "cd_root": 0,
+ "close": 547,
+ "detect": 0,
+ "drvinfo": 0,
+ "file_info": 0,
+ "identify": 0,
+ "load_reu": 676,
+ "mount": 0,
+ "open": 598,
+ "read_header": 0,
+ "seek_payload": 0
+ },
+ "raw_total_ticks": 2024,
+ "stages_ms": {
+ "cd_dir": 367,
+ "cd_image": 367,
+ "cd_root": 333,
+ "close": 9450,
+ "detect": 0,
+ "drvinfo": 317,
+ "file_info": 0,
+ "identify": 333,
+ "load_reu": 11683,
+ "mount": 517,
+ "open": 10333,
+ "read_header": 0,
+ "seek_payload": 0
+ },
+ "subsequent_stages_ms": {
+ "cd_dir": 0,
+ "cd_image": 0,
+ "cd_root": 0,
+ "close": 9117,
+ "detect": 0,
+ "drvinfo": 0,
+ "file_info": 0,
+ "identify": 0,
+ "load_reu": 11267,
+ "mount": 0,
+ "open": 9967,
+ "read_header": 0,
+ "seek_payload": 0
+ },
+ "successes": 29,
+ "total_ms": 33733,
+ "version": 6
+}
diff --git a/build/uci_timing/latest_1mhz_large_dizzy_result.json b/build/uci_timing/latest_1mhz_large_dizzy_result.json
new file mode 100644
index 0000000..70dbd0f
--- /dev/null
+++ b/build/uci_timing/latest_1mhz_large_dizzy_result.json
@@ -0,0 +1,96 @@
+{
+ "avg_header_tax_ms": 0,
+ "dir_probe": {
+ "data_len": 0,
+ "data_prefix_hex": "00000000",
+ "status_len": 0,
+ "status_prefix": ""
+ },
+ "done": 1,
+ "dump": "/private/tmp/uci_timing_probe_c64u_rest_capture/probe_results_3000.bin",
+ "failures": 0,
+ "first_failure": {
+ "debug_status0": 0,
+ "debug_status1": 0,
+ "item": 0,
+ "launcher_error": 0,
+ "name": ""
+ },
+ "header_tax_ms": 0,
+ "items": 2,
+ "loaded_kb": 63,
+ "max_load_ms": 3367,
+ "max_load_name": "editor",
+ "phases_ms": {
+ "first_load": 3367,
+ "subsequent_loads": 1117
+ },
+ "raw_phase_ticks": {
+ "first_load": 202,
+ "subsequent_loads": 67
+ },
+ "raw_stage_ticks": {
+ "cd_dir": 22,
+ "cd_image": 23,
+ "cd_root": 19,
+ "close": 40,
+ "detect": 0,
+ "drvinfo": 20,
+ "file_info": 0,
+ "identify": 20,
+ "load_reu": 50,
+ "mount": 31,
+ "open": 44,
+ "read_header": 0,
+ "seek_payload": 0
+ },
+ "raw_subsequent_stage_ticks": {
+ "cd_dir": 0,
+ "cd_image": 0,
+ "cd_root": 0,
+ "close": 20,
+ "detect": 0,
+ "drvinfo": 0,
+ "file_info": 0,
+ "identify": 0,
+ "load_reu": 25,
+ "mount": 0,
+ "open": 22,
+ "read_header": 0,
+ "seek_payload": 0
+ },
+ "raw_total_ticks": 269,
+ "stages_ms": {
+ "cd_dir": 367,
+ "cd_image": 383,
+ "cd_root": 317,
+ "close": 667,
+ "detect": 0,
+ "drvinfo": 333,
+ "file_info": 0,
+ "identify": 333,
+ "load_reu": 833,
+ "mount": 517,
+ "open": 733,
+ "read_header": 0,
+ "seek_payload": 0
+ },
+ "subsequent_stages_ms": {
+ "cd_dir": 0,
+ "cd_image": 0,
+ "cd_root": 0,
+ "close": 333,
+ "detect": 0,
+ "drvinfo": 0,
+ "file_info": 0,
+ "identify": 0,
+ "load_reu": 417,
+ "mount": 0,
+ "open": 367,
+ "read_header": 0,
+ "seek_payload": 0
+ },
+ "successes": 2,
+ "total_ms": 4483,
+ "version": 6
+}
diff --git a/build/uci_timing/latest_1mhz_safe_result.json b/build/uci_timing/latest_1mhz_safe_result.json
new file mode 100644
index 0000000..a739d4c
--- /dev/null
+++ b/build/uci_timing/latest_1mhz_safe_result.json
@@ -0,0 +1,68 @@
+{
+ "avg_header_tax_ms": 0,
+ "dir_probe": {
+ "data_len": 0,
+ "data_prefix_hex": "00000000",
+ "status_len": 0,
+ "status_prefix": ""
+ },
+ "done": 1,
+ "dump": "/private/tmp/uci_timing_probe_c64u_rest_capture/probe_results_3000.bin",
+ "failures": 0,
+ "first_failure": {
+ "debug_status0": 0,
+ "debug_status1": 0,
+ "item": 0,
+ "launcher_error": 0,
+ "name": ""
+ },
+ "header_tax_ms": 0,
+ "items": 29,
+ "loaded_kb": 611,
+ "max_load_ms": 4417,
+ "max_load_name": "editor",
+ "phases_ms": {
+ "first_load": 4417,
+ "subsequent_loads": 79050
+ },
+ "raw_phase_ticks": {
+ "first_load": 265,
+ "subsequent_loads": 4743
+ },
+ "raw_stage_ticks": {
+ "cd_dir": 21,
+ "cd_image": 23,
+ "cd_root": 20,
+ "close": 580,
+ "detect": 0,
+ "drvinfo": 579,
+ "file_info": 634,
+ "identify": 589,
+ "load_reu": 724,
+ "mount": 32,
+ "open": 640,
+ "read_header": 582,
+ "seek_payload": 579
+ },
+ "raw_subsequent_stage_ticks": null,
+ "raw_total_ticks": 5008,
+ "stages_ms": {
+ "cd_dir": 350,
+ "cd_image": 383,
+ "cd_root": 333,
+ "close": 9667,
+ "detect": 0,
+ "drvinfo": 9650,
+ "file_info": 10567,
+ "identify": 9817,
+ "load_reu": 12067,
+ "mount": 533,
+ "open": 10667,
+ "read_header": 9700,
+ "seek_payload": 9650
+ },
+ "subsequent_stages_ms": null,
+ "successes": 29,
+ "total_ms": 83467,
+ "version": 4
+}
diff --git a/build/uci_timing/latest_1mhz_small_rsedit_result.json b/build/uci_timing/latest_1mhz_small_rsedit_result.json
new file mode 100644
index 0000000..e9e7f4f
--- /dev/null
+++ b/build/uci_timing/latest_1mhz_small_rsedit_result.json
@@ -0,0 +1,96 @@
+{
+ "avg_header_tax_ms": 0,
+ "dir_probe": {
+ "data_len": 0,
+ "data_prefix_hex": "00000000",
+ "status_len": 0,
+ "status_prefix": ""
+ },
+ "done": 1,
+ "dump": "/private/tmp/uci_timing_probe_c64u_rest_capture/probe_results_3000.bin",
+ "failures": 0,
+ "first_failure": {
+ "debug_status0": 0,
+ "debug_status1": 0,
+ "item": 0,
+ "launcher_error": 0,
+ "name": ""
+ },
+ "header_tax_ms": 0,
+ "items": 2,
+ "loaded_kb": 27,
+ "max_load_ms": 3367,
+ "max_load_name": "editor",
+ "phases_ms": {
+ "first_load": 3367,
+ "subsequent_loads": 1033
+ },
+ "raw_phase_ticks": {
+ "first_load": 202,
+ "subsequent_loads": 62
+ },
+ "raw_stage_ticks": {
+ "cd_dir": 21,
+ "cd_image": 23,
+ "cd_root": 20,
+ "close": 39,
+ "detect": 0,
+ "drvinfo": 20,
+ "file_info": 0,
+ "identify": 20,
+ "load_reu": 46,
+ "mount": 31,
+ "open": 44,
+ "read_header": 0,
+ "seek_payload": 0
+ },
+ "raw_subsequent_stage_ticks": {
+ "cd_dir": 0,
+ "cd_image": 0,
+ "cd_root": 0,
+ "close": 19,
+ "detect": 0,
+ "drvinfo": 0,
+ "file_info": 0,
+ "identify": 0,
+ "load_reu": 21,
+ "mount": 0,
+ "open": 22,
+ "read_header": 0,
+ "seek_payload": 0
+ },
+ "raw_total_ticks": 264,
+ "stages_ms": {
+ "cd_dir": 350,
+ "cd_image": 383,
+ "cd_root": 333,
+ "close": 650,
+ "detect": 0,
+ "drvinfo": 333,
+ "file_info": 0,
+ "identify": 333,
+ "load_reu": 767,
+ "mount": 517,
+ "open": 733,
+ "read_header": 0,
+ "seek_payload": 0
+ },
+ "subsequent_stages_ms": {
+ "cd_dir": 0,
+ "cd_image": 0,
+ "cd_root": 0,
+ "close": 317,
+ "detect": 0,
+ "drvinfo": 0,
+ "file_info": 0,
+ "identify": 0,
+ "load_reu": 350,
+ "mount": 0,
+ "open": 367,
+ "read_header": 0,
+ "seek_payload": 0
+ },
+ "successes": 2,
+ "total_ms": 4400,
+ "version": 6
+}
diff --git a/build/uci_timing/latest_fast_raw_result.json b/build/uci_timing/latest_fast_raw_result.json
new file mode 100644
index 0000000..3a5172d
--- /dev/null
+++ b/build/uci_timing/latest_fast_raw_result.json
@@ -0,0 +1,66 @@
+{
+ "avg_header_tax_ms": 0,
+ "dir_probe": {
+ "data_len": 0,
+ "data_prefix_hex": "00000000",
+ "status_len": 0,
+ "status_prefix": ""
+ },
+ "done": 1,
+ "dump": "/private/tmp/uci_timing_probe_c64u_rest_capture/probe_results_3000.bin",
+ "failures": 0,
+ "first_failure": {
+ "debug_status0": 0,
+ "debug_status1": 0,
+ "item": 0,
+ "launcher_error": 0,
+ "name": ""
+ },
+ "header_tax_ms": 0,
+ "items": 29,
+ "loaded_kb": 607,
+ "max_load_ms": 3300,
+ "max_load_name": "editor",
+ "phases_ms": {
+ "first_load": 3300,
+ "subsequent_loads": 30000
+ },
+ "raw_phase_ticks": {
+ "first_load": 198,
+ "subsequent_loads": 1800
+ },
+ "raw_stage_ticks": {
+ "cd_dir": 21,
+ "cd_image": 22,
+ "cd_root": 19,
+ "close": 562,
+ "detect": 0,
+ "drvinfo": 20,
+ "file_info": 0,
+ "identify": 19,
+ "load_reu": 689,
+ "mount": 31,
+ "open": 614,
+ "read_header": 0,
+ "seek_payload": 0
+ },
+ "raw_total_ticks": 1998,
+ "stages_ms": {
+ "cd_dir": 350,
+ "cd_image": 367,
+ "cd_root": 317,
+ "close": 9367,
+ "detect": 0,
+ "drvinfo": 333,
+ "file_info": 0,
+ "identify": 317,
+ "load_reu": 11483,
+ "mount": 517,
+ "open": 10233,
+ "read_header": 0,
+ "seek_payload": 0
+ },
+ "successes": 29,
+ "total_ms": 33300,
+ "version": 5
+}
diff --git a/build/uci_timing/latest_large_dizzy_result.json b/build/uci_timing/latest_large_dizzy_result.json
new file mode 100644
index 0000000..d298361
--- /dev/null
+++ b/build/uci_timing/latest_large_dizzy_result.json
@@ -0,0 +1,96 @@
+{
+ "avg_header_tax_ms": 0,
+ "dir_probe": {
+ "data_len": 0,
+ "data_prefix_hex": "00000000",
+ "status_len": 0,
+ "status_prefix": ""
+ },
+ "done": 1,
+ "dump": "/private/tmp/uci_timing_probe_c64u_rest_capture/probe_results_3000.bin",
+ "failures": 0,
+ "first_failure": {
+ "debug_status0": 0,
+ "debug_status1": 0,
+ "item": 0,
+ "launcher_error": 0,
+ "name": ""
+ },
+ "header_tax_ms": 0,
+ "items": 2,
+ "loaded_kb": 63,
+ "max_load_ms": 3350,
+ "max_load_name": "editor",
+ "phases_ms": {
+ "first_load": 3350,
+ "subsequent_loads": 1100
+ },
+ "raw_phase_ticks": {
+ "first_load": 201,
+ "subsequent_loads": 66
+ },
+ "raw_stage_ticks": {
+ "cd_dir": 21,
+ "cd_image": 23,
+ "cd_root": 20,
+ "close": 40,
+ "detect": 0,
+ "drvinfo": 20,
+ "file_info": 0,
+ "identify": 20,
+ "load_reu": 50,
+ "mount": 31,
+ "open": 42,
+ "read_header": 0,
+ "seek_payload": 0
+ },
+ "raw_subsequent_stage_ticks": {
+ "cd_dir": 0,
+ "cd_image": 0,
+ "cd_root": 0,
+ "close": 20,
+ "detect": 0,
+ "drvinfo": 0,
+ "file_info": 0,
+ "identify": 0,
+ "load_reu": 25,
+ "mount": 0,
+ "open": 21,
+ "read_header": 0,
+ "seek_payload": 0
+ },
+ "raw_total_ticks": 267,
+ "stages_ms": {
+ "cd_dir": 350,
+ "cd_image": 383,
+ "cd_root": 333,
+ "close": 667,
+ "detect": 0,
+ "drvinfo": 333,
+ "file_info": 0,
+ "identify": 333,
+ "load_reu": 833,
+ "mount": 517,
+ "open": 700,
+ "read_header": 0,
+ "seek_payload": 0
+ },
+ "subsequent_stages_ms": {
+ "cd_dir": 0,
+ "cd_image": 0,
+ "cd_root": 0,
+ "close": 333,
+ "detect": 0,
+ "drvinfo": 0,
+ "file_info": 0,
+ "identify": 0,
+ "load_reu": 417,
+ "mount": 0,
+ "open": 350,
+ "read_header": 0,
+ "seek_payload": 0
+ },
+ "successes": 2,
+ "total_ms": 4450,
+ "version": 6
+}
diff --git a/build/uci_timing/latest_result.json b/build/uci_timing/latest_result.json
new file mode 100644
index 0000000..70dbd0f
--- /dev/null
+++ b/build/uci_timing/latest_result.json
@@ -0,0 +1,96 @@
+{
+ "avg_header_tax_ms": 0,
+ "dir_probe": {
+ "data_len": 0,
+ "data_prefix_hex": "00000000",
+ "status_len": 0,
+ "status_prefix": ""
+ },
+ "done": 1,
+ "dump": "/private/tmp/uci_timing_probe_c64u_rest_capture/probe_results_3000.bin",
+ "failures": 0,
+ "first_failure": {
+ "debug_status0": 0,
+ "debug_status1": 0,
+ "item": 0,
+ "launcher_error": 0,
+ "name": ""
+ },
+ "header_tax_ms": 0,
+ "items": 2,
+ "loaded_kb": 63,
+ "max_load_ms": 3367,
+ "max_load_name": "editor",
+ "phases_ms": {
+ "first_load": 3367,
+ "subsequent_loads": 1117
+ },
+ "raw_phase_ticks": {
+ "first_load": 202,
+ "subsequent_loads": 67
+ },
+ "raw_stage_ticks": {
+ "cd_dir": 22,
+ "cd_image": 23,
+ "cd_root": 19,
+ "close": 40,
+ "detect": 0,
+ "drvinfo": 20,
+ "file_info": 0,
+ "identify": 20,
+ "load_reu": 50,
+ "mount": 31,
+ "open": 44,
+ "read_header": 0,
+ "seek_payload": 0
+ },
+ "raw_subsequent_stage_ticks": {
+ "cd_dir": 0,
+ "cd_image": 0,
+ "cd_root": 0,
+ "close": 20,
+ "detect": 0,
+ "drvinfo": 0,
+ "file_info": 0,
+ "identify": 0,
+ "load_reu": 25,
+ "mount": 0,
+ "open": 22,
+ "read_header": 0,
+ "seek_payload": 0
+ },
+ "raw_total_ticks": 269,
+ "stages_ms": {
+ "cd_dir": 367,
+ "cd_image": 383,
+ "cd_root": 317,
+ "close": 667,
+ "detect": 0,
+ "drvinfo": 333,
+ "file_info": 0,
+ "identify": 333,
+ "load_reu": 833,
+ "mount": 517,
+ "open": 733,
+ "read_header": 0,
+ "seek_payload": 0
+ },
+ "subsequent_stages_ms": {
+ "cd_dir": 0,
+ "cd_image": 0,
+ "cd_root": 0,
+ "close": 333,
+ "detect": 0,
+ "drvinfo": 0,
+ "file_info": 0,
+ "identify": 0,
+ "load_reu": 417,
+ "mount": 0,
+ "open": 367,
+ "read_header": 0,
+ "seek_payload": 0
+ },
+ "successes": 2,
+ "total_ms": 4483,
+ "version": 6
+}
diff --git a/build/uci_timing/latest_small_rsedit_result.json b/build/uci_timing/latest_small_rsedit_result.json
new file mode 100644
index 0000000..5f64493
--- /dev/null
+++ b/build/uci_timing/latest_small_rsedit_result.json
@@ -0,0 +1,96 @@
+{
+ "avg_header_tax_ms": 0,
+ "dir_probe": {
+ "data_len": 0,
+ "data_prefix_hex": "00000000",
+ "status_len": 0,
+ "status_prefix": ""
+ },
+ "done": 1,
+ "dump": "/private/tmp/uci_timing_probe_c64u_rest_capture/probe_results_3000.bin",
+ "failures": 0,
+ "first_failure": {
+ "debug_status0": 0,
+ "debug_status1": 0,
+ "item": 0,
+ "launcher_error": 0,
+ "name": ""
+ },
+ "header_tax_ms": 0,
+ "items": 2,
+ "loaded_kb": 27,
+ "max_load_ms": 3367,
+ "max_load_name": "editor",
+ "phases_ms": {
+ "first_load": 3367,
+ "subsequent_loads": 1033
+ },
+ "raw_phase_ticks": {
+ "first_load": 202,
+ "subsequent_loads": 62
+ },
+ "raw_stage_ticks": {
+ "cd_dir": 21,
+ "cd_image": 23,
+ "cd_root": 20,
+ "close": 40,
+ "detect": 0,
+ "drvinfo": 20,
+ "file_info": 0,
+ "identify": 20,
+ "load_reu": 45,
+ "mount": 31,
+ "open": 43,
+ "read_header": 0,
+ "seek_payload": 0
+ },
+ "raw_subsequent_stage_ticks": {
+ "cd_dir": 0,
+ "cd_image": 0,
+ "cd_root": 0,
+ "close": 20,
+ "detect": 0,
+ "drvinfo": 0,
+ "file_info": 0,
+ "identify": 0,
+ "load_reu": 20,
+ "mount": 0,
+ "open": 22,
+ "read_header": 0,
+ "seek_payload": 0
+ },
+ "raw_total_ticks": 264,
+ "stages_ms": {
+ "cd_dir": 350,
+ "cd_image": 383,
+ "cd_root": 333,
+ "close": 667,
+ "detect": 0,
+ "drvinfo": 333,
+ "file_info": 0,
+ "identify": 333,
+ "load_reu": 750,
+ "mount": 517,
+ "open": 717,
+ "read_header": 0,
+ "seek_payload": 0
+ },
+ "subsequent_stages_ms": {
+ "cd_dir": 0,
+ "cd_image": 0,
+ "cd_root": 0,
+ "close": 333,
+ "detect": 0,
+ "drvinfo": 0,
+ "file_info": 0,
+ "identify": 0,
+ "load_reu": 333,
+ "mount": 0,
+ "open": 367,
+ "read_header": 0,
+ "seek_payload": 0
+ },
+ "successes": 2,
+ "total_ms": 4400,
+ "version": 6
+}
diff --git a/build/uci_timing/launcher_uci_dma_timed.s b/build/uci_timing/launcher_uci_dma_timed.s
new file mode 100644
index 0000000..5a74ac8
--- /dev/null
+++ b/build/uci_timing/launcher_uci_dma_timed.s
@@ -0,0 +1,1189 @@
+;
+; launcher_uci_dma.s - Launcher-local Ultimate DOS REU loader.
+;
+; This module deliberately uses Ultimate DOS UCI only. It does not use SoftIEC.
+; The experimental launcher supplies an Ultimate DOS directory path from
+; apps.cfg; this module changes into that path, then loads plain filenames from
+; inside the image filesystem.
+;
+
+ .export _launcher_uci_dma_detect
+ .export _launcher_uci_dma_load_prg
+ .export _launcher_uci_dma_quiesce
+ .export _launcher_uci_dma_clear_stage
+ .export _launcher_uci_dma_available
+ .export _launcher_uci_dma_name
+ .export _launcher_uci_dma_reu_bank
+ .export _launcher_uci_dma_reu_offset
+ .export _launcher_uci_dma_max_len
+ .export _launcher_uci_dma_expected_load_addr
+ .export _launcher_uci_dma_loaded_size
+ .export _launcher_uci_dma_last_error
+ .export _launcher_uci_dma_dbg_stat0
+ .export _launcher_uci_dma_dbg_stat1
+ .export _launcher_uci_dma_image_dir
+ .export _launcher_uci_dma_image_name
+ .export _launcher_uci_dma_mount_name
+ .export _launcher_uci_dma_assume_mounted
+
+CPU_PORT = $0001
+
+UCI_STAT_DATA = $80
+UCI_STAT_STAT = $40
+UCI_STATE_MASK = $30
+UCI_STATE_IDLE = $00
+UCI_STATE_LAST = $20
+UCI_STATE_MORE = $30
+UCI_STAT_ABORT = $04
+UCI_STAT_ERROR = $08
+
+ERR_NO_UCI = $01
+ERR_OPEN = $02
+ERR_STAT = $03
+ERR_SIZE = $04
+ERR_HEADER = $05
+ERR_SEEK = $06
+ERR_LOAD = $07
+ERR_PATH = $08
+ERR_CD_DIR = $09
+ERR_CD_DIR_STATUS = $0A
+ERR_MOUNT = $0B
+ERR_MOUNT_STATUS = $0C
+ERR_CD_IMAGE = $0D
+ERR_CD_IMAGE_STATUS = $0E
+ERR_CD_ROOT = $0F
+ERR_CD_ROOT_STATUS = $10
+
+ .macro BCC_FAR target
+ bcs :+
+ jmp target
+:
+ .endmacro
+
+ .macro BEQ_FAR target
+ bne :+
+ jmp target
+:
+ .endmacro
+
+ .macro BNE_FAR target
+ beq :+
+ jmp target
+:
+ .endmacro
+
+ .segment "CODE"
+
+_launcher_uci_dma_detect:
+ lda #<$DF1C
+ ldx #>$DF1C
+ jsr try_base
+ bcs detect_yes
+ lda #<$DE1C
+ ldx #>$DE1C
+ jsr try_base
+ bcs detect_yes
+ lda #<$DFFC
+ ldx #>$DFFC
+ jsr try_base
+ bcs detect_yes
+ lda #$00
+ sta _launcher_uci_dma_available
+ tax
+ rts
+detect_yes:
+ lda #$01
+ sta _launcher_uci_dma_available
+ tax
+ rts
+
+try_base:
+ jsr set_uci_base
+ jsr uci_id
+ and #$7F
+ cmp #$49
+ beq try_base_yes
+ clc
+ rts
+try_base_yes:
+ sec
+ rts
+
+_launcher_uci_dma_load_prg:
+ lda #'0'
+ jsr debug_stage
+ lda #$00
+ sta _launcher_uci_dma_loaded_size
+ sta _launcher_uci_dma_loaded_size+1
+ sta _launcher_uci_dma_last_error
+ sta clipped_load
+ lda _launcher_uci_dma_assume_mounted
+ beq load_regular_detect
+ lda #'5'
+ jsr debug_stage
+ jmp load_open_current_dir
+load_regular_detect:
+ jsr utime_call_detect
+ bne load_have_uci
+ lda #ERR_NO_UCI
+ jmp load_fail
+load_have_uci:
+ lda #'1'
+ jsr debug_stage
+ jsr utime_call_identify
+ BCC_FAR load_no_uci_fail
+ jsr utime_call_drvinfo
+ BCC_FAR load_no_uci_fail
+ lda _launcher_uci_dma_name
+ sta open_name_abs+1
+ lda _launcher_uci_dma_name+1
+ sta open_name_abs+2
+ lda _launcher_uci_dma_image_dir
+ ora _launcher_uci_dma_image_dir+1
+ beq load_path_missing
+ lda _launcher_uci_dma_image_name
+ ora _launcher_uci_dma_image_name+1
+ beq load_path_missing
+ lda _launcher_uci_dma_mount_name
+ ora _launcher_uci_dma_mount_name+1
+ bne load_have_image_path
+load_path_missing:
+ lda #ERR_PATH
+ jmp load_fail
+load_have_image_path:
+ lda _launcher_uci_dma_assume_mounted
+ beq load_mount_image_path
+ lda #'5'
+ jsr debug_stage
+ jmp load_open_current_dir
+load_mount_image_path:
+ lda #root_name
+ sta cd_name_abs+2
+ jsr utime_call_cd_root
+ BCC_FAR load_cd_root_fail
+
+ lda _launcher_uci_dma_image_dir
+ sta cd_dir_check_abs+1
+ sta cd_dir_retry_slash_abs+1
+ sta cd_name_abs+1
+ lda _launcher_uci_dma_image_dir+1
+ sta cd_dir_check_abs+2
+ sta cd_dir_retry_slash_abs+2
+ sta cd_name_abs+2
+ ldy #$00
+cd_dir_check_abs:
+ lda $FFFF,y
+ bne cd_dir_has_text
+ lda #ERR_PATH
+ jmp load_fail
+cd_dir_has_text:
+ lda #'2'
+ jsr debug_stage
+ jsr utime_call_cd_dir
+ BCC_FAR load_cd_dir_fail
+ jsr status_ok
+ bcs cd_dir_ready
+ ldy #$00
+cd_dir_retry_slash_abs:
+ lda $FFFF,y
+ cmp #'/'
+ bne cd_dir_status_retry_fail
+ iny
+ lda _launcher_uci_dma_image_dir
+ clc
+ adc #$01
+ sta cd_name_abs+1
+ lda _launcher_uci_dma_image_dir+1
+ adc #$00
+ sta cd_name_abs+2
+ jsr utime_call_cd_dir
+ BCC_FAR load_cd_dir_fail
+ jsr status_ok
+ bcs cd_dir_ready
+cd_dir_status_retry_fail:
+ jmp load_cd_dir_status_fail
+
+cd_dir_ready:
+ lda _launcher_uci_dma_image_name
+ sta cd_image_check_abs+1
+ sta cd_name_abs+1
+ lda _launcher_uci_dma_image_name+1
+ sta cd_image_check_abs+2
+ sta cd_name_abs+2
+ lda _launcher_uci_dma_mount_name
+ sta cd_mount_name_abs+1
+ lda _launcher_uci_dma_mount_name+1
+ sta cd_mount_name_abs+2
+ ldy #$00
+cd_image_empty_check:
+cd_image_check_abs:
+ lda $FFFF,y
+ bne cd_image_has_text
+ lda #ERR_PATH
+ jmp load_fail
+cd_image_has_text:
+ lda #'3'
+ jsr debug_stage
+ jsr utime_call_mount
+ BCC_FAR load_mount_fail
+ lda #'4'
+ jsr debug_stage
+ jsr utime_call_cd_image
+ BCC_FAR load_cd_image_fail
+ jsr status_ok
+ bcs cd_image_status_ok
+ lda stat_len
+ BEQ_FAR cd_image_status_ok
+ lda _launcher_uci_dma_mount_name
+ sta cd_name_abs+1
+ lda _launcher_uci_dma_mount_name+1
+ sta cd_name_abs+2
+ jsr utime_call_cd_image
+ BCC_FAR load_cd_image_fail
+ jsr status_ok
+ bcs cd_image_status_ok
+ lda stat_len
+ BEQ_FAR cd_image_status_ok
+ jmp load_cd_image_status_fail
+cd_image_status_ok:
+ lda #'5'
+ jsr debug_stage
+
+load_open_current_dir:
+ jsr utime_call_open
+ BCC_FAR load_open_fail
+ jsr status_ok
+ BCC_FAR load_open_fail
+ lda #'7'
+ jsr debug_stage
+
+ lda _launcher_uci_dma_reu_offset
+ sta current_off_lo
+ lda _launcher_uci_dma_reu_offset+1
+ sta current_off_hi
+ lda _launcher_uci_dma_max_len
+ sta chunk_lo
+ sta _launcher_uci_dma_loaded_size
+ lda _launcher_uci_dma_max_len+1
+ sta chunk_hi
+ sta _launcher_uci_dma_loaded_size+1
+ lda chunk_lo
+ ora chunk_hi
+ BEQ_FAR load_size_fail
+
+ lda #'9'
+ jsr debug_stage
+ jsr utime_call_load_reu
+ BCC_FAR load_load_fail
+ jsr status_ok
+ BCC_FAR load_load_fail
+ jmp load_success
+
+load_success:
+ jsr utime_call_close
+ lda #$00
+ sta _launcher_uci_dma_last_error
+ lda #$01
+ tax
+ rts
+load_stat_fail:
+ lda #ERR_STAT
+ jmp load_fail_close
+load_size_fail:
+ lda data_buf
+ sta _launcher_uci_dma_dbg_stat0
+ lda data_buf+1
+ sta _launcher_uci_dma_dbg_stat1
+ jsr dos_close
+ lda #ERR_SIZE
+ sta _launcher_uci_dma_last_error
+ lda #$00
+ tax
+ rts
+load_open_fail:
+ lda #ERR_OPEN
+ jmp load_fail_close
+load_header_fail:
+ lda #ERR_HEADER
+ jmp load_fail_close
+load_seek_fail:
+ lda #ERR_SEEK
+ jmp load_fail_close
+load_load_fail:
+ lda #ERR_LOAD
+ jmp load_fail_close
+load_cd_root_fail:
+ lda #ERR_CD_ROOT
+ jmp load_fail_close
+load_cd_root_status_fail:
+ lda #ERR_CD_ROOT_STATUS
+ jmp load_fail_close
+load_cd_dir_fail:
+ lda #ERR_CD_DIR
+ jmp load_fail_close
+load_cd_dir_status_fail:
+ lda #ERR_CD_DIR_STATUS
+ jmp load_fail_close
+load_mount_fail:
+ lda #ERR_MOUNT
+ jmp load_fail_close
+load_mount_status_fail:
+ lda #ERR_MOUNT_STATUS
+ jmp load_fail_close
+load_cd_image_fail:
+ lda #ERR_CD_IMAGE
+ jmp load_fail_close
+load_cd_image_status_fail:
+ lda #ERR_CD_IMAGE_STATUS
+ jmp load_fail_close
+load_path_fail:
+ lda #ERR_PATH
+load_fail_close:
+ pha
+ jsr dos_close
+ pla
+load_fail:
+ sta _launcher_uci_dma_last_error
+ lda stat_buf
+ sta _launcher_uci_dma_dbg_stat0
+ lda stat_buf+1
+ sta _launcher_uci_dma_dbg_stat1
+ lda #$00
+ tax
+ rts
+load_no_uci_fail:
+ lda #ERR_NO_UCI
+ jmp load_fail
+
+dos_identify:
+ jsr sync_interface
+ BCC_FAR command_fail
+ lda #$01
+ jsr uci_write_cmd
+ lda #$01
+ jsr uci_write_cmd
+ jsr uci_push_cmd
+ jmp drain_response
+
+ctrl_get_drvinfo:
+ jsr sync_interface
+ BCC_FAR command_fail
+ lda #$04
+ jsr uci_write_cmd
+ lda #$29
+ jsr uci_write_cmd
+ lda #$00
+ jsr uci_write_cmd
+ jsr uci_push_cmd
+ jmp drain_response
+
+dos_close:
+ jsr sync_interface
+ BCC_FAR command_fail
+ lda #$01
+ jsr uci_write_cmd
+ lda #$03
+ jsr uci_write_cmd
+ jsr uci_push_cmd
+ jmp drain_response
+
+dos_cd:
+ jsr sync_interface
+ BCC_FAR command_fail
+ lda #$01
+ jsr uci_write_cmd
+ lda #$11
+ jsr uci_write_cmd
+ ldy #$00
+dos_cd_name:
+cd_name_abs:
+ lda $FFFF,y
+ beq dos_cd_push
+ jsr uci_write_path_cmd
+ iny
+ bne dos_cd_name
+dos_cd_push:
+ jsr uci_push_cmd
+ jmp drain_response
+
+dos_cd_path:
+ ldy #$00
+cd_path_read_abs:
+ lda $FFFF,y
+ beq dos_cd_path_done
+ cmp #'/'
+ bne dos_cd_path_segment
+ lda #$01
+ jsr cd_path_advance
+ jmp dos_cd_path
+dos_cd_path_segment:
+ jsr sync_interface
+ BCC_FAR command_fail
+ lda #$01
+ jsr uci_write_cmd
+ lda #$11
+ jsr uci_write_cmd
+ ldy #$00
+dos_cd_path_seg_loop:
+cd_path_seg_read_abs:
+ lda $FFFF,y
+ beq dos_cd_path_seg_push
+ cmp #'/'
+ beq dos_cd_path_seg_push
+ jsr uci_write_path_cmd
+ iny
+ bne dos_cd_path_seg_loop
+dos_cd_path_seg_push:
+ jsr uci_push_cmd
+ jsr drain_response
+ bcc dos_cd_path_fail
+ jsr status_ok
+ bcc dos_cd_path_fail
+ tya
+ jsr cd_path_advance
+ jmp dos_cd_path
+dos_cd_path_done:
+ sec
+ rts
+dos_cd_path_fail:
+ clc
+ rts
+
+cd_path_advance:
+ clc
+ adc cd_path_read_abs+1
+ sta cd_path_read_abs+1
+ sta cd_path_seg_read_abs+1
+ lda cd_path_read_abs+2
+ adc #$00
+ sta cd_path_read_abs+2
+ sta cd_path_seg_read_abs+2
+ rts
+
+dos_mount_image:
+ jsr sync_interface
+ BCC_FAR command_fail
+ lda #$01
+ jsr uci_write_cmd
+ lda #$23
+ jsr uci_write_cmd
+ lda #$08
+ jsr uci_write_cmd
+ ldy #$00
+dos_mount_name:
+cd_mount_name_abs:
+ lda $FFFF,y
+ beq dos_mount_push
+ jsr uci_write_path_cmd
+ iny
+ bne dos_mount_name
+dos_mount_push:
+ jsr uci_push_cmd
+ jmp drain_response
+
+dos_open_read:
+ jsr sync_interface
+ BCC_FAR command_fail
+ lda #$01
+ jsr uci_write_cmd
+ lda #$02
+ jsr uci_write_cmd
+ lda #$01
+ jsr uci_write_cmd
+ ldy #$00
+dos_open_name:
+open_name_abs:
+ lda $FFFF,y
+ beq dos_open_push
+ jsr uci_write_cmd
+ iny
+ bne dos_open_name
+dos_open_push:
+ jsr uci_push_cmd
+ jmp drain_response
+
+dos_read_header:
+ jsr sync_interface
+ BCC_FAR command_fail
+ lda #$01
+ jsr uci_write_cmd
+ lda #$04
+ jsr uci_write_cmd
+ lda #$02
+ jsr uci_write_cmd
+ lda #$00
+ jsr uci_write_cmd
+ jsr uci_push_cmd
+ jmp drain_response
+
+dos_file_info:
+ jsr sync_interface
+ BCC_FAR command_fail
+ lda #$01
+ jsr uci_write_cmd
+ lda #$07
+ jsr uci_write_cmd
+ jsr uci_push_cmd
+ jmp drain_response
+
+dos_seek_payload:
+ jsr sync_interface
+ BCC_FAR command_fail
+ lda #$01
+ jsr uci_write_cmd
+ lda #$06
+ jsr uci_write_cmd
+ lda #$02
+ jsr uci_write_cmd
+ lda #$00
+ jsr uci_write_cmd
+ jsr uci_write_cmd
+ jsr uci_write_cmd
+ jsr uci_push_cmd
+ jmp drain_response
+
+dos_load_reu_chunk:
+ jsr sync_interface
+ BCC_FAR command_fail
+ lda #$01
+ jsr uci_write_cmd
+ lda #$21
+ jsr uci_write_cmd
+ lda current_off_lo
+ jsr uci_write_cmd
+ lda current_off_hi
+ jsr uci_write_cmd
+ lda _launcher_uci_dma_reu_bank
+ jsr uci_write_cmd
+ lda #$00
+ jsr uci_write_cmd
+ lda chunk_lo
+ jsr uci_write_cmd
+ lda chunk_hi
+ jsr uci_write_cmd
+ lda #$00
+ jsr uci_write_cmd
+ jsr uci_write_cmd
+ jsr uci_push_cmd
+ jmp drain_response
+
+command_fail:
+ clc
+ rts
+
+uci_write_path_cmd:
+ cmp #'a'
+ bcc uci_write_path_raw
+ cmp #'z'+1
+ bcs uci_write_path_raw
+ and #$DF
+uci_write_path_raw:
+ jmp uci_write_cmd
+
+debug_stage:
+ ; Hardware note: this visible screen store is part of the
+ ; C64U-proven UCI transaction shape. Replacing the stage writes with
+ ; private BSS stores made the same logical loader fall back on real
+ ; hardware, so do not "clean this up" without retesting on C64U.
+ sta $052C
+ rts
+
+sync_interface:
+ lda #$40
+ sta timeout_hi
+sync_loop:
+ jsr uci_status
+ sta last_status
+ and #UCI_STAT_ERROR
+ beq sync_no_error
+ jsr uci_clear_error
+ lda #$40
+ sta timeout_hi
+ jmp sync_loop
+sync_no_error:
+ lda last_status
+ and #UCI_STAT_ABORT
+ beq sync_no_abort
+ jsr uci_abort
+ lda #$40
+ sta timeout_hi
+ jmp sync_loop
+sync_no_abort:
+ lda last_status
+ and #UCI_STAT_DATA
+ beq sync_no_data
+ jsr uci_read_data
+ lda #$40
+ sta timeout_hi
+ jmp sync_loop
+sync_no_data:
+ lda last_status
+ and #UCI_STAT_STAT
+ beq sync_no_stat
+ jsr uci_read_stat
+ lda #$40
+ sta timeout_hi
+ jmp sync_loop
+sync_no_stat:
+ lda last_status
+ and #UCI_STATE_MASK
+ cmp #UCI_STATE_LAST
+ beq sync_accept
+ cmp #UCI_STATE_MORE
+ beq sync_accept
+ lda last_status
+ and #$31
+ beq sync_ok
+ dec timeout_hi
+ bne sync_loop
+ jsr uci_abort
+ clc
+ rts
+sync_accept:
+ jsr uci_accept_data
+ lda #$40
+ sta timeout_hi
+ jmp sync_loop
+sync_ok:
+ sec
+ rts
+
+wait_data_state:
+ lda #$80
+ sta timeout_hi
+ ldy #$00
+wait_state_loop:
+ jsr uci_status
+ sta last_status
+ and #UCI_STAT_ERROR
+ bne wait_state_fail
+ lda last_status
+ and #UCI_STATE_MASK
+ cmp #UCI_STATE_LAST
+ beq wait_state_ok
+ cmp #UCI_STATE_MORE
+ beq wait_state_ok
+ cmp #UCI_STATE_IDLE
+ beq wait_state_ok
+ dey
+ bne wait_state_loop
+ dec timeout_hi
+ bne wait_state_loop
+wait_state_fail:
+ clc
+ rts
+wait_state_ok:
+ sec
+ rts
+
+wait_idle:
+ lda #$40
+ sta timeout_hi
+ ldy #$00
+wait_idle_loop:
+ jsr uci_status
+ sta last_status
+ lda last_status
+ and #$31
+ beq wait_idle_ok
+ dey
+ bne wait_idle_loop
+ dec timeout_hi
+ bne wait_idle_loop
+ clc
+ rts
+wait_idle_ok:
+ sec
+ rts
+
+drain_response:
+ lda #$00
+ sta data_len
+ sta stat_len
+ jsr wait_data_state
+ bcs drain_loop
+ clc
+ rts
+drain_loop:
+ jsr uci_status
+ sta last_status
+ and #UCI_STAT_ERROR
+ beq drain_no_error
+ clc
+ rts
+drain_no_error:
+ lda last_status
+ and #UCI_STATE_MASK
+ sta current_state
+ beq drain_done
+ cmp #UCI_STATE_LAST
+ beq drain_state_ok
+ cmp #UCI_STATE_MORE
+ beq drain_state_ok
+ jsr wait_data_state
+ bcs drain_loop
+ clc
+ rts
+drain_state_ok:
+ lda #$10
+ sta timeout_hi
+ ldy #$00
+drain_bytes:
+ jsr uci_status
+ sta last_status
+ and #UCI_STAT_DATA
+ beq drain_check_stat
+ jsr uci_read_data
+ ldx data_len
+ cpx #$20
+ bcs drain_data_count
+ sta data_buf,x
+drain_data_count:
+ lda data_len
+ cmp #$FF
+ beq drain_reset_guard
+ inc data_len
+ jmp drain_reset_guard
+drain_check_stat:
+ lda last_status
+ and #UCI_STAT_STAT
+ beq drain_wait_byte
+ jsr uci_read_stat
+ ldx stat_len
+ cpx #$08
+ bcs drain_reset_guard
+ sta stat_buf,x
+ inc stat_len
+drain_reset_guard:
+ lda #$10
+ sta timeout_hi
+ ldy #$00
+ jmp drain_bytes
+drain_wait_byte:
+ dey
+ bne drain_bytes
+ dec timeout_hi
+ bne drain_bytes
+ jsr uci_accept_data
+ lda current_state
+ cmp #UCI_STATE_LAST
+ bne drain_more
+ jsr wait_idle
+ sec
+ rts
+drain_more:
+ jsr wait_data_state
+ bcc drain_more_fail
+ jmp drain_loop
+drain_more_fail:
+ clc
+ rts
+drain_done:
+ sec
+ rts
+
+status_ok:
+ lda stat_len
+ beq status_not_ok
+ lda stat_buf
+ cmp #'0'
+ bne status_not_ok
+ lda stat_buf+1
+ cmp #'0'
+ bne status_not_ok
+status_is_ok:
+ sec
+ rts
+status_not_ok:
+ clc
+ rts
+
+data_or_status_ok:
+ lda stat_len
+ beq data_or_status_from_data
+ jmp status_ok
+data_or_status_from_data:
+ lda data_len
+ beq status_not_ok
+ sec
+ rts
+
+set_uci_base:
+ sta uci_base_lo
+ stx uci_base_hi
+ lda uci_base_lo
+ sta uci_status_abs+1
+ sta uci_push_abs+1
+ sta uci_accept_abs+1
+ sta uci_abort_abs+1
+ sta uci_clear_abs+1
+ clc
+ adc #$01
+ sta uci_write_abs+1
+ sta uci_id_abs+1
+ clc
+ adc #$01
+ sta uci_data_abs+1
+ clc
+ adc #$01
+ sta uci_stat_abs+1
+ lda uci_base_hi
+ sta uci_status_abs+2
+ sta uci_push_abs+2
+ sta uci_accept_abs+2
+ sta uci_abort_abs+2
+ sta uci_clear_abs+2
+ sta uci_write_abs+2
+ sta uci_id_abs+2
+ sta uci_data_abs+2
+ sta uci_stat_abs+2
+ rts
+
+uci_write_cmd:
+ sta uci_value
+ php
+ sei
+ lda CPU_PORT
+ pha
+ and #$F8
+ ora #$07
+ sta CPU_PORT
+ lda uci_value
+uci_write_abs:
+ sta $DF1D
+ pla
+ sta CPU_PORT
+ plp
+ lda uci_value
+ rts
+
+uci_id:
+ php
+ sei
+ lda CPU_PORT
+ pha
+ and #$F8
+ ora #$07
+ sta CPU_PORT
+uci_id_abs:
+ lda $DF1D
+ tax
+ pla
+ sta CPU_PORT
+ plp
+ txa
+ rts
+
+uci_status:
+ php
+ sei
+ lda CPU_PORT
+ pha
+ and #$F8
+ ora #$07
+ sta CPU_PORT
+uci_status_abs:
+ lda $DF1C
+ tax
+ pla
+ sta CPU_PORT
+ plp
+ txa
+ rts
+
+uci_read_data:
+ php
+ sei
+ lda CPU_PORT
+ pha
+ and #$F8
+ ora #$07
+ sta CPU_PORT
+uci_data_abs:
+ lda $DF1E
+ tax
+ pla
+ sta CPU_PORT
+ plp
+ txa
+ rts
+
+uci_read_stat:
+ php
+ sei
+ lda CPU_PORT
+ pha
+ and #$F8
+ ora #$07
+ sta CPU_PORT
+uci_stat_abs:
+ lda $DF1F
+ tax
+ pla
+ sta CPU_PORT
+ plp
+ txa
+ rts
+
+uci_push_cmd:
+ php
+ sei
+ lda CPU_PORT
+ pha
+ and #$F8
+ ora #$07
+ sta CPU_PORT
+ lda #$01
+uci_push_abs:
+ sta $DF1C
+ pla
+ sta CPU_PORT
+ plp
+ rts
+
+uci_accept_data:
+ php
+ sei
+ lda CPU_PORT
+ pha
+ and #$F8
+ ora #$07
+ sta CPU_PORT
+ lda #$02
+uci_accept_abs:
+ sta $DF1C
+ pla
+ sta CPU_PORT
+ plp
+ rts
+
+uci_abort:
+ php
+ sei
+ lda CPU_PORT
+ pha
+ and #$F8
+ ora #$07
+ sta CPU_PORT
+ lda #$04
+uci_abort_abs:
+ sta $DF1C
+ pla
+ sta CPU_PORT
+ plp
+ rts
+
+uci_clear_error:
+ php
+ sei
+ lda CPU_PORT
+ pha
+ and #$F8
+ ora #$07
+ sta CPU_PORT
+ lda #$08
+uci_clear_abs:
+ sta $DF1C
+ pla
+ sta CPU_PORT
+ plp
+ rts
+
+_launcher_uci_dma_quiesce:
+ lda _launcher_uci_dma_available
+ beq quiesce_done
+ jsr sync_interface
+ bcc quiesce_done
+ jsr wait_idle
+quiesce_done:
+ rts
+
+_launcher_uci_dma_clear_stage:
+ lda #' '
+ sta $052C
+ sta $052D
+ sta $052E
+ sta $052F
+ sta $0530
+ sta $0531
+ sta $0532
+ sta $0533
+ rts
+
+
+
+; Probe-only instrumentation wrappers. These preserve the carry flag returned
+; by the underlying launcher UCI call so the production control flow is intact.
+ .import _utime_stage_begin
+ .import _utime_stage_end
+
+utime_call_detect:
+ lda #$00
+ jsr _utime_stage_begin
+ jsr _launcher_uci_dma_detect
+ php
+ lda #$00
+ jsr _utime_stage_end
+ plp
+ rts
+
+utime_call_identify:
+ lda #$01
+ jsr _utime_stage_begin
+ jsr dos_identify
+ php
+ lda #$01
+ jsr _utime_stage_end
+ plp
+ rts
+
+utime_call_drvinfo:
+ lda #$02
+ jsr _utime_stage_begin
+ jsr ctrl_get_drvinfo
+ php
+ lda #$02
+ jsr _utime_stage_end
+ plp
+ rts
+
+utime_call_cd_root:
+ lda #$03
+ jsr _utime_stage_begin
+ jsr dos_cd
+ php
+ lda #$03
+ jsr _utime_stage_end
+ plp
+ rts
+
+utime_call_cd_dir:
+ lda #$04
+ jsr _utime_stage_begin
+ jsr dos_cd
+ php
+ lda #$04
+ jsr _utime_stage_end
+ plp
+ rts
+
+utime_call_mount:
+ lda #$05
+ jsr _utime_stage_begin
+ jsr dos_mount_image
+ php
+ lda #$05
+ jsr _utime_stage_end
+ plp
+ rts
+
+utime_call_cd_image:
+ lda #$06
+ jsr _utime_stage_begin
+ jsr dos_cd
+ php
+ lda #$06
+ jsr _utime_stage_end
+ plp
+ rts
+
+utime_call_open:
+ lda #$07
+ jsr _utime_stage_begin
+ jsr dos_open_read
+ php
+ lda #$07
+ jsr _utime_stage_end
+ plp
+ rts
+
+utime_call_info:
+ lda #$08
+ jsr _utime_stage_begin
+ jsr dos_file_info
+ php
+ lda #$08
+ jsr _utime_stage_end
+ plp
+ rts
+
+utime_call_read_header:
+ lda #$09
+ jsr _utime_stage_begin
+ jsr dos_read_header
+ php
+ lda #$09
+ jsr _utime_stage_end
+ plp
+ rts
+
+utime_call_seek:
+ lda #$0A
+ jsr _utime_stage_begin
+ jsr dos_seek_payload
+ php
+ lda #$0A
+ jsr _utime_stage_end
+ plp
+ rts
+
+utime_call_load_reu:
+ lda #$0B
+ jsr _utime_stage_begin
+ jsr dos_load_reu_chunk
+ php
+ lda #$0B
+ jsr _utime_stage_end
+ plp
+ rts
+
+utime_call_close:
+ lda #$0C
+ jsr _utime_stage_begin
+ jsr dos_close
+ php
+ lda #$0C
+ jsr _utime_stage_end
+ plp
+ rts
+
+ .segment "RODATA"
+
+root_name: .byte "/", 0
+
+ .segment "BSS"
+
+_launcher_uci_dma_available: .res 1
+_launcher_uci_dma_name: .res 2
+_launcher_uci_dma_reu_bank: .res 1
+_launcher_uci_dma_reu_offset: .res 2
+_launcher_uci_dma_max_len: .res 2
+_launcher_uci_dma_expected_load_addr: .res 2
+_launcher_uci_dma_loaded_size: .res 2
+_launcher_uci_dma_last_error: .res 1
+_launcher_uci_dma_dbg_stat0: .res 1
+_launcher_uci_dma_dbg_stat1: .res 1
+_launcher_uci_dma_image_dir: .res 2
+_launcher_uci_dma_image_name: .res 2
+_launcher_uci_dma_mount_name: .res 2
+_launcher_uci_dma_assume_mounted: .res 1
+
+uci_base_lo: .res 1
+uci_base_hi: .res 1
+uci_value: .res 1
+last_status: .res 1
+current_state: .res 1
+timeout_hi: .res 1
+data_len: .res 1
+stat_len: .res 1
+remaining_lo: .res 1
+remaining_hi: .res 1
+chunk_lo: .res 1
+chunk_hi: .res 1
+current_off_lo: .res 1
+current_off_hi: .res 1
+clipped_load: .res 1
+data_buf: .res 32
+stat_buf: .res 8
diff --git a/build/uci_timing/msg_variant.inc b/build/uci_timing/msg_variant.inc
new file mode 100644
index 0000000..25a9bdc
--- /dev/null
+++ b/build/uci_timing/msg_variant.inc
@@ -0,0 +1,5 @@
+; Auto-generated by build_apps_catalog_petscii.py. Do not edit by hand.
+
+msg_variant:
+ .byte "precog d81"
+msg_variant_end:
diff --git a/build/uci_timing/readback/apps.cfg b/build/uci_timing/readback/apps.cfg
new file mode 100644
index 0000000..fbb41ef
--- /dev/null
+++ b/build/uci_timing/readback/apps.cfg
@@ -0,0 +1 @@
+[SYSTEM]
VARIANT_NAME=PRECOG D81
VARIANT_BOOT_NAME=PRECOG D81
REU_BANK_SKIP=32
[LAUNCHER]
LOAD_ALL_TO_REU=0
RUNAPPFIRST=
C64U_IMAGE_PATH=/USB1/READYOS.D81
[APPS]
8:EDITOR:EDITOR:1
TEXT EDITOR WITH CLIPBOARD
8:READYSHELL:READYSHELL (BETA):2:RSOVL+
COMMAND SHELL POC SCAFFOLD
RSPARSER@0:0000,RSVM@0:3800,RSDRVILST@0:7000,RSLDV@1:0000,RSSTV@0:A800,RSFOPS@1:3800,RSCAT@1:7000,RSCOPY@1:A800,RSEDIT@2:0000
8:SIMPLEFILES:SIMPLE FILES
DUAL PANE FILE MANAGER AND SEQ VIEWER
8:CLIPMGR:CLIPBOARD
MANAGE CLIPBOARD ITEMS
8:READYBASIC:READY BASIC (ALPHA):3:RBCORE+
SCOPED BASIC V2 BRIDGE POC
RBCORE,RBCODE
8:CAL26:CALENDAR 26
CALENDAR FOR 2026 WITH APPOINTMENTS
8:TASKLIST:TASK LIST
OUTLINER WITH NOTES AND SEARCH
8:REUVIEWER:REU VIEWER
VIEW REU MEMORY USAGE
8:SYSINFO:SYSTEM INFO
SYSTEM, REU, AND ULTIMATE STATUS
8:QUICKNOTES:QUICKNOTES
REU-BACKED NOTE EDITOR
8:CALCPLUS:CALC PLUS
KEYBOARD-FIRST EXPRESSION CALCULATOR
8:HEXVIEW:HEX VIEWER
BROWSE MEMORY IN HEX FORMAT
8:SIMPLECELLS:SIMPLE CELLS (ALPHA)
SPREADSHEET WITH FORMULAS AND COLORS
8:GAME2048:2048 GAME
2048 TILE PUZZLE
8:DEMINER:DEMINER
MINESWEEPER-STYLE PUZZLE
8:DIZZY:DIZZY KANBAN
FIZZY INSPIRED KANBAN APP
8:READYIRC:READYIRC
ULTIMATE TCP IRC CLIENT
8:UCITEST:UCI TESTER
ULTIMATE COMMAND INTERFACE LAB
8:RIRC-RRNET:READYIRC RRNET
RR-NET TCP IRC CLIENT
8:README:READ.ME
READYOS, ULTIMATE BUDDY, PRECOG POC OS
\ No newline at end of file
diff --git a/build/uci_timing/readback/utime b/build/uci_timing/readback/utime
new file mode 100644
index 0000000..d42b668
Binary files /dev/null and b/build/uci_timing/readback/utime differ
diff --git a/build/uci_timing/readyos.d81 b/build/uci_timing/readyos.d81
new file mode 100644
index 0000000..7b243fa
Binary files /dev/null and b/build/uci_timing/readyos.d81 differ
diff --git a/build/uci_timing/readyos_reu_config.inc b/build/uci_timing/readyos_reu_config.inc
new file mode 100644
index 0000000..06a529b
--- /dev/null
+++ b/build/uci_timing/readyos_reu_config.inc
@@ -0,0 +1,4 @@
+; Auto-generated by build_apps_catalog_petscii.py. Do not edit by hand.
+; This is compiled into the boot/shim image; runtime apps.cfg is not read for this value.
+
+READYOS_REU_BANK_SKIP = 32
diff --git a/build/uci_timing/uci_timing_probe.prg b/build/uci_timing/uci_timing_probe.prg
new file mode 100644
index 0000000..d42b668
Binary files /dev/null and b/build/uci_timing/uci_timing_probe.prg differ
diff --git a/build/uci_timing/uci_timing_probe.s b/build/uci_timing/uci_timing_probe.s
new file mode 100644
index 0000000..67355ff
--- /dev/null
+++ b/build/uci_timing/uci_timing_probe.s
@@ -0,0 +1,648 @@
+
+ .segment "LOADADDR"
+ .word $0801
+
+ .segment "STARTUP"
+ .word basic_next
+ .word 10
+ .byte $9e, "2061", 0
+basic_next:
+ .word 0
+
+ .import _launcher_uci_dma_detect
+ .import _launcher_uci_dma_load_prg
+ .import _launcher_uci_dma_quiesce
+ .import _launcher_uci_dma_clear_stage
+ .import _launcher_uci_dma_name
+ .import _launcher_uci_dma_reu_bank
+ .import _launcher_uci_dma_reu_offset
+ .import _launcher_uci_dma_max_len
+ .import _launcher_uci_dma_expected_load_addr
+ .import _launcher_uci_dma_loaded_size
+ .import _launcher_uci_dma_last_error
+ .import _launcher_uci_dma_dbg_stat0
+ .import _launcher_uci_dma_dbg_stat1
+ .import _launcher_uci_dma_image_dir
+ .import _launcher_uci_dma_image_name
+ .import _launcher_uci_dma_mount_name
+ .import _launcher_uci_dma_assume_mounted
+
+ .export _utime_stage_begin
+ .export _utime_stage_end
+
+CHROUT = $FFD2
+GETIN = $FFE4
+RESULTS = $3000
+STAGE_COUNT = $0D
+current_name = $04
+
+ .macro PRINT label
+ lda #label
+ jsr print_z
+ .endmacro
+
+ .segment "CODE"
+
+start:
+ lda #$93
+ jsr CHROUT
+ lda #$01
+ sta $0286
+ jsr init_results
+ PRINT title_msg
+ jsr cr
+ PRINT path_msg
+ PRINT image_dir
+ lda #'/'
+ jsr CHROUT
+ PRINT image_name
+ jsr cr
+ jsr _launcher_uci_dma_detect
+ cmp #$00
+ bne have_uci
+ lda #$02
+ sta done_code
+ lda #WORKLOAD_COUNT
+ sta failures
+ jsr update_runtime_results
+ PRINT no_uci_msg
+ jsr cr
+ jmp done
+have_uci:
+ PRINT uci_msg
+ jsr cr
+ jsr workload_run
+ lda failures
+ beq all_ok
+ lda #$04
+ bne set_done
+all_ok:
+ lda #$01
+set_done:
+ sta done_code
+ jsr update_runtime_results
+done:
+ jsr print_summary
+ jmp *
+
+load_one_launcher_timed:
+ jsr print_progress
+ lda #$31
+ sta $052d
+
+ lda #image_dir
+ sta _launcher_uci_dma_image_dir+1
+ lda #image_name
+ sta _launcher_uci_dma_image_name+1
+ sta _launcher_uci_dma_mount_name+1
+ lda current_name
+ sta _launcher_uci_dma_name
+ lda current_name+1
+ sta _launcher_uci_dma_name+1
+ lda current_bank
+ sta _launcher_uci_dma_reu_bank
+ lda current_off
+ sta _launcher_uci_dma_reu_offset
+ lda current_off+1
+ sta _launcher_uci_dma_reu_offset+1
+ lda current_max
+ sta _launcher_uci_dma_max_len
+ lda current_max+1
+ sta _launcher_uci_dma_max_len+1
+ lda current_expected
+ sta _launcher_uci_dma_expected_load_addr
+ lda current_expected+1
+ sta _launcher_uci_dma_expected_load_addr+1
+ lda image_ready
+ sta _launcher_uci_dma_assume_mounted
+
+ jsr read_jiffy16
+ sta tick_start
+ stx tick_start+1
+ jsr _launcher_uci_dma_load_prg
+ sta last_ok
+ tax
+ beq load_failed_quiesce
+ lda #$01
+ sta image_ready
+ sta _launcher_uci_dma_assume_mounted
+ jsr _launcher_uci_dma_quiesce
+ jsr _launcher_uci_dma_clear_stage
+ jmp after_loader_call
+load_failed_quiesce:
+ jsr apply_launcher_failure_state
+ jsr _launcher_uci_dma_quiesce
+after_loader_call:
+ jsr read_jiffy16
+ sec
+ sbc tick_start
+ sta last_ticks
+ txa
+ sbc tick_start+1
+ sta last_ticks+1
+ jsr add_total_ticks
+ jsr add_phase_ticks
+ jsr update_max_load
+ lda last_ok
+ bne load_succeeded
+ jsr store_first_failure
+ clc
+ rts
+load_succeeded:
+ inc successes
+ jsr add_loaded_kb
+ sec
+ rts
+
+apply_launcher_failure_state:
+ lda _launcher_uci_dma_last_error
+ cmp #$01
+ beq fail_disable_path
+ cmp #$08
+ bcc fail_keep_path
+ cmp #$11
+ bcs fail_keep_path
+fail_disable_path:
+ lda #$00
+ sta image_ready
+ sta _launcher_uci_dma_assume_mounted
+ rts
+fail_keep_path:
+ lda #$01
+ sta image_ready
+ sta _launcher_uci_dma_assume_mounted
+ rts
+
+add_total_ticks:
+ lda total_ticks
+ clc
+ adc last_ticks
+ sta total_ticks
+ lda total_ticks+1
+ adc last_ticks+1
+ sta total_ticks+1
+ rts
+
+add_phase_ticks:
+ lda item_index
+ beq add_first_ticks
+ lda subsequent_ticks
+ clc
+ adc last_ticks
+ sta subsequent_ticks
+ lda subsequent_ticks+1
+ adc last_ticks+1
+ sta subsequent_ticks+1
+ rts
+add_first_ticks:
+ lda first_ticks
+ clc
+ adc last_ticks
+ sta first_ticks
+ lda first_ticks+1
+ adc last_ticks+1
+ sta first_ticks+1
+ rts
+
+update_max_load:
+ lda max_load_ticks+1
+ cmp last_ticks+1
+ bcc set_max_load
+ bne max_load_done
+ lda max_load_ticks
+ cmp last_ticks
+ bcs max_load_done
+set_max_load:
+ lda last_ticks
+ sta max_load_ticks
+ lda last_ticks+1
+ sta max_load_ticks+1
+ ldy #$00
+copy_max_name:
+ cpy #$0f
+ beq term_max_name
+ lda (current_name),y
+ sta max_load_name,y
+ beq max_load_done
+ iny
+ bne copy_max_name
+term_max_name:
+ lda #$00
+ sta max_load_name,y
+max_load_done:
+ rts
+
+add_loaded_kb:
+ lda _launcher_uci_dma_loaded_size
+ clc
+ adc #$ff
+ lda _launcher_uci_dma_loaded_size+1
+ adc #$03
+ lsr
+ lsr
+ clc
+ adc total_kb
+ sta total_kb
+ lda total_kb+1
+ adc #$00
+ sta total_kb+1
+ rts
+
+store_first_failure:
+ lda first_fail_error
+ bne first_failure_done
+ lda item_index
+ sta first_fail_item
+ lda _launcher_uci_dma_last_error
+ sta first_fail_error
+ lda _launcher_uci_dma_dbg_stat0
+ sta first_fail_dbg0
+ lda _launcher_uci_dma_dbg_stat1
+ sta first_fail_dbg1
+ ldy #$00
+copy_fail_name:
+ cpy #$0f
+ beq term_fail_name
+ lda (current_name),y
+ sta first_fail_name,y
+ beq first_failure_done
+ iny
+ bne copy_fail_name
+term_fail_name:
+ lda #$00
+ sta first_fail_name,y
+first_failure_done:
+ rts
+
+read_jiffy16:
+ lda $A2
+ ldx $A1
+ rts
+
+_utime_stage_begin:
+ sta stage_id
+ jsr read_jiffy16
+ sta stage_start
+ stx stage_start+1
+ rts
+
+_utime_stage_end:
+ jsr read_jiffy16
+ sta stage_now
+ stx stage_now+1
+ lda stage_now
+ sec
+ sbc stage_start
+ sta stage_delta
+ lda stage_now+1
+ sbc stage_start+1
+ sta stage_delta+1
+ lda stage_id
+ asl
+ tax
+ lda stage_ticks,x
+ clc
+ adc stage_delta
+ sta stage_ticks,x
+ lda stage_ticks+1,x
+ adc stage_delta+1
+ sta stage_ticks+1,x
+ lda item_index
+ beq stage_end_done
+ lda stage_id
+ asl
+ tax
+ lda stage_subseq_ticks,x
+ clc
+ adc stage_delta
+ sta stage_subseq_ticks,x
+ lda stage_subseq_ticks+1,x
+ adc stage_delta+1
+ sta stage_subseq_ticks+1,x
+stage_end_done:
+ rts
+
+init_results:
+ ldx #$00
+ lda #$00
+clear_results:
+ sta RESULTS,x
+ inx
+ cpx #$80
+ bne clear_results
+ lda #'U'
+ sta RESULTS
+ lda #'T'
+ sta RESULTS+1
+ lda #'I'
+ sta RESULTS+2
+ lda #'M'
+ sta RESULTS+3
+ lda #$06
+ sta RESULTS+4
+ lda #WORKLOAD_COUNT
+ sta RESULTS+6
+ jsr update_runtime_results
+ rts
+
+update_runtime_results:
+ lda #$06
+ sta RESULTS+4
+ lda done_code
+ sta RESULTS+5
+ lda item_index
+ sta RESULTS+6
+ lda failures
+ sta RESULTS+7
+ lda total_ticks
+ sta RESULTS+8
+ lda total_ticks+1
+ sta RESULTS+9
+ lda total_kb
+ sta RESULTS+10
+ lda total_kb+1
+ sta RESULTS+11
+ lda max_load_ticks
+ sta RESULTS+12
+ lda max_load_ticks+1
+ sta RESULTS+13
+ lda successes
+ sta RESULTS+14
+ lda #STAGE_COUNT
+ sta RESULTS+15
+ lda first_ticks
+ sta RESULTS+16
+ lda first_ticks+1
+ sta RESULTS+17
+ lda subsequent_ticks
+ sta RESULTS+18
+ lda subsequent_ticks+1
+ sta RESULTS+19
+ ldx #$00
+copy_stages_result:
+ lda stage_ticks,x
+ sta RESULTS+20,x
+ inx
+ cpx #(STAGE_COUNT * 2)
+ bne copy_stages_result
+ ldx #$00
+copy_subseq_stages_result:
+ lda stage_subseq_ticks,x
+ sta RESULTS+80,x
+ inx
+ cpx #(STAGE_COUNT * 2)
+ bne copy_subseq_stages_result
+ ldx #$00
+copy_max_result:
+ lda max_load_name,x
+ sta RESULTS+48,x
+ inx
+ cpx #$10
+ bne copy_max_result
+ lda first_fail_item
+ sta RESULTS+64
+ lda first_fail_error
+ sta RESULTS+65
+ lda first_fail_dbg0
+ sta RESULTS+66
+ lda first_fail_dbg1
+ sta RESULTS+67
+ ldx #$00
+copy_fail_result:
+ lda first_fail_name,x
+ sta RESULTS+72,x
+ inx
+ cpx #$08
+ bne copy_fail_result
+ rts
+
+print_progress:
+ lda #$13
+ jsr CHROUT
+ PRINT loading_msg
+ lda item_index
+ jsr print_hex_a
+ lda #'/'
+ jsr CHROUT
+ lda #WORKLOAD_COUNT
+ jsr print_hex_a
+ lda #' '
+ jsr CHROUT
+ ldy #$00
+progress_name:
+ lda (current_name),y
+ beq progress_done
+ jsr CHROUT
+ iny
+ cpy #$0f
+ bne progress_name
+progress_done:
+ jsr cr
+ rts
+
+print_summary:
+ lda #$13
+ jsr CHROUT
+ PRINT done_msg
+ lda done_code
+ jsr print_hex_a
+ PRINT item_msg
+ lda item_index
+ jsr print_hex_a
+ PRINT fail_msg
+ lda failures
+ jsr print_hex_a
+ jsr cr
+ PRINT succ_msg
+ lda successes
+ jsr print_hex_a
+ PRINT kb_msg
+ lda total_kb+1
+ jsr print_hex_a
+ lda total_kb
+ jsr print_hex_a
+ PRINT ticks_msg
+ lda total_ticks+1
+ jsr print_hex_a
+ lda total_ticks
+ jsr print_hex_a
+ jsr cr
+ PRINT max_msg
+ lda max_load_ticks+1
+ jsr print_hex_a
+ lda max_load_ticks
+ jsr print_hex_a
+ lda #' '
+ jsr CHROUT
+ lda #max_load_name
+ jsr print_z
+ jsr cr
+ lda failures
+ beq no_fail_print
+ PRINT first_fail_msg
+ lda first_fail_item
+ jsr print_hex_a
+ lda #'/'
+ jsr CHROUT
+ lda first_fail_error
+ jsr print_hex_a
+ lda #' '
+ jsr CHROUT
+ lda #first_fail_name
+ jsr print_z
+ jsr cr
+no_fail_print:
+ PRINT probe_done_msg
+ jsr cr
+ rts
+
+print_z:
+ sta pz+1
+ sty pz+2
+ ldy #$00
+pz:
+ lda $FFFF,y
+ beq print_z_done
+ jsr CHROUT
+ iny
+ bne pz
+print_z_done:
+ rts
+
+print_hex_a:
+ pha
+ lsr
+ lsr
+ lsr
+ lsr
+ jsr print_hex_nibble
+ pla
+ and #$0f
+print_hex_nibble:
+ cmp #$0a
+ bcc print_hex_digit
+ adc #$06
+print_hex_digit:
+ adc #'0'
+ jsr CHROUT
+ rts
+
+cr:
+ lda #$0d
+ jsr CHROUT
+ rts
+
+ .segment "RODATA"
+workload_run:
+
+ lda #name_editor
+ sta current_name+1
+ lda #$40
+ sta current_bank
+ lda #<$0000
+ sta current_off
+ lda #>$0000
+ sta current_off+1
+ lda #<$605D
+ sta current_max
+ lda #>$605D
+ sta current_max+1
+ lda #<$1000
+ sta current_expected
+ lda #>$1000
+ sta current_expected+1
+ jsr load_one_launcher_timed
+ bcs @item_0_ok
+ inc failures
+@item_0_ok:
+ inc item_index
+ jsr update_runtime_results
+
+
+ lda #name_dizzy
+ sta current_name+1
+ lda #$4F
+ sta current_bank
+ lda #<$0000
+ sta current_off
+ lda #>$0000
+ sta current_off+1
+ lda #<$9621
+ sta current_max
+ lda #>$9621
+ sta current_max+1
+ lda #<$1000
+ sta current_expected
+ lda #>$1000
+ sta current_expected+1
+ jsr load_one_launcher_timed
+ bcs @item_1_ok
+ inc failures
+@item_1_ok:
+ inc item_index
+ jsr update_runtime_results
+
+ rts
+
+WORKLOAD_COUNT = 2
+name_editor: .byte $65, $64, $69, $74, $6F, $72, 0
+name_dizzy: .byte $64, $69, $7A, $7A, $79, 0
+image_dir: .byte $2F, $75, $73, $62, $31, 0
+image_name: .byte $75, $31, $6C, $32, $30, $35, $35, $35, $37, $2E, $64, $38, $31, 0
+title_msg: .byte $55, $43, $49, $20, $54, $49, $4D, $49, $4E, $47, $20, $46, $41, $53, $54, $20, $52, $41, $57, 0
+path_msg: .byte "PATH ", 0
+uci_msg: .byte "UCI OK", 0
+no_uci_msg: .byte "NO UCI", 0
+loading_msg: .byte "LOADING ", 0
+done_msg: .byte "DONE:", 0
+item_msg: .byte " ITEMS:", 0
+fail_msg: .byte " FAIL:", 0
+succ_msg: .byte "SUCCESS:", 0
+kb_msg: .byte " KB:", 0
+ticks_msg: .byte " TICKS:", 0
+max_msg: .byte "MAX:", 0
+first_fail_msg: .byte "FIRST FAIL:", 0
+probe_done_msg: .byte "PROBE DONE", 0
+
+ .segment "DATA"
+done_code: .byte 0
+item_index: .byte 0
+successes: .byte 0
+failures: .byte 0
+image_ready: .byte 0
+last_ok: .byte 0
+tick_start: .word 0
+last_ticks: .word 0
+total_ticks: .word 0
+first_ticks: .word 0
+subsequent_ticks:.word 0
+total_kb: .word 0
+max_load_ticks: .word 0
+current_bank: .byte 0
+current_off: .word 0
+current_max: .word 0
+current_expected:.word 0
+first_fail_item: .byte 0
+first_fail_error:.byte 0
+first_fail_dbg0: .byte 0
+first_fail_dbg1: .byte 0
+max_load_name: .res 16
+first_fail_name: .res 16
+stage_id: .byte 0
+stage_start: .word 0
+stage_now: .word 0
+stage_delta: .word 0
+stage_ticks: .res STAGE_COUNT * 2
+stage_subseq_ticks: .res STAGE_COUNT * 2
diff --git a/build_support/analyze_uci_dma_probe_run.py b/build_support/analyze_uci_dma_probe_run.py
new file mode 100644
index 0000000..9d88b0b
--- /dev/null
+++ b/build_support/analyze_uci_dma_probe_run.py
@@ -0,0 +1,287 @@
+#!/usr/bin/env python3
+import argparse
+import json
+import pathlib
+import sys
+
+
+EXPECTED_VERSION = 0x20
+FILE_BLOCKS = (
+ (0x10, 0x11, "reu_snap_udma1_6000"),
+ (0x20, 0x42, "reu_snap_udma2_6100"),
+ (0x30, 0x83, "reu_snap_udma3_6200"),
+)
+PLAIN_STAT_OFFSET = 0x40
+COPY_UI_STAT_OFFSET = 0x48
+
+
+def fail(message):
+ print(f"FAIL: {message}")
+ return 1
+
+
+def read_file(path):
+ try:
+ return path.read_bytes()
+ except FileNotFoundError:
+ return None
+
+
+def artifact_path(run_dir, label):
+ direct_capture = run_dir / f"{label}.bin"
+ if direct_capture.exists():
+ return direct_capture
+
+ direct = run_dir / "stages" / "dump_probe_state" / f"{label}.bin"
+ if direct.exists():
+ return direct
+
+ manifest_path = run_dir / "manifest.json"
+ if not manifest_path.exists():
+ return direct
+ try:
+ manifest = json.loads(manifest_path.read_text(encoding="utf-8-sig"))
+ except Exception:
+ return direct
+ for step in manifest.get("steps", []):
+ artifacts = step.get("artifacts", {})
+ value = artifacts.get(f"{label}.bin")
+ if value:
+ return pathlib.Path(value)
+ return direct
+
+
+def validate_result_header(result, expected_version):
+ if result is None:
+ return "missing probe_results_3000.bin"
+ if len(result) < 0x40:
+ return f"short probe result block ({len(result)} bytes)"
+ if result[0:4] != b"UDMA":
+ return "probe result magic is not UDMA"
+ if result[10] != expected_version:
+ return f"version ${result[10]:02X}, expected ${expected_version:02X}"
+ return None
+
+
+def validate_no_uci(result):
+ if result[4] != 0:
+ return f"expected no UCI, but UCI flag is ${result[4]:02X}"
+ for offset, _, _ in FILE_BLOCKS:
+ if result[offset] != 0:
+ return f"file block ${offset:02X} changed on no-UCI path: ${result[offset]:02X}"
+ return None
+
+
+def validate_success(result, ram, reu, snapshots):
+ if result[4] != 1:
+ return f"UCI flag is ${result[4]:02X}, expected $01"
+ if result[9] in (0x00, 0xFF):
+ return f"SoftIEC bus byte ${result[9]:02X}, expected a real bus id"
+ if result[0x0B] not in (0, 1):
+ return f"selected USB byte is invalid: ${result[0x0B]:02X}"
+
+ for index, (offset, pattern, label) in enumerate(FILE_BLOCKS, start=1):
+ status = result[offset]
+ if status != 0x55:
+ return f"file {index} status ${status:02X}, expected $55"
+ if result[offset + 4] != 1:
+ return f"file {index} RAM flag ${result[offset + 4]:02X}, expected $01"
+ if result[offset + 5] != 1:
+ return f"file {index} REU flag ${result[offset + 5]:02X}, expected $01"
+ if result[offset + 6] not in (1, 4):
+ return f"file {index} RAM batch count ${result[offset + 6]:02X}, expected $01 or $04"
+ size = result[offset + 7] | (result[offset + 8] << 8)
+ if size not in (0x0000, 0x0102):
+ return f"file {index} stat size ${size:04X}, expected $0000 or $0102"
+ snapshot_hi = result[offset + 9]
+ expected_hi = 0x5F + index
+ if snapshot_hi != expected_hi:
+ return (
+ f"file {index} snapshot page ${snapshot_hi:02X}, "
+ f"expected ${expected_hi:02X}"
+ )
+ snapshot = snapshots.get(label)
+ if snapshot is None:
+ return f"missing {label}.bin"
+ if len(snapshot) < 0x100:
+ return f"short {label} dump ({len(snapshot)} bytes)"
+ if any(byte != pattern for byte in snapshot[:0x100]):
+ return f"{label} does not contain expected pattern ${pattern:02X}"
+
+ if ram is None:
+ return "missing dma_load_buf_4000.bin"
+ if len(ram) < 0x100:
+ return f"short RAM dump ({len(ram)} bytes)"
+ if any(byte != 0x83 for byte in ram[:0x100]):
+ return "RAM dump does not contain final UDMA3 pattern $83"
+
+ if reu is None:
+ return "missing reu_fetch_buf_5000.bin"
+ if len(reu) < 0x100:
+ return f"short REU fetch dump ({len(reu)} bytes)"
+ if any(byte != 0x83 for byte in reu[:0x100]):
+ return "REU fetch dump does not contain final UDMA3 pattern $83"
+ return None
+
+
+def describe_context_stat(result, offset, name, labels):
+ if result is None or len(result) <= offset + 7:
+ return f"{name} unavailable"
+ status = result[offset]
+ return (
+ f"{name} {labels.get(status, 'unknown')} "
+ f"status=${status:02X} data_len=${result[offset + 1]:02X} "
+ f"stat_len=${result[offset + 2]:02X} "
+ f"stat=${result[offset + 3]:02X}${result[offset + 4]:02X} "
+ f"data0=${result[offset + 5]:02X}${result[offset + 6]:02X} "
+ f"data8=${result[offset + 7]:02X}"
+ )
+
+
+def describe_plain_stat(result):
+ labels = {
+ 0x00: "not-run",
+ 0x41: "transport-fail",
+ 0x42: "not-file-stat",
+ 0x55: "ok",
+ }
+ return describe_context_stat(result, PLAIN_STAT_OFFSET, "plain-stat", labels)
+
+
+def describe_copy_ui_stat(result):
+ labels = {
+ 0x00: "not-run",
+ 0x51: "copy-ui-fail",
+ 0x52: "transport-fail",
+ 0x53: "not-file-stat",
+ 0x55: "ok",
+ }
+ return describe_context_stat(result, COPY_UI_STAT_OFFSET, "copy-ui-stat", labels)
+
+
+def decode_screen(screen):
+ if screen is None:
+ return ""
+ chars = []
+ for index, byte in enumerate(screen[:1000]):
+ if index and index % 40 == 0:
+ chars.append("\n")
+ if 1 <= byte <= 26:
+ chars.append(chr(ord("A") + byte - 1))
+ elif byte == 0:
+ chars.append("@")
+ elif 32 <= byte <= 95:
+ chars.append(chr(byte))
+ else:
+ chars.append(".")
+ return "".join(chars)
+
+
+def validate_screen(screen, expected_version, expect):
+ if screen is None:
+ return "missing screen_0400.bin"
+ text = decode_screen(screen)
+ if "PROBE DONE" not in text:
+ return "screen does not show PROBE DONE"
+ if expect == "no-uci":
+ if "UCI NOT FOUND" not in text:
+ return "screen does not show UCI NOT FOUND"
+ else:
+ if "F1:55 F2:55 F3:55" not in text:
+ return "screen does not show success summary F1:55 F2:55 F3:55"
+ return None
+
+
+def main():
+ parser = argparse.ArgumentParser(
+ description="Validate UCI DMA probe automation artifacts."
+ )
+ parser.add_argument("run_dir", type=pathlib.Path)
+ parser.add_argument(
+ "--expect",
+ choices=("auto", "no-uci", "success"),
+ default="auto",
+ help="Expected result mode. auto treats UCI flag $00 as no-uci, $01 as success.",
+ )
+ parser.add_argument(
+ "--version",
+ default=f"{EXPECTED_VERSION:02x}",
+ help="Expected probe version byte, hex-style text or 0x-prefixed hex.",
+ )
+ parser.add_argument(
+ "--expect-plain",
+ choices=("any", "success", "fail"),
+ default="any",
+ help="Expected result for the pre-CD launcher-style plain STAT check.",
+ )
+ parser.add_argument(
+ "--expect-copy-ui",
+ choices=("any", "success", "fail"),
+ default="any",
+ help="Expected result for COPY_UI_PATH followed by pre-CD plain STAT.",
+ )
+ args = parser.parse_args()
+
+ version_text = args.version.strip().lower()
+ if version_text.startswith("0x"):
+ expected_version = int(version_text, 16)
+ else:
+ expected_version = int(version_text, 16)
+ expected_version &= 0xFF
+
+ run_dir = args.run_dir
+ result = read_file(artifact_path(run_dir, "probe_results_3000"))
+ ram = read_file(artifact_path(run_dir, "dma_load_buf_4000"))
+ reu = read_file(artifact_path(run_dir, "reu_fetch_buf_5000"))
+ screen = read_file(artifact_path(run_dir, "screen_0400"))
+ snapshots = {
+ label: read_file(artifact_path(run_dir, label))
+ for _, _, label in FILE_BLOCKS
+ }
+
+ error = validate_result_header(result, expected_version)
+ if error:
+ return fail(error)
+
+ if args.expect == "auto":
+ expect = "success" if result[4] == 1 else "no-uci"
+ else:
+ expect = args.expect
+
+ if expect == "no-uci":
+ error = validate_no_uci(result)
+ else:
+ error = validate_success(result, ram, reu, snapshots)
+ if error:
+ return fail(error)
+
+ error = validate_screen(screen, expected_version, expect)
+ if error:
+ return fail(error)
+
+ plain_status = result[PLAIN_STAT_OFFSET] if len(result) > PLAIN_STAT_OFFSET else 0
+ if args.expect_plain == "success" and plain_status != 0x55:
+ return fail(describe_plain_stat(result))
+ if args.expect_plain == "fail" and plain_status == 0x55:
+ return fail(describe_plain_stat(result))
+ copy_ui_status = (
+ result[COPY_UI_STAT_OFFSET] if len(result) > COPY_UI_STAT_OFFSET else 0
+ )
+ if args.expect_copy_ui == "success" and copy_ui_status != 0x55:
+ return fail(describe_copy_ui_stat(result))
+ if args.expect_copy_ui == "fail" and copy_ui_status == 0x55:
+ return fail(describe_copy_ui_stat(result))
+
+ print(f"OK: {run_dir} ({expect}, version ${expected_version:02X})")
+ print(f"OK: {describe_plain_stat(result)}")
+ print(f"OK: {describe_copy_ui_stat(result)}")
+ if expect == "success":
+ print(
+ "OK: UCI flag, file statuses, RAM batches, file sizes, RAM buffer, "
+ "SoftIEC flag, REU fetch buffer, and per-file REU snapshots validated"
+ )
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/build_support/analyze_uci_timing_probe_run.py b/build_support/analyze_uci_timing_probe_run.py
new file mode 100644
index 0000000..c90c737
--- /dev/null
+++ b/build_support/analyze_uci_timing_probe_run.py
@@ -0,0 +1,176 @@
+#!/usr/bin/env python3
+from __future__ import annotations
+
+import argparse
+import json
+import pathlib
+import re
+import sys
+
+
+PHASES = ["open", "info", "read2", "seek", "load", "close"]
+LAUNCHER_PHASES = ["first_load", "subsequent_loads"]
+LAUNCHER_STAGES = [
+ "detect",
+ "identify",
+ "drvinfo",
+ "cd_root",
+ "cd_dir",
+ "mount",
+ "cd_image",
+ "open",
+ "file_info",
+ "read_header",
+ "seek_payload",
+ "load_reu",
+ "close",
+]
+
+
+def find_dump(run_dir: pathlib.Path) -> pathlib.Path:
+ candidates = list(run_dir.rglob("*uci_timing_results_3000*"))
+ candidates += list(run_dir.rglob("*3000*.bin"))
+ if not candidates:
+ raise SystemExit(f"no uci timing result dump found under {run_dir}")
+ return max(candidates, key=lambda p: p.stat().st_mtime)
+
+
+def u16(data: bytes, off: int) -> int:
+ return data[off] | (data[off + 1] << 8)
+
+
+def decode(path: pathlib.Path) -> dict[str, object]:
+ data = path.read_bytes()
+ idx = data.find(b"UTIM")
+ if idx < 0:
+ raise SystemExit(f"{path}: missing UTIM magic")
+ b = data[idx:idx + 128]
+ version = b[4]
+ phase_names = LAUNCHER_PHASES if version >= 4 else (LAUNCHER_PHASES + ["unused2", "unused3", "unused4", "unused5"] if version >= 3 else PHASES)
+ raw_phases = {name: u16(b, 16 + i * 2) for i, name in enumerate(phase_names)}
+ if version >= 2:
+ phases = {name: (ticks * 1000 + 30) // 60 for name, ticks in raw_phases.items()}
+ total_ms = (u16(b, 8) * 1000 + 30) // 60
+ max_load_ms = (u16(b, 12) * 1000 + 30) // 60
+ else:
+ phases = raw_phases
+ total_ms = u16(b, 8)
+ max_load_ms = u16(b, 12)
+ if version >= 4:
+ max_name = b[48:64].split(b"\0", 1)[0].decode("latin1", errors="replace")
+ else:
+ max_name = b[32:48].split(b"\0", 1)[0].decode("latin1", errors="replace")
+ fail_status = b[51:56].split(b"\0", 1)[0].decode("latin1", errors="replace")
+ dir_status = b[62:64].split(b"\0", 1)[0].decode("latin1", errors="replace")
+ raw_stage_ticks = None
+ stages_ms = None
+ raw_subseq_stage_ticks = None
+ subseq_stages_ms = None
+ if version >= 4:
+ count = min(b[15], len(LAUNCHER_STAGES))
+ raw_stage_ticks = {
+ LAUNCHER_STAGES[i]: u16(b, 20 + i * 2)
+ for i in range(count)
+ }
+ stages_ms = {
+ name: (ticks * 1000 + 30) // 60
+ for name, ticks in raw_stage_ticks.items()
+ }
+ if version >= 6:
+ count = min(b[15], len(LAUNCHER_STAGES))
+ raw_subseq_stage_ticks = {
+ LAUNCHER_STAGES[i]: u16(b, 80 + i * 2)
+ for i in range(count)
+ }
+ subseq_stages_ms = {
+ name: (ticks * 1000 + 30) // 60
+ for name, ticks in raw_subseq_stage_ticks.items()
+ }
+ if version >= 4:
+ first_failure = {
+ "item": b[64],
+ "launcher_error": b[65],
+ "debug_status0": b[66],
+ "debug_status1": b[67],
+ "name": b[72:80].split(b"\0", 1)[0].decode("latin1", errors="replace"),
+ }
+ avg_header_tax_ms = 0
+ elif version >= 3:
+ first_failure = {
+ "item": b[48],
+ "launcher_error": b[49],
+ "debug_status0": b[50],
+ "debug_status1": b[51],
+ "name": b[56:64].split(b"\0", 1)[0].decode("latin1", errors="replace"),
+ }
+ avg_header_tax_ms = 0
+ else:
+ first_failure = {
+ "stage": b[48],
+ "status_len": b[49],
+ "data_len": b[50],
+ "status_prefix": fail_status,
+ "data_prefix_hex": b[54:56].hex(),
+ }
+ avg_header_tax_ms = (phases["read2"] + phases["seek"]) // b[6] if b[6] else 0
+ result = {
+ "version": version,
+ "done": b[5],
+ "items": b[6],
+ "successes": b[14] if version >= 3 else b[6] - b[7],
+ "failures": b[7],
+ "total_ms": total_ms,
+ "loaded_kb": u16(b, 10),
+ "max_load_ms": max_load_ms,
+ "phases_ms": phases,
+ "stages_ms": stages_ms,
+ "raw_stage_ticks": raw_stage_ticks,
+ "subsequent_stages_ms": subseq_stages_ms,
+ "raw_subsequent_stage_ticks": raw_subseq_stage_ticks,
+ "raw_phase_ticks": raw_phases if version >= 2 else None,
+ "raw_total_ticks": u16(b, 8) if version >= 2 else None,
+ "header_tax_ms": 0 if version >= 3 else phases["read2"] + phases["seek"],
+ "avg_header_tax_ms": avg_header_tax_ms,
+ "max_load_name": max_name,
+ "first_failure": first_failure,
+ "dir_probe": {
+ "data_len": b[56],
+ "status_len": b[57],
+ "data_prefix_hex": b[58:62].hex(),
+ "status_prefix": dir_status,
+ },
+ "dump": str(path),
+ }
+ return result
+
+
+def manifest_run_dir_from_log(log: pathlib.Path) -> pathlib.Path | None:
+ text = log.read_text(encoding="utf-8-sig", errors="ignore")
+ matches = re.findall(r'"Manifest"\s*:\s*"([^"]+)"', text)
+ if not matches:
+ return None
+ return pathlib.Path(matches[-1]).expanduser().resolve().parent
+
+
+def main() -> int:
+ ap = argparse.ArgumentParser()
+ ap.add_argument("path", help="run directory or log containing Manifest path")
+ ap.add_argument("--json-output")
+ args = ap.parse_args()
+
+ path = pathlib.Path(args.path).expanduser().resolve()
+ if path.is_file():
+ run_dir = manifest_run_dir_from_log(path)
+ if run_dir is None:
+ raise SystemExit(f"{path}: no manifest path found")
+ else:
+ run_dir = path
+ result = decode(find_dump(run_dir))
+ print(json.dumps(result, indent=2, sort_keys=True))
+ if args.json_output:
+ pathlib.Path(args.json_output).write_text(json.dumps(result, indent=2, sort_keys=True) + "\n")
+ return 0 if result["done"] == 1 and result["failures"] == 0 else 1
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/build_support/annotate_historical_memory_contracts.py b/build_support/annotate_historical_memory_contracts.py
new file mode 100644
index 0000000..ba4e084
--- /dev/null
+++ b/build_support/annotate_historical_memory_contracts.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+"""Add a repeat-safe current-contract banner to retained historical reports.
+
+The reports below intentionally keep their dated measurements and proposals.
+This script adds context without replacing or deleting the historical body.
+"""
+
+from __future__ import annotations
+
+import re
+from pathlib import Path
+
+
+ROOT = Path(__file__).resolve().parents[1]
+MARKER = "READYOS-CURRENT-CONTRACT-2026-08-02"
+
+MARKDOWN_PATHS = (
+ "ReadyOSREUPhase1Completed.md",
+ "futureREUrefactor.md",
+ "reurefactorlessonslearnt.md",
+ "privatedocs/reports/OLD_READYBASIC_MEMORY_REARRANGEMENT_IMPLEMENTED.md",
+ "privatedocs/reports/easyflash_boot_flow.md",
+ "privatedocs/reports/potential_future_readyos_ram_maximization_plan.md",
+ "privatedocs/reports/readybasic_design_ideas.md",
+ "privatedocs/reports/readyos_all_apps_memory_contract_compare.md",
+ "privatedocs/reports/readyshell_variable_memory_ram_reu_flow.md",
+ "privatedocs/research/architecture.md",
+ "privatedocs/research/dizzy_verification_matrix.md",
+ "privatedocs/research/readyos_c64os_interop_design.md",
+ "privatedocs/research/READYSHELL_EDITOR_OVERLAY_REFACTOR_NOTES.md",
+ "privatedocs/top_level_md/ARCHITECTURE_PLAN.md",
+ "privatedocs/top_level_md/IMPLEMENTATION_PLAN.md",
+)
+
+HTML_PATHS = (
+ "ReadyOSREUPhase1Completed.html",
+ "docs/reports/ReadyOSREUPhase1Completed.html",
+ "docs/reports/readyos_memory_size_comparison_0_1_5_vs_now.html",
+ "docs/reports/simplefiles_once_bss_resume_headroom_0_1_8w.html",
+ "privatedocs/reports/easyflash_boot_flow.html",
+ "privatedocs/reports/old_readybasic_memory_rearrangement_implemented.html",
+ "privatedocs/reports/potential_future_readyos_ram_maximization_plan.html",
+ "privatedocs/reports/readybasic_design_ideas.html",
+ "privatedocs/reports/readyos_c64os_interop_design.html",
+ "privatedocs/reports/readyos_c64os_interop_design_v2.html",
+ "privatedocs/reports/readyos_memory_layout_print.html",
+ "privatedocs/reports/readyos_memory_size_comparison_0_1_5_vs_now.html",
+ "privatedocs/reports/readyos_shim_architecture_report.html",
+ "privatedocs/reports/readyos_shim_architecture_report_v2.html",
+ "privatedocs/reports/readyos_shim_architecture_report_v3 copy.html",
+ "privatedocs/reports/readyshell_overlay_bss_resume_headroom_0_1_8a.html",
+)
+
+MD_NOTE = f"""
+
+> **Current ReadyOS contract (2026-08-02):** Physical `Skip` is the ReadyOS
+> bank and `Skip+1` is the first dynamic bank. The launcher snapshot occupies
+> ReadyOS `$0000-$B5FF`; schema v5 occupies `$B600-$FFFF`, including the token
+> map at `$B740` and status at `$B840`. C64 app RAM is `$1000-$C5FF` (`$B600`),
+> and the resident 1 KB shim owns `$C600-$C9FF` with its public ABI at `$C800`.
+> Dated layouts and measurements below are retained as historical evidence.
+""".strip()
+
+HTML_NOTE = f"""
+
+
+ Current ReadyOS contract (2026-08-02):
+ Physical Skip is the ReadyOS bank and Skip+1 is the first dynamic bank.
+ The launcher snapshot is ReadyOS $0000-$B5FF; schema v5 is $B600-$FFFF,
+ with token map $B740 and status $B840. C64 app RAM is
+ $1000-$C5FF ($B600), and the resident 1 KB shim owns
+ $C600-$C9FF with its public ABI at $C800.
+ Dated layouts and measurements below are retained as historical evidence.
+
+""".strip()
+
+
+def annotate_markdown(path: Path) -> bool:
+ text = path.read_text(encoding="utf-8")
+ if MARKER in text:
+ return False
+ match = re.search(r"(?m)^# .+\n", text)
+ if not match:
+ raise SystemExit(f"missing top-level Markdown heading: {path}")
+ updated = text[: match.end()] + "\n" + MD_NOTE + "\n" + text[match.end():]
+ path.write_text(updated, encoding="utf-8")
+ return True
+
+
+def annotate_html(path: Path) -> bool:
+ text = path.read_text(encoding="utf-8")
+ if MARKER in text:
+ return False
+ match = re.search(r"]*)?>", text, re.IGNORECASE)
+ if not match:
+ updated = HTML_NOTE + "\n" + text
+ else:
+ updated = text[: match.end()] + "\n" + HTML_NOTE + "\n" + text[match.end():]
+ path.write_text(updated, encoding="utf-8")
+ return True
+
+
+def main() -> None:
+ changed: list[Path] = []
+ for rel in MARKDOWN_PATHS:
+ path = ROOT / rel
+ if annotate_markdown(path):
+ changed.append(path)
+ for rel in HTML_PATHS:
+ path = ROOT / rel
+ if annotate_html(path):
+ changed.append(path)
+ print(f"annotated {len(changed)} retained historical reports")
+ for path in changed:
+ print(path.relative_to(ROOT))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/build_support/build_apps_catalog_petscii.py b/build_support/build_apps_catalog_petscii.py
index e830f00..0f8ebf8 100644
--- a/build_support/build_apps_catalog_petscii.py
+++ b/build_support/build_apps_catalog_petscii.py
@@ -12,6 +12,7 @@
[launcher]
load_all_to_reu=0
runappfirst=
+ c64u_image_path=
[apps]
9:editor:editor:1
@@ -206,6 +207,7 @@ def parse_source(path: str) -> Tuple[Dict[str, str], Dict[str, str], List[Tuple[
launcher_cfg: Dict[str, str] = {
"load_all_to_reu": "0",
"runappfirst": "",
+ "c64u_image_path": "",
}
apps: List[Tuple[str, str, str]] = []
@@ -253,6 +255,8 @@ def parse_source(path: str) -> Tuple[Dict[str, str], Dict[str, str], List[Tuple[
launcher_cfg[key] = normalize_prg_token(value, path, idx)
else:
launcher_cfg[key] = ""
+ elif key == "c64u_image_path":
+ launcher_cfg[key] = value.strip()
continue
if section == SECTION_APPS:
@@ -304,6 +308,7 @@ def render_lines(system_cfg: Dict[str, str],
"[launcher]",
f"load_all_to_reu={launcher_cfg['load_all_to_reu']}",
f"runappfirst={launcher_cfg['runappfirst']}",
+ f"c64u_image_path={launcher_cfg['c64u_image_path']}",
"[apps]",
]
for entry, desc, deps in apps:
diff --git a/build_support/c64u_dma_acceptance/README.md b/build_support/c64u_dma_acceptance/README.md
new file mode 100644
index 0000000..e5c2560
--- /dev/null
+++ b/build_support/c64u_dma_acceptance/README.md
@@ -0,0 +1,15 @@
+# C64U DMA Acceptance Configs
+
+These ReadyOS catalog fixtures exercise the launcher DMA path cases that matter
+on C64 Ultimate hardware:
+
+- `precog-d81-dma-valid.ini`: DMA enabled with a configured image path. Upload
+ or copy the tested D81 to the same C64U path before running.
+- `precog-d81-dma-empty-path.ini`: no configured C64U image path, so the
+ launcher must skip DMA setup and use normal disk loading.
+- `precog-d81-dma-bad-path.ini`: configured path cannot be mounted, so the
+ launcher must report DMA unavailable and fall back to disk loading.
+
+The valid-path fixture intentionally uses `/usb1/readyos.d81` as a stable test
+path. Versioned deployment builds may override this value, but the value inside
+`apps.cfg` must exactly match the file path present on the C64U USB volume.
diff --git a/build_support/c64u_dma_acceptance/precog-d81-dma-bad-path.ini b/build_support/c64u_dma_acceptance/precog-d81-dma-bad-path.ini
new file mode 100644
index 0000000..73a90a7
--- /dev/null
+++ b/build_support/c64u_dma_acceptance/precog-d81-dma-bad-path.ini
@@ -0,0 +1,72 @@
+[system]
+variant_name=precog d81
+variant_boot_name=precog d81
+reu_bank_skip=32
+
+[launcher]
+load_all_to_reu=0
+runappfirst=
+c64u_image_path=/usb1/miss.d81
+
+[apps]
+8:editor:editor:1
+text editor with clipboard
+
+8:readyshell:readyshell (beta):2:rsovl+
+command shell poc scaffold
+rsparser@0:0000,rsvm@0:3800,rsdrvilst@0:7000,rsldv@1:0000,rsstv@0:a800,rsfops@1:3800,rscat@1:7000,rscopy@1:a800,rsedit@2:0000
+
+8:simplefiles:simple files
+dual pane file manager and seq viewer
+
+8:clipmgr:clipboard
+manage clipboard items
+
+8:readybasic:ready basic (alpha):3:rbcore+
+scoped basic v2 bridge poc
+rbcore,rbcode
+
+8:cal26:calendar 26
+calendar for 2026 with appointments
+
+8:tasklist:task list
+outliner with notes and search
+
+8:reuviewer:reu viewer
+view reu memory usage
+
+8:sysinfo:system info
+system, reu, and ultimate status
+
+8:quicknotes:quicknotes
+reu-backed note editor
+
+8:calcplus:calc plus
+keyboard-first expression calculator
+
+8:hexview:hex viewer
+browse memory in hex format
+
+8:simplecells:simple cells (alpha)
+spreadsheet with formulas and colors
+
+8:game2048:2048 game
+2048 tile puzzle
+
+8:deminer:deminer
+minesweeper-style puzzle
+
+8:dizzy:dizzy kanban
+fizzy inspired kanban app
+
+8:readyirc:readyirc
+ultimate tcp irc client
+
+8:ucitest:uci tester
+ultimate command interface lab
+
+8:rirc-rrnet:readyirc rrnet
+rr-net tcp irc client
+
+8:readme:read.me
+readyos, ultimate buddy, precog poc os
diff --git a/build_support/c64u_dma_acceptance/precog-d81-dma-empty-path.ini b/build_support/c64u_dma_acceptance/precog-d81-dma-empty-path.ini
new file mode 100644
index 0000000..d498c4a
--- /dev/null
+++ b/build_support/c64u_dma_acceptance/precog-d81-dma-empty-path.ini
@@ -0,0 +1,72 @@
+[system]
+variant_name=precog d81
+variant_boot_name=precog d81
+reu_bank_skip=32
+
+[launcher]
+load_all_to_reu=0
+runappfirst=
+c64u_image_path=
+
+[apps]
+8:editor:editor:1
+text editor with clipboard
+
+8:readyshell:readyshell (beta):2:rsovl+
+command shell poc scaffold
+rsparser@0:0000,rsvm@0:3800,rsdrvilst@0:7000,rsldv@1:0000,rsstv@0:a800,rsfops@1:3800,rscat@1:7000,rscopy@1:a800,rsedit@2:0000
+
+8:simplefiles:simple files
+dual pane file manager and seq viewer
+
+8:clipmgr:clipboard
+manage clipboard items
+
+8:readybasic:ready basic (alpha):3:rbcore+
+scoped basic v2 bridge poc
+rbcore,rbcode
+
+8:cal26:calendar 26
+calendar for 2026 with appointments
+
+8:tasklist:task list
+outliner with notes and search
+
+8:reuviewer:reu viewer
+view reu memory usage
+
+8:sysinfo:system info
+system, reu, and ultimate status
+
+8:quicknotes:quicknotes
+reu-backed note editor
+
+8:calcplus:calc plus
+keyboard-first expression calculator
+
+8:hexview:hex viewer
+browse memory in hex format
+
+8:simplecells:simple cells (alpha)
+spreadsheet with formulas and colors
+
+8:game2048:2048 game
+2048 tile puzzle
+
+8:deminer:deminer
+minesweeper-style puzzle
+
+8:dizzy:dizzy kanban
+fizzy inspired kanban app
+
+8:readyirc:readyirc
+ultimate tcp irc client
+
+8:ucitest:uci tester
+ultimate command interface lab
+
+8:rirc-rrnet:readyirc rrnet
+rr-net tcp irc client
+
+8:readme:read.me
+readyos, ultimate buddy, precog poc os
diff --git a/build_support/c64u_dma_acceptance/precog-d81-dma-valid.ini b/build_support/c64u_dma_acceptance/precog-d81-dma-valid.ini
new file mode 100644
index 0000000..bf83c9b
--- /dev/null
+++ b/build_support/c64u_dma_acceptance/precog-d81-dma-valid.ini
@@ -0,0 +1,72 @@
+[system]
+variant_name=precog d81
+variant_boot_name=precog d81
+reu_bank_skip=32
+
+[launcher]
+load_all_to_reu=0
+runappfirst=
+c64u_image_path=/usb1/readyos.d81
+
+[apps]
+8:editor:editor:1
+text editor with clipboard
+
+8:readyshell:readyshell (beta):2:rsovl+
+command shell poc scaffold
+rsparser@0:0000,rsvm@0:3800,rsdrvilst@0:7000,rsldv@1:0000,rsstv@0:a800,rsfops@1:3800,rscat@1:7000,rscopy@1:a800,rsedit@2:0000
+
+8:simplefiles:simple files
+dual pane file manager and seq viewer
+
+8:clipmgr:clipboard
+manage clipboard items
+
+8:readybasic:ready basic (alpha):3:rbcore+
+scoped basic v2 bridge poc
+rbcore,rbcode
+
+8:cal26:calendar 26
+calendar for 2026 with appointments
+
+8:tasklist:task list
+outliner with notes and search
+
+8:reuviewer:reu viewer
+view reu memory usage
+
+8:sysinfo:system info
+system, reu, and ultimate status
+
+8:quicknotes:quicknotes
+reu-backed note editor
+
+8:calcplus:calc plus
+keyboard-first expression calculator
+
+8:hexview:hex viewer
+browse memory in hex format
+
+8:simplecells:simple cells (alpha)
+spreadsheet with formulas and colors
+
+8:game2048:2048 game
+2048 tile puzzle
+
+8:deminer:deminer
+minesweeper-style puzzle
+
+8:dizzy:dizzy kanban
+fizzy inspired kanban app
+
+8:readyirc:readyirc
+ultimate tcp irc client
+
+8:ucitest:uci tester
+ultimate command interface lab
+
+8:rirc-rrnet:readyirc rrnet
+rr-net tcp irc client
+
+8:readme:read.me
+readyos, ultimate buddy, precog poc os
diff --git a/build_support/c64u_type_text.sh b/build_support/c64u_type_text.sh
new file mode 100755
index 0000000..0af3ae9
--- /dev/null
+++ b/build_support/c64u_type_text.sh
@@ -0,0 +1,64 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+host="${C64U_HOST:-10.0.0.79}"
+text="${1:?usage: c64u_type_text.sh TEXT}"
+api="http://${host}/v1"
+tmp_dir="${TMPDIR:-/tmp}/c64u_type_text.$$"
+
+mkdir -p "$tmp_dir"
+trap 'rm -rf "$tmp_dir"' EXIT
+
+post_bytes() {
+ local address="$1"
+ local file="$2"
+ local hex
+ hex="$(xxd -p -c 256 "$file" | tr -d '\n')"
+ curl --fail --silent --show-error --max-time 10 \
+ -X PUT \
+ "${api}/machine:writemem?address=${address}&data=${hex}" >/dev/null
+}
+
+wait_keyboard_empty() {
+ local sample value
+ for _ in $(seq 1 200); do
+ sample="$tmp_dir/kb_count.bin"
+ if curl --fail --silent --show-error --max-time 5 \
+ "${api}/machine:readmem?address=C6&length=1" -o "$sample" >/dev/null 2>&1; then
+ value="$(od -An -tu1 "$sample" | tr -d ' ')"
+ if [[ "$value" == "0" ]]; then
+ return 0
+ fi
+ fi
+ sleep 0.03
+ done
+ echo "Keyboard buffer did not drain" >&2
+ return 1
+}
+
+python3 - "$tmp_dir/type.bin" "$text" <<'PY'
+import pathlib
+import sys
+
+text = sys.argv[2]
+pathlib.Path(sys.argv[1]).write_bytes(
+ bytes(0x0D if ch in "\r\n" else ord(ch.upper()) for ch in text)
+)
+PY
+
+size="$(wc -c < "$tmp_dir/type.bin" | tr -d ' ')"
+offset=0
+while (( offset < size )); do
+ dd if="$tmp_dir/type.bin" of="$tmp_dir/chunk.bin" bs=1 skip="$offset" count=1 status=none
+ byte_hex="$(xxd -p -c 1 "$tmp_dir/chunk.bin" | tr -d '\n')"
+ printf '\000\000' > "$tmp_dir/kbclear.bin"
+ wait_keyboard_empty
+ post_bytes "C5" "$tmp_dir/kbclear.bin"
+ curl --fail --silent --show-error --max-time 10 \
+ -X PUT \
+ "${api}/machine:writemem?address=277&data=${byte_hex}" >/dev/null
+ printf '\001' > "$tmp_dir/count.bin"
+ post_bytes "C6" "$tmp_dir/count.bin"
+ wait_keyboard_empty
+ offset=$(( offset + 1 ))
+done
diff --git a/build_support/capture_uci_dma_probe_c64u.sh b/build_support/capture_uci_dma_probe_c64u.sh
new file mode 100755
index 0000000..fee0001
--- /dev/null
+++ b/build_support/capture_uci_dma_probe_c64u.sh
@@ -0,0 +1,36 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+repo="$(cd "$(dirname "$0")/.." && pwd)"
+host="${C64U_HOST:-10.0.0.79}"
+out_dir="${1:-/tmp/uci_dma_probe_manual_capture_$(date +%Y%m%d_%H%M%S)}"
+
+mkdir -p "$out_dir"
+
+curl_get() {
+ local url="$1"
+ local output="$2"
+ curl --fail --silent --show-error --max-time 10 "$url" -o "$output"
+}
+
+curl_get "http://${host}/v1/machine:readmem?address=0400&length=1000" "$out_dir/screen_0400.bin"
+curl_get "http://${host}/v1/machine:readmem?address=3000&length=128" "$out_dir/probe_results_3000.bin"
+curl_get "http://${host}/v1/machine:readmem?address=4000&length=256" "$out_dir/dma_load_buf_4000.bin"
+curl_get "http://${host}/v1/machine:readmem?address=5000&length=256" "$out_dir/reu_fetch_buf_5000.bin"
+curl_get "http://${host}/v1/machine:readmem?address=6000&length=256" "$out_dir/reu_snap_udma1_6000.bin"
+curl_get "http://${host}/v1/machine:readmem?address=6100&length=256" "$out_dir/reu_snap_udma2_6100.bin"
+curl_get "http://${host}/v1/machine:readmem?address=6200&length=256" "$out_dir/reu_snap_udma3_6200.bin"
+curl_get "http://${host}/v1/machine:readmem?address=6800&length=2048" "$out_dir/launcher_code_6800.bin"
+curl_get "http://${host}/v1/machine:readmem?address=B800&length=1536" "$out_dir/launcher_bss_b800.bin"
+curl_get "http://${host}/v1/drives" "$out_dir/drives.json"
+
+python3 "$repo/build_support/decode_c64_screen.py" \
+ "$out_dir/screen_0400.bin" \
+ --output "$out_dir/screen.txt"
+
+for bin in "$out_dir"/*.bin; do
+ xxd -g 1 -c 16 "$bin" > "${bin%.bin}.hex.txt"
+done
+
+echo "$out_dir"
+cat "$out_dir/screen.txt"
diff --git a/build_support/decode_c64_screen.py b/build_support/decode_c64_screen.py
new file mode 100755
index 0000000..1fd60ca
--- /dev/null
+++ b/build_support/decode_c64_screen.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python3
+"""Decode a 40x25 C64 screen-code dump into readable text."""
+
+from __future__ import annotations
+
+import argparse
+from pathlib import Path
+
+
+def decode_screen_code(value: int) -> str:
+ if value == 0x20:
+ return " "
+ if 0x01 <= value <= 0x1A:
+ return chr(ord("A") + value - 1)
+ if 0x30 <= value <= 0x39:
+ return chr(value)
+ if 0x20 <= value <= 0x3F:
+ table = {
+ 0x21: "!",
+ 0x22: '"',
+ 0x23: "#",
+ 0x24: "$",
+ 0x25: "%",
+ 0x26: "&",
+ 0x27: "'",
+ 0x28: "(",
+ 0x29: ")",
+ 0x2A: "*",
+ 0x2B: "+",
+ 0x2C: ",",
+ 0x2D: "-",
+ 0x2E: ".",
+ 0x2F: "/",
+ 0x3A: ":",
+ 0x3B: ";",
+ 0x3C: "<",
+ 0x3D: "=",
+ 0x3E: ">",
+ 0x3F: "?",
+ }
+ return table.get(value, chr(value))
+ if 0x41 <= value <= 0x5A:
+ return chr(ord("a") + value - 0x41)
+ return "."
+
+
+def decode_screen(data: bytes, width: int = 40, height: int = 25) -> list[str]:
+ padded = data[: width * height].ljust(width * height, b" ")
+ lines = []
+ for row in range(height):
+ start = row * width
+ text = "".join(decode_screen_code(b) for b in padded[start : start + width])
+ lines.append(text.rstrip())
+ return lines
+
+
+def main() -> int:
+ parser = argparse.ArgumentParser()
+ parser.add_argument("screen_bin", type=Path)
+ parser.add_argument("--output", "-o", type=Path)
+ args = parser.parse_args()
+
+ lines = decode_screen(args.screen_bin.read_bytes())
+ text = "\n".join(f"{idx:02d}: {line}" for idx, line in enumerate(lines)) + "\n"
+ if args.output:
+ args.output.write_text(text, encoding="utf-8")
+ else:
+ print(text, end="")
+ return 0
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/build_support/discover_c64u_host.sh b/build_support/discover_c64u_host.sh
new file mode 100644
index 0000000..187bb4b
--- /dev/null
+++ b/build_support/discover_c64u_host.sh
@@ -0,0 +1,97 @@
+#!/usr/bin/env bash
+set -uo pipefail
+
+log="${C64U_DISCOVERY_LOG:-/tmp/c64u_discovery.log}"
+password="${C64U_PASSWORD:-}"
+scan_subnet="${C64U_SCAN_SUBNET:-}"
+
+rm -f "$log"
+
+add_candidate() {
+ local value="$1"
+ value="${value#http://}"
+ value="${value#https://}"
+ value="${value%%/*}"
+ [[ -n "$value" ]] || return 0
+ printf '%s\n' "$value" >> /tmp/c64u_candidates.$$
+}
+
+probe_http() {
+ local host="$1"
+ local route="$2"
+ local output
+ if [[ -n "$password" ]]; then
+ output="$(curl --connect-timeout 1 --max-time 2 --silent --show-error \
+ -H "X-Password: ${password}" "http://${host}/v1/${route}" 2>&1)"
+ else
+ output="$(curl --connect-timeout 1 --max-time 2 --silent --show-error \
+ "http://${host}/v1/${route}" 2>&1)"
+ fi
+ local rc=$?
+ {
+ echo " /v1/${route} rc=${rc}"
+ printf '%s\n' "$output" | sed 's/^/ /'
+ } >> "$log"
+ [[ "$rc" -eq 0 ]] || return 1
+ printf '%s' "$output" | grep -Eiq 'ultimate|1541|firmware|version|machine|drives|errors|\{'
+}
+
+probe_host() {
+ local host="$1"
+ echo "== ${host} ==" >> "$log"
+ if probe_http "$host" "version"; then
+ printf '%s\n' "$host"
+ return 0
+ fi
+ if probe_http "$host" "info"; then
+ printf '%s\n' "$host"
+ return 0
+ fi
+ return 1
+}
+
+date > "$log"
+echo "C64U discovery" >> "$log"
+
+: > /tmp/c64u_candidates.$$
+host_list="${C64U_HOSTS//,/ }"
+for raw in ${host_list:-}; do
+ add_candidate "$raw"
+done
+if [[ -n "${C64U_HOST:-}" && "${C64U_HOST}" != "auto" ]]; then
+ add_candidate "$C64U_HOST"
+fi
+add_candidate "10.0.0.79"
+arp -an 2>/dev/null |
+ sed -n 's/.*(\([0-9][0-9.]*\)).*/\1/p' |
+ while read -r ip; do
+ case "$ip" in
+ 10.0.0.0|10.0.0.255) ;;
+ 10.0.0.*) add_candidate "$ip" ;;
+ esac
+ done
+
+if [[ -n "$scan_subnet" ]]; then
+ base="${scan_subnet%.}"
+ for last in $(seq 1 254); do
+ add_candidate "${base}.${last}"
+ done
+fi
+
+sort -u /tmp/c64u_candidates.$$ > /tmp/c64u_candidates_sorted.$$
+echo "candidates:" >> "$log"
+sed 's/^/ /' /tmp/c64u_candidates_sorted.$$ >> "$log"
+
+found=""
+while read -r candidate; do
+ if found="$(probe_host "$candidate")"; then
+ echo "selected: ${found}" >> "$log"
+ printf '%s\n' "$found"
+ rm -f /tmp/c64u_candidates.$$ /tmp/c64u_candidates_sorted.$$
+ exit 0
+ fi
+done < /tmp/c64u_candidates_sorted.$$
+
+echo "selected: none" >> "$log"
+rm -f /tmp/c64u_candidates.$$ /tmp/c64u_candidates_sorted.$$
+exit 1
diff --git a/build_support/easyflash_plan_from_regular.py b/build_support/easyflash_plan_from_regular.py
index 11e5ed4..dec16ac 100755
--- a/build_support/easyflash_plan_from_regular.py
+++ b/build_support/easyflash_plan_from_regular.py
@@ -62,7 +62,10 @@ def replace_vice_block(text: str, crt: str, disk8: str) -> str:
return "\n".join(replaced) + "\n"
-def insert_launcher_start(text: str, start_app: str) -> str:
+def insert_launcher_start(text: str, start_app: str | None) -> str:
+ if not start_app:
+ return text
+
lines = text.splitlines()
insert_idx = None
for i, line in enumerate(lines):
@@ -93,37 +96,101 @@ def insert_launcher_start(text: str, start_app: str) -> str:
def adapt_screen_reu_probe(text: str) -> str:
- """The EasyFlash mirror verifies the final screen marker through RAM.
+ """Allow extra cartridge settling time for the screen/REU stress probe.
- This probe intentionally stress-tests SCRCAP/SCRPUT and screen-buffer
- restoration. On the cartridge path the final screen RAM is correct, but
- the VICE display poll can miss the last state after the long REU/display
- churn. Assert the exact bytes at $0400 instead; the regular D81 probe
- keeps the live screen assertion.
+ The regular plan carries the exact-RAM assertion too: the restored
+ ASCII-shaped screen bytes render correctly in VICE but are not decoded
+ as text by the harness screen decoder.
"""
if "plan_id: readybasic_screen_reu_temp_probe_easyflash" not in text:
return text
text = text.replace(" post_delay_s: 30.0", " post_delay_s: 75.0", 1)
- old = """ - id: assert_done
- type: screen.wait_contains
+ return text
+
+
+def adapt_readybasic_reuviewer_chain(text: str) -> str:
+ if "plan_id: readybasic_reuviewer_f2_chain_probe_easyflash" not in text:
+ return text
+
+ old = """ - id: launch_readybasic_from_launcher
+ type: input.sequence
params:
- text: "RBSCRREU DONE"
- wait_timeout_s: 300
- capture_label: scrreu_done
+ keys: [17,17,17,17,17,17,13]
"""
- new = """ - id: assert_done
- type: assert.memory
+ new = """ - id: launch_readybasic_from_launcher
+ type: input.sequence
params:
- start: 1024
- end: 1036
- equals_hex: "52 42 53 43 52 52 45 55 20 44 4F 4E 45"
+ keys: [17,17,17,17,13]
"""
if old not in text:
- raise ValueError("could not locate screen/REU final screen assertion")
+ raise ValueError("could not locate ReadyBASIC launcher navigation in chain probe")
return text.replace(old, new, 1)
+def harden_readybasic_prompt_waits(text: str) -> str:
+ """Avoid matching the ReadyBASIC title before the BASIC prompt is ready."""
+ lines = text.splitlines()
+ in_readybasic_wait = False
+ for i, line in enumerate(lines):
+ stripped = line.strip()
+ if line.startswith(" - id: "):
+ step_id = line.split(":", 1)[1].strip()
+ in_readybasic_wait = "wait_readybasic" in step_id or step_id == "wait_first_readybasic_prompt"
+ continue
+ if in_readybasic_wait and stripped in ('text: "readybasic"', 'text: "READYBASIC"'):
+ lines[i] = line[: len(line) - len(line.lstrip())] + 'text: "READY."'
+ in_readybasic_wait = False
+ return "\n".join(lines) + "\n"
+
+
+def harden_easyflash_launcher_waits(text: str) -> str:
+ """Give cartridge preload enough time to reach the launcher.
+
+ A retry of the wait step observes the same already-stuck cartridge boot.
+ The aggregate runner retries the complete plan with a fresh VICE process,
+ so keep one full readiness window here and preserve functional step retry
+ policy everywhere else.
+ """
+ lines = text.splitlines()
+ output = []
+ in_launcher_wait = False
+ saw_pre_delay = False
+ saw_poll = False
+ for line in lines:
+ stripped = line.strip()
+ if line.startswith(" - id: "):
+ step_id = line.split(":", 1)[1].strip()
+ in_launcher_wait = step_id in ("easyflash_wait_launcher", "wait_launcher_initial")
+ saw_pre_delay = False
+ saw_poll = False
+ output.append(line)
+ if in_launcher_wait:
+ output.extend((
+ " retry:",
+ " max_attempts: 1",
+ " backoff_ms: 0",
+ " jitter: false",
+ ))
+ continue
+ if in_launcher_wait and stripped.startswith("pre_delay_s: "):
+ saw_pre_delay = True
+ if in_launcher_wait and stripped.startswith("poll_s: "):
+ saw_poll = True
+ if in_launcher_wait and stripped.startswith("wait_timeout_s: "):
+ indent = line[: len(line) - len(line.lstrip())]
+ current = int(stripped.split(":", 1)[1].strip())
+ if not saw_pre_delay:
+ output.append(f"{indent}pre_delay_s: 4")
+ if not saw_poll:
+ output.append(f"{indent}poll_s: 0.5")
+ output.append(f"{indent}wait_timeout_s: {max(current, 420)}")
+ in_launcher_wait = False
+ continue
+ output.append(line)
+ return "\n".join(output) + "\n"
+
+
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--input", required=True, type=Path)
@@ -132,7 +199,6 @@ def main() -> int:
parser.add_argument("--disk8", required=True)
parser.add_argument(
"--start-app",
- required=True,
choices=("editor", "readybasic", "readyshell"),
)
parser.add_argument("--plan-id-suffix", default="_easyflash")
@@ -143,6 +209,9 @@ def main() -> int:
text = replace_vice_block(text, args.crt, args.disk8)
text = insert_launcher_start(text, args.start_app)
text = adapt_screen_reu_probe(text)
+ text = adapt_readybasic_reuviewer_chain(text)
+ text = harden_readybasic_prompt_waits(text)
+ text = harden_easyflash_launcher_waits(text)
args.output.parent.mkdir(parents=True, exist_ok=True)
args.output.write_text(text, encoding="utf-8")
diff --git a/build_support/file_dialog_memory_report.py b/build_support/file_dialog_memory_report.py
index 140ea62..5fd3039 100644
--- a/build_support/file_dialog_memory_report.py
+++ b/build_support/file_dialog_memory_report.py
@@ -105,8 +105,8 @@ def collect_metrics(app: str) -> dict[str, object]:
"runtime_end": runtime_end,
"bss_bytes": bss_bytes,
"used_bytes": used_bytes,
- "headroom_c5ff": APP_SNAPSHOT_END - runtime_end,
- "headroom_c600": APP_HIMEM - runtime_end,
+ "headroom_c7ff": APP_SNAPSHOT_END - runtime_end,
+ "headroom_c800": APP_HIMEM - runtime_end,
"effective_limit": effective_limit,
"effective_headroom": effective_limit - runtime_end,
"stack_size": stack_size,
@@ -118,20 +118,21 @@ def collect_metrics(app: str) -> dict[str, object]:
def print_report(rows: list[dict[str, object]], baseline: dict[str, dict[str, object]] | None) -> None:
if baseline:
print(
- "app class end used bss headC5FF effLimit effHead dUsed dBSS dHead"
+ "app class end used bss headC7FF effLimit effHead dUsed dBSS dHead"
)
for row in rows:
old = baseline.get(row["app"])
d_used = row["used_bytes"] - old["used_bytes"] if old else None
d_bss = row["bss_bytes"] - old["bss_bytes"] if old else None
- d_head = row["headroom_c5ff"] - old["headroom_c5ff"] if old else None
+ old_head = old.get("headroom_c7ff", old.get("headroom_c5ff")) if old else None
+ d_head = row["headroom_c7ff"] - old_head if old_head is not None else None
print(
f"{row['app']:<11}"
f"{row['class']:<15}"
f"{fmt_hex(row['runtime_end']):>7} "
f"{fmt_dec(row['used_bytes']):>6} "
f"{fmt_dec(row['bss_bytes']):>6} "
- f"{fmt_dec(row['headroom_c5ff']):>9} "
+ f"{fmt_dec(row['headroom_c7ff']):>9} "
f"{fmt_hex(row['effective_limit']):>9} "
f"{fmt_dec(row['effective_headroom']):>8} "
f"{fmt_dec(d_used):>6} "
@@ -140,7 +141,7 @@ def print_report(rows: list[dict[str, object]], baseline: dict[str, dict[str, ob
)
return
- print("app class end used bss headC5FF effLimit effHead")
+ print("app class end used bss headC7FF effLimit effHead")
for row in rows:
print(
f"{row['app']:<11}"
@@ -148,7 +149,7 @@ def print_report(rows: list[dict[str, object]], baseline: dict[str, dict[str, ob
f"{fmt_hex(row['runtime_end']):>7} "
f"{fmt_dec(row['used_bytes']):>6} "
f"{fmt_dec(row['bss_bytes']):>6} "
- f"{fmt_dec(row['headroom_c5ff']):>9} "
+ f"{fmt_dec(row['headroom_c7ff']):>9} "
f"{fmt_hex(row['effective_limit']):>9} "
f"{fmt_dec(row['effective_headroom']):>8}"
)
diff --git a/build_support/instrument_launcher_uci_dma_for_timing.py b/build_support/instrument_launcher_uci_dma_for_timing.py
new file mode 100644
index 0000000..809810b
--- /dev/null
+++ b/build_support/instrument_launcher_uci_dma_for_timing.py
@@ -0,0 +1,275 @@
+#!/usr/bin/env python3
+from __future__ import annotations
+
+import pathlib
+import sys
+import os
+
+
+REPLACEMENTS = [
+ ("jsr _launcher_uci_dma_detect", "jsr utime_call_detect"),
+ ("jsr dos_identify\n BCC_FAR load_no_uci_fail",
+ "jsr utime_call_identify\n BCC_FAR load_no_uci_fail"),
+ ("jsr ctrl_get_drvinfo\n BCC_FAR load_no_uci_fail",
+ "jsr utime_call_drvinfo\n BCC_FAR load_no_uci_fail"),
+ ("jsr dos_open_read\n BCC_FAR load_open_fail",
+ "jsr utime_call_open\n BCC_FAR load_open_fail"),
+ ("jsr dos_file_info\n BCC_FAR load_stat_fail",
+ "jsr utime_call_info\n BCC_FAR load_stat_fail"),
+ ("jsr dos_read_header\n BCC_FAR load_header_fail",
+ "jsr utime_call_read_header\n BCC_FAR load_header_fail"),
+ ("jsr dos_seek_payload\n BCC_FAR load_seek_fail",
+ "jsr utime_call_seek\n BCC_FAR load_seek_fail"),
+ ("jsr dos_load_reu_chunk\n BCC_FAR load_load_fail",
+ "jsr utime_call_load_reu\n BCC_FAR load_load_fail"),
+ ("jsr dos_close\n lda #$00\n sta _launcher_uci_dma_last_error",
+ "jsr utime_call_close\n lda #$00\n sta _launcher_uci_dma_last_error"),
+]
+
+
+TARGETED_CD_REPLACEMENTS = [
+ ("jsr dos_cd\n BCC_FAR load_cd_root_fail", "jsr utime_call_cd_root\n BCC_FAR load_cd_root_fail"),
+ ("jsr dos_cd\n BCC_FAR load_cd_dir_fail", "jsr utime_call_cd_dir\n BCC_FAR load_cd_dir_fail"),
+ ("jsr dos_cd\n BCC_FAR load_cd_image_fail", "jsr utime_call_cd_image\n BCC_FAR load_cd_image_fail"),
+]
+
+
+WRAPPERS = r'''
+
+; Probe-only instrumentation wrappers. These preserve the carry flag returned
+; by the underlying launcher UCI call so the production control flow is intact.
+ .import _utime_stage_begin
+ .import _utime_stage_end
+
+utime_call_detect:
+ lda #$00
+ jsr _utime_stage_begin
+ jsr _launcher_uci_dma_detect
+ php
+ lda #$00
+ jsr _utime_stage_end
+ plp
+ rts
+
+utime_call_identify:
+ lda #$01
+ jsr _utime_stage_begin
+ jsr dos_identify
+ php
+ lda #$01
+ jsr _utime_stage_end
+ plp
+ rts
+
+utime_call_drvinfo:
+ lda #$02
+ jsr _utime_stage_begin
+ jsr ctrl_get_drvinfo
+ php
+ lda #$02
+ jsr _utime_stage_end
+ plp
+ rts
+
+utime_call_cd_root:
+ lda #$03
+ jsr _utime_stage_begin
+ jsr dos_cd
+ php
+ lda #$03
+ jsr _utime_stage_end
+ plp
+ rts
+
+utime_call_cd_dir:
+ lda #$04
+ jsr _utime_stage_begin
+ jsr dos_cd
+ php
+ lda #$04
+ jsr _utime_stage_end
+ plp
+ rts
+
+utime_call_mount:
+ lda #$05
+ jsr _utime_stage_begin
+ jsr dos_mount_image
+ php
+ lda #$05
+ jsr _utime_stage_end
+ plp
+ rts
+
+utime_call_cd_image:
+ lda #$06
+ jsr _utime_stage_begin
+ jsr dos_cd
+ php
+ lda #$06
+ jsr _utime_stage_end
+ plp
+ rts
+
+utime_call_open:
+ lda #$07
+ jsr _utime_stage_begin
+ jsr dos_open_read
+ php
+ lda #$07
+ jsr _utime_stage_end
+ plp
+ rts
+
+utime_call_info:
+ lda #$08
+ jsr _utime_stage_begin
+ jsr dos_file_info
+ php
+ lda #$08
+ jsr _utime_stage_end
+ plp
+ rts
+
+utime_call_read_header:
+ lda #$09
+ jsr _utime_stage_begin
+ jsr dos_read_header
+ php
+ lda #$09
+ jsr _utime_stage_end
+ plp
+ rts
+
+utime_call_seek:
+ lda #$0A
+ jsr _utime_stage_begin
+ jsr dos_seek_payload
+ php
+ lda #$0A
+ jsr _utime_stage_end
+ plp
+ rts
+
+utime_call_load_reu:
+ lda #$0B
+ jsr _utime_stage_begin
+ jsr dos_load_reu_chunk
+ php
+ lda #$0B
+ jsr _utime_stage_end
+ plp
+ rts
+
+utime_call_close:
+ lda #$0C
+ jsr _utime_stage_begin
+ jsr dos_close
+ php
+ lda #$0C
+ jsr _utime_stage_end
+ plp
+ rts
+'''
+
+
+def main() -> int:
+ if len(sys.argv) != 3:
+ raise SystemExit("usage: instrument_launcher_uci_dma_for_timing.py INPUT OUTPUT")
+ src = pathlib.Path(sys.argv[1]).resolve()
+ out = pathlib.Path(sys.argv[2]).resolve()
+ text = src.read_text(encoding="utf-8")
+
+ load_start = text.index("_launcher_uci_dma_load_prg:")
+ load_end = text.index("dos_identify:")
+ before = text[:load_start]
+ body = text[load_start:load_end]
+ after = text[load_end:]
+ fast_raw = os.environ.get("UCI_TIMING_FAST_RAW", "0") == "1"
+
+ if fast_raw:
+ hot_skip_from = """ jsr _launcher_uci_dma_detect
+ bne load_have_uci"""
+ hot_skip_to = """ lda _launcher_uci_dma_assume_mounted
+ beq load_regular_detect
+ lda #'5'
+ jsr debug_stage
+ jmp load_open_current_dir
+load_regular_detect:
+ jsr _launcher_uci_dma_detect
+ bne load_have_uci"""
+ if hot_skip_from not in body:
+ raise SystemExit("missing detect hot-skip insertion point")
+ body = body.replace(hot_skip_from, hot_skip_to, 1)
+
+ open_start = body.index("load_open_current_dir:")
+ open_end = body.index("load_success:")
+ fast_block = """load_open_current_dir:
+ jsr utime_call_open
+ BCC_FAR load_open_fail
+ jsr status_ok
+ BCC_FAR load_open_fail
+ lda #'7'
+ jsr debug_stage
+
+ lda _launcher_uci_dma_reu_offset
+ sta current_off_lo
+ lda _launcher_uci_dma_reu_offset+1
+ sta current_off_hi
+ lda _launcher_uci_dma_max_len
+ sta chunk_lo
+ sta _launcher_uci_dma_loaded_size
+ lda _launcher_uci_dma_max_len+1
+ sta chunk_hi
+ sta _launcher_uci_dma_loaded_size+1
+ lda chunk_lo
+ ora chunk_hi
+ BEQ_FAR load_size_fail
+
+ lda #'9'
+ jsr debug_stage
+ jsr utime_call_load_reu
+ BCC_FAR load_load_fail
+ jsr status_ok
+ BCC_FAR load_load_fail
+ jmp load_success
+
+"""
+ body = body[:open_start] + fast_block + body[open_end:]
+
+ replacements = REPLACEMENTS
+ if fast_raw:
+ replacements = [
+ item for item in REPLACEMENTS
+ if "dos_file_info" not in item[0]
+ and "dos_read_header" not in item[0]
+ and "dos_seek_payload" not in item[0]
+ and "dos_load_reu_chunk" not in item[0]
+ and "dos_open_read" not in item[0]
+ ]
+ for old, new in replacements:
+ if old not in body:
+ raise SystemExit(f"missing call pattern: {old!r}")
+ body = body.replace(old, new, 1)
+ if "jsr dos_mount_image\n BCC_FAR load_mount_fail" not in body:
+ raise SystemExit("missing mount call pattern")
+ body = body.replace("jsr dos_mount_image\n BCC_FAR load_mount_fail",
+ "jsr utime_call_mount\n BCC_FAR load_mount_fail", 1)
+ for old, new in TARGETED_CD_REPLACEMENTS:
+ if old not in body:
+ raise SystemExit(f"missing cd pattern: {old!r}")
+ body = body.replace(old, new)
+
+ marker = ' .segment "RODATA"\n'
+ if marker not in after:
+ raise SystemExit("missing RODATA marker")
+ after = after.replace(marker, WRAPPERS + "\n" + marker, 1)
+
+ out.parent.mkdir(parents=True, exist_ok=True)
+ out.write_text(before + body + after, encoding="utf-8")
+ print(f"wrote {out}")
+ return 0
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/build_support/launcher_boot_control_ultimate.generated.yaml b/build_support/launcher_boot_control_ultimate.generated.yaml
new file mode 100644
index 0000000..9035380
--- /dev/null
+++ b/build_support/launcher_boot_control_ultimate.generated.yaml
@@ -0,0 +1,69 @@
+version: 1
+kind: ultimate_task_plan
+plan_id: launcher_boot_control
+run_mode: ultimate64
+global_defaults:
+ retry_policy:
+ max_attempts: 1
+ backoff_ms: 500
+ jitter: false
+ timeouts:
+ launch_s: 60
+ step_s: 180
+ read_s: 60
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: true
+ ultimate:
+ host: 10.0.0.79
+ password: null
+ ftp_user: anonymous
+ ftp_password: anonymous@
+ remote_root: USB1
+ disk8: /Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-d81/readyos-v0.2.5d-d81.d81
+ disk9: null
+ autostart_prg: null
+ drive_a_bus_id: 8
+ drive_b_bus_id: 9
+ drive_a_type: '1581'
+ drive_b_type: '1581'
+ drive_a_enabled: true
+ drive_b_enabled: false
+ mount_mode: readwrite
+ boot_drive: 8
+ capture_video_stream: true
+ stream_port: 11000
+ stream_timeout_s: 4.0
+ default_speed_mhz: 1
+ warp_equivalent_mhz: 8
+steps:
+- id: launch_readyos_d81
+ type: ultimate.launch
+ params:
+ boot_mode: disk
+ drives:
+ - slot: a
+ bus_id: 8
+ drive_type: '1581'
+ enabled: true
+ disk: /Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-d81/readyos-v0.2.5d-d81.d81
+ remote_disk: USB1/READY25D.D81
+ mount_mode: readwrite
+ boot_drive: 8
+ boot_command: "load\"boot\",8\nrun\n"
+ reset_before_boot: true
+ post_reset_delay_s: 2.0
+- id: wait_launcher
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 180
+ capture_label: launcher_control_initial
+- id: capture_launcher
+ type: screen.capture
+ criticality: observe
+ params:
+ label: launcher_control_loaded
+ note: Launcher boot control without DMA module linked
+ capture_state: true
diff --git a/build_support/launcher_dma_ultimate.generated.yaml b/build_support/launcher_dma_ultimate.generated.yaml
new file mode 100644
index 0000000..225e1f5
--- /dev/null
+++ b/build_support/launcher_dma_ultimate.generated.yaml
@@ -0,0 +1,126 @@
+version: 1
+kind: ultimate_task_plan
+plan_id: launcher_dma_ultimate_smoke
+run_mode: ultimate64
+global_defaults:
+ retry_policy:
+ max_attempts: 1
+ backoff_ms: 500
+ jitter: false
+ timeouts:
+ launch_s: 60
+ step_s: 180
+ read_s: 60
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: true
+ ultimate:
+ host: 10.0.0.79
+ password: null
+ ftp_user: anonymous
+ ftp_password: anonymous@
+ remote_root: USB1
+ disk8: /Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-d81/readyos-v0.2.5c-d81.d81
+ disk9: null
+ autostart_prg: null
+ drive_a_bus_id: 8
+ drive_b_bus_id: 9
+ drive_a_type: '1581'
+ drive_b_type: '1581'
+ drive_a_enabled: true
+ drive_b_enabled: false
+ mount_mode: readwrite
+ boot_drive: 8
+ capture_video_stream: true
+ stream_port: 11000
+ stream_timeout_s: 4.0
+ default_speed_mhz: 1
+ warp_equivalent_mhz: 8
+steps:
+- id: launch_readyos_d81
+ type: ultimate.launch
+ params:
+ boot_mode: disk
+ drives:
+ - slot: a
+ bus_id: 8
+ drive_type: '1581'
+ enabled: true
+ disk: /Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-d81/readyos-v0.2.5c-d81.d81
+ remote_disk: USB1/READY25C.D81
+ mount_mode: readwrite
+ - slot: b
+ bus_id: 9
+ drive_type: '1581'
+ enabled: false
+ disk: /Users/karlprosserpp/dev/c64projects/readyosprecog/Releases/0.2.5/precog-d81/readyos-v0.2.5c-d81.d81
+ remote_disk: USB1/READY25C.D81
+ mount_mode: readwrite
+ boot_drive: 8
+ boot_command: "load\"boot\",8\nrun\n"
+ reset_before_boot: true
+ post_reset_delay_s: 2.0
+- id: wait_launcher
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 180
+ capture_label: launcher_initial
+- id: wait_dma_available
+ type: screen.wait_contains
+ params:
+ text: "DMA:YES"
+ wait_timeout_s: 20
+ capture_label: launcher_dma_available
+- id: load_all_dma
+ type: input.sequence
+ params:
+ keys: [133]
+ inter_key_delay_s: 0.04
+ post_delay_s: 0.5
+- id: wait_load_all_done
+ type: screen.wait_contains
+ params:
+ text: "PRESS ANY KEY"
+ wait_timeout_s: 120
+ capture_label: load_all_done
+- id: ack_load_all
+ type: input.sequence
+ params:
+ keys: [13]
+ inter_key_delay_s: 0.04
+ post_delay_s: 0.5
+- id: wait_launcher_after_load_all
+ type: screen.wait_contains
+ params:
+ text: "DMA:ON"
+ wait_timeout_s: 30
+ capture_label: launcher_dma_on
+- id: launch_editor_from_menu
+ type: input.sequence
+ params:
+ keys: [17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 1.0
+- id: wait_editor
+ type: screen.wait_contains
+ params:
+ text: "EDITOR"
+ wait_timeout_s: 60
+ capture_label: editor_launched_after_dma
+- id: capture_final
+ type: screen.capture
+ criticality: observe
+ params:
+ label: final_editor
+ note: Final editor screen after C64U DMA load-all smoke
+ capture_state: true
+- id: dump_shim_state
+ type: dump.memory_ranges
+ criticality: observe
+ params:
+ ranges:
+ - { label: shim_hot_state_c834, start: 0xC834, end: 0xC83F }
+ - { label: reu_metadata_c600, start: 0xC600, end: 0xC7FF }
+ - { label: screen_0400, start: 0x0400, end: 0x07E7 }
diff --git a/build_support/launcher_reu_state_probe.generated.yaml b/build_support/launcher_reu_state_probe.generated.yaml
index 1ab0004..d696e12 100644
--- a/build_support/launcher_reu_state_probe.generated.yaml
+++ b/build_support/launcher_reu_state_probe.generated.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4b-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4b-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4b-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
@@ -68,8 +68,7 @@ steps:
params:
ranges: &launcher_reu_ranges
- { label: shim_hot_state_c834, start: 0xC834, end: 0xC83F }
- - { label: shim_resident_c800, start: 0xC800, end: 0xC9FF }
- - { label: reu_metadata_c600, start: 0xC600, end: 0xC7FF }
+ - { label: shim_resident_c600, start: 0xC600, end: 0xC9FF }
- id: dump_after_exit_reu
type: dump.reu
params:
@@ -140,9 +139,21 @@ steps:
- id: launch_reloaded_readybasic
type: input.sequence
params:
- keys: [145,17,13]
+ keys: [145,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.5
+ post_delay_s: 0.3
+ - id: clear_keyboard_buffer_before_relaunch
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ # A lone RETURN immediately after a dump/reload sequence is occasionally
+ # dropped by the binary-monitor key helper. VICE's text-monitor keybuf path
+ # both resumes the CPU after monitor inspection and injects it reliably.
+ - id: enter_reloaded_readybasic
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_reload
type: screen.wait_contains
params:
@@ -165,8 +176,7 @@ steps:
params:
ranges:
- { label: shim_hot_state_c834, start: 0xC834, end: 0xC83F }
- - { label: shim_resident_c800, start: 0xC800, end: 0xC9FF }
- - { label: reu_metadata_c600, start: 0xC600, end: 0xC7FF }
+ - { label: shim_resident_c600, start: 0xC600, end: 0xC9FF }
- { label: readybasic_bridge_c000, start: 0xC000, end: 0xC5FF }
- { label: readybasic_text_1200, start: 0x1200, end: 0x1400 }
- id: dump_final_reu
diff --git a/build_support/memory_map_spec.json b/build_support/memory_map_spec.json
index 2804fc3..ae8d2ec 100644
--- a/build_support/memory_map_spec.json
+++ b/build_support/memory_map_spec.json
@@ -1,8 +1,7 @@
{
"ram_windows": {
"app_runtime": { "start": "0x1000", "end": "0xC5FF" },
- "reu_metadata": { "start": "0xC600", "end": "0xC7FF" },
- "shim": { "start": "0xC800", "end": "0xC9FF" },
+ "shim": { "start": "0xC600", "end": "0xC9FF" },
"io": { "start": "0xD000", "end": "0xDFFF" }
},
"readyshell_overlay": {
@@ -33,12 +32,12 @@
"total_banks": 256,
"first_dynamic": 1,
"first_dynamic_logical": 1,
- "first_dynamic_physical_offset": 2,
+ "first_dynamic_physical_offset": 1,
"bank_skip_max": 39,
- "shim_reu_bank_skip_addr": "0xC83B",
- "bank_system": 0,
- "bank_launcher": 1,
- "bank_app_base": 2,
+ "shim_readyos_bank_addr": "0xC83B",
+ "readyos_physical_offset": 0,
+ "launcher_token": 0,
+ "bank_app_base": 1,
"bank_app_count": 0
},
"map_files": [
@@ -52,15 +51,20 @@
"obj/sysinfo.map",
"obj/tasklist.map",
"obj/simplefiles.map",
+ "obj/simplecells.map",
"obj/game2048.map",
"obj/deminer.map",
+ "obj/sidetris.map",
"obj/cal26.map",
"obj/dizzy.map",
"obj/readyirc.map",
"obj/rirc-rrnet.map",
"obj/readybasic.map",
+ "obj/ucitest.map",
"obj/readme.map",
- "obj/readyshell.map"
+ "obj/readyshell.map",
+ "obj/launcher_easyflash.map",
+ "obj/readyshell_easyflash.map"
],
"compact_prg_files": [
"bin/readybasic.prg"
@@ -89,12 +93,6 @@
"0xC5AA",
"0xC5AF",
"0xC600",
- "0xC700",
- "0xC702",
- "0xC710",
- "0xC7A0",
- "0xC7E0",
- "0xC7F0",
"0xC800",
"0xC803",
"0xC806",
@@ -103,6 +101,8 @@
"0xC80F",
"0xC812",
"0xC815",
+ "0xC818",
+ "0xC81B",
"0xC820",
"0xC821",
"0xC822",
@@ -117,8 +117,8 @@
"0xC839",
"0xC83B",
"0xC83C",
- "0xC84D",
- "0xC89C",
+ "0xC83D",
+ "0xC83E",
"0xCA00",
"0xCE00",
"0xCFF0",
diff --git a/build_support/quicknotes_owned_reu_probe.generated.yaml b/build_support/quicknotes_owned_reu_probe.generated.yaml
index cd7c212..89bd4b4 100644
--- a/build_support/quicknotes_owned_reu_probe.generated.yaml
+++ b/build_support/quicknotes_owned_reu_probe.generated.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4a-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4a-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4a-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5p-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5p-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5p-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
@@ -66,18 +66,11 @@ steps:
wait_timeout_s: 45
capture_on_success: true
capture_label: qn_owned_launcher_after_quicknotes
- - id: assert_owned_banks_before_viewer
- type: assert.memory
- params:
- start: 0xC623
- end: 0xC624
- equals_hex: "03 03"
- id: dump_before_viewer_ram
type: dump.memory_ranges
params:
ranges: &owned_reu_ranges
- - { label: reu_alloc_table_c600, start: 0xC600, end: 0xC67F }
- - { label: reu_metadata_c600, start: 0xC600, end: 0xC7FF }
+ - { label: shim_resident_c600, start: 0xC600, end: 0xC9FF }
- id: open_reuviewer_before_unload
type: input.sequence
params:
diff --git a/build_support/quicknotes_owned_reu_unload_probe.generated.yaml b/build_support/quicknotes_owned_reu_unload_probe.generated.yaml
index d59c58e..b790aa8 100644
--- a/build_support/quicknotes_owned_reu_unload_probe.generated.yaml
+++ b/build_support/quicknotes_owned_reu_unload_probe.generated.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4a-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4a-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4a-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5p-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5p-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5p-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
@@ -66,18 +66,11 @@ steps:
wait_timeout_s: 45
capture_on_success: true
capture_label: qn_owned_after_launcher_after_quicknotes
- - id: assert_owned_banks_before_unload
- type: assert.memory
- params:
- start: 0xC623
- end: 0xC624
- equals_hex: "03 03"
- id: dump_before_unload_ram
type: dump.memory_ranges
params:
ranges: &owned_reu_ranges
- - { label: reu_alloc_table_c600, start: 0xC600, end: 0xC67F }
- - { label: reu_metadata_c600, start: 0xC600, end: 0xC7FF }
+ - { label: shim_resident_c600, start: 0xC600, end: 0xC9FF }
- id: unload_quicknotes
type: input.sequence
params:
@@ -91,12 +84,6 @@ steps:
wait_timeout_s: 45
capture_on_success: true
capture_label: qn_owned_launcher_after_unload
- - id: assert_owned_banks_freed
- type: assert.memory
- params:
- start: 0xC623
- end: 0xC624
- equals_hex: "00 00"
- id: dump_after_unload_ram
type: dump.memory_ranges
params:
diff --git a/build_support/readybasic_cross_app_resume_probe.generated.yaml b/build_support/readybasic_cross_app_resume_probe.generated.yaml
index 3277ea9..fe4889e 100644
--- a/build_support/readybasic_cross_app_resume_probe.generated.yaml
+++ b/build_support/readybasic_cross_app_resume_probe.generated.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4x-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4x-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4x-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
@@ -39,6 +39,17 @@ steps:
text: "ready."
wait_timeout_s: 180
capture_label: readybasic_prompt
+ - id: wait_readybasic_prompt_stable_before_program_entry
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ pre_delay_s: 1.5
+ wait_timeout_s: 30
+ - id: clear_keyboard_buffer_before_program_entry
+ type: memory.write
+ params:
+ start: 198
+ bytes_hex: "00"
- id: build_program_lines
type: input.sequence
params:
@@ -93,20 +104,32 @@ steps:
- id: move_from_readybasic_to_editor_1
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_1
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_1
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_1
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
- id: ctrl_b_to_launcher_from_editor_1
- type: input.sequence
+ type: memory.write
params:
- keys: [2]
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: inject_ctrl_b_to_launcher_from_editor_1
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_1
type: screen.wait_contains
params:
@@ -115,9 +138,18 @@ steps:
- id: move_from_editor_to_readybasic_1
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_1
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_1
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_resume_1
type: screen.wait_contains
params:
@@ -200,20 +232,32 @@ steps:
- id: move_from_readybasic_to_editor_2
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_2
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_2
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_2
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
- id: ctrl_b_to_launcher_from_editor_2
- type: input.sequence
+ type: memory.write
params:
- keys: [2]
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: inject_ctrl_b_to_launcher_from_editor_2
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_2
type: screen.wait_contains
params:
@@ -222,9 +266,18 @@ steps:
- id: move_from_editor_to_readybasic_2
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_2
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_2
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_resume_2
type: screen.wait_contains
params:
@@ -307,20 +360,32 @@ steps:
- id: move_from_readybasic_to_editor_3
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_3
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_3
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_3
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
- id: ctrl_b_to_launcher_from_editor_3
- type: input.sequence
+ type: memory.write
params:
- keys: [2]
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: inject_ctrl_b_to_launcher_from_editor_3
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_3
type: screen.wait_contains
params:
@@ -329,9 +394,18 @@ steps:
- id: move_from_editor_to_readybasic_3
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_3
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_3
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_resume_3
type: screen.wait_contains
params:
@@ -414,20 +488,32 @@ steps:
- id: move_from_readybasic_to_editor_4
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_4
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_4
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_4
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
- id: ctrl_b_to_launcher_from_editor_4
- type: input.sequence
+ type: memory.write
params:
- keys: [2]
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: inject_ctrl_b_to_launcher_from_editor_4
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_4
type: screen.wait_contains
params:
@@ -436,9 +522,18 @@ steps:
- id: move_from_editor_to_readybasic_4
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_4
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_4
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_resume_4
type: screen.wait_contains
params:
@@ -521,20 +616,32 @@ steps:
- id: move_from_readybasic_to_editor_5
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_5
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_5
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_5
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
- id: ctrl_b_to_launcher_from_editor_5
- type: input.sequence
+ type: memory.write
params:
- keys: [2]
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: inject_ctrl_b_to_launcher_from_editor_5
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_5
type: screen.wait_contains
params:
@@ -543,9 +650,18 @@ steps:
- id: move_from_editor_to_readybasic_5
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_5
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_5
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_resume_5
type: screen.wait_contains
params:
@@ -628,20 +744,32 @@ steps:
- id: move_from_readybasic_to_editor_6
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_6
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_6
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_6
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
- id: ctrl_b_to_launcher_from_editor_6
- type: input.sequence
+ type: memory.write
params:
- keys: [2]
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: inject_ctrl_b_to_launcher_from_editor_6
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_6
type: screen.wait_contains
params:
@@ -650,9 +778,18 @@ steps:
- id: move_from_editor_to_readybasic_6
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_6
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_6
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_resume_6
type: screen.wait_contains
params:
@@ -735,20 +872,32 @@ steps:
- id: move_from_readybasic_to_editor_7
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_7
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_7
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_7
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
- id: ctrl_b_to_launcher_from_editor_7
- type: input.sequence
+ type: memory.write
params:
- keys: [2]
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: inject_ctrl_b_to_launcher_from_editor_7
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_7
type: screen.wait_contains
params:
@@ -757,9 +906,18 @@ steps:
- id: move_from_editor_to_readybasic_7
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_7
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_7
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_resume_7
type: screen.wait_contains
params:
@@ -842,20 +1000,32 @@ steps:
- id: move_from_readybasic_to_editor_8
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_8
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_8
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_8
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
- id: ctrl_b_to_launcher_from_editor_8
- type: input.sequence
+ type: memory.write
params:
- keys: [2]
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: inject_ctrl_b_to_launcher_from_editor_8
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_8
type: screen.wait_contains
params:
@@ -864,9 +1034,18 @@ steps:
- id: move_from_editor_to_readybasic_8
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_8
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_8
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_resume_8
type: screen.wait_contains
params:
@@ -949,20 +1128,32 @@ steps:
- id: move_from_readybasic_to_editor_9
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_9
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_9
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_9
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
- id: ctrl_b_to_launcher_from_editor_9
- type: input.sequence
+ type: memory.write
params:
- keys: [2]
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: inject_ctrl_b_to_launcher_from_editor_9
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_9
type: screen.wait_contains
params:
@@ -971,9 +1162,18 @@ steps:
- id: move_from_editor_to_readybasic_9
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_9
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_9
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_resume_9
type: screen.wait_contains
params:
@@ -1056,20 +1256,32 @@ steps:
- id: move_from_readybasic_to_editor_10
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_10
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_10
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_10
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
- id: ctrl_b_to_launcher_from_editor_10
- type: input.sequence
+ type: memory.write
params:
- keys: [2]
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: inject_ctrl_b_to_launcher_from_editor_10
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_10
type: screen.wait_contains
params:
@@ -1078,9 +1290,18 @@ steps:
- id: move_from_editor_to_readybasic_10
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_10
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_10
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_resume_10
type: screen.wait_contains
params:
@@ -1151,7 +1372,7 @@ steps:
type: dump.memory_ranges
params:
ranges:
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_text_and_vars_1200, start: 0x1200, end: 0x1700 }
- { label: string_heap_9400, start: 0x9400, end: 0x9600 }
- { label: runtime_state_9600, start: 0x9600, end: 0x9A00 }
diff --git a/build_support/readybasic_demo_suite.generated.yaml b/build_support/readybasic_demo_suite.generated.yaml
index 84dea48..e596520 100644
--- a/build_support/readybasic_demo_suite.generated.yaml
+++ b/build_support/readybasic_demo_suite.generated.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4o-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4o-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4o-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
@@ -42,13 +42,19 @@ steps:
- id: demo_01_intro
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,49,58,32,82,69,65,68,89,66,65,83,73,67,32,66,65,83,73,67,83,34,13,80,82,73,78,84,32,34,70,82,69,69,77,69,77,44,32,86,65,82,73,65,66,76,69,83,44,32,65,78,68,32,65,32,80,82,79,71,82,65,77,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,49,58,32,82,69,65,68,89,66,65,83,73,67,32,66,65,83,73,67,83,34,13,80,82,73,78,84,32,34,77,69,77,65,86,76,44,32,86,65,82,73,65,66,76,69,83,44,32,65,78,68,32,65,32,80,82,79,71,82,65,77,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
inter_key_delay_s: 0.08
post_delay_s: 3.5
- id: demo_01_setup
type: input.sequence
params:
- keys: [70,82,69,69,77,69,77,40,41,13,78,69,87,13,65,37,61,52,50,13,49,48,32,66,37,61,90,65,68,68,49,54,40,52,50,44,56,41,13,50,48,32,80,82,73,78,84,32,34,80,82,79,71,82,65,77,32,83,85,77,34,59,66,37,13,76,73,83,84,13]
+ keys: [77,69,77,65,86,76,40,41,13,78,69,87,13,65,37,61,52,50,13,49,48,32,66,37,61,90,65,68,68,49,54,40,52,50,44,56,41,13,50,48,32,80,82,73,78,84,32,34,80,82,79,71,82,65,77,32,83,85,77,34,59,66,37,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_01_list
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
inter_key_delay_s: 0.08
post_delay_s: 3.5
- id: demo_01_basics
@@ -121,16 +127,32 @@ steps:
params:
text: "READY."
wait_timeout_s: 60
- - id: demo_03_resume_intro
+ - id: demo_03_resume_liveness
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,82,69,83,85,77,69,32,76,73,86,69,34,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: assert_demo_03_resume_liveness
+ type: assert.screen
+ params:
+ contains: "RESUME LIVE"
+ - id: demo_03_resume_intro_clear
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,66,65,67,75,32,73,78,32,82,69,65,68,89,66,65,83,73,67,34,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 3.5
+ - id: demo_03_resume_intro_detail
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,66,65,67,75,32,73,78,32,82,69,65,68,89,66,65,83,73,67,34,13,80,82,73,78,84,32,34,86,65,82,73,65,66,76,69,83,32,65,78,68,32,80,82,79,71,82,65,77,32,84,69,88,84,32,83,72,79,85,76,68,32,82,69,77,65,73,78,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ keys: [80,82,73,78,84,32,34,86,65,82,73,65,66,76,69,83,32,65,78,68,32,80,82,79,71,82,65,77,32,84,69,88,84,32,83,72,79,85,76,68,32,82,69,77,65,73,78,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
inter_key_delay_s: 0.08
post_delay_s: 3.5
- id: demo_03_resume_var_proof
type: input.sequence
params:
- keys: [70,82,69,69,77,69,77,40,41,13,80,82,73,78,84,32,34,65,32,83,84,73,76,76,34,59,65,37,13,80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,65,32,73,83,32,52,50,32,65,78,68,32,82,85,78,32,83,84,73,76,76,32,87,79,82,75,83,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ keys: [77,69,77,65,86,76,40,41,13,80,82,73,78,84,32,34,65,32,83,84,73,76,76,34,59,65,37,13,80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,65,32,73,83,32,52,50,32,65,78,68,32,82,85,78,32,83,84,73,76,76,32,87,79,82,75,83,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
inter_key_delay_s: 0.08
post_delay_s: 3.5
- id: capture_demo_03_resume_var_proof
@@ -296,13 +318,13 @@ steps:
- id: demo_07_intro
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,56,58,32,82,69,85,32,66,85,70,70,69,82,32,67,79,77,77,65,78,68,83,34,13,80,82,73,78,84,32,34,66,85,70,78,69,87,32,82,69,84,85,82,78,83,59,32,70,73,76,76,32,65,78,68,32,70,82,69,69,32,68,79,32,87,79,82,75,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,59,67,72,82,36,40,49,53,56,41,59,34,68,69,77,79,32,56,58,32,82,69,85,32,66,85,70,70,69,82,32,67,79,77,77,65,78,68,83,34,13,80,82,73,78,84,32,34,66,85,70,77,65,75,69,32,82,69,84,85,82,78,83,59,32,70,73,76,76,32,65,78,68,32,70,82,69,69,32,68,79,32,87,79,82,75,34,58,80,82,73,78,84,32,67,72,82,36,40,53,41,13]
inter_key_delay_s: 0.08
post_delay_s: 3.5
- id: demo_07_reu
type: input.sequence
params:
- keys: [72,37,61,66,85,70,78,69,87,40,54,52,41,13,66,85,70,70,73,76,76,40,72,37,44,49,55,48,41,13,80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,72,65,78,68,76,69,32,49,44,32,84,72,69,78,32,70,82,69,69,68,32,49,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13,80,82,73,78,84,32,34,72,65,78,68,76,69,34,59,72,37,13,66,85,70,70,82,69,69,40,72,37,41,13,80,82,73,78,84,32,34,70,82,69,69,68,34,59,72,37,13]
+ keys: [72,37,61,66,85,70,77,65,75,69,40,54,52,41,13,66,85,70,70,73,76,76,40,72,37,44,49,55,48,41,13,80,82,73,78,84,32,67,72,82,36,40,49,53,56,41,59,34,69,88,80,69,67,84,58,32,72,65,78,68,76,69,32,49,44,32,84,72,69,78,32,70,82,69,69,68,32,49,34,13,80,82,73,78,84,32,67,72,82,36,40,53,41,13,80,82,73,78,84,32,34,72,65,78,68,76,69,34,59,72,37,13,66,85,70,68,82,79,80,40,72,37,41,13,80,82,73,78,84,32,34,70,82,69,69,68,34,59,72,37,13]
inter_key_delay_s: 0.08
post_delay_s: 3.5
- id: assert_demo_07_handle
diff --git a/build_support/readybasic_full_suite_visual_verification.generated.yaml b/build_support/readybasic_full_suite_visual_verification.generated.yaml
index b8312cc..6792a75 100644
--- a/build_support/readybasic_full_suite_visual_verification.generated.yaml
+++ b/build_support/readybasic_full_suite_visual_verification.generated.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4z-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4z-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4z-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
@@ -51,7 +51,7 @@ steps:
- { label: hidden_visible_a000, start: 0xA000, end: 0xA5FF }
- { label: hidden_overlay_a800, start: 0xA800, end: 0xA8FF }
- { label: bridge_c000, start: 0xC000, end: 0xC5FF }
- - { label: reu_alloc_table_c600, start: 0xC600, end: 0xC6FF }
+ - { label: shim_resident_c600, start: 0xC600, end: 0xC9FF }
- id: direct_ping
type: input.sequence
@@ -240,17 +240,17 @@ steps:
params:
contains: "D-RANGE 7 10"
- - id: direct_bufnew
+ - id: direct_bufmake
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,66,85,70,78,69,87,32,82,69,85,32,72,65,78,68,76,69,32,84,65,66,76,69,32,82,69,84,85,82,78,32,72,37,61,49,32,83,67,82,69,69,78,32,68,45,66,85,70,13,72,37,61,66,85,70,78,69,87,40,51,48,48,41,13,80,82,73,78,84,32,34,68,45,66,85,70,34,59,72,37,59,34,58,69,78,68,34,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,66,85,70,77,65,75,69,32,82,69,85,32,72,65,78,68,76,69,32,84,65,66,76,69,32,82,69,84,85,82,78,32,72,37,61,49,32,83,67,82,69,69,78,32,68,45,66,85,70,13,72,37,61,66,85,70,77,65,75,69,40,51,48,48,41,13,80,82,73,78,84,32,34,68,45,66,85,70,34,59,72,37,59,34,58,69,78,68,34,13]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- - id: assert_direct_bufnew
+ - id: assert_direct_bufmake
type: assert.screen
params:
contains: "D-BUF 1 :END"
- - id: dump_direct_bufnew
+ - id: dump_direct_bufmake
type: dump.memory_ranges
params:
ranges: *plugin_ranges
@@ -270,17 +270,17 @@ steps:
params:
not_contains: "?RB ERROR"
- - id: direct_buffree
+ - id: direct_bufdrop
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,66,85,70,70,82,69,69,32,82,69,76,69,65,83,69,32,82,69,85,32,72,65,78,68,76,69,32,72,37,32,83,67,82,69,69,78,32,68,45,70,82,69,69,13,66,85,70,70,82,69,69,40,72,37,41,13,80,82,73,78,84,32,34,68,45,70,82,69,69,32,79,75,34,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,66,85,70,68,82,79,80,32,82,69,76,69,65,83,69,32,82,69,85,32,72,65,78,68,76,69,32,72,37,32,83,67,82,69,69,78,32,68,45,70,82,69,69,13,66,85,70,68,82,79,80,40,72,37,41,13,80,82,73,78,84,32,34,68,45,70,82,69,69,32,79,75,34,13]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- - id: assert_direct_buffree
+ - id: assert_direct_bufdrop
type: assert.screen
params:
contains: "D-FREE OK"
- - id: assert_direct_buffree_no_error
+ - id: assert_direct_bufdrop_no_error
type: assert.screen_not_contains
params:
not_contains: "?RB ERROR"
@@ -309,24 +309,24 @@ steps:
type: assert.screen
params:
contains: "?RB ERROR 40"
- - id: direct_buffree_screen_handle
+ - id: direct_bufdrop_screen_handle
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,66,85,70,70,82,69,69,32,82,69,76,69,65,83,69,83,32,83,67,82,69,69,78,32,72,65,78,68,76,69,32,84,89,80,69,13,66,85,70,70,82,69,69,40,83,37,41,13,80,82,73,78,84,32,34,68,45,83,67,82,70,82,69,69,34,59,83,37,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,66,85,70,68,82,79,80,32,82,69,76,69,65,83,69,83,32,83,67,82,69,69,78,32,72,65,78,68,76,69,32,84,89,80,69,13,66,85,70,68,82,79,80,40,83,37,41,13,80,82,73,78,84,32,34,68,45,83,67,82,70,82,69,69,34,59,83,37,13]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- - id: assert_direct_buffree_screen_handle
+ - id: assert_direct_bufdrop_screen_handle
type: assert.screen
params:
contains: "D-SCRFREE 1"
- - id: assert_direct_buffree_screen_no_error
+ - id: assert_direct_bufdrop_screen_no_error
type: assert.screen_not_contains
params:
not_contains: "?RB ERROR"
- id: direct_scrput_rejects_buffer_handle
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,83,67,82,80,85,84,32,77,85,83,84,32,82,69,74,69,67,84,32,66,85,70,70,69,82,32,72,65,78,68,76,69,32,84,89,80,69,13,66,37,61,66,85,70,78,69,87,40,51,48,48,41,13,83,67,82,80,85,84,40,66,37,41,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,68,45,83,67,82,80,85,84,32,77,85,83,84,32,82,69,74,69,67,84,32,66,85,70,70,69,82,32,72,65,78,68,76,69,32,84,89,80,69,13,66,37,61,66,85,70,77,65,75,69,40,51,48,48,41,13,83,67,82,80,85,84,40,66,37,41,13]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- id: assert_direct_scrput_rejects_buffer_handle
@@ -336,7 +336,7 @@ steps:
- id: direct_free_buffer_after_type_error
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,70,82,69,69,40,66,37,41,13,80,82,73,78,84,32,34,68,45,66,85,70,82,69,69,34,59,66,37,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,68,82,79,80,40,66,37,41,13,80,82,73,78,84,32,34,68,45,66,85,70,82,69,69,34,59,66,37,13]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- id: assert_direct_free_buffer_after_type_error
@@ -351,7 +351,7 @@ steps:
- id: direct_handle_128_edge
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,72,37,61,66,85,70,78,69,87,40,49,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,68,45,72,77,65,88,34,59,72,37,13,82,85,78,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,72,37,61,66,85,70,77,65,75,69,40,49,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,68,45,72,77,65,88,34,59,72,37,13,82,85,78,13]
inter_key_delay_s: 0.03
post_delay_s: 5.0
- id: assert_direct_handle_128_edge
@@ -365,7 +365,7 @@ steps:
- id: direct_handle_129_rejected
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,69,37,61,66,85,70,78,69,87,40,49,41,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,69,37,61,66,85,70,77,65,75,69,40,49,41,13]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- id: assert_direct_handle_129_rejected
@@ -375,7 +375,7 @@ steps:
- id: direct_free_128_handles
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,66,85,70,70,82,69,69,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,68,45,72,70,82,69,69,68,34,13,82,85,78,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,66,85,70,68,82,79,80,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,68,45,72,70,82,69,69,68,34,13,82,85,78,13]
inter_key_delay_s: 0.03
post_delay_s: 5.0
- id: assert_direct_free_128_handles
@@ -389,7 +389,7 @@ steps:
- id: direct_48k_heap_edge
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,77,37,61,66,85,70,78,69,87,40,52,57,49,53,50,41,13,80,82,73,78,84,32,34,68,45,77,65,88,66,85,70,34,59,77,37,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,77,37,61,66,85,70,77,65,75,69,40,52,57,49,53,50,41,13,80,82,73,78,84,32,34,68,45,77,65,88,66,85,70,34,59,77,37,13]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- id: assert_direct_48k_heap_edge
@@ -399,7 +399,7 @@ steps:
- id: direct_48k_heap_full
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,69,37,61,66,85,70,78,69,87,40,49,41,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,69,37,61,66,85,70,77,65,75,69,40,49,41,13]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- id: assert_direct_48k_heap_full
@@ -409,7 +409,7 @@ steps:
- id: direct_free_48k_heap
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,70,82,69,69,40,77,37,41,13,80,82,73,78,84,32,34,68,45,77,65,88,70,82,69,69,34,59,77,37,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,68,82,79,80,40,77,37,41,13,80,82,73,78,84,32,34,68,45,77,65,88,70,82,69,69,34,59,77,37,13]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- id: assert_direct_free_48k_heap
@@ -443,7 +443,7 @@ steps:
- id: direct_free_screen_heap
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,50,52,13,50,48,32,66,85,70,70,82,69,69,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,68,45,83,70,82,69,69,68,34,13,82,85,78,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,50,52,13,50,48,32,66,85,70,68,82,79,80,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,68,45,83,70,82,69,69,68,34,13,82,85,78,13]
inter_key_delay_s: 0.03
post_delay_s: 5.0
- id: assert_direct_free_screen_heap
@@ -640,9 +640,18 @@ steps:
- id: resume_after_exit
type: input.sequence
params:
- keys: [145,17,13]
+ keys: [145,17]
inter_key_delay_s: 0.10
- post_delay_s: 3.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_full_suite_resume
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_after_full_suite_exit
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_resume
type: screen.wait_contains
params:
@@ -851,7 +860,7 @@ steps:
- id: program_handle_enter_and_list
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,77,32,66,85,70,32,82,69,85,32,72,65,78,68,76,69,32,65,76,76,79,67,32,82,69,84,85,82,78,32,70,73,76,76,32,70,82,69,69,32,72,37,61,49,32,83,67,82,69,69,78,32,80,45,66,85,70,13,50,48,32,72,37,61,66,85,70,78,69,87,40,51,48,48,41,13,51,48,32,80,82,73,78,84,32,34,80,45,66,85,70,34,59,72,37,13,52,48,32,66,85,70,70,73,76,76,40,72,37,44,49,55,48,41,13,53,48,32,66,85,70,70,82,69,69,40,72,37,41,13,54,48,32,80,82,73,78,84,32,34,80,45,70,82,69,69,34,59,72,37,13,76,73,83,84,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,82,69,77,32,66,85,70,32,82,69,85,32,72,65,78,68,76,69,32,65,76,76,79,67,32,82,69,84,85,82,78,32,70,73,76,76,32,70,82,69,69,32,72,37,61,49,32,83,67,82,69,69,78,32,80,45,66,85,70,13,50,48,32,72,37,61,66,85,70,77,65,75,69,40,51,48,48,41,13,51,48,32,80,82,73,78,84,32,34,80,45,66,85,70,34,59,72,37,13,52,48,32,66,85,70,70,73,76,76,40,72,37,44,49,55,48,41,13,53,48,32,66,85,70,68,82,79,80,40,72,37,41,13,54,48,32,80,82,73,78,84,32,34,80,45,70,82,69,69,34,59,72,37,13,76,73,83,84,13]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- id: assert_program_handle_rem
diff --git a/build_support/readybasic_gfx_mbitmap_demo.generated.yaml b/build_support/readybasic_gfx_mbitmap_demo.generated.yaml
new file mode 100644
index 0000000..d308e2b
--- /dev/null
+++ b/build_support/readybasic_gfx_mbitmap_demo.generated.yaml
@@ -0,0 +1,153 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_gfx_mbitmap_demo
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 1
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_readyos_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_loaded_by_readyos
+ type: screen.wait_contains
+ params:
+ text: "FREE:"
+ wait_timeout_s: 180
+ capture_on_success: true
+ capture_label: readybasic_gfx_mbitmap_prompt
+ - id: load_rbgfx14
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,49,52,34,44,56,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: capture_existing_circle
+ type: screen.capture
+ params:
+ label: readybasic_gfx_existing_circle
+ pitch: "Existing CIRCLE/FCIRCLE commands under ReadyOS ReadyBASIC"
+ - id: finish_rbgfx14
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 1.0
+ - id: wait_rbgfx14_done
+ type: screen.wait_contains
+ params:
+ text: "PHASE2 PRIMS DONE"
+ wait_timeout_s: 60
+ capture_on_success: true
+ capture_label: readybasic_gfx_existing_circle_done
+ - id: load_rbgfx15
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,49,53,34,44,56,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.8
+ - id: capture_existing_tile_charat
+ type: screen.capture
+ params:
+ label: readybasic_gfx_existing_tile_charat
+ pitch: "Existing TILE/CHARAT commands under ReadyOS ReadyBASIC"
+ - id: finish_rbgfx15
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 1.0
+ - id: wait_rbgfx15_done
+ type: screen.wait_contains
+ params:
+ text: "PHASE2 TILES DONE"
+ wait_timeout_s: 60
+ capture_on_success: true
+ capture_label: readybasic_gfx_existing_tile_charat_done
+ - id: load_rbgfx21
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,50,49,34,44,56,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.4
+ - id: capture_rbgfx21_list
+ type: screen.capture
+ params:
+ label: readybasic_gfx_mbitmap_prims_list
+ pitch: "RBGFX21 listed inside ReadyBASIC under ReadyOS"
+ - id: run_rbgfx21
+ type: input.sequence
+ params:
+ keys: [82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.2
+ - id: capture_mbitmap_prims
+ type: screen.capture
+ params:
+ label: readybasic_gfx_mbitmap_primitives
+ pitch: "MBITMAP primitive color-slot drawing"
+ - id: finish_rbgfx21
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 1.0
+ - id: wait_rbgfx21_done
+ type: screen.wait_contains
+ params:
+ text: "MBITMAP PRIMS DONE"
+ wait_timeout_s: 60
+ capture_on_success: true
+ capture_label: readybasic_gfx_mbitmap_primitives_done
+ - id: load_rbgfx22
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,50,50,34,44,56,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.2
+ - id: capture_mbitmap_pnt_graphics
+ type: screen.capture
+ params:
+ label: readybasic_gfx_mbitmap_pnt_graphics
+ pitch: "MBITMAP pnt-code pixels before text assertion"
+ - id: finish_rbgfx22
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 1.0
+ - id: wait_rbgfx22_done
+ type: screen.wait_contains
+ params:
+ text: "MBITMAP PNT DONE"
+ wait_timeout_s: 60
+ capture_on_success: true
+ capture_label: readybasic_gfx_mbitmap_pnt_done
+ - id: assert_pnt_values
+ type: assert.screen
+ params:
+ contains: "MBITMAP PNT: 1 2 3"
+ - id: assert_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
diff --git a/build_support/readybasic_gfx_phase1_probe.generated.yaml b/build_support/readybasic_gfx_phase1_probe.generated.yaml
new file mode 100644
index 0000000..71c0e73
--- /dev/null
+++ b/build_support/readybasic_gfx_phase1_probe.generated.yaml
@@ -0,0 +1,92 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_gfx_phase1_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 1
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 90
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "readybasic"
+ wait_timeout_s: 180
+ capture_label: readybasic_gfx_prompt
+
+ - id: bitmap_program
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,71,70,88,77,79,68,69,40,34,72,73,82,69,83,34,41,58,71,70,88,67,76,69,65,82,40,48,41,58,80,76,79,84,40,52,48,44,52,48,44,49,41,13,50,48,32,80,78,84,40,52,48,44,52,48,44,65,37,41,13,51,48,32,80,78,84,40,52,49,44,52,48,44,66,37,41,13,52,48,32,72,37,61,71,70,88,83,85,82,70,40,34,72,73,82,69,83,34,41,58,71,70,88,66,76,73,84,40,72,37,41,13,53,48,32,71,70,88,84,69,88,84,40,41,13,54,48,32,80,82,73,78,84,32,34,71,70,88,80,65,83,83,34,59,65,37,59,66,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: capture_bitmap_program
+ type: screen.capture
+ params:
+ label: readybasic_gfx_bitmap_program
+ - id: assert_bitmap_program
+ type: assert.screen
+ params:
+ contains: "GFXPASS"
+
+ - id: tile_sprite_input_program
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,71,70,88,77,79,68,69,40,34,84,73,76,69,34,41,58,71,70,88,67,76,69,65,82,40,48,41,58,80,76,79,84,40,51,44,51,44,53,41,13,50,48,32,80,78,84,40,51,44,51,44,65,37,41,13,51,48,32,83,80,82,83,69,84,40,48,44,49,44,50,44,48,41,58,83,80,82,77,79,86,69,40,48,44,56,48,44,57,48,41,58,83,80,82,67,79,76,40,48,44,52,41,13,52,48,32,74,79,89,40,50,44,74,37,41,58,75,69,89,80,40,75,37,41,58,75,69,89,83,67,65,78,40,41,58,75,69,89,76,65,83,84,40,76,37,41,13,53,48,32,71,70,88,84,69,88,84,40,41,13,54,48,32,80,82,73,78,84,32,34,71,70,88,73,79,34,59,65,37,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: capture_tile_sprite_input_program
+ type: screen.capture
+ params:
+ label: readybasic_gfx_tile_sprite_input_program
+ - id: assert_tile_sprite_input_program
+ type: assert.screen
+ params:
+ contains: "READY."
+ - id: assert_tile_sprite_input_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
+
+ - id: load_demo
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,76,79,65,68,32,34,82,66,71,70,88,48,49,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: list_demo
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_demo_lists
+ type: assert.screen
+ params:
+ contains: "RBGFX01 MODES"
diff --git a/build_support/readybasic_gfx_phase2_demo.generated.yaml b/build_support/readybasic_gfx_phase2_demo.generated.yaml
new file mode 100644
index 0000000..286b160
--- /dev/null
+++ b/build_support/readybasic_gfx_phase2_demo.generated.yaml
@@ -0,0 +1,162 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_gfx_phase2_demo
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 1
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_readyos_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_loaded_by_readyos
+ type: screen.wait_contains
+ params:
+ text: "FREE:"
+ wait_timeout_s: 180
+ capture_on_success: true
+ capture_label: readybasic_gfx_phase2_prompt
+ - id: clear_for_phase2_prims
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: load_rbgfx14
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,49,52,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.2
+ - id: list_rbgfx14
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: capture_list_rbgfx14
+ type: screen.capture
+ params:
+ label: readybasic_gfx_phase2_list_rbgfx14
+ pitch: "RBGFX14 listed inside ReadyBASIC under ReadyOS"
+ - id: assert_list_rbgfx14
+ type: assert.screen
+ params:
+ contains: "PHASE2 PRIMS DONE"
+ - id: clear_run_rbgfx14
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: capture_primitives
+ type: screen.capture
+ params:
+ label: readybasic_gfx_phase2_primitives
+ pitch: "CIRCLE and FCIRCLE visible primitive demo"
+ - id: finish_rbgfx14
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 1.0
+ - id: wait_prims_done
+ type: screen.wait_contains
+ params:
+ text: "PHASE2 PRIMS DONE"
+ wait_timeout_s: 60
+ capture_on_success: true
+ capture_label: readybasic_gfx_phase2_prims_done
+ - id: load_rbgfx15
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,49,53,34,44,56,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.8
+ - id: capture_tiles
+ type: screen.capture
+ params:
+ label: readybasic_gfx_phase2_tiles
+ pitch: "TILE and CHARAT visible tile demo"
+ - id: finish_rbgfx15
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 1.0
+ - id: wait_tiles_done
+ type: screen.wait_contains
+ params:
+ text: "PHASE2 TILES DONE"
+ wait_timeout_s: 60
+ capture_on_success: true
+ capture_label: readybasic_gfx_phase2_tiles_done
+ - id: load_rbgfx16
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,49,54,34,44,56,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.8
+ - id: capture_sprite_normal
+ type: screen.capture
+ params:
+ label: readybasic_gfx_phase2_sprite_normal
+ pitch: "Sprite control baseline before expansion"
+ - id: continue_sprite_expand
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 1.3
+ - id: capture_sprite_expanded
+ type: screen.capture
+ params:
+ label: readybasic_gfx_phase2_sprite_expanded
+ pitch: "SPRSIZE visible sprite enlargement"
+ - id: continue_sprite_multi_priority
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 1.3
+ - id: capture_sprite_multi_priority
+ type: screen.capture
+ params:
+ label: readybasic_gfx_phase2_sprite_multi_priority
+ pitch: "SPRMUL, SPRMCO, SPRPRI, and SPRCOL stage"
+ - id: finish_rbgfx16
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 1.0
+ - id: wait_sprites_done
+ type: screen.wait_contains
+ params:
+ text: "PHASE2 SPRITES DONE"
+ wait_timeout_s: 60
+ capture_on_success: true
+ capture_label: readybasic_gfx_phase2_sprites_done
+ - id: assert_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
diff --git a/build_support/readybasic_gfx_phase3_demo.generated.yaml b/build_support/readybasic_gfx_phase3_demo.generated.yaml
new file mode 100644
index 0000000..eddd8ae
--- /dev/null
+++ b/build_support/readybasic_gfx_phase3_demo.generated.yaml
@@ -0,0 +1,175 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_gfx_phase3_demo
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 1
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_readyos_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_loaded_by_readyos
+ type: screen.wait_contains
+ params:
+ text: "FREE:"
+ wait_timeout_s: 180
+ capture_on_success: true
+ capture_label: readybasic_gfx_phase3_prompt
+ - id: clear_for_phase3
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: probe_pbuf_free
+ type: input.sequence
+ params:
+ keys: [80,66,77,65,75,69,40,51,44,72,37,41,58,80,66,68,82,79,80,40,72,37,41,58,80,82,73,78,84,32,34,79,75,32,55,51,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: assert_pbuf_free
+ type: assert.screen
+ params:
+ contains: "OK 73"
+ - id: load_rbgfx17
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,49,55,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.2
+ - id: list_rbgfx17
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: capture_list_rbgfx17
+ type: screen.capture
+ params:
+ label: readybasic_gfx_phase3_list_rbgfx17
+ pitch: "RBGFX17 listed inside ReadyBASIC under ReadyOS"
+ - id: assert_list_rbgfx17
+ type: assert.screen
+ params:
+ contains: "DEMO 17"
+ - id: run_rbgfx17
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 5.0
+ - id: capture_poly_array
+ type: screen.capture
+ params:
+ label: readybasic_gfx_phase3_poly_array
+ pitch: "POLY(A%(0),count,color) outline polygons"
+ - id: finish_rbgfx17
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 1.0
+ - id: wait_rbgfx17_done
+ type: screen.wait_contains
+ params:
+ text: "PHASE3 DONE 17"
+ wait_timeout_s: 60
+ capture_on_success: true
+ capture_label: readybasic_gfx_phase3_poly_array_done
+ - id: load_rbgfx18
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,49,56,34,44,56,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 5.0
+ - id: capture_fpoly_array
+ type: screen.capture
+ params:
+ label: readybasic_gfx_phase3_fpoly_array
+ pitch: "FPOLY(A%(0),count,color) filled polygon demo"
+ - id: finish_rbgfx18
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 1.0
+ - id: wait_rbgfx18_done
+ type: screen.wait_contains
+ params:
+ text: "PHASE3 DONE 18"
+ wait_timeout_s: 60
+ capture_on_success: true
+ capture_label: readybasic_gfx_phase3_fpoly_array_done
+ - id: load_rbgfx19
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,49,57,34,44,56,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 5.0
+ - id: capture_poly_reu
+ type: screen.capture
+ params:
+ label: readybasic_gfx_phase3_poly_reu
+ pitch: "PBMAKE/PBUFSET plus POLYH handle polygon demo"
+ - id: finish_rbgfx19
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 1.0
+ - id: wait_rbgfx19_done
+ type: screen.wait_contains
+ params:
+ text: "PHASE3 DONE 19"
+ wait_timeout_s: 60
+ capture_on_success: true
+ capture_label: readybasic_gfx_phase3_poly_reu_done
+ - id: load_rbgfx20
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,50,48,34,44,56,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 5.0
+ - id: capture_fpoly_reu
+ type: screen.capture
+ params:
+ label: readybasic_gfx_phase3_fpoly_reu_showcase
+ pitch: "PBMAKE/PBUFSET plus FPOLYH filled polygon showcase"
+ - id: finish_rbgfx20
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 1.0
+ - id: wait_rbgfx20_done
+ type: screen.wait_contains
+ params:
+ text: "PHASE3 DONE 20"
+ wait_timeout_s: 60
+ capture_on_success: true
+ capture_label: readybasic_gfx_phase3_fpoly_reu_done
+ - id: assert_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
diff --git a/build_support/readybasic_gfx_phase4_demo.generated.yaml b/build_support/readybasic_gfx_phase4_demo.generated.yaml
new file mode 100644
index 0000000..5f483f5
--- /dev/null
+++ b/build_support/readybasic_gfx_phase4_demo.generated.yaml
@@ -0,0 +1,215 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_gfx_phase4_demo
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 1
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 220
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_readyos_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_loaded_by_readyos
+ type: screen.wait_contains
+ params:
+ text: "FREE:"
+ wait_timeout_s: 180
+ capture_on_success: true
+ capture_label: readybasic_gfx_phase4_prompt
+ - id: probe_dlnew
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,58,68,76,77,65,75,69,40,49,50,44,72,37,41,58,80,82,73,78,84,32,34,68,76,80,82,79,66,69,34,59,72,37,59,69,82,82,67,79,68,69,40,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: capture_dlnew_probe
+ type: screen.capture
+ params:
+ label: readybasic_gfx_phase4_dlnew_probe
+ - id: assert_dlnew_probe
+ type: assert.screen
+ params:
+ contains: "DLPROBE"
+ - id: load_rbgfx23
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,50,51,34,44,56,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: capture_rbgfx23_list
+ type: screen.capture
+ params:
+ label: readybasic_gfx_phase4_dlist_list
+ - id: run_rbgfx23
+ type: input.sequence
+ params:
+ keys: [82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: capture_dlist
+ type: screen.capture
+ params:
+ label: readybasic_gfx_phase4_dlist
+ pitch: "DLMAKE, DLPLOT, DLLINE, DLRECT, DLFBOX, DLDRAW"
+ - id: finish_rbgfx23
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 1.0
+ - id: wait_rbgfx23_done
+ type: screen.wait_contains
+ params:
+ text: "PHASE4 DLIST DONE"
+ wait_timeout_s: 60
+ capture_on_success: true
+ capture_label: readybasic_gfx_phase4_dlist_done
+ - id: load_rbgfx24
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,50,52,34,44,56,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 18.0
+ - id: capture_tilemap
+ type: screen.capture
+ params:
+ label: readybasic_gfx_phase4_tilemap
+ pitch: "CHRMAKE, CHRROW, CHRUSE, TSMAKE, TSSET, TMMAKE, TMSET, TMDRAW"
+ - id: finish_rbgfx24
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 1.0
+ - id: wait_rbgfx24_done
+ type: screen.wait_contains
+ params:
+ text: "PHASE4 TILEMAP DONE"
+ wait_timeout_s: 60
+ capture_on_success: true
+ capture_label: readybasic_gfx_phase4_tilemap_done
+ - id: load_rbgfx25
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,50,53,34,44,56,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: capture_mbitmap_cells
+ type: screen.capture
+ params:
+ label: readybasic_gfx_phase4_mbitmap_cells
+ pitch: "MCELL and MCBG explicit multicolor bitmap cell controls"
+ - id: finish_rbgfx25
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 1.0
+ - id: wait_rbgfx25_done
+ type: screen.wait_contains
+ params:
+ text: "PHASE4 MBITMAP CELLS DONE"
+ wait_timeout_s: 60
+ capture_on_success: true
+ capture_label: readybasic_gfx_phase4_mbitmap_cells_done
+ - id: load_rbgfx26
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,50,54,34,44,56,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: capture_mode_hires
+ type: screen.capture
+ params:
+ label: readybasic_gfx_phase4_mode_matrix_hires
+ pitch: "Immediate PLOT/LINE/RECT/FBOX/CIRCLE/PNT in HIRES"
+ - id: next_mode_mbitmap
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 3.0
+ - id: capture_mode_mbitmap
+ type: screen.capture
+ params:
+ label: readybasic_gfx_phase4_mode_matrix_mbitmap
+ pitch: "Immediate PLOT/LINE/RECT/FBOX/CIRCLE/PNT in MBITMAP"
+ - id: next_mode_tile
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 3.0
+ - id: capture_mode_tile
+ type: screen.capture
+ params:
+ label: readybasic_gfx_phase4_mode_matrix_tile
+ pitch: "Immediate PLOT/LINE/RECT/FBOX/PNT in TILE"
+ - id: next_mode_mtile
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 3.0
+ - id: capture_mode_mtile
+ type: screen.capture
+ params:
+ label: readybasic_gfx_phase4_mode_matrix_mtile
+ pitch: "Immediate PLOT/LINE/RECT/FBOX/PNT in MTILE"
+ - id: finish_rbgfx26
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 1.0
+ - id: wait_rbgfx26_done
+ type: screen.wait_contains
+ params:
+ text: "MODE MATRIX DONE"
+ wait_timeout_s: 60
+ capture_on_success: true
+ capture_label: readybasic_gfx_phase4_mode_matrix_done
+ - id: load_rbgfx27
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,50,55,34,44,56,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 4.0
+ - id: capture_target_blit_text
+ type: screen.capture
+ params:
+ label: readybasic_gfx_phase4_target_blit_text
+ pitch: "GFXSURF/GFXTGT/GFXSYNC/GFXBLIT status output"
+ - id: finish_rbgfx27
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 1.0
+ - id: wait_rbgfx27_done
+ type: screen.wait_contains
+ params:
+ text: "TARGET BLIT DONE"
+ wait_timeout_s: 60
+ capture_on_success: true
+ capture_label: readybasic_gfx_phase4_target_blit_done
+ - id: assert_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
diff --git a/build_support/readybasic_gfx_phase5_demo.generated.yaml b/build_support/readybasic_gfx_phase5_demo.generated.yaml
new file mode 100644
index 0000000..7c40818
--- /dev/null
+++ b/build_support/readybasic_gfx_phase5_demo.generated.yaml
@@ -0,0 +1,181 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_gfx_phase5_demo
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 1
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 240
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_readyos_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_loaded_by_readyos
+ type: screen.wait_contains
+ params:
+ text: "FREE:"
+ wait_timeout_s: 180
+ capture_on_success: true
+ capture_label: readybasic_gfx_phase5_prompt
+ - id: load_rbgfx28
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,50,56,34,44,56,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: capture_tile_visible
+ type: screen.capture
+ params:
+ label: readybasic_gfx_phase5_tile_visible
+ pitch: "TILE immediate PLOT/LINE/RECT/FBOX through default Bank D glyphs"
+ - id: finish_rbgfx28
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 1.0
+ - id: wait_rbgfx28_done
+ type: screen.wait_contains
+ params:
+ text: "TILE VISIBLE"
+ wait_timeout_s: 60
+ capture_on_success: true
+ capture_label: readybasic_gfx_phase5_tile_visible_done
+ - id: load_rbgfx29
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,50,57,34,44,56,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: capture_mtile_visible
+ type: screen.capture
+ params:
+ label: readybasic_gfx_phase5_mtile_visible
+ pitch: "MTILE immediate PLOT/LINE/RECT/FBOX through default Bank D glyphs"
+ - id: finish_rbgfx29
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 1.0
+ - id: wait_rbgfx29_done
+ type: screen.wait_contains
+ params:
+ text: "MTILE VISIBLE"
+ wait_timeout_s: 60
+ capture_on_success: true
+ capture_label: readybasic_gfx_phase5_mtile_visible_done
+ - id: load_rbgfx30
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,51,48,34,44,56,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: capture_mbitmap_dlist
+ type: screen.capture
+ params:
+ label: readybasic_gfx_phase5_mbitmap_dlist
+ pitch: "MBITMAP retained DLPLOT/DLLINE/DLRECT/DLFBOX/DLDRAW replay"
+ - id: finish_rbgfx30
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 1.0
+ - id: wait_rbgfx30_done
+ type: screen.wait_contains
+ params:
+ text: "MBITMAP DLIST DONE"
+ wait_timeout_s: 60
+ capture_on_success: true
+ capture_label: readybasic_gfx_phase5_mbitmap_dlist_done
+ - id: load_rbgfx31
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,51,49,34,44,56,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: capture_sync_source
+ type: screen.capture
+ params:
+ label: readybasic_gfx_phase5_sync_source
+ pitch: "Visible Bank D surface before GFXSYNC snapshot"
+ - id: sync_next_clear
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 1.0
+ - id: capture_sync_cleared
+ type: screen.capture
+ params:
+ label: readybasic_gfx_phase5_sync_cleared
+ pitch: "Visible Bank D surface after GFXCLEAR"
+ - id: sync_next_blit
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 1.0
+ - id: capture_sync_restored
+ type: screen.capture
+ params:
+ label: readybasic_gfx_phase5_sync_restored
+ pitch: "Visible Bank D surface restored by GFXBLIT"
+ - id: finish_rbgfx31
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 1.0
+ - id: wait_rbgfx31_done
+ type: screen.wait_contains
+ params:
+ text: "SYNC BLIT DONE"
+ wait_timeout_s: 60
+ capture_on_success: true
+ capture_label: readybasic_gfx_phase5_sync_blit_done
+ - id: load_rbgfx32
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,51,50,34,44,56,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: capture_convex_poly
+ type: screen.capture
+ params:
+ label: readybasic_gfx_phase5_convex_poly
+ pitch: "POLY and FPOLY convex polygon showcase"
+ - id: finish_rbgfx32
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 1.0
+ - id: wait_rbgfx32_done
+ type: screen.wait_contains
+ params:
+ text: "CONVEX POLY DONE"
+ wait_timeout_s: 60
+ capture_on_success: true
+ capture_label: readybasic_gfx_phase5_convex_poly_done
+ - id: assert_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
diff --git a/build_support/readybasic_hotkey_probe.generated.yaml b/build_support/readybasic_hotkey_probe.generated.yaml
new file mode 100644
index 0000000..acc4950
--- /dev/null
+++ b/build_support/readybasic_hotkey_probe.generated.yaml
@@ -0,0 +1,929 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_hotkey_launcher_cycle
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5n-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5n-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5n-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_launcher_initial
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 300
+ pre_delay_s: 8.0
+ capture_on_success: true
+ capture_label: readybasic_hotkey_launcher_initial
+ - id: move_to_editor_for_preload
+ type: input.sequence
+ params:
+ keys: [17,17]
+ inter_key_delay_s: 0.10
+ post_delay_s: 0.8
+ - id: move_to_editor_for_preload_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_launcher_editor_selected
+ pitch: after selecting Editor in launcher before F3 preload
+ - id: load_editor_to_reu
+ type: input.sequence
+ params:
+ keys: [134]
+ inter_key_delay_s: 0.10
+ post_delay_s: 8.0
+ - id: load_editor_to_reu_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_launcher_editor_preloaded
+ pitch: after F3 loading Editor to REU
+ - id: assert_editor_preload_label
+ type: assert.screen
+ params:
+ contains: "EDITOR"
+ - id: wait_editor_preloaded
+ type: screen.wait_contains
+ params:
+ text: "PRESS ANY KEY"
+ wait_timeout_s: 60
+ capture_on_success: true
+ capture_label: readybasic_hotkey_editor_preload_done
+ - id: dismiss_editor_preload_done
+ type: input.sequence
+ params:
+ keys: [32]
+ inter_key_delay_s: 0.10
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_preload
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ capture_on_success: true
+ capture_label: readybasic_hotkey_launcher_after_editor_preload
+ - id: move_editor_to_reuviewer_for_preload
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,17,17,17]
+ inter_key_delay_s: 0.10
+ post_delay_s: 0.8
+ - id: move_editor_to_reuviewer_for_preload_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_launcher_reuviewer_selected
+ pitch: after selecting REU Viewer in launcher before F3 preload
+ - id: load_reuviewer_to_reu
+ type: input.sequence
+ params:
+ keys: [134]
+ inter_key_delay_s: 0.10
+ post_delay_s: 8.0
+ - id: load_reuviewer_to_reu_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_launcher_reuviewer_preloaded
+ pitch: after F3 loading REU Viewer to REU
+ - id: assert_reuviewer_preload_label
+ type: assert.screen
+ params:
+ contains: "REU VIEWER"
+ - id: wait_reuviewer_preloaded
+ type: screen.wait_contains
+ params:
+ text: "PRESS ANY KEY"
+ wait_timeout_s: 60
+ capture_on_success: true
+ capture_label: readybasic_hotkey_reuviewer_preload_done
+ - id: dismiss_reuviewer_preload_done
+ type: input.sequence
+ params:
+ keys: [32]
+ inter_key_delay_s: 0.10
+ post_delay_s: 1.0
+ - id: wait_launcher_after_reuviewer_preload
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ capture_on_success: true
+ capture_label: readybasic_hotkey_launcher_after_reuviewer_preload
+ - id: launch_readybasic_from_reuviewer_position
+ type: input.sequence
+ params:
+ keys: [145,145,145,13]
+ inter_key_delay_s: 0.10
+ post_delay_s: 2.5
+ - id: launch_readybasic_from_reuviewer_position_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_launcher_after_readybasic_nav
+ pitch: after navigating launcher from REU Viewer to ReadyBASIC
+ - id: wait_readybasic_prompt
+ type: screen.wait_contains
+ params:
+ text: "readybasic"
+ wait_timeout_s: 180
+ capture_on_success: true
+ capture_label: readybasic_hotkey_prompt
+ - id: assert_readybasic_initial_bank
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "03"
+ - id: assert_chrin_vector_installed
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "08 12"
+ - id: assert_keylog_vector_installed
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "7E C1"
+ - id: seed_readybasic_list_program
+ type: input.sequence
+ params:
+ keys: [49,48,32,80,82,73,78,84,32,34,72,79,84,32,67,89,67,76,69,34,13,76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: seed_readybasic_list_program_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_seed_list_program
+ pitch: after listing the seed program in ReadyBASIC
+ - id: assert_readybasic_list_program
+ type: assert.screen
+ params:
+ contains: "10 PRINT \"HOT CYCLE\""
+ - id: f2_round1_to_editor_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 4C 74 A4"
+ - id: f2_round1_to_editor_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: f2_round1_to_editor
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: f2_round1_to_editor_capture_after_input
+ type: screen.capture
+ params:
+ label: "readybasic_hotkey_f2_round1_editor_after_input"
+ pitch: "after f2 input before waiting for EDITOR:"
+ - id: wait_f2_round1_to_editor
+ type: screen.wait_contains
+ params:
+ text: "EDITOR:"
+ wait_timeout_s: 60
+ capture_label: "readybasic_hotkey_f2_round1_editor"
+ - id: assert_keyboard_buffer_empty_f2_round1_to_editor
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: assert_active_bank_f2_round1_to_editor
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "01"
+ - id: wait_f2_round1_to_editor_stable
+ type: screen.wait_contains
+ params:
+ text: "EDITOR:"
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: "readybasic_hotkey_f2_round1_editor_stable"
+ - id: assert_keyboard_buffer_empty_stable_f2_round1_to_editor
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: assert_active_bank_stable_f2_round1_to_editor
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "01"
+ - id: f2_round1_to_reuviewer
+ type: monitor.command
+ params:
+ command: "keybuf \\x89"
+ - id: f2_round1_to_reuviewer_capture_after_input
+ type: screen.capture
+ params:
+ label: "readybasic_hotkey_f2_round1_reuviewer_after_input"
+ pitch: "after f2 input before waiting for REU MEMORY"
+ - id: wait_f2_round1_to_reuviewer
+ type: screen.wait_contains
+ params:
+ text: "REU MEMORY"
+ wait_timeout_s: 60
+ capture_label: "readybasic_hotkey_f2_round1_reuviewer"
+ - id: assert_keyboard_buffer_empty_f2_round1_to_reuviewer
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: assert_active_bank_f2_round1_to_reuviewer
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "02"
+ - id: wait_f2_round1_to_reuviewer_stable
+ type: screen.wait_contains
+ params:
+ text: "REU MEMORY"
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: "readybasic_hotkey_f2_round1_reuviewer_stable"
+ - id: assert_keyboard_buffer_empty_stable_f2_round1_to_reuviewer
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: assert_active_bank_stable_f2_round1_to_reuviewer
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "02"
+ - id: f2_round1_back_to_readybasic
+ type: monitor.command
+ params:
+ command: "keybuf \\x89"
+ - id: f2_round1_back_to_readybasic_capture_after_input
+ type: screen.capture
+ params:
+ label: "readybasic_hotkey_f2_round1_readybasic_after_input"
+ pitch: "after f2 input before waiting for ready."
+ - id: wait_f2_round1_back_to_readybasic
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: "readybasic_hotkey_f2_round1_readybasic"
+ - id: assert_keyboard_buffer_empty_f2_round1_back_to_readybasic
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: assert_active_bank_f2_round1_back_to_readybasic
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "03"
+ - id: wait_f2_round1_back_to_readybasic_stable
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: "readybasic_hotkey_f2_round1_readybasic_stable"
+ - id: assert_keyboard_buffer_empty_stable_f2_round1_back_to_readybasic
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: assert_active_bank_stable_f2_round1_back_to_readybasic
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "03"
+ - id: f2_round2_to_editor_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 4C 74 A4"
+ - id: f2_round2_to_editor_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: f2_round2_to_editor
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: f2_round2_to_editor_capture_after_input
+ type: screen.capture
+ params:
+ label: "readybasic_hotkey_f2_round2_editor_after_input"
+ pitch: "after f2 input before waiting for EDITOR:"
+ - id: wait_f2_round2_to_editor
+ type: screen.wait_contains
+ params:
+ text: "EDITOR:"
+ wait_timeout_s: 60
+ capture_label: "readybasic_hotkey_f2_round2_editor"
+ - id: assert_keyboard_buffer_empty_f2_round2_to_editor
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: assert_active_bank_f2_round2_to_editor
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "01"
+ - id: wait_f2_round2_to_editor_stable
+ type: screen.wait_contains
+ params:
+ text: "EDITOR:"
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: "readybasic_hotkey_f2_round2_editor_stable"
+ - id: assert_keyboard_buffer_empty_stable_f2_round2_to_editor
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: assert_active_bank_stable_f2_round2_to_editor
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "01"
+ - id: f2_round2_to_reuviewer
+ type: monitor.command
+ params:
+ command: "keybuf \\x89"
+ - id: f2_round2_to_reuviewer_capture_after_input
+ type: screen.capture
+ params:
+ label: "readybasic_hotkey_f2_round2_reuviewer_after_input"
+ pitch: "after f2 input before waiting for REU MEMORY"
+ - id: wait_f2_round2_to_reuviewer
+ type: screen.wait_contains
+ params:
+ text: "REU MEMORY"
+ wait_timeout_s: 60
+ capture_label: "readybasic_hotkey_f2_round2_reuviewer"
+ - id: assert_keyboard_buffer_empty_f2_round2_to_reuviewer
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: assert_active_bank_f2_round2_to_reuviewer
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "02"
+ - id: wait_f2_round2_to_reuviewer_stable
+ type: screen.wait_contains
+ params:
+ text: "REU MEMORY"
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: "readybasic_hotkey_f2_round2_reuviewer_stable"
+ - id: assert_keyboard_buffer_empty_stable_f2_round2_to_reuviewer
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: assert_active_bank_stable_f2_round2_to_reuviewer
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "02"
+ - id: f2_round2_back_to_readybasic
+ type: monitor.command
+ params:
+ command: "keybuf \\x89"
+ - id: f2_round2_back_to_readybasic_capture_after_input
+ type: screen.capture
+ params:
+ label: "readybasic_hotkey_f2_round2_readybasic_after_input"
+ pitch: "after f2 input before waiting for ready."
+ - id: wait_f2_round2_back_to_readybasic
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: "readybasic_hotkey_f2_round2_readybasic"
+ - id: assert_keyboard_buffer_empty_f2_round2_back_to_readybasic
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: assert_active_bank_f2_round2_back_to_readybasic
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "03"
+ - id: wait_f2_round2_back_to_readybasic_stable
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: "readybasic_hotkey_f2_round2_readybasic_stable"
+ - id: assert_keyboard_buffer_empty_stable_f2_round2_back_to_readybasic
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: assert_active_bank_stable_f2_round2_back_to_readybasic
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "03"
+ - id: f4_round1_to_reuviewer_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 01 8D 8D 02 A9 05 85 CB 20 7E C1 A9 01 8D 8D 02 A9 05 85 CB 20 7E C1 4C 74 A4"
+ - id: f4_round1_to_reuviewer_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: f4_round1_to_reuviewer
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: f4_round1_to_reuviewer_capture_after_input
+ type: screen.capture
+ params:
+ label: "readybasic_hotkey_f4_round1_reuviewer_after_input"
+ pitch: "after f4 input before waiting for REU MEMORY"
+ - id: wait_f4_round1_to_reuviewer
+ type: screen.wait_contains
+ params:
+ text: "REU MEMORY"
+ wait_timeout_s: 60
+ capture_label: "readybasic_hotkey_f4_round1_reuviewer"
+ - id: assert_keyboard_buffer_empty_f4_round1_to_reuviewer
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: assert_active_bank_f4_round1_to_reuviewer
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "02"
+ - id: wait_f4_round1_to_reuviewer_stable
+ type: screen.wait_contains
+ params:
+ text: "REU MEMORY"
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: "readybasic_hotkey_f4_round1_reuviewer_stable"
+ - id: assert_keyboard_buffer_empty_stable_f4_round1_to_reuviewer
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: assert_active_bank_stable_f4_round1_to_reuviewer
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "02"
+ - id: f4_round1_to_editor
+ type: monitor.command
+ params:
+ command: "keybuf \\x8a"
+ - id: f4_round1_to_editor_capture_after_input
+ type: screen.capture
+ params:
+ label: "readybasic_hotkey_f4_round1_editor_after_input"
+ pitch: "after f4 input before waiting for EDITOR:"
+ - id: wait_f4_round1_to_editor
+ type: screen.wait_contains
+ params:
+ text: "EDITOR:"
+ wait_timeout_s: 60
+ capture_label: "readybasic_hotkey_f4_round1_editor"
+ - id: assert_keyboard_buffer_empty_f4_round1_to_editor
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: assert_active_bank_f4_round1_to_editor
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "01"
+ - id: wait_f4_round1_to_editor_stable
+ type: screen.wait_contains
+ params:
+ text: "EDITOR:"
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: "readybasic_hotkey_f4_round1_editor_stable"
+ - id: assert_keyboard_buffer_empty_stable_f4_round1_to_editor
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: assert_active_bank_stable_f4_round1_to_editor
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "01"
+ - id: f4_round1_back_to_readybasic
+ type: monitor.command
+ params:
+ command: "keybuf \\x8a"
+ - id: f4_round1_back_to_readybasic_capture_after_input
+ type: screen.capture
+ params:
+ label: "readybasic_hotkey_f4_round1_readybasic_after_input"
+ pitch: "after f4 input before waiting for ready."
+ - id: wait_f4_round1_back_to_readybasic
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: "readybasic_hotkey_f4_round1_readybasic"
+ - id: assert_keyboard_buffer_empty_f4_round1_back_to_readybasic
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: assert_active_bank_f4_round1_back_to_readybasic
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "03"
+ - id: wait_f4_round1_back_to_readybasic_stable
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: "readybasic_hotkey_f4_round1_readybasic_stable"
+ - id: assert_keyboard_buffer_empty_stable_f4_round1_back_to_readybasic
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: assert_active_bank_stable_f4_round1_back_to_readybasic
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "03"
+ - id: f4_round2_to_reuviewer_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 01 8D 8D 02 A9 05 85 CB 20 7E C1 A9 01 8D 8D 02 A9 05 85 CB 20 7E C1 4C 74 A4"
+ - id: f4_round2_to_reuviewer_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: f4_round2_to_reuviewer
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: f4_round2_to_reuviewer_capture_after_input
+ type: screen.capture
+ params:
+ label: "readybasic_hotkey_f4_round2_reuviewer_after_input"
+ pitch: "after f4 input before waiting for REU MEMORY"
+ - id: wait_f4_round2_to_reuviewer
+ type: screen.wait_contains
+ params:
+ text: "REU MEMORY"
+ wait_timeout_s: 60
+ capture_label: "readybasic_hotkey_f4_round2_reuviewer"
+ - id: assert_keyboard_buffer_empty_f4_round2_to_reuviewer
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: assert_active_bank_f4_round2_to_reuviewer
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "02"
+ - id: wait_f4_round2_to_reuviewer_stable
+ type: screen.wait_contains
+ params:
+ text: "REU MEMORY"
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: "readybasic_hotkey_f4_round2_reuviewer_stable"
+ - id: assert_keyboard_buffer_empty_stable_f4_round2_to_reuviewer
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: assert_active_bank_stable_f4_round2_to_reuviewer
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "02"
+ - id: f4_round2_to_editor
+ type: monitor.command
+ params:
+ command: "keybuf \\x8a"
+ - id: f4_round2_to_editor_capture_after_input
+ type: screen.capture
+ params:
+ label: "readybasic_hotkey_f4_round2_editor_after_input"
+ pitch: "after f4 input before waiting for EDITOR:"
+ - id: wait_f4_round2_to_editor
+ type: screen.wait_contains
+ params:
+ text: "EDITOR:"
+ wait_timeout_s: 60
+ capture_label: "readybasic_hotkey_f4_round2_editor"
+ - id: assert_keyboard_buffer_empty_f4_round2_to_editor
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: assert_active_bank_f4_round2_to_editor
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "01"
+ - id: wait_f4_round2_to_editor_stable
+ type: screen.wait_contains
+ params:
+ text: "EDITOR:"
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: "readybasic_hotkey_f4_round2_editor_stable"
+ - id: assert_keyboard_buffer_empty_stable_f4_round2_to_editor
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: assert_active_bank_stable_f4_round2_to_editor
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "01"
+ - id: f4_round2_back_to_readybasic
+ type: monitor.command
+ params:
+ command: "keybuf \\x8a"
+ - id: f4_round2_back_to_readybasic_capture_after_input
+ type: screen.capture
+ params:
+ label: "readybasic_hotkey_f4_round2_readybasic_after_input"
+ pitch: "after f4 input before waiting for ready."
+ - id: wait_f4_round2_back_to_readybasic
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: "readybasic_hotkey_f4_round2_readybasic"
+ - id: assert_keyboard_buffer_empty_f4_round2_back_to_readybasic
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: assert_active_bank_f4_round2_back_to_readybasic
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "03"
+ - id: wait_f4_round2_back_to_readybasic_stable
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: "readybasic_hotkey_f4_round2_readybasic_stable"
+ - id: assert_keyboard_buffer_empty_stable_f4_round2_back_to_readybasic
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: assert_active_bank_stable_f4_round2_back_to_readybasic
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "03"
+ - id: list_after_cycles_before_ctrl_b
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: list_after_cycles_before_ctrl_b_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_list_after_cycles_before_ctrl_b
+ pitch: after LIST following two F2 and two F4 loaded-app cycles
+ - id: assert_list_after_cycles_before_ctrl_b
+ type: assert.screen
+ params:
+ contains: "HOT CYCLE"
+ - id: run_after_cycles_before_ctrl_b
+ type: input.sequence
+ params:
+ keys: [82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: run_after_cycles_before_ctrl_b_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_run_after_cycles_before_ctrl_b
+ pitch: after RUN following two F2 and two F4 loaded-app cycles
+ - id: assert_run_after_cycles_before_ctrl_b
+ type: assert.screen
+ params:
+ contains: "HOT CYCLE"
+ - id: debug_hotkey_state_before_ctrl_b_after_cycles
+ type: monitor.command
+ params:
+ command: "raw:m 2a51 2a54"
+ - id: debug_basic_state_before_ctrl_b_after_cycles
+ type: monitor.command
+ params:
+ command: "raw:m 0039 003a; m 007a 007b; m 0099 0099; m 00c5 00cb; m 028d 028d"
+ - id: ctrl_b_from_readybasic_after_cycles_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 4C 74 A4"
+ - id: ctrl_b_from_readybasic_after_cycles_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: ctrl_b_from_readybasic_after_cycles
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: debug_hotkey_state_after_ctrl_b_after_cycles
+ type: monitor.command
+ params:
+ command: "raw:m 2a51 2a54"
+ - id: debug_basic_state_after_ctrl_b_after_cycles
+ type: monitor.command
+ params:
+ command: "raw:m 0039 003a; m 007a 007b; m 0099 0099; m 00c5 00cb; m 028d 028d"
+ - id: ctrl_b_from_readybasic_after_cycles_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_ctrl_b_after_cycles
+ pitch: after Ctrl+B at end of cycling before launcher wait
+ - id: wait_launcher_after_readybasic_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ capture_on_success: true
+ capture_label: readybasic_hotkey_launcher_after_readybasic_ctrl_b
+ - id: assert_launcher_bank_after_readybasic_ctrl_b
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "00"
+ - id: reenter_readybasic_after_ctrl_b
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
+ - id: reenter_readybasic_after_ctrl_b_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_reenter_after_ctrl_b
+ pitch: after returning from launcher before ReadyBASIC reentry wait
+ - id: wait_readybasic_after_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: readybasic_hotkey_readybasic_after_ctrl_b
+ - id: assert_readybasic_bank_after_ctrl_b
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "03"
+ - id: final_list_after_reentry
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: final_list_after_reentry_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_final_list_after_reentry
+ pitch: after LIST on final ReadyBASIC reentry
+ - id: assert_final_list_after_reentry
+ type: assert.screen
+ params:
+ contains: "HOT CYCLE"
+ - id: final_run_after_reentry
+ type: input.sequence
+ params:
+ keys: [82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.5
+ - id: final_run_after_reentry_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_final_run_after_reentry
+ pitch: after RUN on final ReadyBASIC reentry
+ - id: assert_final_run_output
+ type: assert.screen
+ params:
+ contains: "HOT CYCLE"
+ - id: exit_after_final_run
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: exit_after_final_run_capture
+ type: screen.capture
+ params:
+ label: readybasic_hotkey_exit_after_final_run
+ pitch: after EXIT before launcher wait
+ - id: wait_launcher_after_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ pre_delay_s: 2.0
+ capture_on_success: true
+ capture_label: readybasic_hotkey_launcher_after_exit
+ - id: assert_launcher_stable_after_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 20
+ pre_delay_s: 2.5
+ capture_on_success: true
+ capture_label: readybasic_hotkey_launcher_stable_after_exit
diff --git a/build_support/readybasic_keyboard_regression_probe.generated.yaml b/build_support/readybasic_keyboard_regression_probe.generated.yaml
new file mode 100644
index 0000000..0c91add
--- /dev/null
+++ b/build_support/readybasic_keyboard_regression_probe.generated.yaml
@@ -0,0 +1,243 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_keyboard_regression_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_initial
+ type: screen.wait_contains
+ params:
+ text: "readybasic"
+ wait_timeout_s: 180
+ capture_label: keyboard_regression_readybasic_initial
+ - id: assert_readybasic_bank_initial
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "01"
+ - id: assert_chrin_vector_initial
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "08 12"
+ - id: assert_keylog_vector_initial
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "7E C1"
+ - id: assert_warp_enabled
+ type: warp.set
+ params:
+ enabled: true
+ capture_after: false
+ - id: type_space_string_once
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,65,32,66,32,67,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_single_space_string_output
+ type: assert.screen
+ params:
+ contains: "A B C"
+ - id: assert_keyboard_buffer_empty_after_space_string
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: type_partial_line_10
+ type: input.sequence
+ params:
+ keys: [49,48]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.1
+ - id: partial_line_ctrl_b_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 4C 74 A4"
+ - id: partial_line_ctrl_b_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: partial_line_ctrl_b
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_launcher_after_partial_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ capture_label: keyboard_regression_launcher_after_partial_ctrl_b
+ - id: assert_no_rem_after_partial_ctrl_b
+ type: assert.screen_not_contains
+ params:
+ not_contains: "REM"
+ - id: assert_launcher_bank_after_partial_ctrl_b
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "00"
+ - id: reenter_readybasic_after_partial_ctrl_b
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
+ - id: wait_readybasic_after_partial_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: keyboard_regression_readybasic_after_partial_ctrl_b
+ - id: list_after_partial_ctrl_b
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_no_rem_listed_after_partial_ctrl_b
+ type: assert.screen_not_contains
+ params:
+ not_contains: "REM"
+ - id: type_after_partial_ctrl_b
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,65,70,84,69,82,67,84,82,76,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_type_after_partial_ctrl_b
+ type: assert.screen
+ params:
+ contains: "AFTERCTRL"
+ - id: clean_ctrl_b_to_launcher_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 4C 74 A4"
+ - id: clean_ctrl_b_to_launcher_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: clean_ctrl_b_to_launcher
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_launcher_to_load_editor
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ - id: move_readybasic_to_editor
+ type: input.sequence
+ params:
+ keys: [145,145,145,145,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_editor_loaded
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ capture_label: keyboard_regression_editor_loaded
+ - id: editor_ctrl_b_to_launcher
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
+ - id: wait_launcher_after_editor_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ - id: move_editor_to_readybasic
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.0
+ - id: wait_readybasic_before_partial_f2
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 60
+ capture_label: keyboard_regression_readybasic_before_partial_f2
+ - id: type_partial_line_20
+ type: input.sequence
+ params:
+ keys: [50,48]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.1
+ - id: partial_line_f2_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 4C 74 A4"
+ - id: partial_line_f2_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: partial_line_f2
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_editor_after_partial_f2
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ wait_timeout_s: 60
+ capture_label: keyboard_regression_editor_after_partial_f2
+ - id: assert_no_rem_after_partial_f2
+ type: assert.screen_not_contains
+ params:
+ not_contains: "REM"
+ - id: assert_keylog_restored_after_partial_f2
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "48 EB"
+ - id: assert_chrin_restored_after_partial_f2
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "57 F1"
+ - id: assert_keyboard_buffer_empty_after_partial_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
diff --git a/build_support/readybasic_large_vars_probe.generated.yaml b/build_support/readybasic_large_vars_probe.generated.yaml
index ca85e29..5a6186e 100644
--- a/build_support/readybasic_large_vars_probe.generated.yaml
+++ b/build_support/readybasic_large_vars_probe.generated.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4w-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4w-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4w-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
@@ -73,7 +73,7 @@ steps:
type: dump.memory_ranges
params:
ranges:
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
- { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
- { label: bridge_c000, start: 0xC000, end: 0xC5FF }
@@ -87,7 +87,7 @@ steps:
type: dump.memory_ranges
params:
ranges:
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
- { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
- { label: bridge_c000, start: 0xC000, end: 0xC5FF }
@@ -105,7 +105,7 @@ steps:
type: dump.memory_ranges
params:
ranges:
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
- { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
- { label: bridge_c000, start: 0xC000, end: 0xC5FF }
@@ -119,7 +119,7 @@ steps:
type: dump.memory_ranges
params:
ranges:
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
- { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
- { label: bridge_c000, start: 0xC000, end: 0xC5FF }
@@ -131,7 +131,7 @@ steps:
type: dump.memory_ranges
params:
ranges:
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
- { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
- id: dim_large_array
@@ -150,7 +150,7 @@ steps:
type: dump.memory_ranges
params:
ranges:
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
- { label: basic_vars_start_1200, start: 0x1200, end: 0x1600 }
- { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
@@ -184,11 +184,9 @@ steps:
text: "READY OS"
wait_timeout_s: 30
- id: resume_readybasic
- type: input.sequence
+ type: monitor.command
params:
- keys: [13]
- inter_key_delay_s: 0.03
- post_delay_s: 2.0
+ command: "keybuf \\x0d"
- id: wait_prompt_after_resume
type: screen.wait_contains
params:
@@ -204,7 +202,7 @@ steps:
type: dump.memory_ranges
params:
ranges:
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
- { label: basic_vars_start_1200, start: 0x1200, end: 0x1600 }
- { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
@@ -238,7 +236,7 @@ steps:
type: dump.memory_ranges
params:
ranges:
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_var_table_2b00, start: 0x2B00, end: 0x2B3F }
- { label: basic_vars_start_1200, start: 0x1200, end: 0x1600 }
- { label: string_heap_9f80, start: 0x9F80, end: 0x9FFF }
diff --git a/build_support/readybasic_lifecycle_probe.generated.yaml b/build_support/readybasic_lifecycle_probe.generated.yaml
index 289a450..44cb6ef 100644
--- a/build_support/readybasic_lifecycle_probe.generated.yaml
+++ b/build_support/readybasic_lifecycle_probe.generated.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4q-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4q-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4q-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
@@ -42,7 +42,7 @@ steps:
type: screen.capture
params:
label: after_readybasic_loading
- note: after READYBASIC first appears, before READY prompt wait
+ pitch: after READYBASIC first appears, before READY prompt wait
- id: wait_readybasic_prompt
type: screen.wait_contains
params:
@@ -77,7 +77,7 @@ steps:
type: screen.capture
params:
label: after_print_1
- note: after direct print 1
+ pitch: after direct print 1
- id: assert_print_1_no_error
type: assert.screen_not_contains
params:
@@ -96,7 +96,7 @@ steps:
type: screen.capture
params:
label: after_print_hello
- note: after direct print hello
+ pitch: after direct print hello
- id: assert_print_hello_no_error
type: assert.screen_not_contains
params:
@@ -115,7 +115,7 @@ steps:
type: screen.capture
params:
label: after_10_print_1
- note: after numbered line entry
+ pitch: after numbered line entry
- id: dump_line_entry_core
type: dump.memory_ranges
params:
@@ -138,7 +138,7 @@ steps:
type: screen.capture
params:
label: after_list
- note: after LIST
+ pitch: after LIST
- id: assert_list_has_line
type: assert.screen
params:
@@ -153,7 +153,7 @@ steps:
type: screen.capture
params:
label: after_run
- note: after RUN
+ pitch: after RUN
- id: assert_run_no_error
type: assert.screen_not_contains
params:
@@ -176,7 +176,7 @@ steps:
type: screen.capture
params:
label: after_rb_direct_text
- note: after direct scalar command statement
+ pitch: after direct scalar command statement
- id: dump_rb_direct_text_core
type: dump.memory_ranges
params:
@@ -195,7 +195,7 @@ steps:
type: screen.capture
params:
label: after_rb_direct_add
- note: after direct ZADD16 statement
+ pitch: after direct ZADD16 statement
- id: dump_rb_direct_add_core
type: dump.memory_ranges
params:
@@ -220,7 +220,7 @@ steps:
type: screen.capture
params:
label: after_run_with_rb_line
- note: after RUN with stored ReadyBASIC command
+ pitch: after RUN with stored ReadyBASIC command
- id: assert_run_with_rb_line
type: assert.screen
params:
@@ -235,7 +235,7 @@ steps:
type: screen.capture
params:
label: after_exit
- note: after uppercase exit command
+ pitch: after uppercase exit command
- id: wait_launcher_after_exit
type: screen.wait_contains
params:
@@ -244,9 +244,20 @@ steps:
- id: type_resume_readybasic
type: input.sequence
params:
- keys: [145,17,13]
+ keys: [145,17]
inter_key_delay_s: 0.10
- post_delay_s: 3.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_readybasic_resume
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ # The binary-monitor input helper can drop a lone RETURN immediately after
+ # ReadyBASIC's EXIT return. VICE's text-monitor keybuf path is deterministic.
+ - id: launch_readybasic_after_exit
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_prompt_after_resume
type: screen.wait_contains
params:
@@ -264,7 +275,7 @@ steps:
type: screen.capture
params:
label: after_list_after_resume
- note: after relaunching ReadyBASIC from REU and LISTing
+ pitch: after relaunching ReadyBASIC from REU and LISTing
- id: assert_resume_preserved_line
type: assert.screen
params:
diff --git a/build_support/readybasic_memory_report.py b/build_support/readybasic_memory_report.py
index 961f998..6f70497 100644
--- a/build_support/readybasic_memory_report.py
+++ b/build_support/readybasic_memory_report.py
@@ -9,6 +9,8 @@
from dataclasses import dataclass
from pathlib import Path
+from update_documentation_html_status import CURRENT, banner
+
ROOT = Path(__file__).resolve().parents[1]
@@ -78,6 +80,10 @@ def parse_map_segments(path: Path) -> dict[str, Segment]:
"SPANPACK",
"OVL1PACK",
"OVL2PACK",
+ "OVL3PACK",
+ "OVL4PACK",
+ "OVL5PACK",
+ "OVL6PACK",
"BRIDGE",
}
missing = sorted(required - set(segments))
@@ -119,7 +125,7 @@ def parse_memory_config(path: Path) -> dict[str, tuple[int, int]]:
out: dict[str, tuple[int, int]] = {}
for name, start_s, size_s in mem_re.findall(src):
out[name] = (int(start_s, 16), int(size_s, 16))
- required = {"ENTRY", "RESIDENT", "SLOT0", "SLOT1", "SLOT2", "CMDPACK", "HIDLOAD", "BRLOAD", "REGSEED"}
+ required = {"ENTRY", "RESIDENT", "SLOT0", "SLOT1", "SLOT2", "CMDPACK", "CMDPACK2", "HIDLOAD", "BRLOAD", "REGSEED"}
missing = sorted(required - set(out))
if missing:
raise SystemExit(f"{path}: missing MEMORY regions: {', '.join(missing)}")
@@ -230,6 +236,14 @@ def command_groups(commands: list[tuple[str, str]]) -> dict[str, tuple[str, ...]
"slot2": [],
"span": [],
"overlay": [],
+ "gfxcore": [],
+ "gfxprim": [],
+ "gfxspr": [],
+ "inputev": [],
+ "gfxpoly": [],
+ "gfxdl": [],
+ "gfxtile": [],
+ "sidcore": [],
"end": [],
}
for macro, name in commands:
@@ -245,6 +259,22 @@ def command_groups(commands: list[tuple[str, str]]) -> dict[str, tuple[str, ...]
groups["span"].append(name)
elif macro in ("CMD_OVL1", "CMD_OVL2"):
groups["overlay"].append(name)
+ elif macro == "CMD_GFXCORE":
+ groups["gfxcore"].append(name)
+ elif macro == "CMD_GFXPRIM":
+ groups["gfxprim"].append(name)
+ elif macro == "CMD_GFXSPR":
+ groups["gfxspr"].append(name)
+ elif macro == "CMD_INPUTEV":
+ groups["inputev"].append(name)
+ elif macro == "CMD_GFXPOLY":
+ groups["gfxpoly"].append(name)
+ elif macro == "CMD_GFXDL":
+ groups["gfxdl"].append(name)
+ elif macro == "CMD_GFXTILE":
+ groups["gfxtile"].append(name)
+ elif macro == "CMD_SIDCORE":
+ groups["sidcore"].append(name)
return {k: tuple(v) for k, v in groups.items()}
@@ -281,10 +311,26 @@ def render(ctx: dict[str, object]) -> str:
app_window = 0xB600
slot_size = 0x0800
cmdpack_start, cmdpack_size = cfg["CMDPACK"]
+ cmdpack2_start, cmdpack2_size = cfg["CMDPACK2"]
hidload_start, hidload_size = cfg["HIDLOAD"]
brload_start, brload_size = cfg["BRLOAD"]
regseed_start, regseed_size = cfg["REGSEED"]
- built_in_payload_size = (sym["__OVL2PACK_LOAD__"] - sym["__LOWPACK_LOAD__"]) + seg["OVL2PACK"].size
+ base_builtin_size = (sym["__SPANPACK_LOAD__"] - sym["__LOWPACK_LOAD__"]) + seg["SPANPACK"].size
+ built_in_payload_size = (
+ base_builtin_size
+ + seg["OVL1PACK"].size
+ + seg["OVL2PACK"].size
+ + seg["OVL3PACK"].size
+ + seg["OVL4PACK"].size
+ + seg["OVL5PACK"].size
+ + seg["OVL6PACK"].size
+ )
+ gfxspr_off = const["RB_CODE_GFXSPR_OFF"]
+ inputev_off = const["RB_CODE_INPUTEV_OFF"]
+ gfxpoly_off = const["RB_CODE_GFXPOLY_OFF"]
+ gfxdl_off = const["RB_CODE_GFXDL_OFF"]
+ gfxtile_off = const["RB_CODE_GFXTILE_OFF"]
+ sidcore_off = const["RB_CODE_SIDCORE_OFF"]
ram_blocks = [
Block("Zero page", 0x0000, 0x0100, "system", "C64/BASIC/KERNAL zero page; cc65 ZP is not stomped."),
@@ -295,9 +341,15 @@ def render(ctx: dict[str, object]) -> str:
Block("BASIC sentinel", basic_start - 1, 1, "sentinel", "Must be zero before stored-program RUN."),
Block("BASIC workspace", basic_start, basic_limit - basic_start, "basic", "Program text, variables, arrays, strings, and reclaimed cold-load seed space."),
Block("Under BASIC ROM", 0xA000, 0x2000, "underrom", "Common helper plus three 2K command submodule slots."),
- Block("Bridge and frames", seg["BRIDGE"].start, 0x0600, "bridge", "Bridge through $C1F6, shared frames and buffers through $C5FF."),
- Block("ReadyOS REU metadata", 0xC600, 0x0200, "readyos", "Allocation table and system metadata; not ReadyBASIC scratch."),
- Block("ReadyOS shim ABI", 0xC800, 0x0200, "shim", "Resident jump table/data."),
+ Block(
+ "Bridge and frames",
+ seg["BRIDGE"].start,
+ 0x0600,
+ "bridge",
+ f"Bridge through ${seg['BRIDGE'].end:04X}, shared frames and buffers through $C5FF.",
+ ),
+ Block("ReadyOS shim expansion reserve", 0xC600, 0x0200, "shim", "Resident capacity reserved for future shim functionality; not app RAM."),
+ Block("ReadyOS shim ABI", 0xC800, 0x0200, "shim", "Resident jump table/data; public addresses remain stable."),
Block("High RAM gap", 0xCA00, 0x0600, "reserved", "Outside app snapshot and below I/O."),
Block("I/O / color", 0xD000, 0x1000, "io", "REU registers at $DF00-$DF0A when I/O visible."),
Block("KERNAL ROM", 0xE000, 0x2000, "rom", "Normally visible after banking is restored."),
@@ -306,23 +358,31 @@ def render(ctx: dict[str, object]) -> str:
cold_basic_blocks = [
Block("Sentinel/pad", basic_start - 1, cmdpack_start - (basic_start - 1), "sentinel", "Cold padding before command seed bytes."),
Block("CMDPACK seed window", cmdpack_start, cmdpack_size, "seed", "Built-in module payload seed; prestashed into the assigned code bank before BASIC owns this RAM."),
- Block("HIDLOAD helper seed", hidload_start, seg["HIDDEN"].size, "seed2", "Copied to $A000 and $C280 shadow."),
+ Block("HIDLOAD helper seed", hidload_start, seg["HIDDEN"].size, "seed2", "Copied to $A000 and REU core-bank $3000 shadow."),
Block("HIDLOAD reserved tail", hidload_start + seg["HIDDEN"].size, hidload_size - seg["HIDDEN"].size, "free", "Reserved load window tail."),
Block("BRLOAD bridge seed", brload_start, seg["BRIDGE"].size, "bridge", "Copied to $C000 bridge state."),
Block("BRLOAD reserved tail", brload_start + seg["BRIDGE"].size, brload_size - seg["BRIDGE"].size, "free", "Reserved load window tail."),
Block("REGSEED registry", regseed_start, seg["REGSEED"].size, "registry", "Header plus 128 command descriptors; prestashed into the assigned core bank."),
Block("REGSEED reserved tail", regseed_start + seg["REGSEED"].size, regseed_size - seg["REGSEED"].size, "free", "Reserved load window tail."),
- Block("Future BASIC bytes", regseed_start + regseed_size, basic_limit - (regseed_start + regseed_size), "basic", "Also reclaimed by BASIC after cold setup."),
+ Block("CMDPACK2 overlay seed window", cmdpack2_start, cmdpack2_size, "seed", "Additional built-in overlay payload seed; prestashed into sparse assigned code-bank offsets."),
+ Block("Future BASIC bytes", cmdpack2_start + cmdpack2_size, basic_limit - (cmdpack2_start + cmdpack2_size), "basic", "Also reclaimed by BASIC after cold setup."),
]
cmdpack_blocks = [
Block("Slot 0 payload seed", sym["__LOWPACK_LOAD__"], seg["LOWPACK"].size, "module-a", f"Module 1 system/default payload; runtime {fmt_range(seg['LOWPACK'].start, seg['LOWPACK'].end)}.", groups["slot0"] + groups["end"]),
- Block("Slot 1 payload seed", sym["__SLOTPACK1_LOAD__"], seg["SLOTPACK1"].size, "module-b", f"Module 2 proof and loader payload; runtime {fmt_range(seg['SLOTPACK1'].start, seg['SLOTPACK1'].end)}.", groups["slot1"]),
- Block("Slot 2 base seed", sym["__SLOTPACK2_LOAD__"], seg["SLOTPACK2"].size, "module-c", f"Module 2 slot-2 proof payload; runtime {fmt_range(seg['SLOTPACK2'].start, seg['SLOTPACK2'].end)}.", groups["slot2"]),
+ Block("Slot 1 payload seed", sym["__SLOTPACK1_LOAD__"], seg["SLOTPACK1"].size, "module-b", f"Module 2 proof, loader, and GFXCORE payload; runtime {fmt_range(seg['SLOTPACK1'].start, seg['SLOTPACK1'].end)}.", groups["slot1"] + groups["gfxcore"]),
+ Block("Slot 2 base seed", sym["__SLOTPACK2_LOAD__"], seg["SLOTPACK2"].size, "module-c", f"Module 2 slot-2 proof plus GFXPRIM payload; runtime {fmt_range(seg['SLOTPACK2'].start, seg['SLOTPACK2'].end)}.", groups["slot2"] + groups["gfxprim"]),
Block("Span seed", sym["__SPANPACK_LOAD__"], seg["SPANPACK"].size, "span", f"Two-slot proof payload; runtime {fmt_range(seg['SPANPACK'].start, seg['SPANPACK'].end)}.", groups["span"]),
- Block("Overlay 1 seed", sym["__OVL1PACK_LOAD__"], seg["OVL1PACK"].size, "overlay", f"Slot-2 overlay proof payload; runtime {fmt_range(seg['OVL1PACK'].start, seg['OVL1PACK'].end)}.", ("ZOVL1",)),
- Block("Overlay 2 seed", sym["__OVL2PACK_LOAD__"], seg["OVL2PACK"].size, "overlay", f"Slot-2 overlay proof payload; runtime {fmt_range(seg['OVL2PACK'].start, seg['OVL2PACK'].end)}.", ("ZOVL2",)),
- Block("CMDPACK free seed room", sym["__OVL2PACK_LOAD__"] + seg["OVL2PACK"].size, (cmdpack_start + cmdpack_size) - (sym["__OVL2PACK_LOAD__"] + seg["OVL2PACK"].size), "free", "Unused cold-load seed capacity."),
+ Block("CMDPACK free seed room", sym["__SPANPACK_LOAD__"] + seg["SPANPACK"].size, (cmdpack_start + cmdpack_size) - (sym["__SPANPACK_LOAD__"] + seg["SPANPACK"].size), "free", "Unused cold-load seed capacity."),
+ ]
+ cmdpack2_blocks = [
+ Block("Overlay 1 seed", sym["__OVL1PACK_LOAD__"], seg["OVL1PACK"].size, "overlay", f"Slot-2 replacement overlay; runtime {fmt_range(seg['OVL1PACK'].start, seg['OVL1PACK'].end)}; REU code offset {fmt_hex(gfxspr_off)}.", ("ZOVL1",)),
+ Block("Overlay 2 seed", sym["__OVL2PACK_LOAD__"], seg["OVL2PACK"].size, "overlay", f"Slot-2 replacement overlay; runtime {fmt_range(seg['OVL2PACK'].start, seg['OVL2PACK'].end)}; REU code offset {fmt_hex(inputev_off)}.", ("ZOVL2",)),
+ Block("Overlay 3 seed", sym["__OVL3PACK_LOAD__"], seg["OVL3PACK"].size, "overlay", f"Slot-2 replacement overlay; runtime {fmt_range(seg['OVL3PACK'].start, seg['OVL3PACK'].end)}; REU code offset {fmt_hex(gfxpoly_off)}.", groups["gfxpoly"]),
+ Block("Overlay 4 seed", sym["__OVL4PACK_LOAD__"], seg["OVL4PACK"].size, "overlay", f"Slot-2 replacement overlay; runtime {fmt_range(seg['OVL4PACK'].start, seg['OVL4PACK'].end)}; REU code offset {fmt_hex(gfxdl_off)}.", groups["gfxdl"]),
+ Block("Overlay 5 seed", sym["__OVL5PACK_LOAD__"], seg["OVL5PACK"].size, "overlay", f"Slot-2 replacement overlay; runtime {fmt_range(seg['OVL5PACK'].start, seg['OVL5PACK'].end)}; REU code offset {fmt_hex(gfxtile_off)}.", groups["gfxtile"]),
+ Block("Overlay 6 seed", sym["__OVL6PACK_LOAD__"], seg["OVL6PACK"].size, "overlay", f"Slot-2 replacement overlay; runtime {fmt_range(seg['OVL6PACK'].start, seg['OVL6PACK'].end)}; REU code offset {fmt_hex(sidcore_off)}.", groups["sidcore"]),
+ Block("CMDPACK2 free seed room", sym["__OVL6PACK_LOAD__"] + seg["OVL6PACK"].size, (cmdpack2_start + cmdpack2_size) - (sym["__OVL6PACK_LOAD__"] + seg["OVL6PACK"].size), "free", "Unused cold-load seed capacity."),
]
post_blocks = [
@@ -334,14 +394,25 @@ def render(ctx: dict[str, object]) -> str:
slot0_used = seg["LOWPACK"].size
slot1_used = seg["SLOTPACK1"].size
- slot2_used = seg["OVL2PACK"].end - seg["SLOTPACK2"].start + 1
slot_blocks = [
Block("Slot 0 current", 0xA800, slot0_used, "module-a", "Module 1 system/default payload.", groups["slot0"] + groups["end"]),
Block("Slot 0 free", 0xA800 + slot0_used, slot_size - slot0_used, "free", f"{fmt_size(slot_size - slot0_used)} free inside slot 0."),
- Block("Slot 1 current", 0xB000, slot1_used, "module-b", "Module 2 proof plus ZMODLD.", groups["slot1"]),
+ Block("Slot 1 current", 0xB000, slot1_used, "module-b", "Module 2 proof, ZMODLD, and GFXCORE.", groups["slot1"] + groups["gfxcore"]),
Block("Slot 1 free", 0xB000 + slot1_used, slot_size - slot1_used, "free", f"{fmt_size(slot_size - slot1_used)} free inside slot 1."),
- Block("Slot 2 current front", 0xB800, slot2_used, "module-c", "Base proof plus two overlay proof slices in the slot-2 address space.", groups["slot2"] + groups["overlay"]),
- Block("Slot 2 free", 0xB800 + slot2_used, slot_size - slot2_used, "free", f"{fmt_size(slot_size - slot2_used)} free inside slot 2."),
+ Block("Slot 2 GFXPRIM current", 0xB800, seg["SLOTPACK2"].size, "module-c", "Base proof plus GFXPRIM; replacement overlays load over this when called.", groups["slot2"] + groups["gfxprim"]),
+ Block("Slot 2 GFXPRIM free", 0xB800 + seg["SLOTPACK2"].size, slot_size - seg["SLOTPACK2"].size, "free", f"{fmt_size(slot_size - seg['SLOTPACK2'].size)} free in the GFXPRIM slot image."),
+ Block("Slot 2 GFXSPR overlay", 0xB800, seg["OVL1PACK"].size, "overlay", "Replacement overlay for sprite commands.", groups["overlay"][:1] + groups["gfxspr"]),
+ Block("Slot 2 GFXSPR free", 0xB800 + seg["OVL1PACK"].size, slot_size - seg["OVL1PACK"].size, "free", f"{fmt_size(slot_size - seg['OVL1PACK'].size)} free in the GFXSPR overlay image."),
+ Block("Slot 2 INPUTEV overlay", 0xB800, seg["OVL2PACK"].size, "overlay", "Replacement overlay for polling input commands.", groups["overlay"][1:] + groups["inputev"]),
+ Block("Slot 2 INPUTEV free", 0xB800 + seg["OVL2PACK"].size, slot_size - seg["OVL2PACK"].size, "free", f"{fmt_size(slot_size - seg['OVL2PACK'].size)} free in the INPUTEV overlay image."),
+ Block("Slot 2 GFXPOLY overlay", 0xB800, seg["OVL3PACK"].size, "overlay", "Replacement overlay for polygon and point-buffer commands.", groups["gfxpoly"]),
+ Block("Slot 2 GFXPOLY free", 0xB800 + seg["OVL3PACK"].size, slot_size - seg["OVL3PACK"].size, "free", f"{fmt_size(slot_size - seg['OVL3PACK'].size)} free in the GFXPOLY overlay image."),
+ Block("Slot 2 GFXDL overlay", 0xB800, seg["OVL4PACK"].size, "overlay", "Replacement overlay for retained display-list commands.", groups["gfxdl"]),
+ Block("Slot 2 GFXDL free", 0xB800 + seg["OVL4PACK"].size, slot_size - seg["OVL4PACK"].size, "free", f"{fmt_size(slot_size - seg['OVL4PACK'].size)} free in the GFXDL overlay image."),
+ Block("Slot 2 GFXTILE overlay", 0xB800, seg["OVL5PACK"].size, "overlay", "Replacement overlay for charset, tileset, tilemap, and multicolor-cell commands.", groups["gfxtile"]),
+ Block("Slot 2 GFXTILE free", 0xB800 + seg["OVL5PACK"].size, slot_size - seg["OVL5PACK"].size, "free", f"{fmt_size(slot_size - seg['OVL5PACK'].size)} free in the GFXTILE overlay image."),
+ Block("Slot 2 SIDCORE overlay", 0xB800, seg["OVL6PACK"].size, "overlay", "Replacement overlay for immediate SID sound commands.", groups["sidcore"]),
+ Block("Slot 2 SIDCORE free", 0xB800 + seg["OVL6PACK"].size, slot_size - seg["OVL6PACK"].size, "free", f"{fmt_size(slot_size - seg['OVL6PACK'].size)} free in the SIDCORE overlay image."),
]
reu44_blocks = [
@@ -360,19 +431,30 @@ def render(ctx: dict[str, object]) -> str:
disk_blocks = disk_module_blocks()
reu45_blocks = [
- Block("Built-in payloads", 0x0000, built_in_payload_size, "module-a", "Current built-in module/submodule payload blob prestashed from CMDPACK."),
- Block("Built-in free gap", built_in_payload_size, 0x1500 - built_in_payload_size, "free", "Free before current disk-module descriptor samples."),
+ Block("Built-in base payloads", 0x0000, base_builtin_size, "module-a", "LOWPACK, SLOTPACK1, SLOTPACK2, and SPANPACK prestashed from CMDPACK."),
+ Block("Built-in base free gap", base_builtin_size, 0x1500 - base_builtin_size, "free", "Free before current disk-module descriptor samples."),
*disk_blocks[:2],
Block("Free gap", 0x1660, 0x3000 - 0x1660, "free", "Available packed-code space before sample payloads."),
*disk_blocks[2:],
- Block("Payload bank free tail", 0x463D, 0x10000 - 0x463D, "free", "Remaining space in the current single ReadyBASIC code bank."),
+ Block("Free gap before built-in overlays", 0x463D, gfxspr_off - 0x463D, "free", "Available packed-code space before fixed built-in overlay offsets."),
+ Block("Built-in GFXSPR overlay", gfxspr_off, seg["OVL1PACK"].size, "overlay", "Prestashed from CMDPACK2 and fetched into slot 2 when sprite commands run.", groups["overlay"][:1] + groups["gfxspr"]),
+ Block("GFXSPR reserved headroom", gfxspr_off + seg["OVL1PACK"].size, 0x0800 - seg["OVL1PACK"].size, "free", "Reserved so the overlay can grow toward a full 2K slot without moving INPUTEV."),
+ Block("Built-in INPUTEV overlay", inputev_off, seg["OVL2PACK"].size, "overlay", "Prestashed from CMDPACK2 and fetched into slot 2 when input commands run.", groups["inputev"]),
+ Block("INPUTEV reserved headroom", inputev_off + seg["OVL2PACK"].size, 0x0800 - seg["OVL2PACK"].size, "free", "Reserved so the overlay can grow toward a full 2K slot without moving GFXPOLY."),
+ Block("Built-in GFXPOLY overlay", gfxpoly_off, seg["OVL3PACK"].size, "overlay", "Prestashed from CMDPACK2 and fetched into slot 2 when polygon commands run.", groups["gfxpoly"]),
+ Block("GFXPOLY reserved headroom", gfxpoly_off + seg["OVL3PACK"].size, 0x0800 - seg["OVL3PACK"].size, "free", "Reserved so the overlay can grow toward a full 2K slot without moving GFXDL."),
+ Block("Built-in GFXDL overlay", gfxdl_off, seg["OVL4PACK"].size, "overlay", "Prestashed from CMDPACK2 and fetched into slot 2 when display-list commands run.", groups["gfxdl"]),
+ Block("GFXDL reserved headroom", gfxdl_off + seg["OVL4PACK"].size, 0x0800 - seg["OVL4PACK"].size, "free", "Reserved so the overlay can grow toward a full 2K slot without moving GFXTILE."),
+ Block("Built-in GFXTILE overlay", gfxtile_off, seg["OVL5PACK"].size, "overlay", "Prestashed from CMDPACK2 and fetched into slot 2 when charset/tile commands run.", groups["gfxtile"]),
+ Block("GFXTILE reserved headroom", gfxtile_off + seg["OVL5PACK"].size, 0x0800 - seg["OVL5PACK"].size, "free", "Reserved for charset/tile overlay growth."),
+ Block("Built-in SIDCORE overlay", sidcore_off, seg["OVL6PACK"].size, "overlay", "Prestashed from CMDPACK2 and fetched into slot 2 when sound commands run.", groups["sidcore"]),
+ Block("SIDCORE reserved headroom", sidcore_off + seg["OVL6PACK"].size, 0x0800 - seg["OVL6PACK"].size, "free", "Reserved for immediate sound command growth."),
+ Block("Payload bank free tail", sidcore_off + 0x0800, 0x10000 - (sidcore_off + 0x0800), "free", "Remaining space in the current single ReadyBASIC code bank."),
]
reu_overview_blocks = [
- Block("Launcher/system", 0x000000, 0x010000, "readyos", "Bank 0 logical launcher/system state."),
- Block("App snapshots", 0x020000, 24 * 0x10000, "entry", "Historical low-bank snapshot capacity; current snapshots are launcher-assigned and resolved through logical bank 0."),
- Block("Legacy high-bank gap", 0x430000, 0x60000, "underrom", "No current ReadyOS fixed resource assignment here; ReadyBASIC banks and ReadyShell diagnostics/scratch are no longer fixed in this range."),
- Block("Dynamic resources / free", 0x490000, (reu["REU_TOTAL_BANKS"] - 0x49) * 0x10000, "free", "Remaining 16MB REU space, including launcher-assigned ReadyBASIC core/code resource banks."),
+ Block("ReadyOS bank", 0x000000, 0x010000, "readyos", "Physical Skip: launcher snapshot at $0000-$B5FF plus schema-v5 mappings, status, clipboard, hotkeys, app/resource registry, catalog, audit, and runtime records at $B600-$FFFF."),
+ Block("Dynamic pool", 0x010000, (reu["REU_TOTAL_BANKS"] - 1) * 0x10000, "free", "Physical Skip+1 through the detected end, shared by mapped app snapshots, ReadyBASIC/ReadyShell resources, clipboard payloads, and app-owned allocations. Physical Skip is reserved for ReadyOS."),
]
example_blocks = [
@@ -503,6 +585,7 @@ def render(ctx: dict[str, object]) -> str:
+{banner("current", CURRENT["docs/readybasic_memory_diagrams.html"])}
ReadyBASIC Memory Diagrams
@@ -526,7 +609,7 @@ def render(ctx: dict[str, object]) -> str:
Whole C64 RAM: ReadyOS Contract And ReadyBASIC Runtime
- ReadyOS snapshots app RAM from $1000-$C5FF. ReadyBASIC stays inside that contract, while using RAM behind BASIC ROM for command payloads and loader-assigned REU resource banks for durable runtime state.
+ ReadyOS snapshots app RAM from $1000-$C5FF. The resident 1 KB shim owns $C600-$C9FF, while ReadyBASIC deliberately keeps its custom compact image and bridge shape through $C5FF; its custom assembler/linker contract must remain compatible with this exact shape. Loader-assigned REU resource banks hold durable module state.
{stacked_map(ram_blocks, 0x10000)}
@@ -545,8 +628,11 @@ def render(ctx: dict[str, object]) -> str:
Inside The Cold CMDPACK Seed Window
- This is the built-in command/module payload portion that is prestashed contiguously into the loader-assigned ReadyBASIC payload bank.
+ This is the original built-in command/module payload portion that is prestashed into the loader-assigned ReadyBASIC payload bank.
{stacked_map(cmdpack_blocks, cmdpack_size, cls="short")}
+ Inside The Cold CMDPACK2 Overlay Seed Window
+ This second cold-only seed window carries built-in replacement overlays and is stashed into sparse, fixed REU code offsets before BASIC owns the memory.
+ {stacked_map(cmdpack2_blocks, cmdpack2_size, cls="short")}
@@ -595,11 +681,15 @@ def render(ctx: dict[str, object]) -> str:
Block("RESIDENT", seg["RESIDENT"].start, seg["RESIDENT"].size, "resident", "Visible ReadyBASIC core."),
Block("HIDDEN", seg["HIDDEN"].start, seg["HIDDEN"].size, "underrom", "Common under-ROM helper."),
Block("LOWPACK", seg["LOWPACK"].start, seg["LOWPACK"].size, "module-a", "Slot 0 built-in payload.", groups["slot0"] + groups["end"]),
- Block("SLOTPACK1", seg["SLOTPACK1"].start, seg["SLOTPACK1"].size, "module-b", "Slot 1 proof/loader payload.", groups["slot1"]),
- Block("SLOTPACK2", seg["SLOTPACK2"].start, seg["SLOTPACK2"].size, "module-c", "Slot 2 proof payload.", groups["slot2"]),
+ Block("SLOTPACK1", seg["SLOTPACK1"].start, seg["SLOTPACK1"].size, "module-b", "Slot 1 proof/loader/GFXCORE payload.", groups["slot1"] + groups["gfxcore"]),
+ Block("SLOTPACK2", seg["SLOTPACK2"].start, seg["SLOTPACK2"].size, "module-c", "Slot 2 proof/GFXPRIM payload.", groups["slot2"] + groups["gfxprim"]),
Block("SPANPACK", seg["SPANPACK"].start, seg["SPANPACK"].size, "span", "Two-slot proof payload.", groups["span"]),
- Block("OVL1PACK", seg["OVL1PACK"].start, seg["OVL1PACK"].size, "overlay", "Slot 2 overlay proof.", ("ZOVL1",)),
- Block("OVL2PACK", seg["OVL2PACK"].start, seg["OVL2PACK"].size, "overlay", "Slot 2 overlay proof.", ("ZOVL2",)),
+ Block("OVL1PACK", seg["OVL1PACK"].start, seg["OVL1PACK"].size, "overlay", "Slot 2 replacement overlay for GFXSPR.", groups["overlay"][:1] + groups["gfxspr"]),
+ Block("OVL2PACK", seg["OVL2PACK"].start, seg["OVL2PACK"].size, "overlay", "Slot 2 replacement overlay for INPUTEV.", groups["overlay"][1:] + groups["inputev"]),
+ Block("OVL3PACK", seg["OVL3PACK"].start, seg["OVL3PACK"].size, "overlay", "Slot 2 replacement overlay for GFXPOLY.", groups["gfxpoly"]),
+ Block("OVL4PACK", seg["OVL4PACK"].start, seg["OVL4PACK"].size, "overlay", "Slot 2 replacement overlay for GFXDL.", groups["gfxdl"]),
+ Block("OVL5PACK", seg["OVL5PACK"].start, seg["OVL5PACK"].size, "overlay", "Slot 2 replacement overlay for GFXTILE.", groups["gfxtile"]),
+ Block("OVL6PACK", seg["OVL6PACK"].start, seg["OVL6PACK"].size, "overlay", "Slot 2 replacement overlay for SIDCORE.", groups["sidcore"]),
Block("BRIDGE", seg["BRIDGE"].start, seg["BRIDGE"].size, "bridge", "Persistent bridge state."),
Block("REGSEED", seg["REGSEED"].start, seg["REGSEED"].size, "registry", "Load-only registry seed."),
])}
@@ -625,6 +715,10 @@ def build_context(args: argparse.Namespace) -> dict[str, object]:
"__SPANPACK_LOAD__",
"__OVL1PACK_LOAD__",
"__OVL2PACK_LOAD__",
+ "__OVL3PACK_LOAD__",
+ "__OVL4PACK_LOAD__",
+ "__OVL5PACK_LOAD__",
+ "__OVL6PACK_LOAD__",
},
)
const = parse_asm_constants(args.asm)
diff --git a/build_support/readybasic_module_overlay_probe.generated.yaml b/build_support/readybasic_module_overlay_probe.generated.yaml
index 5d3493e..2f6fb30 100644
--- a/build_support/readybasic_module_overlay_probe.generated.yaml
+++ b/build_support/readybasic_module_overlay_probe.generated.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4r-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4r-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4r-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
@@ -42,7 +42,7 @@ steps:
- id: builtin_overlay_bank_probe
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,70,82,69,69,77,69,77,40,41,13,80,82,73,78,84,32,34,83,76,79,84,83,34,59,90,83,76,79,84,48,40,41,59,34,47,34,59,90,83,76,79,84,49,40,41,59,34,47,34,59,90,83,76,79,84,50,40,41,13,80,82,73,78,84,32,34,83,80,65,78,34,59,90,83,80,65,78,40,41,13,80,82,73,78,84,32,34,79,86,76,34,59,90,79,86,76,49,40,41,59,34,47,34,59,90,79,86,76,50,40,41,13,80,82,73,78,84,32,34,67,80,89,34,59,90,67,80,89,82,83,84,40,41,59,34,47,34,59,90,67,79,80,89,40,41,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,77,69,77,65,86,76,40,41,13,80,82,73,78,84,32,34,83,76,79,84,83,34,59,90,83,76,79,84,48,40,41,59,34,47,34,59,90,83,76,79,84,49,40,41,59,34,47,34,59,90,83,76,79,84,50,40,41,13,80,82,73,78,84,32,34,83,80,65,78,34,59,90,83,80,65,78,40,41,13,80,82,73,78,84,32,34,79,86,76,34,59,90,79,86,76,49,40,41,59,34,47,34,59,90,79,86,76,50,40,41,13,80,82,73,78,84,32,34,67,80,89,34,59,90,67,80,89,82,83,84,40,41,59,34,47,34,59,90,67,79,80,89,40,41,13]
inter_key_delay_s: 0.03
post_delay_s: 1.5
- id: capture_builtin_overlay_bank_probe
@@ -104,7 +104,7 @@ steps:
- id: rbm_sample3_probe
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,82,66,77,51,32,70,73,82,83,84,32,67,65,76,76,83,58,32,69,65,67,72,32,79,86,69,82,76,65,89,32,83,84,65,84,69,32,83,84,65,82,84,83,32,65,84,32,90,69,82,79,32,65,70,84,69,82,32,76,79,65,68,13,80,82,73,78,84,32,34,77,51,65,34,59,90,83,65,65,40,41,59,34,47,34,59,90,83,69,66,40,41,13,80,82,73,78,84,32,34,77,51,66,34,59,90,84,65,65,40,41,59,34,47,34,59,90,84,69,66,40,41,13,80,82,73,78,84,32,34,77,51,67,34,59,90,85,65,65,40,41,59,34,47,34,59,90,85,69,66,40,41,13,70,82,69,69,77,69,77,40,41,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,69,77,32,82,66,77,51,32,70,73,82,83,84,32,67,65,76,76,83,58,32,69,65,67,72,32,79,86,69,82,76,65,89,32,83,84,65,84,69,32,83,84,65,82,84,83,32,65,84,32,90,69,82,79,32,65,70,84,69,82,32,76,79,65,68,13,80,82,73,78,84,32,34,77,51,65,34,59,90,83,65,65,40,41,59,34,47,34,59,90,83,69,66,40,41,13,80,82,73,78,84,32,34,77,51,66,34,59,90,84,65,65,40,41,59,34,47,34,59,90,84,69,66,40,41,13,80,82,73,78,84,32,34,77,51,67,34,59,90,85,65,65,40,41,59,34,47,34,59,90,85,69,66,40,41,13,77,69,77,65,86,76,40,41,13]
inter_key_delay_s: 0.03
post_delay_s: 2.0
- id: capture_rbm_sample3
diff --git a/build_support/readybasic_plugin_command_probe.generated.yaml b/build_support/readybasic_plugin_command_probe.generated.yaml
index 0e1a3f0..e146411 100644
--- a/build_support/readybasic_plugin_command_probe.generated.yaml
+++ b/build_support/readybasic_plugin_command_probe.generated.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4s-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4s-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4s-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
@@ -51,7 +51,7 @@ steps:
- { label: hidden_visible_a000, start: 0xA000, end: 0xA5FF }
- { label: hidden_overlay_a800, start: 0xA800, end: 0xA8FF }
- { label: bridge_c000, start: 0xC000, end: 0xC5FF }
- - { label: reu_alloc_table_c600, start: 0xC600, end: 0xC6FF }
+ - { label: shim_resident_c600, start: 0xC600, end: 0xC9FF }
- id: probe_01_ping
type: input.sequence
@@ -179,17 +179,17 @@ steps:
params:
contains: "RANGE 7 10"
- - id: probe_08_bufnew
+ - id: probe_08_bufmake
type: input.sequence
params:
- keys: [72,37,61,66,85,70,78,69,87,40,51,48,48,41,13,80,82,73,78,84,32,34,66,85,70,78,69,87,34,59,72,37,59,34,58,69,78,68,34,13]
+ keys: [72,37,61,66,85,70,77,65,75,69,40,51,48,48,41,13,80,82,73,78,84,32,34,66,85,70,77,65,75,69,34,59,72,37,59,34,58,69,78,68,34,13]
inter_key_delay_s: 0.03
post_delay_s: 0.8
- - id: assert_08_bufnew
+ - id: assert_08_bufmake
type: assert.screen
params:
- contains: "BUFNEW 1 :END"
- - id: dump_08_bufnew
+ contains: "BUFMAKE 1 :END"
+ - id: dump_08_bufmake
type: dump.memory_ranges
params:
ranges: *plugin_ranges
@@ -209,17 +209,17 @@ steps:
params:
not_contains: "?RB ERROR"
- - id: probe_10_buffree
+ - id: probe_10_bufdrop
type: input.sequence
params:
- keys: [66,85,70,70,82,69,69,40,72,37,41,13,80,82,73,78,84,32,34,70,82,69,69,32,79,75,34,13]
+ keys: [66,85,70,68,82,79,80,40,72,37,41,13,80,82,73,78,84,32,34,70,82,69,69,32,79,75,34,13]
inter_key_delay_s: 0.03
post_delay_s: 0.8
- - id: assert_10_buffree
+ - id: assert_10_bufdrop
type: assert.screen
params:
contains: "FREE OK"
- - id: assert_10_buffree_no_error
+ - id: assert_10_bufdrop_no_error
type: assert.screen_not_contains
params:
not_contains: "?RB ERROR"
@@ -248,24 +248,24 @@ steps:
type: assert.screen
params:
contains: "?RB ERROR 40"
- - id: probe_10c_buffree_screen_handle
+ - id: probe_10c_bufdrop_screen_handle
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,70,82,69,69,40,83,37,41,13,80,82,73,78,84,32,34,83,67,82,70,82,69,69,34,59,83,37,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,68,82,79,80,40,83,37,41,13,80,82,73,78,84,32,34,83,67,82,70,82,69,69,34,59,83,37,13]
inter_key_delay_s: 0.03
post_delay_s: 0.8
- - id: assert_10c_buffree_screen_handle
+ - id: assert_10c_bufdrop_screen_handle
type: assert.screen
params:
contains: "SCRFREE 1"
- - id: assert_10c_buffree_screen_no_error
+ - id: assert_10c_bufdrop_screen_no_error
type: assert.screen_not_contains
params:
not_contains: "?RB ERROR"
- id: probe_10d_scrput_rejects_buffer_handle
type: input.sequence
params:
- keys: [66,37,61,66,85,70,78,69,87,40,51,48,48,41,13,83,67,82,80,85,84,40,66,37,41,13]
+ keys: [66,37,61,66,85,70,77,65,75,69,40,51,48,48,41,13,83,67,82,80,85,84,40,66,37,41,13]
inter_key_delay_s: 0.03
post_delay_s: 0.8
- id: assert_10d_scrput_rejects_buffer_handle
@@ -275,7 +275,7 @@ steps:
- id: probe_10e_free_buffer_after_type_error
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,70,82,69,69,40,66,37,41,13,80,82,73,78,84,32,34,66,85,70,82,69,69,34,59,66,37,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,68,82,79,80,40,66,37,41,13,80,82,73,78,84,32,34,66,85,70,82,69,69,34,59,66,37,13]
inter_key_delay_s: 0.03
post_delay_s: 0.8
- id: assert_10e_free_buffer_after_type_error
@@ -290,7 +290,7 @@ steps:
- id: probe_10f_allocate_128_handles
type: input.sequence
params:
- keys: [78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,72,37,61,66,85,70,78,69,87,40,49,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,72,77,65,88,34,59,72,37,13,82,85,78,13]
+ keys: [78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,72,37,61,66,85,70,77,65,75,69,40,49,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,72,77,65,88,34,59,72,37,13,82,85,78,13]
inter_key_delay_s: 0.03
post_delay_s: 4.0
- id: assert_10f_allocate_128_handles
@@ -305,7 +305,7 @@ steps:
- id: probe_10g_handle_129_rejected
type: input.sequence
params:
- keys: [69,37,61,66,85,70,78,69,87,40,49,41,13]
+ keys: [69,37,61,66,85,70,77,65,75,69,40,49,41,13]
inter_key_delay_s: 0.03
post_delay_s: 0.8
- id: assert_10g_handle_129_rejected
@@ -316,7 +316,7 @@ steps:
- id: probe_10h_free_128_handles
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,66,85,70,70,82,69,69,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,72,70,82,69,69,68,34,13,82,85,78,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,49,50,56,13,50,48,32,66,85,70,68,82,79,80,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,72,70,82,69,69,68,34,13,82,85,78,13]
inter_key_delay_s: 0.03
post_delay_s: 4.0
- id: assert_10h_free_128_handles
@@ -331,7 +331,7 @@ steps:
- id: probe_10i_reuse_low_handle
type: input.sequence
params:
- keys: [82,37,61,66,85,70,78,69,87,40,49,41,13,80,82,73,78,84,32,34,72,82,69,85,83,69,34,59,82,37,13,66,85,70,70,82,69,69,40,82,37,41,13]
+ keys: [82,37,61,66,85,70,77,65,75,69,40,49,41,13,80,82,73,78,84,32,34,72,82,69,85,83,69,34,59,82,37,13,66,85,70,68,82,79,80,40,82,37,41,13]
inter_key_delay_s: 0.03
post_delay_s: 0.8
- id: assert_10i_reuse_low_handle
@@ -346,7 +346,7 @@ steps:
- id: probe_10j_allocate_48k_heap
type: input.sequence
params:
- keys: [77,37,61,66,85,70,78,69,87,40,52,57,49,53,50,41,13,80,82,73,78,84,32,34,72,77,65,88,66,85,70,34,59,77,37,13]
+ keys: [77,37,61,66,85,70,77,65,75,69,40,52,57,49,53,50,41,13,80,82,73,78,84,32,34,72,77,65,88,66,85,70,34,59,77,37,13]
inter_key_delay_s: 0.03
post_delay_s: 1.0
- id: assert_10j_allocate_48k_heap
@@ -361,7 +361,7 @@ steps:
- id: probe_10k_heap_full_rejected
type: input.sequence
params:
- keys: [69,37,61,66,85,70,78,69,87,40,49,41,13]
+ keys: [69,37,61,66,85,70,77,65,75,69,40,49,41,13]
inter_key_delay_s: 0.03
post_delay_s: 0.8
- id: assert_10k_heap_full_rejected
@@ -372,7 +372,7 @@ steps:
- id: probe_10l_free_48k_heap
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,70,82,69,69,40,77,37,41,13,80,82,73,78,84,32,34,72,77,65,88,70,82,69,69,34,59,77,37,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,66,85,70,68,82,79,80,40,77,37,41,13,80,82,73,78,84,32,34,72,77,65,88,70,82,69,69,34,59,77,37,13]
inter_key_delay_s: 0.03
post_delay_s: 0.8
- id: assert_10l_free_48k_heap
@@ -413,7 +413,7 @@ steps:
- id: probe_10o_free_screen_handles
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,50,52,13,50,48,32,66,85,70,70,82,69,69,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,83,70,82,69,69,68,34,13,82,85,78,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,70,79,82,32,73,61,49,32,84,79,32,50,52,13,50,48,32,66,85,70,68,82,79,80,40,73,41,13,51,48,32,78,69,88,84,32,73,13,52,48,32,80,82,73,78,84,32,34,83,70,82,69,69,68,34,13,82,85,78,13]
inter_key_delay_s: 0.03
post_delay_s: 4.0
- id: assert_10o_free_screen_handles
@@ -611,9 +611,20 @@ steps:
- id: resume_after_exit
type: input.sequence
params:
- keys: [145,17,13]
+ keys: [145,17]
inter_key_delay_s: 0.10
- post_delay_s: 3.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_plugin_resume
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ # Use VICE's text-monitor keyboard buffer for the post-EXIT RETURN; the
+ # binary-monitor input helper can otherwise drop this lone key.
+ - id: launch_readybasic_after_plugin_exit
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_resume
type: screen.wait_contains
params:
diff --git a/build_support/readybasic_program_probe.generated.yaml b/build_support/readybasic_program_probe.generated.yaml
index d9694b5..e9d0dc8 100644
--- a/build_support/readybasic_program_probe.generated.yaml
+++ b/build_support/readybasic_program_probe.generated.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4t-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4t-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4t-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
@@ -182,7 +182,7 @@ steps:
- id: program_handle_lifecycle_run
type: input.sequence
params:
- keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,72,37,61,66,85,70,78,69,87,40,51,48,48,41,13,50,48,32,80,82,73,78,84,32,34,80,82,66,85,70,34,59,72,37,13,51,48,32,66,85,70,70,73,76,76,40,72,37,44,49,55,48,41,13,52,48,32,66,85,70,70,82,69,69,40,72,37,41,13,53,48,32,80,82,73,78,84,32,34,80,82,70,82,69,69,34,59,72,37,13,82,85,78,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,78,69,87,13,49,48,32,72,37,61,66,85,70,77,65,75,69,40,51,48,48,41,13,50,48,32,80,82,73,78,84,32,34,80,82,66,85,70,34,59,72,37,13,51,48,32,66,85,70,70,73,76,76,40,72,37,44,49,55,48,41,13,52,48,32,66,85,70,68,82,79,80,40,72,37,41,13,53,48,32,80,82,73,78,84,32,34,80,82,70,82,69,69,34,59,72,37,13,82,85,78,13]
inter_key_delay_s: 0.03
post_delay_s: 1.5
- id: assert_program_handle_new
diff --git a/build_support/readybasic_rbtest1_probe.generated.yaml b/build_support/readybasic_rbtest1_probe.generated.yaml
index 357a47a..c66883a 100644
--- a/build_support/readybasic_rbtest1_probe.generated.yaml
+++ b/build_support/readybasic_rbtest1_probe.generated.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4u-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4u-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4u-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
diff --git a/build_support/readybasic_readyos_loaded_apps_suite.generated.yaml b/build_support/readybasic_readyos_loaded_apps_suite.generated.yaml
new file mode 100644
index 0000000..a043639
--- /dev/null
+++ b/build_support/readybasic_readyos_loaded_apps_suite.generated.yaml
@@ -0,0 +1,1105 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_readyos_loaded_apps_suite
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 1
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_readyos_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_loaded_by_readyos
+ type: screen.wait_contains
+ params:
+ text: "FREE:"
+ wait_timeout_s: 180
+ capture_on_success: true
+ capture_label: readyos_loaded_readybasic_prompt
+ - id: assert_readybasic_banner
+ type: assert.screen
+ params:
+ contains: "READYBASIC"
+ - id: clear_before_rbtest1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: load_rbtest1
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,84,69,83,84,49,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.2
+ - id: capture_loaded_rbtest1
+ type: screen.capture
+ params:
+ label: readybasic_loaded_rbtest1
+ pitch: "ReadyOS-loaded ReadyBASIC after LOAD RBTEST1"
+ - id: list_rbtest1
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_list_rbtest1
+ type: screen.capture
+ params:
+ label: readybasic_list_rbtest1
+ - id: assert_list_rbtest1
+ type: assert.screen
+ params:
+ contains: "10 ZECHO1"
+ - id: run_rbtest1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: capture_run_rbtest1
+ type: screen.capture
+ params:
+ label: readybasic_run_rbtest1
+ pitch: "RUN RBTEST1 from inside ReadyBASIC under ReadyOS"
+ - id: assert_run_rbtest1
+ type: assert.screen
+ params:
+ contains: "EXPRSTRREADY"
+ - id: assert_no_error_rbtest1
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
+ - id: clear_before_rbproc1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: load_rbproc1
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,80,82,79,67,49,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.2
+ - id: capture_loaded_rbproc1
+ type: screen.capture
+ params:
+ label: readybasic_loaded_rbproc1
+ pitch: "ReadyOS-loaded ReadyBASIC after LOAD RBPROC1"
+ - id: list_rbproc1
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_list_rbproc1
+ type: screen.capture
+ params:
+ label: readybasic_list_rbproc1
+ - id: assert_list_rbproc1
+ type: assert.screen
+ params:
+ contains: "2220 ENDP"
+ - id: run_rbproc1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 4.0
+ - id: capture_run_rbproc1
+ type: screen.capture
+ params:
+ label: readybasic_run_rbproc1
+ pitch: "RUN RBPROC1 from inside ReadyBASIC under ReadyOS"
+ - id: assert_run_rbproc1
+ type: assert.screen
+ params:
+ contains: "NGS MIX"
+ - id: assert_no_error_rbproc1
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
+ - id: clear_before_rbgfx01
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: load_rbgfx01
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,48,49,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.2
+ - id: capture_loaded_rbgfx01
+ type: screen.capture
+ params:
+ label: readybasic_loaded_rbgfx01
+ pitch: "ReadyOS-loaded ReadyBASIC after LOAD RBGFX01"
+ - id: list_rbgfx01
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_list_rbgfx01
+ type: screen.capture
+ params:
+ label: readybasic_list_rbgfx01
+ - id: assert_list_rbgfx01
+ type: assert.screen
+ params:
+ contains: "RBGFX01 MODES"
+ - id: run_rbgfx01
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: capture_graphics_rbgfx01
+ type: screen.capture
+ params:
+ label: readybasic_graphics_rbgfx01
+ pitch: "Graphics screenshot after RUN RBGFX01 from inside ReadyBASIC under ReadyOS"
+ - id: restore_text_rbgfx01
+ type: input.sequence
+ params:
+ keys: [58,58,71,70,88,84,69,88,84,40,41,58,80,82,73,78,84,32,34,82,66,71,70,88,48,49,32,67,79,77,80,76,69,84,69,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_restored_rbgfx01
+ type: screen.capture
+ params:
+ label: readybasic_restored_rbgfx01
+ - id: assert_complete_rbgfx01
+ type: assert.screen
+ params:
+ contains: "RBGFX01 COMPLETE"
+ - id: assert_no_error_rbgfx01
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
+ - id: clear_before_rbgfx02
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: load_rbgfx02
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,48,50,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.2
+ - id: capture_loaded_rbgfx02
+ type: screen.capture
+ params:
+ label: readybasic_loaded_rbgfx02
+ pitch: "ReadyOS-loaded ReadyBASIC after LOAD RBGFX02"
+ - id: list_rbgfx02
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_list_rbgfx02
+ type: screen.capture
+ params:
+ label: readybasic_list_rbgfx02
+ - id: assert_list_rbgfx02
+ type: assert.screen
+ params:
+ contains: "RBGFX02 HIRES PLOT"
+ - id: run_rbgfx02
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: capture_graphics_rbgfx02
+ type: screen.capture
+ params:
+ label: readybasic_graphics_rbgfx02
+ pitch: "Graphics screenshot after RUN RBGFX02 from inside ReadyBASIC under ReadyOS"
+ - id: restore_text_rbgfx02
+ type: input.sequence
+ params:
+ keys: [58,58,71,70,88,84,69,88,84,40,41,58,80,82,73,78,84,32,34,82,66,71,70,88,48,50,32,67,79,77,80,76,69,84,69,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_restored_rbgfx02
+ type: screen.capture
+ params:
+ label: readybasic_restored_rbgfx02
+ - id: assert_complete_rbgfx02
+ type: assert.screen
+ params:
+ contains: "RBGFX02 COMPLETE"
+ - id: assert_no_error_rbgfx02
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
+ - id: clear_before_rbgfx03
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: load_rbgfx03
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,48,51,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.2
+ - id: capture_loaded_rbgfx03
+ type: screen.capture
+ params:
+ label: readybasic_loaded_rbgfx03
+ pitch: "ReadyOS-loaded ReadyBASIC after LOAD RBGFX03"
+ - id: list_rbgfx03
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_list_rbgfx03
+ type: screen.capture
+ params:
+ label: readybasic_list_rbgfx03
+ - id: assert_list_rbgfx03
+ type: assert.screen
+ params:
+ contains: "RBGFX03 HIRES LINES"
+ - id: run_rbgfx03
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: capture_graphics_rbgfx03
+ type: screen.capture
+ params:
+ label: readybasic_graphics_rbgfx03
+ pitch: "Graphics screenshot after RUN RBGFX03 from inside ReadyBASIC under ReadyOS"
+ - id: restore_text_rbgfx03
+ type: input.sequence
+ params:
+ keys: [58,58,71,70,88,84,69,88,84,40,41,58,80,82,73,78,84,32,34,82,66,71,70,88,48,51,32,67,79,77,80,76,69,84,69,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_restored_rbgfx03
+ type: screen.capture
+ params:
+ label: readybasic_restored_rbgfx03
+ - id: assert_complete_rbgfx03
+ type: assert.screen
+ params:
+ contains: "RBGFX03 COMPLETE"
+ - id: assert_no_error_rbgfx03
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
+ - id: clear_before_rbgfx04
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: load_rbgfx04
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,48,52,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.2
+ - id: capture_loaded_rbgfx04
+ type: screen.capture
+ params:
+ label: readybasic_loaded_rbgfx04
+ pitch: "ReadyOS-loaded ReadyBASIC after LOAD RBGFX04"
+ - id: list_rbgfx04
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_list_rbgfx04
+ type: screen.capture
+ params:
+ label: readybasic_list_rbgfx04
+ - id: assert_list_rbgfx04
+ type: assert.screen
+ params:
+ contains: "RBGFX04 RECTS"
+ - id: run_rbgfx04
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: capture_graphics_rbgfx04
+ type: screen.capture
+ params:
+ label: readybasic_graphics_rbgfx04
+ pitch: "Graphics screenshot after RUN RBGFX04 from inside ReadyBASIC under ReadyOS"
+ - id: restore_text_rbgfx04
+ type: input.sequence
+ params:
+ keys: [58,58,71,70,88,84,69,88,84,40,41,58,80,82,73,78,84,32,34,82,66,71,70,88,48,52,32,67,79,77,80,76,69,84,69,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_restored_rbgfx04
+ type: screen.capture
+ params:
+ label: readybasic_restored_rbgfx04
+ - id: assert_complete_rbgfx04
+ type: assert.screen
+ params:
+ contains: "RBGFX04 COMPLETE"
+ - id: assert_no_error_rbgfx04
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
+ - id: clear_before_rbgfx05
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: load_rbgfx05
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,48,53,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.2
+ - id: capture_loaded_rbgfx05
+ type: screen.capture
+ params:
+ label: readybasic_loaded_rbgfx05
+ pitch: "ReadyOS-loaded ReadyBASIC after LOAD RBGFX05"
+ - id: list_rbgfx05
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_list_rbgfx05
+ type: screen.capture
+ params:
+ label: readybasic_list_rbgfx05
+ - id: assert_list_rbgfx05
+ type: assert.screen
+ params:
+ contains: "RBGFX05 PNT READ"
+ - id: run_rbgfx05
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: capture_graphics_rbgfx05
+ type: screen.capture
+ params:
+ label: readybasic_graphics_rbgfx05
+ pitch: "Graphics screenshot after RUN RBGFX05 from inside ReadyBASIC under ReadyOS"
+ - id: restore_text_rbgfx05
+ type: input.sequence
+ params:
+ keys: [58,58,71,70,88,84,69,88,84,40,41,58,80,82,73,78,84,32,34,82,66,71,70,88,48,53,32,67,79,77,80,76,69,84,69,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_restored_rbgfx05
+ type: screen.capture
+ params:
+ label: readybasic_restored_rbgfx05
+ - id: assert_complete_rbgfx05
+ type: assert.screen
+ params:
+ contains: "RBGFX05 COMPLETE"
+ - id: assert_no_error_rbgfx05
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
+ - id: clear_before_rbgfx06
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: load_rbgfx06
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,48,54,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.2
+ - id: capture_loaded_rbgfx06
+ type: screen.capture
+ params:
+ label: readybasic_loaded_rbgfx06
+ pitch: "ReadyOS-loaded ReadyBASIC after LOAD RBGFX06"
+ - id: list_rbgfx06
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_list_rbgfx06
+ type: screen.capture
+ params:
+ label: readybasic_list_rbgfx06
+ - id: assert_list_rbgfx06
+ type: assert.screen
+ params:
+ contains: "RBGFX06 REU SURFACE"
+ - id: run_rbgfx06
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: capture_graphics_rbgfx06
+ type: screen.capture
+ params:
+ label: readybasic_graphics_rbgfx06
+ pitch: "Graphics screenshot after RUN RBGFX06 from inside ReadyBASIC under ReadyOS"
+ - id: restore_text_rbgfx06
+ type: input.sequence
+ params:
+ keys: [58,58,71,70,88,84,69,88,84,40,41,58,80,82,73,78,84,32,34,82,66,71,70,88,48,54,32,67,79,77,80,76,69,84,69,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_restored_rbgfx06
+ type: screen.capture
+ params:
+ label: readybasic_restored_rbgfx06
+ - id: assert_complete_rbgfx06
+ type: assert.screen
+ params:
+ contains: "RBGFX06 COMPLETE"
+ - id: assert_no_error_rbgfx06
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
+ - id: clear_before_rbgfx07
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: load_rbgfx07
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,48,55,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.2
+ - id: capture_loaded_rbgfx07
+ type: screen.capture
+ params:
+ label: readybasic_loaded_rbgfx07
+ pitch: "ReadyOS-loaded ReadyBASIC after LOAD RBGFX07"
+ - id: list_rbgfx07
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_list_rbgfx07
+ type: screen.capture
+ params:
+ label: readybasic_list_rbgfx07
+ - id: assert_list_rbgfx07
+ type: assert.screen
+ params:
+ contains: "RBGFX07 MBITMAP"
+ - id: run_rbgfx07
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: capture_graphics_rbgfx07
+ type: screen.capture
+ params:
+ label: readybasic_graphics_rbgfx07
+ pitch: "Graphics screenshot after RUN RBGFX07 from inside ReadyBASIC under ReadyOS"
+ - id: restore_text_rbgfx07
+ type: input.sequence
+ params:
+ keys: [58,58,71,70,88,84,69,88,84,40,41,58,80,82,73,78,84,32,34,82,66,71,70,88,48,55,32,67,79,77,80,76,69,84,69,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_restored_rbgfx07
+ type: screen.capture
+ params:
+ label: readybasic_restored_rbgfx07
+ - id: assert_complete_rbgfx07
+ type: assert.screen
+ params:
+ contains: "RBGFX07 COMPLETE"
+ - id: assert_no_error_rbgfx07
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
+ - id: clear_before_rbgfx08
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: load_rbgfx08
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,48,56,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.2
+ - id: capture_loaded_rbgfx08
+ type: screen.capture
+ params:
+ label: readybasic_loaded_rbgfx08
+ pitch: "ReadyOS-loaded ReadyBASIC after LOAD RBGFX08"
+ - id: list_rbgfx08
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_list_rbgfx08
+ type: screen.capture
+ params:
+ label: readybasic_list_rbgfx08
+ - id: assert_list_rbgfx08
+ type: assert.screen
+ params:
+ contains: "RBGFX08 TILE"
+ - id: run_rbgfx08
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: capture_graphics_rbgfx08
+ type: screen.capture
+ params:
+ label: readybasic_graphics_rbgfx08
+ pitch: "Graphics screenshot after RUN RBGFX08 from inside ReadyBASIC under ReadyOS"
+ - id: restore_text_rbgfx08
+ type: input.sequence
+ params:
+ keys: [58,58,71,70,88,84,69,88,84,40,41,58,80,82,73,78,84,32,34,82,66,71,70,88,48,56,32,67,79,77,80,76,69,84,69,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_restored_rbgfx08
+ type: screen.capture
+ params:
+ label: readybasic_restored_rbgfx08
+ - id: assert_complete_rbgfx08
+ type: assert.screen
+ params:
+ contains: "RBGFX08 COMPLETE"
+ - id: assert_no_error_rbgfx08
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
+ - id: clear_before_rbgfx09
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: load_rbgfx09
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,48,57,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.2
+ - id: capture_loaded_rbgfx09
+ type: screen.capture
+ params:
+ label: readybasic_loaded_rbgfx09
+ pitch: "ReadyOS-loaded ReadyBASIC after LOAD RBGFX09"
+ - id: list_rbgfx09
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_list_rbgfx09
+ type: screen.capture
+ params:
+ label: readybasic_list_rbgfx09
+ - id: assert_list_rbgfx09
+ type: assert.screen
+ params:
+ contains: "RBGFX09 SPRITES"
+ - id: run_rbgfx09
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_graphics_rbgfx09
+ type: screen.capture
+ params:
+ label: readybasic_graphics_rbgfx09
+ pitch: "Graphics screenshot after RUN RBGFX09 from inside ReadyBASIC under ReadyOS"
+ - id: wait_complete_rbgfx09
+ type: screen.wait_contains
+ params:
+ text: "RBGFX09 COMPLETE"
+ wait_timeout_s: 10
+ - id: capture_restored_rbgfx09
+ type: screen.capture
+ params:
+ label: readybasic_restored_rbgfx09
+ - id: assert_complete_rbgfx09
+ type: assert.screen
+ params:
+ contains: "RBGFX09 COMPLETE"
+ - id: assert_no_error_rbgfx09
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
+ - id: clear_before_rbgfx10
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: load_rbgfx10
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,49,48,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.2
+ - id: capture_loaded_rbgfx10
+ type: screen.capture
+ params:
+ label: readybasic_loaded_rbgfx10
+ pitch: "ReadyOS-loaded ReadyBASIC after LOAD RBGFX10"
+ - id: list_rbgfx10
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_list_rbgfx10
+ type: screen.capture
+ params:
+ label: readybasic_list_rbgfx10
+ - id: assert_list_rbgfx10
+ type: assert.screen
+ params:
+ contains: "RBGFX10 COLLISION"
+ - id: run_rbgfx10
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.5
+ - id: capture_graphics_rbgfx10
+ type: screen.capture
+ params:
+ label: readybasic_graphics_rbgfx10
+ pitch: "Graphics screenshot after RUN RBGFX10 from inside ReadyBASIC under ReadyOS"
+ - id: restore_text_rbgfx10
+ type: input.sequence
+ params:
+ keys: [58,58,71,70,88,84,69,88,84,40,41,58,80,82,73,78,84,32,34,82,66,71,70,88,49,48,32,67,79,77,80,76,69,84,69,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_restored_rbgfx10
+ type: screen.capture
+ params:
+ label: readybasic_restored_rbgfx10
+ - id: assert_complete_rbgfx10
+ type: assert.screen
+ params:
+ contains: "RBGFX10 COMPLETE"
+ - id: assert_no_error_rbgfx10
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
+ - id: clear_before_rbgfx11
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: load_rbgfx11
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,49,49,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.2
+ - id: capture_loaded_rbgfx11
+ type: screen.capture
+ params:
+ label: readybasic_loaded_rbgfx11
+ pitch: "ReadyOS-loaded ReadyBASIC after LOAD RBGFX11"
+ - id: list_rbgfx11
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_list_rbgfx11
+ type: screen.capture
+ params:
+ label: readybasic_list_rbgfx11
+ - id: assert_list_rbgfx11
+ type: assert.screen
+ params:
+ contains: "RBGFX11 INPUT"
+ - id: run_rbgfx11
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 4.0
+ - id: capture_graphics_rbgfx11
+ type: screen.capture
+ params:
+ label: readybasic_graphics_rbgfx11
+ pitch: "Graphics screenshot after RUN RBGFX11 from inside ReadyBASIC under ReadyOS"
+ - id: restore_text_rbgfx11
+ type: input.sequence
+ params:
+ keys: [58,58,71,70,88,84,69,88,84,40,41,58,80,82,73,78,84,32,34,82,66,71,70,88,49,49,32,67,79,77,80,76,69,84,69,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_restored_rbgfx11
+ type: screen.capture
+ params:
+ label: readybasic_restored_rbgfx11
+ - id: assert_complete_rbgfx11
+ type: assert.screen
+ params:
+ contains: "RBGFX11 COMPLETE"
+ - id: assert_no_error_rbgfx11
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
+ - id: clear_before_rbgfx12
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: load_rbgfx12
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,49,50,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.2
+ - id: capture_loaded_rbgfx12
+ type: screen.capture
+ params:
+ label: readybasic_loaded_rbgfx12
+ pitch: "ReadyOS-loaded ReadyBASIC after LOAD RBGFX12"
+ - id: list_rbgfx12
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_list_rbgfx12
+ type: screen.capture
+ params:
+ label: readybasic_list_rbgfx12
+ - id: assert_list_rbgfx12
+ type: assert.screen
+ params:
+ contains: "RBGFX12 SHOWCASE"
+ - id: run_rbgfx12
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: capture_graphics_rbgfx12
+ type: screen.capture
+ params:
+ label: readybasic_graphics_rbgfx12
+ pitch: "Graphics screenshot after RUN RBGFX12 from inside ReadyBASIC under ReadyOS"
+ - id: restore_text_rbgfx12
+ type: input.sequence
+ params:
+ keys: [58,58,71,70,88,84,69,88,84,40,41,58,80,82,73,78,84,32,34,82,66,71,70,88,49,50,32,67,79,77,80,76,69,84,69,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_restored_rbgfx12
+ type: screen.capture
+ params:
+ label: readybasic_restored_rbgfx12
+ - id: assert_complete_rbgfx12
+ type: assert.screen
+ params:
+ contains: "RBGFX12 COMPLETE"
+ - id: assert_no_error_rbgfx12
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
+ - id: clear_before_rbgfx17
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: load_rbgfx17
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,49,55,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.2
+ - id: capture_loaded_rbgfx17
+ type: screen.capture
+ params:
+ label: readybasic_loaded_rbgfx17
+ pitch: "ReadyOS-loaded ReadyBASIC after LOAD RBGFX17"
+ - id: list_rbgfx17
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_list_rbgfx17
+ type: screen.capture
+ params:
+ label: readybasic_list_rbgfx17
+ - id: assert_list_rbgfx17
+ type: assert.screen
+ params:
+ contains: "DEMO 17"
+ - id: run_rbgfx17
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: capture_graphics_rbgfx17
+ type: screen.capture
+ params:
+ label: readybasic_graphics_rbgfx17
+ pitch: "Graphics screenshot after RUN RBGFX17 from inside ReadyBASIC under ReadyOS"
+ - id: restore_text_rbgfx17
+ type: input.sequence
+ params:
+ keys: [58,58,71,70,88,84,69,88,84,40,41,58,80,82,73,78,84,32,34,82,66,71,70,88,49,55,32,67,79,77,80,76,69,84,69,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_restored_rbgfx17
+ type: screen.capture
+ params:
+ label: readybasic_restored_rbgfx17
+ - id: assert_complete_rbgfx17
+ type: assert.screen
+ params:
+ contains: "RBGFX17 COMPLETE"
+ - id: assert_no_error_rbgfx17
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
+ - id: clear_before_rbgfx18
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: load_rbgfx18
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,49,56,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.2
+ - id: capture_loaded_rbgfx18
+ type: screen.capture
+ params:
+ label: readybasic_loaded_rbgfx18
+ pitch: "ReadyOS-loaded ReadyBASIC after LOAD RBGFX18"
+ - id: list_rbgfx18
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_list_rbgfx18
+ type: screen.capture
+ params:
+ label: readybasic_list_rbgfx18
+ - id: assert_list_rbgfx18
+ type: assert.screen
+ params:
+ contains: "DEMO 18"
+ - id: run_rbgfx18
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: capture_graphics_rbgfx18
+ type: screen.capture
+ params:
+ label: readybasic_graphics_rbgfx18
+ pitch: "Graphics screenshot after RUN RBGFX18 from inside ReadyBASIC under ReadyOS"
+ - id: restore_text_rbgfx18
+ type: input.sequence
+ params:
+ keys: [58,58,71,70,88,84,69,88,84,40,41,58,80,82,73,78,84,32,34,82,66,71,70,88,49,56,32,67,79,77,80,76,69,84,69,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_restored_rbgfx18
+ type: screen.capture
+ params:
+ label: readybasic_restored_rbgfx18
+ - id: assert_complete_rbgfx18
+ type: assert.screen
+ params:
+ contains: "RBGFX18 COMPLETE"
+ - id: assert_no_error_rbgfx18
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
+ - id: clear_before_rbgfx19
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: load_rbgfx19
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,49,57,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.2
+ - id: capture_loaded_rbgfx19
+ type: screen.capture
+ params:
+ label: readybasic_loaded_rbgfx19
+ pitch: "ReadyOS-loaded ReadyBASIC after LOAD RBGFX19"
+ - id: list_rbgfx19
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_list_rbgfx19
+ type: screen.capture
+ params:
+ label: readybasic_list_rbgfx19
+ - id: assert_list_rbgfx19
+ type: assert.screen
+ params:
+ contains: "DEMO 19"
+ - id: run_rbgfx19
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: capture_graphics_rbgfx19
+ type: screen.capture
+ params:
+ label: readybasic_graphics_rbgfx19
+ pitch: "Graphics screenshot after RUN RBGFX19 from inside ReadyBASIC under ReadyOS"
+ - id: restore_text_rbgfx19
+ type: input.sequence
+ params:
+ keys: [58,58,71,70,88,84,69,88,84,40,41,58,80,82,73,78,84,32,34,82,66,71,70,88,49,57,32,67,79,77,80,76,69,84,69,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_restored_rbgfx19
+ type: screen.capture
+ params:
+ label: readybasic_restored_rbgfx19
+ - id: assert_complete_rbgfx19
+ type: assert.screen
+ params:
+ contains: "RBGFX19 COMPLETE"
+ - id: assert_no_error_rbgfx19
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
+ - id: clear_before_rbgfx20
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: load_rbgfx20
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,50,48,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.2
+ - id: capture_loaded_rbgfx20
+ type: screen.capture
+ params:
+ label: readybasic_loaded_rbgfx20
+ pitch: "ReadyOS-loaded ReadyBASIC after LOAD RBGFX20"
+ - id: list_rbgfx20
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_list_rbgfx20
+ type: screen.capture
+ params:
+ label: readybasic_list_rbgfx20
+ - id: assert_list_rbgfx20
+ type: assert.screen
+ params:
+ contains: "DEMO 20"
+ - id: run_rbgfx20
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: capture_graphics_rbgfx20
+ type: screen.capture
+ params:
+ label: readybasic_graphics_rbgfx20
+ pitch: "Graphics screenshot after RUN RBGFX20 from inside ReadyBASIC under ReadyOS"
+ - id: restore_text_rbgfx20
+ type: input.sequence
+ params:
+ keys: [58,58,71,70,88,84,69,88,84,40,41,58,80,82,73,78,84,32,34,82,66,71,70,88,50,48,32,67,79,77,80,76,69,84,69,34,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_restored_rbgfx20
+ type: screen.capture
+ params:
+ label: readybasic_restored_rbgfx20
+ - id: assert_complete_rbgfx20
+ type: assert.screen
+ params:
+ contains: "RBGFX20 COMPLETE"
+ - id: assert_no_error_rbgfx20
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
diff --git a/build_support/readybasic_repeat_label_probe.generated.yaml b/build_support/readybasic_repeat_label_probe.generated.yaml
index 34faa5a..b8e123f 100644
--- a/build_support/readybasic_repeat_label_probe.generated.yaml
+++ b/build_support/readybasic_repeat_label_probe.generated.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4p-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4p-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4p-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
diff --git a/build_support/readybasic_resume_min_probe.generated.yaml b/build_support/readybasic_resume_min_probe.generated.yaml
index 085265c..b5c04e6 100644
--- a/build_support/readybasic_resume_min_probe.generated.yaml
+++ b/build_support/readybasic_resume_min_probe.generated.yaml
@@ -19,14 +19,14 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4z-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4z-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4z-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
close_vice: true
- headless: false
+ headless: true
speed_percent: 100
steps:
- id: launch_preboot
@@ -66,7 +66,7 @@ steps:
- id: initial_state_seed
type: input.sequence
params:
- keys: [86,37,61,51,50,49,58,86,83,36,61,34,79,75,34,13,80,82,73,78,84,32,34,83,84,65,84,69,34,59,86,37,59,34,58,34,59,86,83,36,13]
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,86,37,61,51,50,49,58,86,83,36,61,34,79,75,34,13,80,82,73,78,84,32,34,83,84,65,84,69,34,59,86,37,59,34,58,34,59,86,83,36,13]
inter_key_delay_s: 0.03
post_delay_s: 0.8
- id: assert_initial_state_seed
@@ -92,11 +92,9 @@ steps:
text: "READY OS"
wait_timeout_s: 30
- id: resume_1
- type: input.sequence
+ type: monitor.command
params:
- keys: [13]
- inter_key_delay_s: 0.03
- post_delay_s: 3.0
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_resume_1
type: screen.wait_contains
params:
@@ -132,11 +130,9 @@ steps:
text: "READY OS"
wait_timeout_s: 30
- id: resume_2
- type: input.sequence
+ type: monitor.command
params:
- keys: [13]
- inter_key_delay_s: 0.03
- post_delay_s: 3.0
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_resume_2
type: screen.wait_contains
params:
diff --git a/build_support/readybasic_reuviewer_f2_chain_probe.generated.yaml b/build_support/readybasic_reuviewer_f2_chain_probe.generated.yaml
new file mode 100644
index 0000000..645423a
--- /dev/null
+++ b/build_support/readybasic_reuviewer_f2_chain_probe.generated.yaml
@@ -0,0 +1,387 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_reuviewer_f2_chain_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_initial
+ type: screen.wait_contains
+ params:
+ text: "READYBASIC"
+ wait_timeout_s: 180
+ capture_label: chain_readybasic_initial
+ - id: assert_readybasic_bank_initial
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "01"
+ - id: assert_chrin_vector_initial
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "08 12"
+ - id: assert_keylog_vector_initial
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "7E C1"
+ - id: readybasic_first_type
+ type: input.sequence
+ params:
+ keys: [81,37,61,49,48,49,58,80,82,73,78,84,32,34,67,72,65,73,78,49,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_first_type
+ type: assert.screen
+ params:
+ contains: "CHAIN1 101"
+ - id: readybasic_ctrl_b_1_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 4C 74 A4"
+ - id: readybasic_ctrl_b_1_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: readybasic_ctrl_b_1
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_launcher_after_readybasic_ctrl_b_1
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ pre_delay_s: 1.0
+ capture_label: chain_launcher_after_rb_ctrl_b_1
+ - id: assert_launcher_bank_after_ctrl_b_1
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "00"
+ - id: reenter_readybasic_1
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
+ - id: capture_readybasic_reentry_1
+ type: screen.capture
+ params:
+ label: chain_readybasic_reentry_1
+ pitch: warm ReadyBASIC entry evidence; bank/vector assertions and typed sentinel prove keyboard liveness
+ - id: assert_readybasic_bank_reentry_1
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "01"
+ - id: readybasic_second_type
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,67,72,65,73,78,50,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_second_type
+ type: assert.screen
+ params:
+ contains: "CHAIN2 101"
+ - id: readybasic_ctrl_b_2_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 A9 04 8D 8D 02 A9 1C 85 CB 20 7E C1 4C 74 A4"
+ - id: readybasic_ctrl_b_2_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: readybasic_ctrl_b_2
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_launcher_after_readybasic_ctrl_b_2
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ pre_delay_s: 1.0
+ capture_label: chain_launcher_after_rb_ctrl_b_2
+ - id: launch_reuviewer_from_readybasic_position
+ type: input.sequence
+ params:
+ keys: [17,17,17,13]
+ inter_key_delay_s: 0.08
+ post_delay_s: 2.5
+ - id: wait_reuviewer
+ type: screen.wait_contains
+ params:
+ text: "REU MEMORY"
+ wait_timeout_s: 90
+ capture_label: chain_reuviewer_loaded
+ - id: assert_reuviewer_bank
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "02"
+ - id: capture_loaded_bitmap_before_reuviewer_f2
+ type: monitor.command
+ params:
+ command: "raw:m c836 c838"
+ - id: reuviewer_f2_to_readybasic
+ type: input.sequence
+ params:
+ keys: [137]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.2
+ - id: capture_readybasic_after_reuviewer_f2
+ type: screen.capture
+ params:
+ label: chain_readybasic_after_reuviewer_f2
+ pitch: warm ReadyBASIC entry evidence; bank/vector assertions and typed sentinel prove keyboard liveness
+ - id: assert_readybasic_bank_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "01"
+ - id: assert_chrin_vector_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "08 12"
+ - id: assert_keylog_vector_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "7E C1"
+ - id: assert_keyboard_buffer_empty_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: wait_readybasic_stable_after_reuviewer_f2
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: chain_readybasic_stable_after_reuviewer_f2
+ - id: assert_readybasic_bank_stable_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "01"
+ - id: assert_keyboard_buffer_empty_stable_after_reuviewer_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: readybasic_type_after_reuviewer_f2
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,67,72,65,73,78,51,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_type_after_reuviewer_f2
+ type: assert.screen
+ params:
+ contains: "CHAIN3 101"
+ - id: readybasic_f2_back_to_reuviewer_keylog_stub
+ type: memory.write
+ params:
+ start: 828
+ bytes_hex: "A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 A9 01 8D 8D 02 A9 04 85 CB 20 7E C1 4C 74 A4"
+ - id: readybasic_f2_back_to_reuviewer_clear_keylog_breakpnts
+ type: monitor.command
+ params:
+ command: "raw:delete"
+ - id: readybasic_f2_back_to_reuviewer
+ type: monitor.command
+ params:
+ command: "raw:g 033c"
+ - id: wait_reuviewer_after_readybasic_f2
+ type: screen.wait_contains
+ params:
+ text: "REU MEMORY"
+ wait_timeout_s: 80
+ pre_delay_s: 1.0
+ capture_label: chain_reuviewer_after_readybasic_f2
+ - id: assert_app_keylog_vector_restored_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 655
+ end: 656
+ equals_hex: "48 EB"
+ - id: assert_app_chrin_vector_restored_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 804
+ end: 805
+ equals_hex: "57 F1"
+ - id: assert_default_input_device_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 153
+ end: 153
+ equals_hex: "00"
+ - id: assert_reuviewer_bank_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "02"
+ - id: assert_keyboard_buffer_empty_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: wait_reuviewer_stable_after_readybasic_f2
+ type: screen.wait_contains
+ params:
+ text: "REU MEMORY"
+ wait_timeout_s: 30
+ pre_delay_s: 2.5
+ capture_label: chain_reuviewer_stable_after_readybasic_f2
+ - id: assert_reuviewer_bank_stable_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "02"
+ - id: assert_keyboard_buffer_empty_stable_after_readybasic_f2
+ type: assert.memory
+ params:
+ start: 198
+ end: 198
+ equals_hex: "00"
+ - id: reuviewer_ctrl_b_after_readybasic_f2
+ type: monitor.command
+ params:
+ command: "keybuf \\x02"
+ - id: capture_after_reuviewer_ctrl_b_input
+ type: screen.capture
+ params:
+ label: chain_after_reuviewer_ctrl_b_hotkey
+ pitch: capture after resumed REU Viewer Ctrl+B hotkey
+ - id: wait_launcher_after_reuviewer_ctrl_b
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 40
+ capture_label: chain_launcher_after_reuviewer_ctrl_b
+ - id: assert_launcher_bank_after_reuviewer_ctrl_b
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "00"
+ - id: select_readybasic_after_reuviewer_ctrl_b
+ type: memory.write
+ params:
+ start: 51232
+ bytes_hex: "01"
+ - id: launch_readybasic_after_reuviewer_ctrl_b
+ type: monitor.command
+ params:
+ command: "raw:g c80f"
+ - id: capture_readybasic_after_reuviewer_ctrl_b_reentry
+ type: screen.capture
+ params:
+ label: chain_readybasic_after_reuviewer_ctrl_b_reentry
+ pitch: warm ReadyBASIC entry evidence; bank/vector assertions and typed sentinel prove keyboard liveness
+ - id: readybasic_type_after_reuviewer_ctrl_b_reentry
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,67,72,65,73,78,52,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_type_after_reuviewer_ctrl_b_reentry
+ type: assert.screen
+ params:
+ contains: "CHAIN4 101"
+ - id: readybasic_exit_after_multi_hop_reentry
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: wait_launcher_stable_after_readybasic_exit
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 30
+ pre_delay_s: 2.0
+ capture_label: chain_launcher_stable_after_readybasic_exit
+ - id: assert_launcher_bank_after_readybasic_exit
+ type: assert.memory
+ params:
+ start: 51252
+ end: 51252
+ equals_hex: "00"
+ - id: assert_readybasic_not_auto_reentered_after_exit
+ type: assert.screen_not_contains
+ params:
+ not_contains: "ready."
+ - id: select_readybasic_after_exit_guard
+ type: memory.write
+ params:
+ start: 51232
+ bytes_hex: "01"
+ - id: reenter_readybasic_after_exit_guard
+ type: monitor.command
+ params:
+ command: "raw:g c80f"
+ - id: capture_readybasic_after_exit_guard_reentry
+ type: screen.capture
+ params:
+ label: chain_readybasic_after_exit_guard_reentry
+ pitch: warm ReadyBASIC entry evidence; bank/vector assertions and typed sentinel prove keyboard liveness
+ - id: readybasic_type_after_exit_guard_reentry
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,67,72,65,73,78,53,34,59,81,37,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: assert_readybasic_type_after_exit_guard_reentry
+ type: assert.screen
+ params:
+ contains: "CHAIN5 101"
diff --git a/build_support/readybasic_screen_reu_temp_probe.generated.yaml b/build_support/readybasic_screen_reu_temp_probe.generated.yaml
index 8a088ab..91a9d94 100644
--- a/build_support/readybasic_screen_reu_temp_probe.generated.yaml
+++ b/build_support/readybasic_screen_reu_temp_probe.generated.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4j-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4j-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4j-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
@@ -48,7 +48,7 @@ steps:
- { label: descriptors_1000, start: 0x1000, end: 0x11FF }
- { label: resident_1200, start: 0x1200, end: 0x1BFF }
- { label: command_overlay_a800, start: 0xA800, end: 0xAFFF }
- - { label: reu_alloc_c600, start: 0xC600, end: 0xC6FF }
+ - { label: shim_resident_c600, start: 0xC600, end: 0xC9FF }
- id: load_temp_program
type: input.sequence
params:
@@ -71,10 +71,17 @@ steps:
keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
inter_key_delay_s: 0.03
post_delay_s: 30.0
+ - id: capture_temp_program_progress
+ type: screen.capture
+ params:
+ label: scrreu_progress
+ pitch: screen-backed REU program progress after 30 seconds
- id: assert_done
- type: assert.screen
+ type: assert.memory
params:
- contains: "RBSCRREU DONE"
+ start: 1024
+ end: 1036
+ equals_hex: "52 42 53 43 52 52 45 55 20 44 4F 4E 45"
- id: dump_after_done
type: dump.memory_ranges
params:
diff --git a/build_support/readybasic_second_entry_editor_probe.generated.yaml b/build_support/readybasic_second_entry_editor_probe.generated.yaml
index 40e6554..bd51bab 100644
--- a/build_support/readybasic_second_entry_editor_probe.generated.yaml
+++ b/build_support/readybasic_second_entry_editor_probe.generated.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4y-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4y-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4y-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
@@ -89,28 +89,50 @@ steps:
- id: move_readybasic_to_editor_before_setup
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_editor_before_setup
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_before_setup
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_before_setup
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
+ - id: wait_editor_stable_before_setup
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ pre_delay_s: 1.5
+ wait_timeout_s: 30
+ - id: clear_keyboard_before_editor_text_before_setup
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: type_editor_chars_before_setup
type: input.sequence
params:
keys: [80,82,79,66,69,32,76,73,78,69,13]
inter_key_delay_s: 0.035
post_delay_s: 0.6
+ - id: clear_keyboard_before_editor_ctrl_b_before_setup
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: ctrl_b_editor_before_setup
- type: input.sequence
+ type: monitor.command
params:
- keys: [2]
- pre_delay_s: 0
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_before_setup
type: screen.wait_contains
params:
@@ -119,10 +141,19 @@ steps:
- id: move_editor_to_readybasic_before_setup
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_readybasic_before_setup
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_before_setup
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_tour_before_setup
type: screen.wait_contains
params:
@@ -269,7 +300,7 @@ steps:
type: dump.memory_ranges
params:
ranges: &state_ranges
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_text_and_vars_1200, start: 0x1200, end: 0x1800 }
- { label: string_heap_9300, start: 0x9300, end: 0x9600 }
- { label: runtime_state_9600, start: 0x9600, end: 0x9A00 }
@@ -288,28 +319,50 @@ steps:
- id: move_readybasic_to_editor_verify_1
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_editor_verify_1
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_verify_1
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_verify_1
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
+ - id: wait_editor_stable_verify_1
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ pre_delay_s: 1.5
+ wait_timeout_s: 30
+ - id: clear_keyboard_before_editor_text_verify_1
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: type_editor_chars_verify_1
type: input.sequence
params:
keys: [80,82,79,66,69,32,76,73,78,69,13]
inter_key_delay_s: 0.035
post_delay_s: 0.6
+ - id: clear_keyboard_before_editor_ctrl_b_verify_1
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: ctrl_b_editor_verify_1
- type: input.sequence
+ type: monitor.command
params:
- keys: [2]
- pre_delay_s: 0
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_verify_1
type: screen.wait_contains
params:
@@ -318,10 +371,19 @@ steps:
- id: move_editor_to_readybasic_verify_1
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_readybasic_verify_1
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_verify_1
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_tour_verify_1
type: screen.wait_contains
params:
@@ -402,28 +464,50 @@ steps:
- id: move_readybasic_to_editor_verify_2
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_editor_verify_2
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_verify_2
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_verify_2
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
+ - id: wait_editor_stable_verify_2
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ pre_delay_s: 1.5
+ wait_timeout_s: 30
+ - id: clear_keyboard_before_editor_text_verify_2
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: type_editor_chars_verify_2
type: input.sequence
params:
keys: [80,82,79,66,69,32,76,73,78,69,13]
inter_key_delay_s: 0.035
post_delay_s: 0.6
+ - id: clear_keyboard_before_editor_ctrl_b_verify_2
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: ctrl_b_editor_verify_2
- type: input.sequence
+ type: monitor.command
params:
- keys: [2]
- pre_delay_s: 0
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_verify_2
type: screen.wait_contains
params:
@@ -432,10 +516,19 @@ steps:
- id: move_editor_to_readybasic_verify_2
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_readybasic_verify_2
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_verify_2
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_tour_verify_2
type: screen.wait_contains
params:
@@ -516,28 +609,50 @@ steps:
- id: move_readybasic_to_editor_verify_3
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_editor_verify_3
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_verify_3
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_verify_3
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
+ - id: wait_editor_stable_verify_3
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ pre_delay_s: 1.5
+ wait_timeout_s: 30
+ - id: clear_keyboard_before_editor_text_verify_3
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: type_editor_chars_verify_3
type: input.sequence
params:
keys: [80,82,79,66,69,32,76,73,78,69,13]
inter_key_delay_s: 0.035
post_delay_s: 0.6
+ - id: clear_keyboard_before_editor_ctrl_b_verify_3
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: ctrl_b_editor_verify_3
- type: input.sequence
+ type: monitor.command
params:
- keys: [2]
- pre_delay_s: 0
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_verify_3
type: screen.wait_contains
params:
@@ -546,10 +661,19 @@ steps:
- id: move_editor_to_readybasic_verify_3
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_readybasic_verify_3
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_verify_3
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_tour_verify_3
type: screen.wait_contains
params:
@@ -630,28 +754,50 @@ steps:
- id: move_readybasic_to_editor_verify_4
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_editor_verify_4
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_verify_4
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_verify_4
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
+ - id: wait_editor_stable_verify_4
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ pre_delay_s: 1.5
+ wait_timeout_s: 30
+ - id: clear_keyboard_before_editor_text_verify_4
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: type_editor_chars_verify_4
type: input.sequence
params:
keys: [80,82,79,66,69,32,76,73,78,69,13]
inter_key_delay_s: 0.035
post_delay_s: 0.6
+ - id: clear_keyboard_before_editor_ctrl_b_verify_4
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: ctrl_b_editor_verify_4
- type: input.sequence
+ type: monitor.command
params:
- keys: [2]
- pre_delay_s: 0
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_verify_4
type: screen.wait_contains
params:
@@ -660,10 +806,19 @@ steps:
- id: move_editor_to_readybasic_verify_4
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_readybasic_verify_4
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_verify_4
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_tour_verify_4
type: screen.wait_contains
params:
@@ -744,28 +899,50 @@ steps:
- id: move_readybasic_to_editor_verify_5
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_editor_verify_5
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_editor_verify_5
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_editor_verify_5
type: screen.wait_contains
params:
text: "editor"
wait_timeout_s: 60
+ - id: wait_editor_stable_verify_5
+ type: screen.wait_contains
+ params:
+ text: "editor"
+ pre_delay_s: 1.5
+ wait_timeout_s: 30
+ - id: clear_keyboard_before_editor_text_verify_5
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: type_editor_chars_verify_5
type: input.sequence
params:
keys: [80,82,79,66,69,32,76,73,78,69,13]
inter_key_delay_s: 0.035
post_delay_s: 0.6
+ - id: clear_keyboard_before_editor_ctrl_b_verify_5
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
- id: ctrl_b_editor_verify_5
- type: input.sequence
+ type: monitor.command
params:
- keys: [2]
- pre_delay_s: 0
- inter_key_delay_s: 0.03
- post_delay_s: 1.0
+ command: "keybuf \\x02"
- id: wait_launcher_after_editor_verify_5
type: screen.wait_contains
params:
@@ -774,10 +951,19 @@ steps:
- id: move_editor_to_readybasic_verify_5
type: input.sequence
params:
- keys: [17,17,17,17,13]
+ keys: [17,17,17,17]
pre_delay_s: 0
inter_key_delay_s: 0.10
- post_delay_s: 1.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_before_readybasic_verify_5
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_verify_5
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
- id: wait_readybasic_after_tour_verify_5
type: screen.wait_contains
params:
diff --git a/build_support/readybasic_sound_phase1_demo.generated.yaml b/build_support/readybasic_sound_phase1_demo.generated.yaml
new file mode 100644
index 0000000..89734fe
--- /dev/null
+++ b/build_support/readybasic_sound_phase1_demo.generated.yaml
@@ -0,0 +1,175 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_sound_phase1_demo
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 1
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 240
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_readyos_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_loaded_by_readyos
+ type: screen.wait_contains
+ params:
+ text: "FREE:"
+ wait_timeout_s: 180
+ capture_on_success: true
+ capture_label: readybasic_sound_phase1_prompt
+ - id: load_rbsnd01_for_list
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,83,78,68,48,49,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: list_rbsnd01
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: capture_list_rbsnd01
+ type: screen.capture
+ params:
+ label: readybasic_sound_phase1_list_rbsnd01
+ pitch: "RBSND01 listed inside ReadyBASIC under ReadyOS"
+ - id: assert_list_rbsnd01
+ type: assert.screen
+ params:
+ contains: "SID BASICS"
+ - id: run_rbsnd01
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: capture_rbsnd01
+ type: screen.capture
+ params:
+ label: readybasic_sound_phase1_sid_basics
+ pitch: "Human audio: triangle, saw, pulse, then noise"
+ - id: wait_rbsnd01_done
+ type: screen.wait_contains
+ params:
+ text: "RBSND01 DONE"
+ wait_timeout_s: 120
+ capture_on_success: true
+ capture_label: readybasic_sound_phase1_sid_basics_done
+ - id: run_rbsnd02
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,83,78,68,48,50,34,44,56,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: capture_rbsnd02
+ type: screen.capture
+ params:
+ label: readybasic_sound_phase1_voice_state
+ pitch: "Human audio: pulse width and ADSR changes"
+ - id: wait_rbsnd02_done
+ type: screen.wait_contains
+ params:
+ text: "RBSND02 DONE"
+ wait_timeout_s: 120
+ capture_on_success: true
+ capture_label: readybasic_sound_phase1_voice_state_done
+ - id: run_rbsnd03
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,83,78,68,48,51,34,44,56,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: capture_rbsnd03
+ type: screen.capture
+ params:
+ label: readybasic_sound_phase1_pitchs
+ pitch: "Human audio: chromatic PITCH command"
+ - id: wait_rbsnd03_done
+ type: screen.wait_contains
+ params:
+ text: "RBSND03 DONE"
+ wait_timeout_s: 120
+ capture_on_success: true
+ capture_label: readybasic_sound_phase1_pitchs_done
+ - id: run_rbsnd04
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,83,78,68,48,52,34,44,56,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: capture_rbsnd04
+ type: screen.capture
+ params:
+ label: readybasic_sound_phase1_filter
+ pitch: "Human audio: filter mode and cutoff changes"
+ - id: wait_rbsnd04_done
+ type: screen.wait_contains
+ params:
+ text: "RBSND04 DONE"
+ wait_timeout_s: 120
+ capture_on_success: true
+ capture_label: readybasic_sound_phase1_filter_done
+ - id: run_rbsnd05
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,83,78,68,48,53,34,44,56,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: capture_rbsnd05
+ type: screen.capture
+ params:
+ label: readybasic_sound_phase1_voice_batch
+ pitch: "Human audio: VOICE packed fast path"
+ - id: wait_rbsnd05_done
+ type: screen.wait_contains
+ params:
+ text: "RBSND05 DONE"
+ wait_timeout_s: 120
+ capture_on_success: true
+ capture_label: readybasic_sound_phase1_voice_batch_done
+ - id: run_rbsnd06
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,83,78,68,48,54,34,44,56,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: capture_rbsnd06
+ type: screen.capture
+ params:
+ label: readybasic_sound_phase1_three_voice
+ pitch: "Human audio: three SID voices and chord changes"
+ - id: wait_rbsnd06_done
+ type: screen.wait_contains
+ params:
+ text: "RBSND06 DONE"
+ wait_timeout_s: 120
+ capture_on_success: true
+ capture_label: readybasic_sound_phase1_three_voice_done
+ - id: assert_no_basic_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
diff --git a/build_support/readybasic_sprite_steps_demo.generated.yaml b/build_support/readybasic_sprite_steps_demo.generated.yaml
new file mode 100644
index 0000000..b2bd14a
--- /dev/null
+++ b/build_support/readybasic_sprite_steps_demo.generated.yaml
@@ -0,0 +1,122 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_sprite_steps_demo
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 1
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 180
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5o-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_readyos_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_loaded_by_readyos
+ type: screen.wait_contains
+ params:
+ text: "FREE:"
+ wait_timeout_s: 180
+ capture_on_success: true
+ capture_label: readybasic_sprite_steps_prompt
+ - id: clear_before_load
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: load_rbgfx13
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,49,51,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.2
+ - id: list_rbgfx13
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_list_rbgfx13
+ type: screen.capture
+ params:
+ label: readybasic_sprite_steps_list_rbgfx13
+ pitch: "RBGFX13 loaded/listed inside ReadyBASIC under ReadyOS"
+ - id: assert_list_rbgfx13
+ type: assert.screen
+ params:
+ contains: "SPRITE DEMO DONE"
+ - id: clear_before_run
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.6
+ - id: run_rbgfx13
+ type: input.sequence
+ params:
+ keys: [82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+ - id: capture_stage_1_initial
+ type: screen.capture
+ params:
+ label: readybasic_sprite_steps_stage_1_initial
+ pitch: "Stage 1: sprites placed from explicit SPRROW pixel data"
+ - id: continue_to_stage_2
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 1.2
+ - id: capture_stage_2_moved
+ type: screen.capture
+ params:
+ label: readybasic_sprite_steps_stage_2_moved
+ pitch: "Stage 2: sprites moved after ZPAUSE/key gate"
+ - id: continue_to_stage_3
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 1.2
+ - id: capture_stage_3_recolored
+ type: screen.capture
+ params:
+ label: readybasic_sprite_steps_stage_3_recolored
+ pitch: "Stage 3: sprite colors changed"
+ - id: continue_to_finish
+ type: input.key
+ params:
+ key: SPACE
+ post_delay_s: 1.0
+ - id: wait_done
+ type: screen.wait_contains
+ params:
+ text: "SPRITE DEMO DONE"
+ wait_timeout_s: 60
+ capture_on_success: true
+ capture_label: readybasic_sprite_steps_done
+ - id: assert_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
diff --git a/build_support/readybasic_sprite_visual_probe.generated.yaml b/build_support/readybasic_sprite_visual_probe.generated.yaml
new file mode 100644
index 0000000..156105d
--- /dev/null
+++ b/build_support/readybasic_sprite_visual_probe.generated.yaml
@@ -0,0 +1,164 @@
+version: 1
+kind: vice_task_plan
+plan_id: readybasic_sprite_visual_probe
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ retry_policy:
+ max_attempts: 1
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 45
+ step_s: 120
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ vice:
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5d-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5d-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5d-d81-preboot.prg"
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 100
+steps:
+ - id: launch_readyos_preboot
+ type: vice.launch
+ params:
+ kill_stale: true
+ - id: wait_readybasic_loaded_by_readyos
+ type: screen.wait_contains
+ params:
+ text: "FREE:"
+ wait_timeout_s: 180
+ capture_on_success: true
+ capture_label: readybasic_sprite_prompt
+ - id: clear_before_rbgfx09
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: load_rbgfx09
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,48,57,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.2
+ - id: list_rbgfx09
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_list_rbgfx09
+ type: screen.capture
+ params:
+ label: readybasic_sprite_list_rbgfx09
+ note: "RBGFX09 loaded and listed from inside ReadyBASIC under ReadyOS"
+ - id: assert_list_rbgfx09
+ type: assert.screen
+ params:
+ contains: "RBGFX09 SPRITES"
+ - id: clear_for_run_rbgfx09
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: run_rbgfx09
+ type: input.sequence
+ params:
+ keys: [82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: capture_two_sprites
+ type: screen.capture
+ params:
+ label: readybasic_sprite_two_sprites
+ note: "RBGFX09 running from inside ReadyBASIC under ReadyOS"
+ - id: dump_two_sprite_state
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: vic_sprite_regs, start: 0xD000, end: 0xD02F }
+ - { label: sprite_pointers, start: 0xCFF8, end: 0xCFFF }
+ - { label: sprite_pattern_0, start: 0xCA00, end: 0xCA3F }
+ - { label: sprite_pattern_1, start: 0xCA40, end: 0xCA7F }
+ - id: wait_rbgfx09_done
+ type: screen.wait_contains
+ params:
+ text: "TWO HARDWARE SPRITES"
+ wait_timeout_s: 300
+ - id: clear_before_rbgfx10
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.4
+ - id: load_rbgfx10
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,32,34,82,66,71,70,88,49,48,34,44,56,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.2
+ - id: list_rbgfx10
+ type: input.sequence
+ params:
+ keys: [76,73,83,84,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 1.0
+ - id: capture_list_rbgfx10
+ type: screen.capture
+ params:
+ label: readybasic_sprite_list_rbgfx10
+ note: "RBGFX10 loaded and listed from inside ReadyBASIC under ReadyOS"
+ - id: assert_list_rbgfx10
+ type: assert.screen
+ params:
+ contains: "RBGFX10 COLLISION"
+ - id: clear_for_run_rbgfx10
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,67,72,82,36,40,49,52,55,41,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 0.8
+ - id: run_rbgfx10
+ type: input.sequence
+ params:
+ keys: [82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 3.0
+ - id: capture_collision_pair
+ type: screen.capture
+ params:
+ label: readybasic_sprite_collision_pair
+ note: "RBGFX10 running from inside ReadyBASIC under ReadyOS"
+ - id: dump_collision_state
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: vic_sprite_regs_collision, start: 0xD000, end: 0xD02F }
+ - { label: sprite_pointers_collision, start: 0xCFF8, end: 0xCFFF }
+ - id: capture_collision_report
+ type: screen.wait_contains
+ params:
+ text: "SPRITE COLLISION"
+ wait_timeout_s: 300
+ capture_on_success: true
+ capture_label: readybasic_sprite_collision_report
+ - id: assert_collision_report
+ type: assert.screen
+ params:
+ contains: "SPRCOLL"
+ - id: assert_no_error
+ type: assert.screen_not_contains
+ params:
+ not_contains: "?"
diff --git a/build_support/readybasic_state_probe.generated.yaml b/build_support/readybasic_state_probe.generated.yaml
index 7bcfa92..d31175c 100644
--- a/build_support/readybasic_state_probe.generated.yaml
+++ b/build_support/readybasic_state_probe.generated.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4v-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4v-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4v-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5m-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
@@ -77,11 +77,9 @@ steps:
text: "READY OS"
wait_timeout_s: 30
- id: resume_direct_string
- type: input.sequence
+ type: monitor.command
params:
- keys: [13]
- inter_key_delay_s: 0.03
- post_delay_s: 2.0
+ command: "keybuf \\x0d"
- id: wait_prompt_after_direct_string_resume
type: screen.wait_contains
params:
@@ -146,11 +144,9 @@ steps:
text: "READY OS"
wait_timeout_s: 30
- id: resume_multiline
- type: input.sequence
+ type: monitor.command
params:
- keys: [13]
- inter_key_delay_s: 0.03
- post_delay_s: 2.0
+ command: "keybuf \\x0d"
- id: wait_prompt_after_multiline_resume
type: screen.wait_contains
params:
@@ -203,11 +199,9 @@ steps:
text: "READY OS"
wait_timeout_s: 30
- id: resume_after_new
- type: input.sequence
+ type: monitor.command
params:
- keys: [13]
- inter_key_delay_s: 0.03
- post_delay_s: 2.0
+ command: "keybuf \\x0d"
- id: wait_prompt_after_new_resume
type: screen.wait_contains
params:
@@ -252,11 +246,9 @@ steps:
text: "READY OS"
wait_timeout_s: 30
- id: resume_variables
- type: input.sequence
+ type: monitor.command
params:
- keys: [13]
- inter_key_delay_s: 0.03
- post_delay_s: 2.0
+ command: "keybuf \\x0d"
- id: wait_prompt_after_variables_resume
type: screen.wait_contains
params:
@@ -309,11 +301,9 @@ steps:
text: "READY OS"
wait_timeout_s: 30
- id: resume_rb_program
- type: input.sequence
+ type: monitor.command
params:
- keys: [13]
- inter_key_delay_s: 0.03
- post_delay_s: 2.0
+ command: "keybuf \\x0d"
- id: wait_prompt_after_rb_resume
type: screen.wait_contains
params:
diff --git a/build_support/readyirc_fixture_server.py b/build_support/readyirc_fixture_server.py
new file mode 100755
index 0000000..bbcdae6
--- /dev/null
+++ b/build_support/readyirc_fixture_server.py
@@ -0,0 +1,352 @@
+#!/usr/bin/env python3
+"""Deterministic plain-TCP IRC fixture for ReadyIRC C64 Ultimate tests."""
+
+from __future__ import annotations
+
+import argparse
+import json
+import signal
+import socket
+import socketserver
+import threading
+import time
+import urllib.request
+from pathlib import Path
+
+
+class FixtureState:
+ def __init__(self, log_path: Path, status_path: Path, channel: str) -> None:
+ self.log_path = log_path
+ self.status_path = status_path
+ self.channel = channel
+ self.lock = threading.Lock()
+ self.connections = 0
+ self.registered = 0
+ self.quit_count = 0
+ self.exact_pong = False
+ self.registrations: list[dict[str, object]] = []
+ self.part_channels: list[str] = []
+ self.join_switches: list[str] = []
+ self.channel_commands: list[str] = []
+ self.names_requests: list[str] = []
+ self.privmsg_targets: list[str] = []
+ self.events: list[str] = []
+
+ def record(self, event: str) -> None:
+ with self.lock:
+ stamp = time.strftime("%Y-%m-%dT%H:%M:%S", time.localtime())
+ self.events.append(event)
+ with self.log_path.open("a", encoding="utf-8") as handle:
+ handle.write(f"{stamp} {event}\n")
+ payload = {
+ "connections": self.connections,
+ "registered": self.registered,
+ "quit_count": self.quit_count,
+ "exact_pong": self.exact_pong,
+ "registrations": self.registrations,
+ "part_channels": self.part_channels,
+ "join_switches": self.join_switches,
+ "channel_commands": self.channel_commands,
+ "names_requests": self.names_requests,
+ "privmsg_targets": self.privmsg_targets,
+ "events": self.events[-40:],
+ }
+ temp_path = self.status_path.with_suffix(self.status_path.suffix + ".tmp")
+ temp_path.write_text(json.dumps(payload, indent=2) + "\n", encoding="utf-8")
+ temp_path.replace(self.status_path)
+
+ def new_connection(self) -> int:
+ with self.lock:
+ self.connections += 1
+ number = self.connections
+ self.record(f"connection {number} accepted")
+ return number
+
+
+class ReadyIrcHandler(socketserver.StreamRequestHandler):
+ state: FixtureState
+
+ def setup(self) -> None:
+ super().setup()
+ self.connection_number = self.server.state.new_connection() # type: ignore[attr-defined]
+ self.nick = "enteryournick"
+ self.user = ""
+ self.join_channel = ""
+ self.got_user = False
+ self.got_join = False
+ self.registered = False
+ self.send_lock = threading.Lock()
+ self.closed = False
+
+ def send_line(self, line: str) -> None:
+ with self.send_lock:
+ if self.closed:
+ return
+ try:
+ self.wfile.write((line + "\r\n").encode("ascii"))
+ self.wfile.flush()
+ self.server.state.record( # type: ignore[attr-defined]
+ f"connection {self.connection_number} tx {line}"
+ )
+ except OSError:
+ self.closed = True
+
+ def finish_registration(self) -> None:
+ if self.registered or not (self.got_user and self.got_join):
+ return
+ self.registered = True
+ with self.server.state.lock: # type: ignore[attr-defined]
+ self.server.state.registered += 1 # type: ignore[attr-defined]
+ self.server.state.registrations.append( # type: ignore[attr-defined]
+ {
+ "connection": self.connection_number,
+ "nick": self.nick,
+ "user": self.user,
+ "channel": self.join_channel,
+ }
+ )
+ self.server.state.record( # type: ignore[attr-defined]
+ f"connection {self.connection_number} registered nick={self.nick}"
+ )
+ self.send_line(f":Fixture.Server 001 {self.nick} :WELCOME MIXED CASE")
+ self.send_line(
+ f":UpperNick!user@fixture PRIVMSG {self.join_channel} "
+ f":CONNECTION {self.connection_number} MIXED CASE WELCOME"
+ )
+ self.send_line("PING :MiXeDToken")
+
+ def schedule_line(self, delay: float, line: str) -> None:
+ timer = threading.Timer(delay, self.send_line, args=(line,))
+ timer.daemon = True
+ timer.start()
+
+ def schedule_close(self, delay: float) -> None:
+ def close_connection() -> None:
+ self.server.state.record( # type: ignore[attr-defined]
+ f"connection {self.connection_number} forced close"
+ )
+ self.closed = True
+ try:
+ self.request.shutdown(socket.SHUT_RDWR)
+ except OSError:
+ pass
+ try:
+ self.request.close()
+ except OSError:
+ pass
+
+ timer = threading.Timer(delay, close_connection)
+ timer.daemon = True
+ timer.start()
+
+ def write_ultimate_memory(self, address: int, value: int) -> None:
+ host = self.server.ultimate_host # type: ignore[attr-defined]
+ write_url = (
+ f"http://{host}/v1/machine:writemem?address={address:04X}"
+ )
+ read_url = (
+ f"http://{host}/v1/machine:readmem?address={address:04X}&length=1"
+ )
+ for attempt in range(3):
+ request = urllib.request.Request(
+ write_url,
+ data=bytes((value,)),
+ headers={"Content-Type": "application/octet-stream"},
+ method="POST",
+ )
+ with urllib.request.urlopen(request, timeout=5) as response:
+ response.read()
+ with urllib.request.urlopen(read_url, timeout=5) as response:
+ actual = response.read(1)
+ if actual == bytes((value,)):
+ break
+ if attempt == 2:
+ got = actual.hex() if actual else "no data"
+ raise RuntimeError(
+ f"Ultimate sentinel readback ${address:04x}: "
+ f"expected ${value:02x}, got {got}"
+ )
+ time.sleep(0.05)
+ self.server.state.record( # type: ignore[attr-defined]
+ f"ultimate sentinel ${address:04x}=${value:02x}"
+ )
+
+ def plant_sentinel(self, screen_value: int, color_value: int) -> None:
+ self.write_ultimate_memory(0x0607, screen_value)
+ self.write_ultimate_memory(0xDA07, color_value)
+
+ def schedule_sentinel(self, screen_value: int, color_value: int) -> None:
+ # ReadyIRC adds its local echo after socket_write returns. Plant after
+ # that echo so the following app action, not the setup command itself,
+ # is what moves (or preserves) the sentinel.
+ def plant() -> None:
+ try:
+ self.plant_sentinel(screen_value, color_value)
+ except Exception as exc: # surfaced by the following readback step
+ self.server.state.record( # type: ignore[attr-defined]
+ f"ultimate sentinel failed: {exc}"
+ )
+
+ timer = threading.Timer(0.2, plant)
+ timer.daemon = True
+ timer.start()
+
+ def handle(self) -> None:
+ while not self.closed:
+ raw = self.rfile.readline(1024)
+ if not raw:
+ break
+ line = raw.decode("ascii", errors="replace").rstrip("\r\n")
+ self.server.state.record( # type: ignore[attr-defined]
+ f"connection {self.connection_number} rx {line}"
+ )
+ upper = line.upper()
+ if upper.startswith("NICK "):
+ self.nick = line[5:].strip() or self.nick
+ elif upper.startswith("USER "):
+ self.user = line[5:].split(" ", 1)[0].strip()
+ self.got_user = True
+ elif upper.startswith("JOIN "):
+ channel = line[5:].strip().lstrip(":")
+ self.join_channel = channel
+ if self.registered:
+ with self.server.state.lock: # type: ignore[attr-defined]
+ self.server.state.join_switches.append(channel) # type: ignore[attr-defined]
+ self.server.state.channel_commands.append(f"join {channel}") # type: ignore[attr-defined]
+ self.server.state.record( # type: ignore[attr-defined]
+ f"connection {self.connection_number} switched join {channel}"
+ )
+ self.send_line(
+ f":{self.nick}!user@fixture JOIN :{channel}"
+ )
+ self.send_line(
+ f":SwitchBot!user@fixture PRIVMSG {channel} "
+ ":JOINED NEW CHANNEL"
+ )
+ else:
+ self.got_join = True
+ elif upper.startswith("PART "):
+ channel = line[5:].split(" ", 1)[0].strip().lstrip(":")
+ with self.server.state.lock: # type: ignore[attr-defined]
+ self.server.state.part_channels.append(channel) # type: ignore[attr-defined]
+ self.server.state.channel_commands.append(f"part {channel}") # type: ignore[attr-defined]
+ self.server.state.record( # type: ignore[attr-defined]
+ f"connection {self.connection_number} parted {channel}"
+ )
+ self.send_line(
+ f":{self.nick}!user@fixture PART {channel} :changing channel"
+ )
+ elif upper.startswith("NAMES "):
+ channel = line[6:].strip().lstrip(":")
+ with self.server.state.lock: # type: ignore[attr-defined]
+ self.server.state.names_requests.append(channel) # type: ignore[attr-defined]
+ self.server.state.record( # type: ignore[attr-defined]
+ f"connection {self.connection_number} names requested {channel}"
+ )
+ if channel.lower() == "#longnames":
+ names = " ".join(f"LongNick{index:02d}" for index in range(1, 31))
+ else:
+ names = "@Alpha +Beta Gamma"
+ self.send_line(
+ f":Fixture.Server 353 {self.nick} = {channel} :{names}"
+ )
+ self.send_line(
+ f":Fixture.Server 366 {self.nick} {channel} :End of /NAMES list."
+ )
+ elif line == "PONG :MiXeDToken":
+ with self.server.state.lock: # type: ignore[attr-defined]
+ self.server.state.exact_pong = True # type: ignore[attr-defined]
+ self.server.state.record("exact mixed-case pong received") # type: ignore[attr-defined]
+ elif upper.startswith("QUIT "):
+ with self.server.state.lock: # type: ignore[attr-defined]
+ self.server.state.quit_count += 1 # type: ignore[attr-defined]
+ self.server.state.record( # type: ignore[attr-defined]
+ f"connection {self.connection_number} quit received"
+ )
+ break
+ elif upper.startswith("PRIVMSG ") and " :" in line:
+ target = line.split(" ", 2)[1]
+ message = line.split(" :", 1)[1]
+ with self.server.state.lock: # type: ignore[attr-defined]
+ self.server.state.privmsg_targets.append(target) # type: ignore[attr-defined]
+ if message.lower() == "queuewhileaway":
+ self.schedule_line(
+ 3.0,
+ f":QueueBot!user@fixture PRIVMSG {target} "
+ ":QUEUED WHILE SUSPENDED",
+ )
+ elif message.lower() == "dropwhileaway":
+ self.schedule_close(3.0)
+ elif message.lower() == "fillscroll":
+ for index in range(1, 26):
+ self.send_line(
+ f":FillBot!user@fixture PRIVMSG {target} "
+ f":FILL LINE {index:02d}"
+ )
+ elif message.lower() == "plantsentinelappend":
+ self.schedule_sentinel(0x7F, 0x0E)
+ elif message.lower() == "plantsentinelscroll":
+ self.schedule_sentinel(0x7E, 0x07)
+ elif message.lower() == "plantsentinelhistory":
+ self.schedule_sentinel(0x7D, 0x06)
+ elif message.lower() in {"renderprobe", "historyprobe"}:
+ pass
+ else:
+ self.send_line(
+ f":EchoBot!user@fixture PRIVMSG {target} "
+ f":ECHO MIXED {message.upper()}"
+ )
+ self.finish_registration()
+
+ def finish(self) -> None:
+ self.closed = True
+ self.server.state.record( # type: ignore[attr-defined]
+ f"connection {self.connection_number} closed"
+ )
+ super().finish()
+
+
+class FixtureServer(socketserver.ThreadingTCPServer):
+ allow_reuse_address = True
+ daemon_threads = True
+
+ def __init__(
+ self, address: tuple[str, int], state: FixtureState, ultimate_host: str
+ ) -> None:
+ self.state = state
+ self.ultimate_host = ultimate_host
+ super().__init__(address, ReadyIrcHandler)
+
+
+def main() -> int:
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--bind", default="0.0.0.0")
+ parser.add_argument("--port", type=int, default=16667)
+ parser.add_argument("--channel", default="#readyostest")
+ parser.add_argument("--ultimate-host", default="10.0.0.79")
+ parser.add_argument("--log", type=Path, required=True)
+ parser.add_argument("--status", type=Path, required=True)
+ args = parser.parse_args()
+
+ args.log.parent.mkdir(parents=True, exist_ok=True)
+ args.status.parent.mkdir(parents=True, exist_ok=True)
+ args.log.write_text("", encoding="utf-8")
+ state = FixtureState(args.log, args.status, args.channel)
+ server = FixtureServer((args.bind, args.port), state, args.ultimate_host)
+
+ def stop_server(_signum: int, _frame: object) -> None:
+ threading.Thread(target=server.shutdown, daemon=True).start()
+
+ signal.signal(signal.SIGTERM, stop_server)
+ signal.signal(signal.SIGINT, stop_server)
+ state.record(f"fixture listening {args.bind}:{args.port}")
+ try:
+ server.serve_forever(poll_interval=0.2)
+ finally:
+ server.server_close()
+ state.record("fixture stopped")
+ return 0
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/build_support/readyos_easyflash.py b/build_support/readyos_easyflash.py
index 1a7d77c..5db0d6f 100644
--- a/build_support/readyos_easyflash.py
+++ b/build_support/readyos_easyflash.py
@@ -165,6 +165,7 @@ def launcher_header_text(catalog: Dict[str, object]) -> str:
resource_banks = catalog_resource_banks(catalog)
rs_banks = resource_banks["readyshell"]
rb_banks = resource_banks["readybasic"]
+ app_physical_banks = catalog_app_physical_banks(catalog)
rs_rows = readyshell_overlay_rows(rs_banks)
lines = [
"/* Auto-generated by readyos_easyflash.py. Do not edit by hand. */",
@@ -188,6 +189,10 @@ def launcher_header_text(catalog: Dict[str, object]) -> str:
" " + ", ".join(str(int(entry["bank"])) for entry in apps),
"};",
"",
+ "static const unsigned char readyos_easyflash_app_physical_banks[READYOS_EASYFLASH_APP_COUNT] = {",
+ " " + ", ".join(str(bank) for bank in app_physical_banks),
+ "};",
+ "",
"static const unsigned char readyos_easyflash_default_slots[READYOS_EASYFLASH_APP_COUNT] = {",
" " + ", ".join(str(int(entry["default_slot"])) for entry in apps),
"};",
@@ -263,6 +268,20 @@ def allocate_reu_bank(used: set[int], first: int) -> int:
return 0
+def catalog_app_physical_banks(catalog: Dict[str, object]) -> List[int]:
+ """Assign explicit app snapshot banks beginning at physical Skip+1.
+
+ Skip is the ReadyOS bank. No token arithmetic is part of the runtime
+ contract, so the generated cartridge catalog carries this mapping.
+ """
+ skip = reu_bank_skip_from_system(catalog["system"])
+ used = {skip}
+ result: List[int] = []
+ for _entry in list(catalog["apps"]):
+ result.append(allocate_reu_bank(used, skip + 1))
+ return result
+
+
def catalog_needs_readyshell_resources(catalog: Dict[str, object]) -> bool:
return any(
int(entry.get("resource_set", RESOURCE_NONE)) == RESOURCE_READYSHELL_OVL
@@ -279,10 +298,9 @@ def catalog_needs_readybasic_resources(catalog: Dict[str, object]) -> bool:
def catalog_resource_banks(catalog: Dict[str, object]) -> Dict[str, List[int]]:
reu_bank_skip = reu_bank_skip_from_system(catalog["system"])
- used = {reu_bank_skip, reu_bank_skip + 1}
- for entry in list(catalog["apps"]):
- used.add(reu_bank_skip + 1 + int(entry["bank"]))
- first_resource_bank = reu_bank_skip + 2
+ used = {reu_bank_skip}
+ used.update(catalog_app_physical_banks(catalog))
+ first_resource_bank = reu_bank_skip + 1
rs_banks = [0, 0, 0, 0]
rb_banks = [0, 0]
if catalog_needs_readyshell_resources(catalog):
@@ -314,7 +332,8 @@ def catalog_readybasic_banks(catalog: Dict[str, object]) -> List[int]:
def build_layout(catalog: Dict[str, object]) -> Dict[str, object]:
next_bank = 1
reu_bank_skip = reu_bank_skip_from_system(catalog["system"])
- used_reu_banks = {reu_bank_skip, reu_bank_skip + 1}
+ used_reu_banks = {reu_bank_skip}
+ app_physical_banks = catalog_app_physical_banks(catalog)
needs_readyshell_resources = catalog_needs_readyshell_resources(catalog)
resource_banks = catalog_resource_banks(catalog)
@@ -342,7 +361,7 @@ def build_layout(catalog: Dict[str, object]) -> Dict[str, object]:
}
next_bank += launcher_span
- for entry in list(catalog["apps"]):
+ for app_index, entry in enumerate(list(catalog["apps"])):
app_path = resolve_app_artifact(str(entry["prg"]))
payload_len = payload_len_from_prg(app_path)
load_addr = payload_load_from_prg(app_path)
@@ -351,6 +370,7 @@ def build_layout(catalog: Dict[str, object]) -> Dict[str, object]:
bank_span = int(math.ceil(float(payload_len) / float(EASYFLASH_PAYLOAD_SLOT_BYTES)))
layout["apps"].append({
"bank": int(entry["bank"]),
+ "reu_bank": int(app_physical_banks[app_index]),
"prg": str(entry["prg"]),
"label": str(entry["label"]),
"artifact": str(app_path.relative_to(ROOT)),
@@ -362,7 +382,7 @@ def build_layout(catalog: Dict[str, object]) -> Dict[str, object]:
"default_slot": int(entry["default_slot"]),
"resource_set": int(entry.get("resource_set", RESOURCE_NONE)),
})
- used_reu_banks.add(reu_bank_skip + 1 + int(entry["bank"]))
+ used_reu_banks.add(int(app_physical_banks[app_index]))
next_bank += bank_span
for name, rel_path, reu_slot, reu_off, valid_bit in OVERLAY_SPECS:
@@ -421,7 +441,8 @@ def layout_inc_text(layout: Dict[str, object]) -> str:
]
for entry in apps:
lines.append(
- f" .byte {int(entry['bank'])}, {int(entry['start_bank'])}, {int(entry['bank_span'])}, "
+ f" .byte {int(entry['bank'])}, {int(entry['reu_bank'])}, "
+ f"{int(entry['start_bank'])}, {int(entry['bank_span'])}, "
f"<${int(entry['load_addr']):04X}, >${int(entry['load_addr']):04X}, "
f"<${int(entry['payload_len']):04X}, >${int(entry['payload_len']):04X}, "
f"<${int(entry['checksum16']):04X}, >${int(entry['checksum16']):04X}"
diff --git a/build_support/readyos_profiles.py b/build_support/readyos_profiles.py
index 58b36b0..0b82d90 100644
--- a/build_support/readyos_profiles.py
+++ b/build_support/readyos_profiles.py
@@ -1204,11 +1204,11 @@ def build_help_text(profile: Dict[str, object],
"",
"- This SKU is intentionally limited to `1MB` REU, which is `16` physical `64KB` REU banks.",
"- It uses `reu_bank_skip=0`, so ReadyOS can use all 16 physical banks instead of skipping the lower bank range used by the normal test profiles.",
- "- Fresh launcher state uses `2` banks by default: bank `0` for ReadyOS control/global metadata and bank `1` for the launcher snapshot. That leaves `14` banks for suspended apps and app resources.",
+ "- Fresh launcher state uses `1` bank by default: bank `0` is the combined ReadyOS bank, holding both the launcher snapshot and schema-v5 system state. That leaves `15` banks for suspended apps and app resources.",
"- Each suspended app normally costs `1` additional bank.",
- "- ReadyShell costs `5` banks when loaded: `1` app snapshot bank, `3` overlay cache banks, and `1` state/scratch bank. With only ReadyShell loaded, expect about `7/16` banks in use.",
- "- ReadyBasic costs `3` banks when loaded: `1` app snapshot bank plus `2` ReadyBasic core/code resource banks. With only ReadyBasic loaded, expect about `5/16` banks in use.",
- "- ReadyShell and ReadyBasic loaded at the same time can use about `10/16` banks before any other suspended apps are counted.",
+ "- ReadyShell costs `5` additional banks when loaded: `1` app snapshot bank, `3` overlay cache banks, and `1` state/scratch bank. With only ReadyShell loaded, expect about `6/16` banks in use including the ReadyOS bank.",
+ "- ReadyBasic costs `3` additional banks when loaded: `1` app snapshot bank plus `2` ReadyBasic core/code resource banks. With only ReadyBasic loaded, expect about `4/16` banks in use including the ReadyOS bank.",
+ "- ReadyShell and ReadyBasic loaded at the same time can use about `9/16` banks including the ReadyOS bank, before any other suspended apps are counted.",
"- When REU Viewer or the launcher shows the 1MB REU getting close to full, unload suspended apps before launching more. Unloading frees their app snapshot and resource banks.",
"- If all REU banks are full, launching another app may simply do nothing instead of showing an error. Unload one or more apps to make room, then launch the app again.",
"",
@@ -1240,6 +1240,7 @@ def build_help_text(profile: Dict[str, object],
"- Copy the listed disk image files to the target storage.",
c64_ultimate_reu_line,
"- The host-side boot PRGs are optional convenience files for emulator launching; the disk-side `PREBOOT` entry is the standard hardware boot path.",
+ "- Choosing a disk SKU does not enable the experimental Ultimate DOS DMA launcher. Normal release artifacts use the portable disk loader; DMA requires an explicit `LAUNCHER_DMA_LOAD=1` source build and retains disk fallback.",
])
if preboot_mode == "setd71":
lines.extend([
diff --git a/build_support/readyshell_cross_app_resume_c64u.generated.ini b/build_support/readyshell_cross_app_resume_c64u.generated.ini
new file mode 100644
index 0000000..eca71db
--- /dev/null
+++ b/build_support/readyshell_cross_app_resume_c64u.generated.ini
@@ -0,0 +1,72 @@
+[system]
+variant_name=precog d81
+variant_boot_name=precog d81
+reu_bank_skip=32
+
+[launcher]
+load_all_to_reu=0
+runappfirst=
+c64u_image_path=/usb1/readyos-v0.2.5e-d81.d81
+
+[apps]
+8:editor:editor:1
+text editor with clipboard
+
+8:readyshell:readyshell (beta):2:rsovl+
+command shell poc scaffold
+rsparser@0:0000,rsvm@0:3800,rsdrvilst@0:7000,rsldv@1:0000,rsstv@0:a800,rsfops@1:3800,rscat@1:7000,rscopy@1:a800,rsedit@2:0000
+
+8:simplefiles:simple files
+dual pane file manager and seq viewer
+
+8:clipmgr:clipboard
+manage clipboard items
+
+8:readybasic:ready basic (alpha):3:rbcore+
+scoped basic v2 bridge poc
+rbcore,rbcode
+
+8:cal26:calendar 26
+calendar for 2026 with appointments
+
+8:tasklist:task list
+outliner with notes and search
+
+8:reuviewer:reu viewer
+view reu memory usage
+
+8:sysinfo:system info
+system, reu, and ultimate status
+
+8:quicknotes:quicknotes
+reu-backed note editor
+
+8:calcplus:calc plus
+keyboard-first expression calculator
+
+8:hexview:hex viewer
+browse memory in hex format
+
+8:simplecells:simple cells (alpha)
+spreadsheet with formulas and colors
+
+8:game2048:2048 game
+2048 tile puzzle
+
+8:deminer:deminer
+minesweeper-style puzzle
+
+8:dizzy:dizzy kanban
+fizzy inspired kanban app
+
+8:readyirc:readyirc
+ultimate tcp irc client
+
+8:ucitest:uci tester
+ultimate command interface lab
+
+8:rirc-rrnet:readyirc rrnet
+rr-net tcp irc client
+
+8:readme:read.me
+readyos, ultimate buddy, precog poc os
diff --git a/build_support/readyshell_cross_app_resume_c64u.generated.yaml b/build_support/readyshell_cross_app_resume_c64u.generated.yaml
new file mode 100644
index 0000000..67d20bd
--- /dev/null
+++ b/build_support/readyshell_cross_app_resume_c64u.generated.yaml
@@ -0,0 +1,249 @@
+version: 1
+kind: ultimate_task_plan
+plan_id: readyshell_cross_app_resume_c64u
+run_mode: ultimate64
+global_defaults:
+ retry_policy:
+ max_attempts: 2
+ backoff_ms: 500
+ jitter: false
+ timeouts:
+ launch_s: 180
+ step_s: 300
+ read_s: 5
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: false
+ ultimate:
+ host: 10.0.0.79
+ password: null
+ ftp_user: anonymous
+ ftp_password: anonymous@
+ remote_root: USB1
+ disk8: ""
+ disk9: null
+ autostart_prg: null
+ drive_a_bus_id: 8
+ drive_b_bus_id: 9
+ drive_a_type: '1581'
+ drive_b_type: '1581'
+ drive_a_enabled: true
+ drive_b_enabled: false
+ mount_mode: readwrite
+ boot_drive: 8
+ capture_video_stream: false
+ stream_port: 11000
+ stream_timeout_s: 4.0
+ default_speed_mhz: 1
+ warp_equivalent_mhz: 8
+steps:
+ - id: launch_d81
+ type: ultimate.launch
+ params:
+ boot_mode: disk
+ drives:
+ - slot: a
+ bus_id: 8
+ drive_type: '1581'
+ enabled: true
+ disk: ""
+ remote_disk: ""
+ image_type: d81
+ mount_mode: readwrite
+ boot_drive: 8
+ boot_command: "LOAD\"BOOT\",8\r"
+ reset_before_boot: true
+ post_reset_delay_s: 3.0
+ boot_inter_chunk_delay_s: 0.25
+ - id: wait_basic_loading_boot
+ type: screen.wait_contains
+ params:
+ text: "LOADING"
+ wait_timeout_s: 60
+ poll_s: 1.0
+ capture_label: basic_loading_boot
+ - id: run_readyos_booter
+ type: input.sequence
+ params:
+ pre_delay_s: 45
+ keys: [82,85,78,13]
+ inter_key_delay_s: 0.25
+ post_delay_s: 1.0
+ - id: wait_launcher_initial
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 360
+ poll_s: 1.0
+ pre_delay_s: 90
+ capture_label: launcher_initial_c64u
+ - id: select_editor_from_launcher_initial
+ type: input.sequence
+ params:
+ keys: [19,17,17,13]
+ inter_key_delay_s: 0.25
+ post_delay_s: 2.0
+ - id: wait_editor_dma_progress
+ type: screen.wait_contains
+ params:
+ text: "DMA LOADING 1/1"
+ wait_timeout_s: 90
+ poll_s: 0.25
+ capture_label: editor_dma_progress_c64u
+ - id: wait_editor_initial
+ type: screen.wait_contains
+ params:
+ text: "F1:CPY"
+ wait_timeout_s: 300
+ poll_s: 1.0
+ pre_delay_s: 10
+ capture_label: editor_initial_c64u
+ - id: editor_touch_1
+ type: input.sequence
+ params:
+ keys: [82,69,65,68,89,83,72,69,76,76,32,80,82,79,66,69,32,69,68,73,84,79,82,32,76,69,71,13]
+ inter_key_delay_s: 0.25
+ post_delay_s: 0.8
+ - id: ctrl_b_editor_to_launcher_1
+ type: input.sequence
+ params:
+ keys: [2]
+ inter_key_delay_s: 0.25
+ post_delay_s: 1.0
+ - id: wait_launcher_after_editor_1
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 60
+ poll_s: 1.0
+ capture_label: launcher_after_editor_1
+ - id: move_editor_to_readybasic_1
+ type: input.sequence
+ params:
+ keys: [17,17,17,17,13]
+ inter_key_delay_s: 0.25
+ post_delay_s: 2.0
+ - id: wait_readybasic_from_editor_1
+ type: screen.wait_contains
+ params:
+ text: "ready."
+ wait_timeout_s: 120
+ poll_s: 1.0
+ pre_delay_s: 10
+ capture_label: readybasic_from_editor_1
+ - id: readybasic_touch_1
+ type: input.sequence
+ params:
+ keys: [80,82,73,78,84,32,34,82,66,79,75,34,13]
+ inter_key_delay_s: 0.25
+ post_delay_s: 0.8
+ - id: assert_readybasic_touch_1
+ type: assert.screen
+ params:
+ contains: "RBOK"
+ - id: exit_readybasic_1
+ type: input.sequence
+ params:
+ keys: [69,88,73,84,13]
+ inter_key_delay_s: 0.25
+ post_delay_s: 1.0
+ - id: wait_launcher_after_readybasic_1
+ type: screen.wait_contains
+ params:
+ text: "READY OS"
+ wait_timeout_s: 60
+ poll_s: 1.0
+ capture_label: launcher_after_readybasic_1
+ - id: move_launcher_to_readyshell_1
+ type: input.sequence
+ params:
+ keys: [19,17,17,17]
+ inter_key_delay_s: 0.25
+ post_delay_s: 0.8
+ - id: launch_readyshell_after_readybasic_1
+ type: input.sequence
+ params:
+ keys: [13]
+ inter_key_delay_s: 0.25
+ post_delay_s: 2.0
+ - id: wait_readyshell_dma_progress_1
+ type: screen.wait_contains
+ params:
+ text: "DMA LOADING"
+ wait_timeout_s: 120
+ poll_s: 0.25
+ capture_label: readyshell_dma_progress_1
+ - id: wait_readyshell_loaded_after_readybasic_1
+ type: screen.wait_contains
+ params:
+ text: "run: cat"
+ wait_timeout_s: 180
+ poll_s: 1.0
+ pre_delay_s: 10
+ capture_label: readyshell_after_readybasic_1
+ - id: readyshell_ver_after_readybasic_1
+ type: input.sequence
+ params:
+ keys: [86,69,82,13]
+ inter_key_delay_s: 0.25
+ post_delay_s: 1.5
+ - id: assert_readyshell_ver_after_readybasic_1
+ type: assert.screen
+ params:
+ contains: "version 0.2"
+ - id: readyshell_lst_after_readybasic_1
+ type: input.sequence
+ params:
+ keys: [76,83,84,32,34,82,83,72,69,76,80,34,13]
+ inter_key_delay_s: 0.25
+ post_delay_s: 2.0
+ - id: wait_readyshell_lst_result_after_readybasic_1
+ type: screen.wait_contains
+ params:
+ text: "BLOCKS"
+ wait_timeout_s: 90
+ poll_s: 1.0
+ - id: readyshell_ver_after_lst_after_readybasic_1
+ type: input.sequence
+ params:
+ keys: [86,69,82,13]
+ inter_key_delay_s: 0.25
+ post_delay_s: 1.5
+ - id: assert_readyshell_ver_after_lst_after_readybasic_1
+ type: assert.screen
+ params:
+ contains: "version 0.2"
+ - id: readyshell_cat_after_readybasic_1
+ type: input.sequence
+ params:
+ keys: [67,65,84,32,34,82,83,72,69,76,80,34,32,33,32,84,79,80,32,49,13]
+ inter_key_delay_s: 0.25
+ post_delay_s: 2.0
+ - id: capture_readyshell_cat_after_readybasic_1
+ type: screen.capture
+ params:
+ label: readyshell_cat_after_readybasic_1
+ - id: wait_readyshell_cat_result_after_readybasic_1
+ type: screen.wait_contains
+ params:
+ text: "readyshell quick ref"
+ wait_timeout_s: 90
+ poll_s: 1.0
+ - id: readyshell_ver_after_cat_after_readybasic_1
+ type: input.sequence
+ params:
+ keys: [86,69,82,13]
+ inter_key_delay_s: 0.25
+ post_delay_s: 1.5
+ - id: assert_readyshell_ver_after_cat_after_readybasic_1
+ type: assert.screen
+ params:
+ contains: "version 0.2"
+ - id: dump_final_state
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: launcher_shim_c800, start: 0xC800, end: 0xCA00 }
+ - { label: app_work_1000, start: 0x1000, end: 0x1800 }
+ - { label: upper_app_a000, start: 0xA000, end: 0xC600 }
diff --git a/build_support/readyshell_cross_app_resume_probe.generated.yaml b/build_support/readyshell_cross_app_resume_probe.generated.yaml
index 66fe47e..c233472 100644
--- a/build_support/readyshell_cross_app_resume_probe.generated.yaml
+++ b/build_support/readyshell_cross_app_resume_probe.generated.yaml
@@ -19,9 +19,9 @@ global_defaults:
capture_state: true
capture_dump: false
vice:
- disk8: "Releases/0.2.4/precog-d81/readyos-v0.2.4c-d81.d81"
- disk9: "Releases/0.2.4/precog-d81/readyos-v0.2.4c-d81.d81"
- autostart_prg: "Releases/0.2.4/precog-d81/readyos-v0.2.4c-d81-preboot.prg"
+ disk8: "Releases/0.2.5/precog-d81/readyos-v0.2.5q-d81.d81"
+ disk9: "Releases/0.2.5/precog-d81/readyos-v0.2.5q-d81.d81"
+ autostart_prg: "Releases/0.2.5/precog-d81/readyos-v0.2.5q-d81-preboot.prg"
drive8_type: 1581
drive9_type: 1581
true_drive: false
@@ -36,9 +36,14 @@ steps:
- id: wait_editor_initial
type: screen.wait_contains
params:
- text: "editor"
+ text: "EDITOR:"
wait_timeout_s: 180
capture_label: editor_initial
+ - id: clear_keyboard_buffer_before_editor_entry
+ type: memory.write
+ params:
+ start: 198
+ bytes_hex: "00"
- id: editor_touch_1
type: input.sequence
params:
@@ -92,13 +97,28 @@ steps:
- id: move_readybasic_to_editor_1
type: input.sequence
params:
- keys: [145,145,145,145,13]
+ keys: [145,145,145,145]
inter_key_delay_s: 0.08
- post_delay_s: 2.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_editor_relaunch_1
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ # The binary-monitor key helper can drop a lone RETURN immediately after
+ # ReadyBASIC's EXIT return. VICE's text-monitor keybuf path is deterministic.
+ - id: launch_editor_after_readybasic_1
+ type: monitor.command
+ params:
+ command: "keybuf \\x0d"
+ - id: capture_after_move_readybasic_to_editor_1
+ type: screen.capture
+ params:
+ label: after_move_readybasic_to_editor_1
- id: wait_editor_after_readybasic_1
type: screen.wait_contains
params:
- text: "editor"
+ text: "EDITOR:"
wait_timeout_s: 60
capture_label: editor_after_readybasic_1
- id: ctrl_b_editor_to_launcher_before_readyshell_1
@@ -184,6 +204,6 @@ steps:
type: dump.memory_ranges
params:
ranges:
- - { label: launcher_shim_c800, start: 0xC800, end: 0xCA00 }
+ - { label: launcher_shim_c600, start: 0xC600, end: 0xCA00 }
- { label: app_work_1000, start: 0x1000, end: 0x1800 }
- { label: upper_app_a000, start: 0xA000, end: 0xC600 }
diff --git a/build_support/readyshell_overlay_report.py b/build_support/readyshell_overlay_report.py
index d858eb5..779876e 100644
--- a/build_support/readyshell_overlay_report.py
+++ b/build_support/readyshell_overlay_report.py
@@ -13,6 +13,7 @@
from pathlib import Path
from readyos_profiles import resolve_profile
+from update_documentation_html_status import CURRENT, banner
ROOT = Path(__file__).resolve().parents[1]
@@ -963,7 +964,7 @@ def render_markdown(ctx: dict[str, object]) -> str:
"",
"| Region | Range | Size | Notes |",
"| --- | --- | ---: | --- |",
- f"| Resident app window | `$1000-$C5FF` | `{0xB600}` | ReadyOS app-owned RAM window for ReadyShell. |",
+ f"| ReadyOS snapshot window | `$1000-$C5FF` | `{0xB600}` | Full app-owned RAM captured by the shim; the resident 1 KB shim begins at `$C600`. |",
f"| Overlay load address bytes | `{fmt_range(ctx['overlay_loadaddr'], ctx['overlay_start'] - 1)}` | `2` | PRG load address emitted ahead of each overlay sidecar file. |",
f"| Overlay execution window | `{fmt_range(ctx['overlay_start'], ctx['himem'] - 1)}` | `{ctx['window_size']}` | Shared live area for whichever overlay is active. |",
f"| Resident BSS | `{fmt_range(ctx['bss_start'], ctx['bss_end'])}` | `{ctx['bss_size']}` | Resident writable data below the overlay load address. |",
@@ -1098,7 +1099,7 @@ def render_markdown(ctx: dict[str, object]) -> str:
)
-def render_html(ctx: dict[str, object]) -> str:
+def render_html(ctx: dict[str, object], status_message: str) -> str:
cmd_reu_rows = []
for row in command_reu_usage_rows(ctx):
cmd_reu_rows.append(
@@ -1414,6 +1415,7 @@ def render_html(ctx: dict[str, object]) -> str:
+{banner("current", status_message)}
ReadyShell Overlay Inventory Report ({html.escape(ctx['version'])})
@@ -1445,7 +1447,7 @@ def render_html(ctx: dict[str, object]) -> str:
Runtime Memory Map
- Resident app window: $1000-$C5FF ({0xB600} bytes)
+ ReadyOS snapshot window: $1000-$C5FF ({0xB600} bytes); the resident 1 KB shim begins at $C600.
Overlay load bytes: {fmt_range(ctx['overlay_loadaddr'], ctx['overlay_start'] - 1)}
Overlay execution window: {fmt_range(ctx['overlay_start'], ctx['himem'] - 1)} ({ctx['window_size']} bytes)
Resident BSS: {fmt_range(ctx['bss_start'], ctx['bss_end'])} ({ctx['bss_size']} bytes)
@@ -1738,12 +1740,17 @@ def main() -> int:
)
markdown_text = render_markdown(ctx) + "\n"
- html_text = render_html(ctx)
+ html_text = render_html(
+ ctx, CURRENT["docs/readyshell_overlay_inventory.html"]
+ )
+ private_html_text = render_html(
+ ctx, CURRENT["privatedocs/reports/readyshell_overlay_inventory.html"]
+ )
for out_path, text in (
(args.markdown_out, markdown_text),
(args.html_out, html_text),
(private_markdown_out, markdown_text),
- (private_html_out, html_text),
+ (private_html_out, private_html_text),
):
out_path.parent.mkdir(parents=True, exist_ok=True)
out_path.write_text(text, encoding="utf-8")
diff --git a/build_support/report_app_headroom.py b/build_support/report_app_headroom.py
index 1f65f46..dce087d 100644
--- a/build_support/report_app_headroom.py
+++ b/build_support/report_app_headroom.py
@@ -53,8 +53,8 @@ def readyshell_heap_report(txt: str, segs: dict[str, tuple[int, int, int]]):
}
-def map_report(rel: str, spec: dict) -> dict:
- path = ROOT / rel
+def map_report(root: Path, rel: str, spec: dict, app_window_end: int) -> dict:
+ path = root / rel
txt, segs = memmap.parse_map_segments(path)
main_names = spec["main_segments"]
used_segments = {
@@ -68,22 +68,87 @@ def map_report(rel: str, spec: dict) -> dict:
}
max_end = max(end for name, (_start, end, _size) in segs.items() if name in main_names)
total_size = sum(size for name, (_start, _end, size) in segs.items() if name in main_names)
+ code_names = ("STARTUP", "LOWCODE", "CODE", "RODATA", "INIT", "ONCE", "ENTRY", "RESIDENT", "HIDDEN", "BRIDGE")
+ code_size = sum(segs[name][2] for name in code_names if name in segs)
+ data_size = segs.get("DATA", (0, 0, 0))[2]
+ bss_size = segs.get("BSS", (0, 0, 0))[2]
report = {
"name": Path(rel).stem,
"map": rel,
"runtime_end": hex4(max_end),
- "app_window_end": hex4(APP_WINDOW_END),
- "app_window_headroom": APP_WINDOW_END - max_end,
+ "app_window_end": hex4(app_window_end),
+ "app_window_headroom": app_window_end - max_end,
"main_segment_total": total_size,
+ "code_ro_init_bytes": code_size,
+ "data_bytes": data_size,
+ "bss_bytes": bss_size,
"segments": used_segments,
}
- if rel.endswith("readyshell.map"):
+ if "readyshell" in Path(rel).stem:
heap = readyshell_heap_report(txt, segs)
if heap:
report["readyshell"] = heap
+ report["heap_capacity"] = heap["heap_size"]
+ elif "BSS" in segs:
+ try:
+ himem = memmap.parse_map_symbol(txt, "__HIMEM__")
+ stack_size = memmap.parse_map_symbol(txt, "__STACKSIZE__")
+ heap_start = segs["BSS"][1] + 1
+ if heap_start & 1:
+ heap_start += 1
+ heap_end = himem - stack_size - 1
+ report["heap_capacity"] = max(0, heap_end - heap_start + 1)
+ report["heap_start"] = hex4(heap_start)
+ report["heap_end"] = hex4(heap_end)
+ report["stack_reserve"] = stack_size
+ except ValueError:
+ pass
return report
+def comparison_markdown(before: dict, after: dict) -> str:
+ old_by_name = {row["name"]: row for row in before["maps"]}
+ lines = [
+ "# ReadyOS Bank Refactor Memory Comparison",
+ "",
+ "Generated from linker maps before and after the schema-v5 ReadyOS-bank refactor.",
+ "Positive headroom/heap deltas mean more free C64 RAM; negative code/data/BSS deltas mean smaller linked segments.",
+ "",
+ "| App/map | Code/RO/init before | after | delta | Data before | after | delta | BSS before | after | delta | Heap before | after | delta | Window headroom before | after | delta |",
+ "| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: |",
+ ]
+ for new in after["maps"]:
+ old = old_by_name.get(new["name"])
+ if not old:
+ continue
+
+ def val(row: dict, key: str):
+ return row.get(key)
+
+ def cell(value):
+ return "—" if value is None else str(value)
+
+ def delta(key: str):
+ a, b = val(old, key), val(new, key)
+ return None if a is None or b is None else b - a
+
+ lines.append(
+ f"| {new['name']} | {cell(val(old, 'code_ro_init_bytes'))} | {cell(val(new, 'code_ro_init_bytes'))} | {cell(delta('code_ro_init_bytes'))} "
+ f"| {cell(val(old, 'data_bytes'))} | {cell(val(new, 'data_bytes'))} | {cell(delta('data_bytes'))} "
+ f"| {cell(val(old, 'bss_bytes'))} | {cell(val(new, 'bss_bytes'))} | {cell(delta('bss_bytes'))} "
+ f"| {cell(val(old, 'heap_capacity'))} | {cell(val(new, 'heap_capacity'))} | {cell(delta('heap_capacity'))} "
+ f"| {cell(val(old, 'app_window_headroom'))} | {cell(val(new, 'app_window_headroom'))} | {cell(delta('app_window_headroom'))} |"
+ )
+ lines.extend([
+ "",
+ f"Before snapshot end: `{before['app_window_end']}`. After snapshot end: `{after['app_window_end']}`.",
+ "ReadyBASIC has no conventional cc65 BSS/heap: its custom assembler/linker budget is enforced separately by `verify_readybasic_plugin.py`.",
+ "ReadyShell heap is bounded by its unchanged overlay load address; the full snapshot ends at `$C5FF` before the 1 KB resident shim.",
+ "",
+ ])
+ return "\n".join(lines)
+
+
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument(
@@ -91,20 +156,28 @@ def main() -> int:
type=Path,
help="Optional JSON output path. Prints to stdout when omitted.",
)
+ parser.add_argument("--root", type=Path, default=ROOT,
+ help="Repository root containing the map files.")
+ parser.add_argument("--app-window-end", type=lambda s: int(s, 0), default=APP_WINDOW_END,
+ help="Inclusive snapshot window end (default: 0xC5FF).")
+ parser.add_argument("--compare-json", type=Path,
+ help="Earlier JSON report to compare with this report.")
+ parser.add_argument("--markdown-output", type=Path,
+ help="Write a Markdown comparison (requires --compare-json).")
args = parser.parse_args()
spec = json.loads(memmap.SPEC_PATH.read_text(encoding="utf-8"))
reports = []
for rel in spec["map_files"]:
- path = ROOT / rel
+ path = args.root / rel
if not path.exists():
print(f"missing map file: {rel}", file=sys.stderr)
return 1
- reports.append(map_report(rel, spec))
+ reports.append(map_report(args.root, rel, spec, args.app_window_end))
payload = {
"app_window_start": hex4(int(str(spec["ram_windows"]["app_runtime"]["start"]), 0)),
- "app_window_end": hex4(APP_WINDOW_END),
+ "app_window_end": hex4(args.app_window_end),
"maps": reports,
}
text = json.dumps(payload, indent=2, sort_keys=True) + "\n"
@@ -113,6 +186,12 @@ def main() -> int:
args.output.write_text(text, encoding="utf-8")
else:
print(text, end="")
+ if args.markdown_output:
+ if not args.compare_json:
+ parser.error("--markdown-output requires --compare-json")
+ before = json.loads(args.compare_json.read_text(encoding="utf-8"))
+ args.markdown_output.parent.mkdir(parents=True, exist_ok=True)
+ args.markdown_output.write_text(comparison_markdown(before, payload), encoding="utf-8")
return 0
diff --git a/build_support/run_c64u_config_probe.sh b/build_support/run_c64u_config_probe.sh
new file mode 100644
index 0000000..0855f5d
--- /dev/null
+++ b/build_support/run_c64u_config_probe.sh
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+set -u
+
+log="${1:-/tmp/c64u_configs_probe.log}"
+status="${2:-/tmp/c64u_configs_probe.status}"
+
+rm -f "$log" "$status"
+date > "$log"
+
+query() {
+ local label="$1"
+ local url="$2"
+ {
+ echo
+ echo "### $label"
+ curl -sS --max-time 30 "$url"
+ echo
+ } >> "$log" 2>&1
+}
+
+query "iec all" "http://10.0.0.79/v1/configs/iec*/*"
+query "drive paths" "http://10.0.0.79/v1/configs/*drive*/*path*"
+query "drive bus ids" "http://10.0.0.79/v1/configs/*drive*/*bus*"
+query "all configs" "http://10.0.0.79/v1/configs"
+
+echo done > "$status"
diff --git a/build_support/run_easyflash_vice_suites.sh b/build_support/run_easyflash_vice_suites.sh
index 0aa5472..9bc86d6 100755
--- a/build_support/run_easyflash_vice_suites.sh
+++ b/build_support/run_easyflash_vice_suites.sh
@@ -24,6 +24,8 @@ case "$SCOPE" in
esac
cd "$READYOS_ROOT"
+PUBLIC_VERSION_TEXT="$(python3 build_support/update_build_version.py --current)"
+PUBLIC_VERSION="${PUBLIC_VERSION_TEXT%[A-Z]}"
mkdir -p "$OUT_DIR"
RUN_VERSION_TEXT="$(python3 build_support/update_build_version.py --next)"
@@ -31,38 +33,85 @@ make -B \
BUILD_SUPPORT_DIR=build_support \
PROFILE=precog-d81 \
READYOS_VERSION_TEXT="$RUN_VERSION_TEXT" \
- READYOS_CONFIG_RUN_FIRST=readybasic \
profile
make READYOS_VERSION_TEXT="$RUN_VERSION_TEXT" easyflash
-CRT_REL="$(ls -t Releases/0.2.4/precog-easyflash/readyos_easyflash.crt | head -1)"
-D64_REL="$(ls -t Releases/0.2.4/precog-easyflash/readyos_data.d64 | head -1)"
+CRT_REL="$(ls -t Releases/$PUBLIC_VERSION/precog-easyflash/readyos_easyflash.crt | head -1)"
+D64_REL="$(ls -t Releases/$PUBLIC_VERSION/precog-easyflash/readyos_data.d64 | head -1)"
CRT="$(cd "$(dirname "$CRT_REL")" && pwd)/$(basename "$CRT_REL")"
TEST_D64="$OUT_DIR/readyos_data.easyflash-vice.d64"
cp -f "$D64_REL" "$TEST_D64"
D64="$(cd "$(dirname "$TEST_D64")" && pwd)/$(basename "$TEST_D64")"
declare -a RUN_PLANS=()
+PLAN_START_PAUSE_S="${EASYFLASH_PLAN_START_PAUSE_S:-20}"
+PLAN_RETRY_PAUSE_S="${EASYFLASH_PLAN_RETRY_PAUSE_S:-20}"
+PLAN_TIMEOUT_S="${EASYFLASH_PLAN_TIMEOUT_S:-1200}"
+SHORT_PLAN_TIMEOUT_S="${EASYFLASH_SHORT_PLAN_TIMEOUT_S:-900}"
+DEMO_PLAN_TIMEOUT_S="${EASYFLASH_DEMO_PLAN_TIMEOUT_S:-1800}"
+PLUGIN_PLAN_TIMEOUT_S="${EASYFLASH_PLUGIN_PLAN_TIMEOUT_S:-1800}"
+VISUAL_PLAN_TIMEOUT_S="${EASYFLASH_VISUAL_PLAN_TIMEOUT_S:-1800}"
+
+run_vice_plan_with_timeout() {
+ local plan="$1"
+ local timeout_s="$2"
+ python3 - "$PROJECT" "$plan" "$timeout_s" <<'PY'
+import os
+import signal
+import subprocess
+import sys
+
+project, plan, timeout_s = sys.argv[1], sys.argv[2], int(sys.argv[3])
+cmd = ["dotnet", "run", "--project", project, "--", "run-plan", "--plan", plan, "--close-vice"]
+proc = subprocess.Popen(cmd, start_new_session=True)
+try:
+ raise SystemExit(proc.wait(timeout=timeout_s))
+except subprocess.TimeoutExpired:
+ print(f"[timeout] VICE plan exceeded {timeout_s}s: {plan}", flush=True)
+ os.killpg(proc.pid, signal.SIGTERM)
+ try:
+ proc.wait(timeout=10)
+ except subprocess.TimeoutExpired:
+ os.killpg(proc.pid, signal.SIGKILL)
+ proc.wait()
+ raise SystemExit(124)
+PY
+}
emit_readybasic_plan() {
local name="$1"
local script="$2"
local plan_var="$3"
+ local start_app="${4-readybasic}"
local regular_plan="$OUT_DIR/$name.regular.yaml"
local easyflash_plan="$OUT_DIR/$name.easyflash.yaml"
env \
READYBASIC_SKIP_BUILD=1 \
READYBASIC_GENERATE_PLAN_ONLY=1 \
+ READYBASIC_HOTKEY_EXPECT_F4="${READYBASIC_HOTKEY_EXPECT_F4:-}" \
+ READYBASIC_HOTKEY_EXPECT_F2="${READYBASIC_HOTKEY_EXPECT_F2:-}" \
+ READYBASIC_HOTKEY_F4_RETURN_MODE="${READYBASIC_HOTKEY_F4_RETURN_MODE:-}" \
+ READYBASIC_HOTKEY_SCENARIO="${READYBASIC_HOTKEY_SCENARIO:-}" \
+ READYBASIC_CHAIN_BOOT_MODE="${READYBASIC_CHAIN_BOOT_MODE:-launcher}" \
+ READYBASIC_CHAIN_READYBASIC_BANK="${READYBASIC_CHAIN_READYBASIC_BANK:-}" \
+ READYBASIC_CHAIN_REUVIEWER_BANK="${READYBASIC_CHAIN_REUVIEWER_BANK:-}" \
+ READYBASIC_CHAIN_RESOURCE_BANKS="${READYBASIC_CHAIN_RESOURCE_BANKS:-}" \
+ READYBASIC_CHAIN_CONSTRAIN_BITMAP="${READYBASIC_CHAIN_CONSTRAIN_BITMAP:-}" \
+ READYBASIC_CHAIN_READYOS_BANK="${READYBASIC_CHAIN_READYOS_BANK:-}" \
"$plan_var=$regular_plan" \
"$script"
- python3 build_support/easyflash_plan_from_regular.py \
- --input "$regular_plan" \
- --output "$easyflash_plan" \
- --crt "$CRT" \
- --disk8 "$D64" \
- --start-app readybasic
+ local -a convert_args=(
+ --input "$regular_plan"
+ --output "$easyflash_plan"
+ --crt "$CRT"
+ --disk8 "$D64"
+ )
+ if [ -n "$start_app" ]; then
+ convert_args+=(--start-app "$start_app")
+ fi
+ python3 build_support/easyflash_plan_from_regular.py "${convert_args[@]}"
RUN_PLANS+=("$easyflash_plan")
}
@@ -101,6 +150,14 @@ if [ "$SCOPE" = "all" ] || [ "$SCOPE" = "readybasic" ]; then
emit_readybasic_plan readybasic_screen_reu_temp_probe "$SCRIPT_DIR/run_readybasic_screen_reu_temp_probe.sh" READYBASIC_SCRREU_PLAN
emit_readybasic_plan readybasic_state_probe "$SCRIPT_DIR/run_readybasic_state_probe.sh" READYBASIC_PLAN
emit_readybasic_plan readybasic_large_vars_probe "$SCRIPT_DIR/run_readybasic_large_vars_probe.sh" READYBASIC_PLAN
+ READYBASIC_HOTKEY_EXPECT_F4="CLIPBOARD" READYBASIC_HOTKEY_F4_RETURN_MODE="stop_after_f4" \
+ emit_readybasic_plan readybasic_hotkey_f4_probe "$SCRIPT_DIR/run_readybasic_hotkey_probe.sh" READYBASIC_HOTKEY_PLAN
+ READYBASIC_HOTKEY_EXPECT_F2="CALENDAR 26" READYBASIC_HOTKEY_SCENARIO="f2_only" \
+ emit_readybasic_plan readybasic_hotkey_f2_probe "$SCRIPT_DIR/run_readybasic_hotkey_probe.sh" READYBASIC_HOTKEY_PLAN
+ READYBASIC_KEYBOARD_BOOT_MODE=launcher READYBASIC_KEYBOARD_READYBASIC_BANK=5 READYBASIC_KEYBOARD_LAUNCH_KEYS="17,17,17,17,13" READYBASIC_KEYBOARD_PARTIAL_F2_EXPECT="CALENDAR 26" \
+ emit_readybasic_plan readybasic_keyboard_regression_probe "$SCRIPT_DIR/run_readybasic_keyboard_regression_probe.sh" READYBASIC_KEYBOARD_REGRESSION_PLAN ""
+ READYBASIC_CHAIN_READYBASIC_BANK=5 READYBASIC_CHAIN_REUVIEWER_BANK=8 READYBASIC_CHAIN_CONSTRAIN_BITMAP=1 READYBASIC_CHAIN_BOOT_MODE=launcher \
+ emit_readybasic_plan readybasic_reuviewer_f2_chain_probe "$SCRIPT_DIR/run_readybasic_reuviewer_f2_chain_probe.sh" READYBASIC_REUVIEWER_CHAIN_PLAN ""
emit_readybasic_plan readybasic_cross_app_resume_probe "$SCRIPT_DIR/run_readybasic_cross_app_resume_probe.sh" READYBASIC_PLAN
emit_readybasic_plan readybasic_second_entry_editor_probe "$SCRIPT_DIR/run_readybasic_second_entry_editor_probe.sh" READYBASIC_PLAN
emit_readybasic_plan readybasic_full_suite_visual_verification "$SCRIPT_DIR/run_readybasic_full_suite_visual_verification.sh" READYBASIC_FULL_PLAN
@@ -140,16 +197,24 @@ dotnet build "$PROJECT"
for plan in "${RUN_PLANS[@]}"; do
echo "==> EasyFlash VICE plan: $(basename "$plan")"
+ plan_timeout_s="$PLAN_TIMEOUT_S"
+ case "$(basename "$plan")" in
+ readybasic_demo_suite.*) plan_timeout_s="$DEMO_PLAN_TIMEOUT_S" ;;
+ readybasic_plugin_command_probe.*) plan_timeout_s="$PLUGIN_PLAN_TIMEOUT_S" ;;
+ readybasic_reuviewer_f2_chain_probe.*) plan_timeout_s="$PLUGIN_PLAN_TIMEOUT_S" ;;
+ readybasic_full_suite_visual_verification.*) plan_timeout_s="$VISUAL_PLAN_TIMEOUT_S" ;;
+ *) plan_timeout_s="$SHORT_PLAN_TIMEOUT_S" ;;
+ esac
plan_rc=1
for attempt in 1 2; do
if [ "$attempt" -gt 1 ]; then
echo "==> Retrying EasyFlash VICE plan after cold-start pause: $(basename "$plan")"
- sleep 15
+ sleep "$PLAN_RETRY_PAUSE_S"
else
- sleep 5
+ sleep "$PLAN_START_PAUSE_S"
fi
set +e
- dotnet run --project "$PROJECT" -- run-plan --plan "$plan" --close-vice
+ run_vice_plan_with_timeout "$plan" "$plan_timeout_s"
plan_rc=$?
set -e
if [ "$plan_rc" -eq 0 ]; then
diff --git a/build_support/run_launcher_dma_no_uci_fallback_probe.sh b/build_support/run_launcher_dma_no_uci_fallback_probe.sh
new file mode 100755
index 0000000..579ecb0
--- /dev/null
+++ b/build_support/run_launcher_dma_no_uci_fallback_probe.sh
@@ -0,0 +1,129 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+READYOS_ROOT="${READYOS_ROOT:-$(cd "$SCRIPT_DIR/.." && pwd)}"
+if [ -n "${VICE_TASKS_ROOT:-}" ]; then
+ VICE_TOOL_ROOT="$(cd "$VICE_TASKS_ROOT" && pwd)"
+else
+ HARNESS_REPO="${VICE_TASKS_REPO:-$READYOS_ROOT/../agenticdevharness}"
+ VICE_TOOL_ROOT="$(cd "$HARNESS_REPO/tools/vice_tasks_dotnet" && pwd)"
+fi
+
+PROJECT="${VICE_TASKS_DOTNET_PROJECT:-$VICE_TOOL_ROOT/src/ViceTasks.Binary/ViceTasks.Binary.csproj}"
+PROFILE="${READYOS_PROFILE:-precog-d81}"
+D81="${1:-$(python3 "$READYOS_ROOT/build_support/readyos_profiles.py" latest-disk --profile "$PROFILE" --drive 8)}"
+PREBOOT="${2:-${D81%.d81}-preboot.prg}"
+PLAN="${LAUNCHER_DMA_FALLBACK_PLAN:-$SCRIPT_DIR/launcher_dma_no_uci_fallback.generated.yaml}"
+VICE_HEADLESS="${VICE_HEADLESS:-true}"
+
+if [ ! -f "$D81" ]; then
+ echo "D81 not found: $D81" >&2
+ exit 1
+fi
+if [ ! -f "$PREBOOT" ]; then
+ echo "preboot PRG not found: $PREBOOT" >&2
+ exit 1
+fi
+
+cat >"$PLAN" <>"$PLAN" <>"$PLAN" <>"$PLAN" <<'YAML'
type: dump.memory_ranges
params:
ranges:
- - { label: basic_pointers_002b, start: 0x002B, end: 0x003F }
+ - { label: basic_pnters_002b, start: 0x002B, end: 0x003F }
- { label: basic_text_and_vars_1200, start: 0x1200, end: 0x1700 }
- { label: string_heap_9400, start: 0x9400, end: 0x9600 }
- { label: runtime_state_9600, start: 0x9600, end: 0x9A00 }
diff --git a/build_support/run_readybasic_demo_suite.sh b/build_support/run_readybasic_demo_suite.sh
index 854dca2..684045f 100755
--- a/build_support/run_readybasic_demo_suite.sh
+++ b/build_support/run_readybasic_demo_suite.sh
@@ -109,6 +109,8 @@ YAML
mkdir -p "$(dirname "$PLAN")"
cd "$READYOS_ROOT"
+PUBLIC_VERSION_TEXT="$(python3 build_support/update_build_version.py --current)"
+PUBLIC_VERSION="${PUBLIC_VERSION_TEXT%[A-Z]}"
if [ "${READYBASIC_SKIP_BUILD:-0}" != "1" ]; then
RUN_VERSION_TEXT="$(python3 build_support/update_build_version.py --next)"
make -B \
@@ -119,8 +121,8 @@ if [ "${READYBASIC_SKIP_BUILD:-0}" != "1" ]; then
profile
fi
-D81_REL="$(ls -t Releases/0.2.4/precog-d81/*.d81 | head -1)"
-PREBOOT_REL="$(ls -t Releases/0.2.4/precog-d81/*-preboot.prg | head -1)"
+D81_REL="$(ls -t Releases/$PUBLIC_VERSION/precog-d81/*.d81 | head -1)"
+PREBOOT_REL="$(ls -t Releases/$PUBLIC_VERSION/precog-d81/*-preboot.prg | head -1)"
D81="$D81_REL"
PREBOOT="$PREBOOT_REL"
@@ -172,8 +174,9 @@ if [ "$READYBASIC_DEMO_WARP_OFF" = "1" ]; then
emit_warp_step "warp_off_for_visible_demo" "false"
fi
-emit_type_step "demo_01_intro" $'PRINT CHR$(147);CHR$(158);"DEMO 1: READYBASIC BASICS"\rPRINT "FREEMEM, VARIABLES, AND A PROGRAM":PRINT CHR$(5)\r' "$READ_PAUSE"
-emit_type_step "demo_01_setup" $'FREEMEM()\rNEW\rA%=42\r10 B%=ZADD16(42,8)\r20 PRINT "PROGRAM SUM";B%\rLIST\r' "$STEP_POST"
+emit_type_step "demo_01_intro" $'PRINT CHR$(147);CHR$(158);"DEMO 1: READYBASIC BASICS"\rPRINT "MEMAVL, VARIABLES, AND A PROGRAM":PRINT CHR$(5)\r' "$READ_PAUSE"
+emit_type_step "demo_01_setup" $'MEMAVL()\rNEW\rA%=42\r10 B%=ZADD16(42,8)\r20 PRINT "PROGRAM SUM";B%\r' "$STEP_POST"
+emit_type_step "demo_01_list" $'LIST\r' "$STEP_POST"
emit_type_step "demo_01_basics" $'PRINT CHR$(158);"EXPECT: RUN PRINTS PROGRAM SUM 50"\rPRINT CHR$(5)\rRUN\rA%=42\r' "$RUN_POST"
emit_assert_step "assert_demo_01_program_sum" "PROGRAM SUM 50"
@@ -193,8 +196,11 @@ emit_key_step "ctrl_b_editor_demo" "2" "$STEP_POST"
emit_wait_step "wait_launcher_after_editor_demo" "READY OS" "30"
emit_key_step "move_editor_to_readybasic_demo" "17,17,17,17,13" "$STEP_POST"
emit_wait_step "wait_readybasic_after_editor_demo" "READY." "60"
-emit_type_step "demo_03_resume_intro" $'PRINT CHR$(147);CHR$(158);"BACK IN READYBASIC"\rPRINT "VARIABLES AND PROGRAM TEXT SHOULD REMAIN":PRINT CHR$(5)\r' "$READ_PAUSE"
-emit_type_step "demo_03_resume_var_proof" $'FREEMEM()\rPRINT "A STILL";A%\rPRINT CHR$(158);"EXPECT: A IS 42 AND RUN STILL WORKS"\rPRINT CHR$(5)\r' "$STEP_POST"
+emit_type_step "demo_03_resume_liveness" $'PRINT "RESUME LIVE"\r' "$STEP_POST"
+emit_assert_step "assert_demo_03_resume_liveness" "RESUME LIVE"
+emit_type_step "demo_03_resume_intro_clear" $'PRINT CHR$(147);CHR$(158);"BACK IN READYBASIC"\r' "$STEP_POST"
+emit_type_step "demo_03_resume_intro_detail" $'PRINT "VARIABLES AND PROGRAM TEXT SHOULD REMAIN":PRINT CHR$(5)\r' "$READ_PAUSE"
+emit_type_step "demo_03_resume_var_proof" $'MEMAVL()\rPRINT "A STILL";A%\rPRINT CHR$(158);"EXPECT: A IS 42 AND RUN STILL WORKS"\rPRINT CHR$(5)\r' "$STEP_POST"
cat >>"$PLAN" <<'YAML'
- id: capture_demo_03_resume_var_proof
type: screen.capture
@@ -237,8 +243,8 @@ emit_assert_step "assert_demo_06_sum" "SUM 6"
emit_assert_step "assert_demo_06_range" "RANGE 7 10"
emit_assert_step "assert_demo_06_fadd" "FADD 3.5"
-emit_type_step "demo_07_intro" $'PRINT CHR$(147);CHR$(158);"DEMO 8: REU BUFFER COMMANDS"\rPRINT "BUFNEW RETURNS; FILL AND FREE DO WORK":PRINT CHR$(5)\r' "$READ_PAUSE"
-emit_type_step "demo_07_reu" $'H%=BUFNEW(64)\rBUFFILL(H%,170)\rPRINT CHR$(158);"EXPECT: HANDLE 1, THEN FREED 1"\rPRINT CHR$(5)\rPRINT "HANDLE";H%\rBUFFREE(H%)\rPRINT "FREED";H%\r' "$READ_PAUSE"
+emit_type_step "demo_07_intro" $'PRINT CHR$(147);CHR$(158);"DEMO 8: REU BUFFER COMMANDS"\rPRINT "BUFMAKE RETURNS; FILL AND FREE DO WORK":PRINT CHR$(5)\r' "$READ_PAUSE"
+emit_type_step "demo_07_reu" $'H%=BUFMAKE(64)\rBUFFILL(H%,170)\rPRINT CHR$(158);"EXPECT: HANDLE 1, THEN FREED 1"\rPRINT CHR$(5)\rPRINT "HANDLE";H%\rBUFDROP(H%)\rPRINT "FREED";H%\r' "$READ_PAUSE"
emit_assert_step "assert_demo_07_handle" "HANDLE 1"
emit_assert_step "assert_demo_07_freed" "FREED 1"
@@ -278,4 +284,74 @@ fi
cd "$READYOS_ROOT"
dotnet build "$PROJECT"
-dotnet run --project "$PROJECT" -- run-plan --plan "$PLAN" $CLI_CLOSE_ARG
+RUN_RC=2
+for HARNESS_ATTEMPT in 1 2; do
+ RESULT_LOG="$(mktemp "${TMPDIR:-/tmp}/readybasic_demo_suite.XXXXXX")"
+ set +e
+ dotnet run --project "$PROJECT" -- run-plan --plan "$PLAN" $CLI_CLOSE_ARG | tee "$RESULT_LOG"
+ RUN_RC=${PIPESTATUS[0]}
+ set -e
+ if [ "$RUN_RC" -ne 2 ]; then
+ rm -f "$RESULT_LOG"
+ break
+ fi
+ set +e
+ python3 - "$RESULT_LOG" "$HARNESS_ATTEMPT" <<'PY'
+import json
+import sys
+from pathlib import Path
+
+text = Path(sys.argv[1]).read_text(encoding="utf-8", errors="replace")
+attempt = int(sys.argv[2])
+start = text.rfind("{")
+while start != -1:
+ try:
+ payload = json.loads(text[start:])
+ break
+ except json.JSONDecodeError:
+ start = text.rfind("{", 0, start)
+else:
+ sys.exit(2)
+
+manifest = payload.get("Manifest")
+steps_ok = False
+if manifest:
+ try:
+ manifest_payload = json.loads(Path(manifest).read_text(encoding="utf-8-sig"))
+ steps = manifest_payload.get("steps", [])
+ steps_ok = bool(steps) and all(step.get("status") == "ok" for step in steps)
+ except Exception:
+ steps_ok = False
+
+if (
+ payload.get("Status") == "partial"
+ and payload.get("FailedStep") is None
+ and not payload.get("DegradedSteps")
+ and steps_ok
+):
+ print("treating final-dump-only partial as pass; all ReadyBASIC demo steps passed")
+ sys.exit(0)
+if (
+ attempt < 2
+ and payload.get("Status") == "partial"
+ and payload.get("FailedStep") == "wait_readybasic_prompt"
+):
+ print("retrying ReadyBASIC demo after initial prompt timeout")
+ sys.exit(10)
+sys.exit(2)
+PY
+ PARSE_RC=$?
+ set -e
+ rm -f "$RESULT_LOG"
+ if [ "$PARSE_RC" -eq 0 ]; then
+ RUN_RC=0
+ break
+ fi
+ if [ "$PARSE_RC" -eq 10 ]; then
+ RUN_RC=2
+ continue
+ fi
+ RUN_RC="$PARSE_RC"
+ break
+done
+exit "$RUN_RC"
diff --git a/build_support/run_readybasic_full_suite_visual_verification.sh b/build_support/run_readybasic_full_suite_visual_verification.sh
index ee49425..a94273e 100755
--- a/build_support/run_readybasic_full_suite_visual_verification.sh
+++ b/build_support/run_readybasic_full_suite_visual_verification.sh
@@ -42,6 +42,8 @@ PY
}
cd "$READYOS_ROOT"
+PUBLIC_VERSION_TEXT="$(python3 build_support/update_build_version.py --current)"
+PUBLIC_VERSION="${PUBLIC_VERSION_TEXT%[A-Z]}"
if [ "${READYBASIC_SKIP_BUILD:-0}" != "1" ]; then
RUN_VERSION_TEXT="$(python3 build_support/update_build_version.py --next)"
make -B \
@@ -52,8 +54,8 @@ if [ "${READYBASIC_SKIP_BUILD:-0}" != "1" ]; then
profile
fi
-D81_REL="$(ls -t Releases/0.2.4/precog-d81/*.d81 | head -1)"
-PREBOOT_REL="$(ls -t Releases/0.2.4/precog-d81/*-preboot.prg | head -1)"
+D81_REL="$(ls -t Releases/$PUBLIC_VERSION/precog-d81/*.d81 | head -1)"
+PREBOOT_REL="$(ls -t Releases/$PUBLIC_VERSION/precog-d81/*-preboot.prg | head -1)"
D81="$D81_REL"
PREBOOT="$PREBOOT_REL"
@@ -111,7 +113,7 @@ steps:
- { label: hidden_visible_a000, start: 0xA000, end: 0xA5FF }
- { label: hidden_overlay_a800, start: 0xA800, end: 0xA8FF }
- { label: bridge_c000, start: 0xC000, end: 0xC5FF }
- - { label: reu_alloc_table_c600, start: 0xC600, end: 0xC6FF }
+ - { label: shim_resident_c600, start: 0xC600, end: 0xC9FF }
- id: direct_ping
type: input.sequence
@@ -300,17 +302,17 @@ steps:
params:
contains: "D-RANGE 7 10"
- - id: direct_bufnew
+ - id: direct_bufmake
type: input.sequence
params:
- keys: [$(keys $'PRINT CHR$(147)\rREM D-BUFNEW REU HANDLE TABLE RETURN H%=1 SCREEN D-BUF\rH%=BUFNEW(300)\rPRINT "D-BUF";H%;":END"\r')]
+ keys: [$(keys $'PRINT CHR$(147)\rREM D-BUFMAKE REU HANDLE TABLE RETURN H%=1 SCREEN D-BUF\rH%=BUFMAKE(300)\rPRINT "D-BUF";H%;":END"\r')]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- - id: assert_direct_bufnew
+ - id: assert_direct_bufmake
type: assert.screen
params:
contains: "D-BUF 1 :END"
- - id: dump_direct_bufnew
+ - id: dump_direct_bufmake
type: dump.memory_ranges
params:
ranges: *plugin_ranges
@@ -330,17 +332,17 @@ steps:
params:
not_contains: "?RB ERROR"
- - id: direct_buffree
+ - id: direct_bufdrop
type: input.sequence
params:
- keys: [$(keys $'PRINT CHR$(147)\rREM D-BUFFREE RELEASE REU HANDLE H% SCREEN D-FREE\rBUFFREE(H%)\rPRINT "D-FREE OK"\r')]
+ keys: [$(keys $'PRINT CHR$(147)\rREM D-BUFDROP RELEASE REU HANDLE H% SCREEN D-FREE\rBUFDROP(H%)\rPRINT "D-FREE OK"\r')]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- - id: assert_direct_buffree
+ - id: assert_direct_bufdrop
type: assert.screen
params:
contains: "D-FREE OK"
- - id: assert_direct_buffree_no_error
+ - id: assert_direct_bufdrop_no_error
type: assert.screen_not_contains
params:
not_contains: "?RB ERROR"
@@ -369,24 +371,24 @@ steps:
type: assert.screen
params:
contains: "?RB ERROR 40"
- - id: direct_buffree_screen_handle
+ - id: direct_bufdrop_screen_handle
type: input.sequence
params:
- keys: [$(keys $'PRINT CHR$(147)\rREM D-BUFFREE RELEASES SCREEN HANDLE TYPE\rBUFFREE(S%)\rPRINT "D-SCRFREE";S%\r')]
+ keys: [$(keys $'PRINT CHR$(147)\rREM D-BUFDROP RELEASES SCREEN HANDLE TYPE\rBUFDROP(S%)\rPRINT "D-SCRFREE";S%\r')]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- - id: assert_direct_buffree_screen_handle
+ - id: assert_direct_bufdrop_screen_handle
type: assert.screen
params:
contains: "D-SCRFREE 1"
- - id: assert_direct_buffree_screen_no_error
+ - id: assert_direct_bufdrop_screen_no_error
type: assert.screen_not_contains
params:
not_contains: "?RB ERROR"
- id: direct_scrput_rejects_buffer_handle
type: input.sequence
params:
- keys: [$(keys $'PRINT CHR$(147)\rREM D-SCRPUT MUST REJECT BUFFER HANDLE TYPE\rB%=BUFNEW(300)\rSCRPUT(B%)\r')]
+ keys: [$(keys $'PRINT CHR$(147)\rREM D-SCRPUT MUST REJECT BUFFER HANDLE TYPE\rB%=BUFMAKE(300)\rSCRPUT(B%)\r')]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- id: assert_direct_scrput_rejects_buffer_handle
@@ -396,7 +398,7 @@ steps:
- id: direct_free_buffer_after_type_error
type: input.sequence
params:
- keys: [$(keys $'PRINT CHR$(147)\rBUFFREE(B%)\rPRINT "D-BUFREE";B%\r')]
+ keys: [$(keys $'PRINT CHR$(147)\rBUFDROP(B%)\rPRINT "D-BUFREE";B%\r')]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- id: assert_direct_free_buffer_after_type_error
@@ -411,7 +413,7 @@ steps:
- id: direct_handle_128_edge
type: input.sequence
params:
- keys: [$(keys $'PRINT CHR$(147)\rNEW\r10 FOR I=1 TO 128\r20 H%=BUFNEW(1)\r30 NEXT I\r40 PRINT "D-HMAX";H%\rRUN\r')]
+ keys: [$(keys $'PRINT CHR$(147)\rNEW\r10 FOR I=1 TO 128\r20 H%=BUFMAKE(1)\r30 NEXT I\r40 PRINT "D-HMAX";H%\rRUN\r')]
inter_key_delay_s: 0.03
post_delay_s: 5.0
- id: assert_direct_handle_128_edge
@@ -425,7 +427,7 @@ steps:
- id: direct_handle_129_rejected
type: input.sequence
params:
- keys: [$(keys $'PRINT CHR$(147)\rE%=BUFNEW(1)\r')]
+ keys: [$(keys $'PRINT CHR$(147)\rE%=BUFMAKE(1)\r')]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- id: assert_direct_handle_129_rejected
@@ -435,7 +437,7 @@ steps:
- id: direct_free_128_handles
type: input.sequence
params:
- keys: [$(keys $'PRINT CHR$(147)\rNEW\r10 FOR I=1 TO 128\r20 BUFFREE(I)\r30 NEXT I\r40 PRINT "D-HFREED"\rRUN\r')]
+ keys: [$(keys $'PRINT CHR$(147)\rNEW\r10 FOR I=1 TO 128\r20 BUFDROP(I)\r30 NEXT I\r40 PRINT "D-HFREED"\rRUN\r')]
inter_key_delay_s: 0.03
post_delay_s: 5.0
- id: assert_direct_free_128_handles
@@ -449,7 +451,7 @@ steps:
- id: direct_48k_heap_edge
type: input.sequence
params:
- keys: [$(keys $'PRINT CHR$(147)\rM%=BUFNEW(49152)\rPRINT "D-MAXBUF";M%\r')]
+ keys: [$(keys $'PRINT CHR$(147)\rM%=BUFMAKE(49152)\rPRINT "D-MAXBUF";M%\r')]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- id: assert_direct_48k_heap_edge
@@ -459,7 +461,7 @@ steps:
- id: direct_48k_heap_full
type: input.sequence
params:
- keys: [$(keys $'PRINT CHR$(147)\rE%=BUFNEW(1)\r')]
+ keys: [$(keys $'PRINT CHR$(147)\rE%=BUFMAKE(1)\r')]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- id: assert_direct_48k_heap_full
@@ -469,7 +471,7 @@ steps:
- id: direct_free_48k_heap
type: input.sequence
params:
- keys: [$(keys $'PRINT CHR$(147)\rBUFFREE(M%)\rPRINT "D-MAXFREE";M%\r')]
+ keys: [$(keys $'PRINT CHR$(147)\rBUFDROP(M%)\rPRINT "D-MAXFREE";M%\r')]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- id: assert_direct_free_48k_heap
@@ -503,7 +505,7 @@ steps:
- id: direct_free_screen_heap
type: input.sequence
params:
- keys: [$(keys $'PRINT CHR$(147)\rNEW\r10 FOR I=1 TO 24\r20 BUFFREE(I)\r30 NEXT I\r40 PRINT "D-SFREED"\rRUN\r')]
+ keys: [$(keys $'PRINT CHR$(147)\rNEW\r10 FOR I=1 TO 24\r20 BUFDROP(I)\r30 NEXT I\r40 PRINT "D-SFREED"\rRUN\r')]
inter_key_delay_s: 0.03
post_delay_s: 5.0
- id: assert_direct_free_screen_heap
@@ -700,9 +702,18 @@ steps:
- id: resume_after_exit
type: input.sequence
params:
- keys: [145,17,13]
+ keys: [145,17]
inter_key_delay_s: 0.10
- post_delay_s: 3.0
+ post_delay_s: 0.5
+ - id: clear_keyboard_buffer_before_full_suite_resume
+ type: memory.write
+ params:
+ start: 0x00C6
+ bytes_hex: "00"
+ - id: launch_readybasic_after_full_suite_exit
+ type: monitor.command
+ params:
+ command: "keybuf \\\\x0d"
- id: wait_readybasic_after_resume
type: screen.wait_contains
params:
@@ -911,7 +922,7 @@ steps:
- id: program_handle_enter_and_list
type: input.sequence
params:
- keys: [$(keys $'PRINT CHR$(147)\rNEW\r10 REM BUF REU HANDLE ALLOC RETURN FILL FREE H%=1 SCREEN P-BUF\r20 H%=BUFNEW(300)\r30 PRINT "P-BUF";H%\r40 BUFFILL(H%,170)\r50 BUFFREE(H%)\r60 PRINT "P-FREE";H%\rLIST\r')]
+ keys: [$(keys $'PRINT CHR$(147)\rNEW\r10 REM BUF REU HANDLE ALLOC RETURN FILL FREE H%=1 SCREEN P-BUF\r20 H%=BUFMAKE(300)\r30 PRINT "P-BUF";H%\r40 BUFFILL(H%,170)\r50 BUFDROP(H%)\r60 PRINT "P-FREE";H%\rLIST\r')]
inter_key_delay_s: 0.03
post_delay_s: 3.0
- id: assert_program_handle_rem
diff --git a/build_support/run_readybasic_gfx_mbitmap_demo.sh b/build_support/run_readybasic_gfx_mbitmap_demo.sh
new file mode 100755
index 0000000..571b4ce
--- /dev/null
+++ b/build_support/run_readybasic_gfx_mbitmap_demo.sh
@@ -0,0 +1,216 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+READYOS_ROOT="${READYOS_ROOT:-$(cd "$SCRIPT_DIR/.." && pwd)}"
+if [ -n "${VICE_TASKS_ROOT:-}" ]; then
+ VICE_TOOL_ROOT="$(cd "$VICE_TASKS_ROOT" && pwd)"
+ HARNESS_REPO="$(cd "$VICE_TOOL_ROOT/../.." && pwd)"
+else
+ HARNESS_REPO="${VICE_TASKS_REPO:-$READYOS_ROOT/../agenticdevharness}"
+ HARNESS_REPO="$(cd "$HARNESS_REPO" && pwd)"
+ VICE_TOOL_ROOT="$HARNESS_REPO/tools/vice_tasks_dotnet"
+fi
+PROJECT="$VICE_TOOL_ROOT/src/ViceTasks.Binary/ViceTasks.Binary.csproj"
+PLAN="${READYBASIC_PLAN:-$SCRIPT_DIR/readybasic_gfx_mbitmap_demo.generated.yaml}"
+READYBASIC_VISIBLE="${READYBASIC_VISIBLE:-0}"
+READYBASIC_KEEP_VICE="${READYBASIC_KEEP_VICE:-0}"
+VICE_HEADLESS="true"
+VICE_CLOSE="true"
+CLI_CLOSE_ARG="--close-vice"
+if [ "$READYBASIC_VISIBLE" = "1" ]; then
+ VICE_HEADLESS="false"
+fi
+if [ "$READYBASIC_KEEP_VICE" = "1" ]; then
+ VICE_CLOSE="false"
+ CLI_CLOSE_ARG=""
+fi
+
+keys() {
+ python3 - "$1" <<'PY'
+import sys
+s = sys.argv[1]
+print(",".join(str(ord(ch)) for ch in s))
+PY
+}
+
+cd "$READYOS_ROOT"
+PUBLIC_VERSION_TEXT="$(python3 build_support/update_build_version.py --current)"
+PUBLIC_VERSION="${PUBLIC_VERSION_TEXT%[A-Z]}"
+if [ "${READYBASIC_SKIP_BUILD:-0}" != "1" ]; then
+ RUN_VERSION_TEXT="$(python3 build_support/update_build_version.py --next)"
+ make -B \
+ BUILD_SUPPORT_DIR=build_support \
+ PROFILE=precog-d81 \
+ READYOS_VERSION_TEXT="$RUN_VERSION_TEXT" \
+ READYOS_CONFIG_RUN_FIRST=readybasic \
+ profile
+fi
+
+D81_REL="$(ls -t Releases/$PUBLIC_VERSION/precog-d81/*.d81 | head -1)"
+PREBOOT_REL="$(ls -t Releases/$PUBLIC_VERSION/precog-d81/*-preboot.prg | head -1)"
+D81="$D81_REL"
+PREBOOT="$PREBOOT_REL"
+
+cat >"$PLAN" <"$PLAN" <"$PLAN" <"$PLAN" <"$PLAN" <"$PLAN" <&2
+ exit 1
+ ;;
+esac
+
+keys() {
+ python3 - "$1" <<'PY'
+import sys
+s = sys.argv[1]
+print(",".join(str(ord(ch)) for ch in s))
+PY
+}
+
+emit_hotkey_step() {
+ local id="$1"
+ local hotkey="$2"
+ local post_delay="${3:-1.0}"
+ local target_context="${4:-readybasic}"
+ local pre_delay="${5:-1.0}"
+ local effective_mode="$HOTKEY_INPUT_MODE"
+ local key_byte=""
+ local key_code=""
+ local modifiers=""
+ local matrix_hex=""
+ local shift_hex=""
+
+ case "$hotkey" in
+ ctrl_b)
+ key_byte="2"
+ key_code="11"
+ modifiers=" modifiers: [control]"
+ matrix_hex="1C"
+ shift_hex="04"
+ ;;
+ f2)
+ key_byte="137"
+ key_code="120"
+ matrix_hex="04"
+ shift_hex="01"
+ ;;
+ f4)
+ key_byte="138"
+ key_code="118"
+ matrix_hex="05"
+ shift_hex="01"
+ ;;
+ *)
+ echo "unknown hotkey '$hotkey'" >&2
+ exit 1
+ ;;
+ esac
+
+ if [ "$effective_mode" = "keylog" ] && [ "$target_context" != "readybasic" ]; then
+ effective_mode="keybuf"
+ fi
+
+ if [ "$effective_mode" = "host" ]; then
+ if [ -n "$modifiers" ]; then
+ cat <&2
+ exit 1
+fi
+PENDING_DEC="$((0x1200 + 16#$PENDING_OFF_HEX))"
+SUPPRESS_OFF_HEX="$(awk '/rb_hotkey_suppress:/ { sub(/r.*/, "", $1); sub(/.*:/, "", $1); print $1; exit }' obj/readybasic_hotkey_probe.lst)"
+if [ -z "$SUPPRESS_OFF_HEX" ]; then
+ echo "Could not find rb_hotkey_suppress in obj/readybasic_hotkey_probe.lst" >&2
+ exit 1
+fi
+SUPPRESS_DEC="$((0x1200 + 16#$SUPPRESS_OFF_HEX))"
+CHRIN_ADDR_HEX="$(awk '/rb_chrin:/ { sub(/r.*/, "", $1); sub(/.*:/, "", $1); print $1; exit }' obj/readybasic_hotkey_probe.lst)"
+if [ -z "$CHRIN_ADDR_HEX" ]; then
+ echo "Could not find rb_chrin in obj/readybasic_hotkey_probe.lst" >&2
+ exit 1
+fi
+CHRIN_ADDR_DEC="$((0x1200 + 16#$CHRIN_ADDR_HEX))"
+CHRIN_VEC_HEX="$(printf '%02X %02X' $((CHRIN_ADDR_DEC & 255)) $(((CHRIN_ADDR_DEC >> 8) & 255)))"
+KEYLOG_ADDR_HEX="$(awk '/rb_keylog:/ { sub(/r.*/, "", $1); sub(/.*:/, "", $1); print $1; exit }' obj/readybasic_hotkey_probe.lst)"
+if [ -z "$KEYLOG_ADDR_HEX" ]; then
+ echo "Could not find rb_keylog in obj/readybasic_hotkey_probe.lst" >&2
+ exit 1
+fi
+KEYLOG_ADDR_DEC="$((0xC000 + 16#$KEYLOG_ADDR_HEX))"
+KEYLOG_VEC_HEX="$(printf '%02X %02X' $((KEYLOG_ADDR_DEC & 255)) $(((KEYLOG_ADDR_DEC >> 8) & 255)))"
+CHRIN_DISPATCH_HEX="$(awk '/rb_hotkey_chrin_dispatch:/ { sub(/r.*/, "", $1); sub(/.*:/, "", $1); print $1; exit }' obj/readybasic_hotkey_probe.lst)"
+if [ -z "$CHRIN_DISPATCH_HEX" ]; then
+ echo "Could not find rb_hotkey_chrin_dispatch in obj/readybasic_hotkey_probe.lst" >&2
+ exit 1
+fi
+CHRIN_DISPATCH_DEC="$((0x1200 + 16#$CHRIN_DISPATCH_HEX))"
+if [ "$SCENARIO" = "f2_only" ]; then
+cat >"$PLAN" <&2
+ exit 1
+ fi
+cat >"$PLAN" <"$PLAN" <>"$PLAN" <>"$PLAN" <>"$PLAN" <>"$PLAN" <&2
+ exit 1
+ ;;
+esac
+
+keys() {
+ python3 - "$1" <<'PY'
+import sys
+s = sys.argv[1]
+print(",".join(str(ord(ch)) for ch in s))
+PY
+}
+
+emit_initial_entry_steps() {
+ if [ "$BOOT_MODE" = "launcher" ]; then
+ cat <&2
+ exit 1
+ ;;
+ esac
+
+ if [ "$effective_mode" = "keylog" ] && [ "$target_context" != "readybasic" ]; then
+ if [ "$hotkey" = "ctrl_b" ]; then
+ effective_mode="keybuf"
+ else
+ effective_mode="input"
+ fi
+ fi
+
+ if [ "$effective_mode" = "host" ]; then
+ if [ -n "$modifiers" ]; then
+ cat <&2
+ exit 1
+fi
+CHRIN_ADDR_DEC="$((0x1200 + 16#$CHRIN_ADDR_HEX))"
+CHRIN_VEC_HEX="$(printf '%02X %02X' $((CHRIN_ADDR_DEC & 255)) $(((CHRIN_ADDR_DEC >> 8) & 255)))"
+KEYLOG_ADDR_DEC="$((0xC000 + 16#$KEYLOG_ADDR_HEX))"
+KEYLOG_VEC_HEX="$(printf '%02X %02X' $((KEYLOG_ADDR_DEC & 255)) $(((KEYLOG_ADDR_DEC >> 8) & 255)))"
+READYBASIC_BANK_HEX="$(printf '%02X' "$((READYBASIC_BANK_RAW))")"
+KERNAL_KEYLOG_VEC_HEX="48 EB"
+KERNAL_CHRIN_VEC_HEX="57 F1"
+
+cat >"$PLAN" <>"$PLAN" <>"$PLAN" <>"$PLAN" <>"$PLAN" <"$PLAN" </dev/null || true)"
+fi
+if [ -z "$READYOS_BANK_RAW" ]; then
+ echo "cannot determine the physical ReadyOS bank; build a profile or set READYBASIC_CHAIN_READYOS_BANK" >&2
+ exit 1
+fi
+STABILITY_WAIT="${READYBASIC_CHAIN_STABILITY_WAIT:-2.5}"
+DUPLICATE_KEYLOG="${READYBASIC_HOTKEY_DUPLICATE_KEYLOG:-1}"
+VICE_HEADLESS="true"
+VICE_CLOSE="true"
+CLI_CLOSE_ARG="--close-vice"
+
+if [ "$HOTKEY_INPUT_MODE" = "host" ]; then
+ VICE_HEADLESS="false"
+fi
+if [ "$READYBASIC_VISIBLE" = "1" ]; then
+ VICE_HEADLESS="false"
+fi
+if [ "$READYBASIC_KEEP_VICE" = "1" ]; then
+ VICE_CLOSE="false"
+ CLI_CLOSE_ARG=""
+fi
+
+keys() {
+ python3 - "$1" <<'PY'
+import sys
+s = sys.argv[1]
+print(",".join(str(ord(ch)) for ch in s))
+PY
+}
+
+READYBASIC_BANK="$((READYBASIC_BANK_RAW))"
+REUVIEWER_BANK="$((REUVIEWER_BANK_RAW))"
+if [ "$READYBASIC_BANK" -lt 1 ] || [ "$READYBASIC_BANK" -gt 23 ]; then
+ echo "READYBASIC_CHAIN_READYBASIC_BANK must be in 1..23, got '$READYBASIC_BANK_RAW'" >&2
+ exit 1
+fi
+if [ "$REUVIEWER_BANK" -lt 1 ] || [ "$REUVIEWER_BANK" -gt 23 ]; then
+ echo "READYBASIC_CHAIN_REUVIEWER_BANK must be in 1..23, got '$REUVIEWER_BANK_RAW'" >&2
+ exit 1
+fi
+if [ "$READYBASIC_BANK" -eq "$REUVIEWER_BANK" ]; then
+ echo "ReadyBASIC and REUViewer chain banks must differ" >&2
+ exit 1
+fi
+case "$BOOT_MODE" in
+ runfirst|launcher) ;;
+ *)
+ echo "READYBASIC_CHAIN_BOOT_MODE must be runfirst or launcher, got '$BOOT_MODE'" >&2
+ exit 1
+ ;;
+esac
+
+READYBASIC_BANK_HEX="$(printf '%02X' "$READYBASIC_BANK")"
+REUVIEWER_BANK_HEX="$(printf '%02X' "$REUVIEWER_BANK")"
+
+bitmap_add_bank() {
+ local bank="$1"
+ if [ "$bank" -lt 1 ] || [ "$bank" -gt 23 ]; then
+ echo "chain bitmap bank must be in 1..23, got '$bank'" >&2
+ exit 1
+ fi
+ if [ "$bank" -lt 8 ]; then
+ BITMAP_LO=$((BITMAP_LO | (1 << bank)))
+ elif [ "$bank" -lt 16 ]; then
+ BITMAP_HI=$((BITMAP_HI | (1 << (bank - 8))))
+ else
+ BITMAP_XHI=$((BITMAP_XHI | (1 << (bank - 16))))
+ fi
+}
+
+BITMAP_LO=0
+BITMAP_HI=0
+BITMAP_XHI=0
+bitmap_add_bank "$READYBASIC_BANK"
+bitmap_add_bank "$REUVIEWER_BANK"
+if [ -n "$RESOURCE_BANKS_RAW" ]; then
+ IFS=',' read -r -a RESOURCE_BANKS <<<"$RESOURCE_BANKS_RAW"
+ for raw_bank in "${RESOURCE_BANKS[@]}"; do
+ bank="${raw_bank//[[:space:]]/}"
+ [ -z "$bank" ] && continue
+ bitmap_add_bank "$((bank))"
+ done
+fi
+CHAIN_BITMAP_HEX="$(printf '%02X %02X %02X' "$BITMAP_LO" "$BITMAP_HI" "$BITMAP_XHI")"
+
+# Schema v5 made the ReadyOS-bank token-status table authoritative. Build a
+# 24-byte test image (token 0 plus app tokens 1..23) with only the two chain
+# participants marked VALID|LOADED|RESUMABLE. The probe writes this image by
+# DMA; the retired $C836-$C838 bitmap must not influence navigation anymore.
+CHAIN_STATUS_HEX=""
+for token in $(seq 0 23); do
+ status=0
+ if [ "$token" -eq "$READYBASIC_BANK" ] || [ "$token" -eq "$REUVIEWER_BANK" ]; then
+ status=7
+ fi
+ byte="$(printf '%02X' "$status")"
+ if [ -n "$CHAIN_STATUS_HEX" ]; then
+ CHAIN_STATUS_HEX="$CHAIN_STATUS_HEX $byte"
+ else
+ CHAIN_STATUS_HEX="$byte"
+ fi
+done
+READYOS_BANK_HEX="$(printf '%02X' "$((READYOS_BANK_RAW))")"
+TOKEN_STATUS_RAW="$(awk '$2 == "REUCB_TOKEN_STATUS_OFF" { print $3; exit }' \
+ "$READYOS_ROOT/src/lib/reu_control_bank.h" | sed 's/[uUlL]*$//')"
+if [ -z "$TOKEN_STATUS_RAW" ]; then
+ echo "cannot determine REUCB_TOKEN_STATUS_OFF from reu_control_bank.h" >&2
+ exit 1
+fi
+TOKEN_STATUS_OFF="$((TOKEN_STATUS_RAW))"
+TOKEN_STATUS_LO_HEX="$(printf '%02X' "$((TOKEN_STATUS_OFF & 255))")"
+TOKEN_STATUS_HI_HEX="$(printf '%02X' "$(((TOKEN_STATUS_OFF >> 8) & 255))")"
+
+emit_bitmap_control_steps() {
+ if [ "$CONSTRAIN_BITMAP" = "1" ] || [ -n "$RESOURCE_BANKS_RAW" ]; then
+ cat <&2
+ exit 1
+ ;;
+ esac
+
+ if [ "$effective_mode" = "keylog" ] && [ "$target_context" != "readybasic" ]; then
+ if [ "$hotkey" = "ctrl_b" ]; then
+ effective_mode="keybuf"
+ else
+ effective_mode="keyd"
+ fi
+ fi
+ if [ "$effective_mode" = "pending" ] && [ "$target_context" != "readybasic" ]; then
+ if [ "$hotkey" = "ctrl_b" ]; then
+ effective_mode="keybuf"
+ else
+ effective_mode="input"
+ fi
+ fi
+
+ if [ "$effective_mode" = "host" ]; then
+ if [ -n "$modifiers" ]; then
+ cat <&2
+ exit 1
+fi
+CHRIN_ADDR_DEC="$((0x1200 + 16#$CHRIN_ADDR_HEX))"
+CHRIN_VEC_HEX="$(printf '%02X %02X' $((CHRIN_ADDR_DEC & 255)) $(((CHRIN_ADDR_DEC >> 8) & 255)))"
+KEYLOG_ADDR_DEC="$((0xC000 + 16#$KEYLOG_ADDR_HEX))"
+KEYLOG_VEC_HEX="$(printf '%02X %02X' $((KEYLOG_ADDR_DEC & 255)) $(((KEYLOG_ADDR_DEC >> 8) & 255)))"
+PENDING_DEC="$((0x1200 + 16#$PENDING_OFF_HEX))"
+KERNAL_KEYLOG_VEC_HEX="48 EB"
+KERNAL_CHRIN_VEC_HEX="57 F1"
+
+cat >"$PLAN" <>"$PLAN" <>"$PLAN" <>"$PLAN" <>"$PLAN" <>"$PLAN" <"$PLAN" <"$PLAN" <"$PLAN" </dev/null; then
+ kill "$FIXTURE_PID" 2>/dev/null || true
+ wait "$FIXTURE_PID" 2>/dev/null || true
+ fi
+}
+trap cleanup EXIT
+
+keys() {
+ python3 - "$1" <<'PY'
+import sys
+values = []
+for char in sys.argv[1]:
+ code = ord(char)
+ if 0x61 <= code <= 0x7a:
+ code -= 0x20
+ values.append(str(code))
+print(",".join(values))
+PY
+}
+
+repeat_key() {
+ python3 - "$1" "$2" <<'PY'
+import sys
+print(",".join([sys.argv[1]] * int(sys.argv[2])))
+PY
+}
+
+discover_fixture_host() {
+ if [ -n "${READYIRC_FIXTURE_HOST:-}" ]; then
+ printf '%s\n' "$READYIRC_FIXTURE_HOST"
+ return
+ fi
+ local iface=""
+ local address=""
+ if command -v route >/dev/null 2>&1; then
+ iface="$(route -n get "$C64U_HOST" 2>/dev/null | awk '/interface:/{print $2; exit}')"
+ fi
+ if [ -n "$iface" ] && command -v ipconfig >/dev/null 2>&1; then
+ address="$(ipconfig getifaddr "$iface" 2>/dev/null || true)"
+ fi
+ if [ -z "$address" ] && command -v hostname >/dev/null 2>&1; then
+ address="$(hostname -I 2>/dev/null | awk '{print $1}')"
+ fi
+ if [ -z "$address" ] || [ "$address" = "127.0.0.1" ]; then
+ echo "Unable to discover a LAN address; set READYIRC_FIXTURE_HOST" >&2
+ return 1
+ fi
+ printf '%s\n' "$address"
+}
+
+mkdir -p "$OUT_DIR"
+cd "$READYOS_ROOT"
+
+FIXTURE_HOST="$(discover_fixture_host)"
+
+if [ "${READYIRC_C64U_GENERATE_PLAN_ONLY:-0}" != "1" ] &&
+ [ "${READYIRC_C64U_SKIP_BUILD:-0}" != "1" ]; then
+ VERSION_TEXT="$(python3 build_support/update_build_version.py --current)"
+ make -B \
+ BUILD_SUPPORT_DIR=build_support \
+ PROFILE=precog-d81 \
+ LAUNCHER_DMA_LOAD=1 \
+ READYOS_VERSION_TEXT="$VERSION_TEXT" \
+ profile
+fi
+
+if [ -n "${READYIRC_C64U_D81:-}" ]; then
+ D81="$READYIRC_C64U_D81"
+else
+ PUBLIC_VERSION="$(python3 build_support/update_build_version.py --current)"
+ PUBLIC_VERSION="${PUBLIC_VERSION%[A-Z]}"
+ D81="$(ls -t "Releases/$PUBLIC_VERSION/precog-d81/"*.d81 | head -1)"
+fi
+
+if [ "${READYIRC_C64U_GENERATE_PLAN_ONLY:-0}" != "1" ]; then
+ # The suite's first launch must not resume a stale launcher or ReadyIRC image.
+ # Reuse the established ReadyOS Ultimate preflight to clear REU before boot.
+ if [ "${READYIRC_C64U_SKIP_REU_CLEAR:-0}" != "1" ]; then
+ C64U_HOST="$C64U_HOST" \
+ C64U_SKIP_UPLOAD=1 \
+ C64U_SKIP_CONFIG=1 \
+ READYOS_CLEAR_REU=1 \
+ READYOS_CLEAR_REU_ONLY=1 \
+ /bin/bash build_support/run_readyos_boot_c64u_rest.sh \
+ "$D81" readyirc-clear.d81 "$OUT_DIR/reu-clear-preflight"
+ fi
+
+ # A soft C64 reset can preserve a wedged cartridge/UCI state. Reboot the
+ # Ultimate core before the harness mounts and boots the test disk.
+ if [ "${READYIRC_C64U_SKIP_REBOOT:-0}" != "1" ]; then
+ /usr/bin/curl --fail --silent --show-error --request PUT \
+ "http://$C64U_HOST/v1/machine:reboot" \
+ --output "$OUT_DIR/ultimate-reboot.json"
+ sleep 8
+ fi
+
+ python3 build_support/readyirc_fixture_server.py \
+ --port "$FIXTURE_PORT" \
+ --channel "$FIXTURE_CHANNEL" \
+ --ultimate-host "$C64U_HOST" \
+ --log "$FIXTURE_LOG" \
+ --status "$FIXTURE_STATUS" &
+ FIXTURE_PID=$!
+
+ for _ in $(seq 1 50); do
+ [ -s "$FIXTURE_STATUS" ] && break
+ sleep 0.1
+ done
+ if [ ! -s "$FIXTURE_STATUS" ]; then
+ echo "ReadyIRC fixture did not start" >&2
+ exit 1
+ fi
+fi
+
+DEL_SERVER="$(repeat_key 20 26)"
+DEL_PORT="$(repeat_key 20 5)"
+DEL_NICK="$(repeat_key 20 30)"
+DEL_CHANNEL="$(repeat_key 20 30)"
+SELECT_READYIRC="19,$(repeat_key 17 18),13"
+
+cat >"$PLAN" < }"
+remote_name="${2:?usage: run_readyos_boot_c64u_rest.sh }"
+out_dir="${3:?usage: run_readyos_boot_c64u_rest.sh }"
+api="http://${host}/v1"
+remote_root="${C64U_REMOTE_DIR:-USB1}"
+remote="${remote_root}/${remote_name}"
+tmp_dir="${out_dir}/tmp"
+connect_wait_s="${C64U_CONNECT_WAIT_S:-300}"
+skip_upload="${C64U_SKIP_UPLOAD:-0}"
+skip_config="${C64U_SKIP_CONFIG:-0}"
+clear_reu="${READYOS_CLEAR_REU:-0}"
+clear_reu_banks="${READYOS_CLEAR_REU_BANKS:-256}"
+clear_reu_only="${READYOS_CLEAR_REU_ONLY:-0}"
+machine_reboot="${C64U_MACHINE_REBOOT:-0}"
+mkdir -p "$out_dir" "$tmp_dir"
+log="${out_dir}/run.log"
+: > "$log"
+
+run() {
+ echo "+ $*" >> "$log"
+ "$@" >> "$log" 2>&1
+}
+
+wait_for_http() {
+ local deadline now
+ deadline=$((SECONDS + connect_wait_s))
+ while (( SECONDS <= deadline )); do
+ if curl --fail --silent --show-error --max-time 5 \
+ "${api}/drives" -o "${tmp_dir}/drives.json" >> "$log" 2>&1; then
+ echo "REST ready after ${SECONDS}s" >> "$log"
+ return 0
+ fi
+ sleep 3
+ done
+ now="$(date)"
+ echo "REST not reachable after ${connect_wait_s}s at ${now}" >> "$log"
+ return 1
+}
+
+wait_for_ftp() {
+ local deadline now
+ deadline=$((SECONDS + connect_wait_s))
+ while (( SECONDS <= deadline )); do
+ if curl --fail --silent --show-error --max-time 8 \
+ "ftp://${host}/${remote_root}/" --user anonymous:anonymous@ \
+ -o "${tmp_dir}/ftp-list.txt" >> "$log" 2>&1; then
+ echo "FTP ready after ${SECONDS}s" >> "$log"
+ return 0
+ fi
+ sleep 3
+ done
+ now="$(date)"
+ echo "FTP not reachable after ${connect_wait_s}s at ${now}" >> "$log"
+ return 1
+}
+
+delete_remote_image() {
+ echo "delete remote /${remote}" >> "$log"
+ curl --silent --show-error --max-time 20 \
+ -Q "DELE /${remote}" "ftp://${host}/" --user anonymous:anonymous@ \
+ >> "$log" 2>&1 || true
+}
+
+verify_remote_image() {
+ run curl --fail --silent --show-error --max-time 20 \
+ "ftp://${host}/${remote_root}/" --user anonymous:anonymous@ \
+ -o "${tmp_dir}/ftp-list-after-upload.txt"
+ if ! grep -F -i -q "$remote_name" "${tmp_dir}/ftp-list-after-upload.txt"; then
+ echo "remote image not found after upload: ${remote_name}" >> "$log"
+ return 1
+ fi
+}
+
+reset_machine() {
+ local label="$1"
+ local action="reset"
+ if [[ "$machine_reboot" == "1" ]]; then
+ action="reboot"
+ fi
+ echo "${action} ${label}" >> "$log"
+ run curl --fail --silent --show-error --max-time 10 -X PUT "${api}/machine:${action}"
+ sleep "${READYOS_RESET_WAIT_S:-3}"
+ run curl --fail --silent --show-error --max-time 10 -X PUT "${api}/machine:resume"
+ sleep "${READYOS_RESUME_WAIT_S:-7}"
+}
+
+clear_reu_data() {
+ python3 - "${tmp_dir}/clear_reu.prg" "$clear_reu_banks" <<'PY'
+import pathlib
+import sys
+
+banks = int(sys.argv[2], 0)
+if not 1 <= banks <= 256:
+ raise SystemExit("READYOS_CLEAR_REU_BANKS must be 1..256")
+
+prg = bytearray([
+ 0x01, 0x08, 0x0B, 0x08, 0x0A, 0x00, 0x9E, 0x32,
+ 0x30, 0x36, 0x31, 0x00, 0x00, 0x00, 0x78, 0xA9,
+ 0x00, 0x8D, 0x0A, 0xDF, 0xA2, 0x20, 0x8E, 0x1E,
+ 0x08, 0xA0, 0x00, 0xA9, 0x00, 0x99, 0x00, 0x20,
+ 0xC8, 0xD0, 0xFA, 0xE8, 0xE0, 0x30, 0xD0, 0xEE,
+ 0xA9, 0x00, 0x8D, 0x79, 0x08, 0xAD, 0x79, 0x08,
+ 0x8D, 0x06, 0xDF, 0xA9, 0x00, 0x8D, 0x7A, 0x08,
+ 0xA9, 0x00, 0x8D, 0x02, 0xDF, 0xA9, 0x20, 0x8D,
+ 0x03, 0xDF, 0xA9, 0x00, 0x8D, 0x04, 0xDF, 0xAD,
+ 0x7A, 0x08, 0x8D, 0x05, 0xDF, 0xAD, 0x79, 0x08,
+ 0x8D, 0x06, 0xDF, 0xA9, 0x00, 0x8D, 0x07, 0xDF,
+ 0xA9, 0x10, 0x8D, 0x08, 0xDF, 0xA9, 0x90, 0x8D,
+ 0x01, 0xDF, 0x18, 0xAD, 0x7A, 0x08, 0x69, 0x10,
+ 0x8D, 0x7A, 0x08, 0xD0, 0xCB, 0xEE, 0x79, 0x08,
+ 0xAD, 0x79, 0x08, 0xCD, 0x7B, 0x08, 0xD0, 0xB5,
+ 0x58, 0x60, 0x00, 0x00, 0x00,
+])
+prg[-1] = banks & 0xFF
+pathlib.Path(sys.argv[1]).write_bytes(prg)
+PY
+ echo "clear REU banks=${clear_reu_banks}" >> "$log"
+ run curl --fail --silent --show-error --max-time 30 \
+ -H "Content-Type: application/octet-stream" \
+ --data-binary "@${tmp_dir}/clear_reu.prg" \
+ "${api}/runners:run_prg"
+ sleep "${READYOS_CLEAR_REU_WAIT_S:-20}"
+}
+
+post_bytes() {
+ local address="$1"
+ local file="$2"
+ run curl --fail --silent --show-error --max-time 10 \
+ -X PUT --data-binary "@${file}" \
+ "${api}/machine:writemem?address=${address}"
+}
+
+write_byte_file() {
+ python3 - "$1" "$2" <<'PY'
+import pathlib
+import sys
+pathlib.Path(sys.argv[1]).write_bytes(bytes([int(sys.argv[2], 0) & 0xFF]))
+PY
+}
+
+wait_keyboard_empty() {
+ local sample value
+ for _ in $(seq 1 250); do
+ sample="${tmp_dir}/kb_count.bin"
+ if curl --fail --silent --show-error --max-time 5 \
+ "${api}/machine:readmem?address=C6&length=1" -o "$sample" >> "$log" 2>&1; then
+ value="$(od -An -tu1 "$sample" | tr -d ' ')"
+ if [[ "$value" == "0" ]]; then
+ return 0
+ fi
+ fi
+ sleep 0.03
+ done
+ echo "keyboard buffer did not drain" >> "$log"
+ return 1
+}
+
+type_text() {
+ python3 - "$tmp_dir/type.bin" "$1" <<'PY'
+import pathlib
+import sys
+text = sys.argv[2]
+pathlib.Path(sys.argv[1]).write_bytes(
+ bytes(0x0D if ch in "\r\n" else ord(ch.upper()) for ch in text)
+)
+PY
+
+ local size offset byte_hex
+ size="$(wc -c < "$tmp_dir/type.bin" | tr -d ' ')"
+ offset=0
+ while (( offset < size )); do
+ dd if="$tmp_dir/type.bin" of="$tmp_dir/chunk.bin" bs=1 skip="$offset" count=1 status=none
+ byte_hex="$(xxd -p -c 1 "$tmp_dir/chunk.bin" | tr -d '\n')"
+ printf '\000\000' > "$tmp_dir/kbclear.bin"
+ wait_keyboard_empty
+ run curl --fail --silent --show-error --max-time 10 \
+ -X PUT "${api}/machine:writemem?address=00C5&data=0000"
+ run curl --fail --silent --show-error --max-time 10 \
+ -X PUT "${api}/machine:writemem?address=0277&data=${byte_hex}"
+ run curl --fail --silent --show-error --max-time 10 \
+ -X PUT "${api}/machine:writemem?address=00C6&data=01"
+ wait_keyboard_empty
+ offset=$((offset + 1))
+ done
+}
+
+type_key() {
+ local byte_hex
+ byte_hex="$(printf '%02x' "$1")"
+ wait_keyboard_empty
+ run curl --fail --silent --show-error --max-time 10 \
+ -X PUT "${api}/machine:writemem?address=00C5&data=0000"
+ run curl --fail --silent --show-error --max-time 10 \
+ -X PUT "${api}/machine:writemem?address=0277&data=${byte_hex}"
+ run curl --fail --silent --show-error --max-time 10 \
+ -X PUT "${api}/machine:writemem?address=00C6&data=01"
+ wait_keyboard_empty
+}
+
+select_editor() {
+ type_key 19
+ type_key 17
+ type_key 17
+}
+
+select_menu_downs() {
+ local count="$1"
+ type_key 19
+ for _ in $(seq 1 "$count"); do
+ type_key 17
+ done
+}
+
+select_relative_downs() {
+ local count="$1"
+ if (( count <= 0 )); then
+ return 0
+ fi
+ for _ in $(seq 1 "$count"); do
+ type_key 17
+ done
+}
+
+capture_screen() {
+ local label="$1"
+ local dir="${out_dir}/${label}"
+ rm -rf "$dir"
+ C64U_HOST="$host" /bin/bash "$repo/build_support/capture_uci_dma_probe_c64u.sh" "$dir" >> "$log" 2>&1
+}
+
+screen_has() {
+ local label="$1"
+ local text="$2"
+ grep -q "$text" "${out_dir}/${label}/screen.txt"
+}
+
+screen_matches() {
+ local label="$1"
+ local pattern="$2"
+ grep -Eq "$pattern" "${out_dir}/${label}/screen.txt"
+}
+
+wait_for_loaded_marker() {
+ local label="$1"
+ local app_text="$2"
+ local count="$3"
+ for i in $(seq 1 "$count"); do
+ if capture_screen "$label"; then
+ if screen_matches "$label" "${app_text}.*\\*"; then
+ echo "screen matched loaded marker for ${app_text} at poll ${i}" >> "$log"
+ return 0
+ fi
+ fi
+ sleep 1
+ done
+ return 1
+}
+
+wait_for_screen() {
+ local label="$1"
+ local text="$2"
+ local count="$3"
+ for i in $(seq 1 "$count"); do
+ if capture_screen "$label"; then
+ if screen_has "$label" "$text"; then
+ echo "screen matched ${text} at poll ${i}" >> "$log"
+ return 0
+ fi
+ fi
+ sleep 1
+ done
+ return 1
+}
+
+wait_for_screen_re() {
+ local label="$1"
+ local pattern="$2"
+ local count="$3"
+ for i in $(seq 1 "$count"); do
+ if capture_screen "$label"; then
+ if screen_matches "$label" "$pattern"; then
+ echo "screen matched regex ${pattern} at poll ${i}" >> "$log"
+ return 0
+ fi
+ fi
+ sleep 1
+ done
+ return 1
+}
+
+wait_for_loader_done() {
+ local label_prefix="$1"
+ local count="$2"
+ local fail_on_disk="${3:-0}"
+ local context="${4:-loader}"
+ local failure_file="${5:-${label_prefix}_disk_loading_failure.txt}"
+ local label
+ local saw_dma=0
+ local saw_disk=0
+
+ for i in $(seq 1 "$count"); do
+ label="${label_prefix}_${i}"
+ if capture_screen "$label"; then
+ if screen_has "$label" "DMA LOADING"; then
+ saw_dma=1
+ echo "${context} saw DMA LOADING at poll ${i}" >> "$log"
+ fi
+ if screen_has "$label" "FAIL" || screen_has "$label" "INCOMPLETE LOAD"; then
+ echo "${context} saw load failure at poll ${i}" >> "$log"
+ cp "${out_dir}/${label}/screen.txt" "${out_dir}/${label_prefix}_load_failure.txt" 2>/dev/null || true
+ return 3
+ fi
+ if screen_has "$label" "DISK LOADING"; then
+ saw_disk=1
+ echo "${context} saw DISK LOADING at poll ${i}" >> "$log"
+ if [[ "$fail_on_disk" == "1" ]]; then
+ cp "${out_dir}/${label}/screen.txt" "${out_dir}/${failure_file}" 2>/dev/null || true
+ return 2
+ fi
+ fi
+ if screen_has "$label" "PRESS ANY KEY"; then
+ if [[ "${READYOS_EXPECT_DISK_LOADING:-0}" != "0" && "$saw_disk" != "1" ]]; then
+ echo "${context} did not see expected DISK LOADING before completion" >> "$log"
+ return 4
+ fi
+ echo "${context} done at poll ${i}; saw_dma=${saw_dma}" >> "$log"
+ return 0
+ fi
+ fi
+ sleep 1
+ done
+ return 1
+}
+
+wait_for_loadall_done() {
+ wait_for_loader_done "$1" "$2" "${3:-0}" "loadall" "loadall_disk_loading_failure.txt"
+}
+
+wait_for_app_or_disk() {
+ local label_prefix="$1"
+ local expected_text="$2"
+ local count="$3"
+ local fail_on_disk="${4:-0}"
+ local context="${5:-app-load}"
+ local failure_file="${6:-${label_prefix}_disk_loading_failure.txt}"
+ local label
+ local saw_dma=0
+ local saw_disk=0
+
+ for i in $(seq 1 "$count"); do
+ label="${label_prefix}_${i}"
+ if capture_screen "$label"; then
+ if screen_has "$label" "DMA LOADING"; then
+ saw_dma=1
+ echo "${context} saw DMA LOADING at poll ${i}" >> "$log"
+ fi
+ if screen_has "$label" "FAIL" || screen_has "$label" "INCOMPLETE LOAD"; then
+ echo "${context} saw load failure at poll ${i}" >> "$log"
+ cp "${out_dir}/${label}/screen.txt" "${out_dir}/${label_prefix}_load_failure.txt" 2>/dev/null || true
+ return 3
+ fi
+ if screen_has "$label" "DISK LOADING"; then
+ saw_disk=1
+ echo "${context} saw DISK LOADING at poll ${i}" >> "$log"
+ if [[ "$fail_on_disk" == "1" ]]; then
+ cp "${out_dir}/${label}/screen.txt" "${out_dir}/${failure_file}" 2>/dev/null || true
+ return 2
+ fi
+ fi
+ if screen_has "$label" "$expected_text"; then
+ if [[ "${READYOS_EXPECT_DISK_LOADING:-0}" != "0" && "$saw_disk" != "1" ]]; then
+ echo "${context} did not see expected DISK LOADING before ${expected_text}" >> "$log"
+ return 4
+ fi
+ echo "${context} matched ${expected_text} at poll ${i}; saw_dma=${saw_dma}" >> "$log"
+ return 0
+ fi
+ fi
+ sleep 1
+ done
+ return 1
+}
+
+readyshell_overlay_smoke() {
+ if ! wait_for_screen "readyshell_prompt_wait" "RUN: CAT" 120; then
+ capture_screen "readyshell_prompt_failure"
+ echo "READYOS_READYSHELL_PROMPT_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+
+ type_text $'VER\r'
+ if ! wait_for_screen "readyshell_ver_wait" "VERSION 0.2" 90; then
+ capture_screen "readyshell_ver_failure"
+ echo "READYOS_READYSHELL_VER_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+
+ type_text $'LST "RSHELP"\r'
+ if ! wait_for_screen "readyshell_lst_wait" "NAME:RSHELP" 120; then
+ capture_screen "readyshell_lst_failure"
+ echo "READYOS_READYSHELL_LST_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+
+ type_text $'VER\r'
+ if ! wait_for_screen "readyshell_ver_after_lst_wait" "VERSION 0.2" 90; then
+ capture_screen "readyshell_ver_after_lst_failure"
+ echo "READYOS_READYSHELL_VER_AFTER_LST_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+
+ type_text $'CAT "RSHELP" ! TOP 1\r'
+ if ! wait_for_screen "readyshell_cat_wait" "READYSHELL QUICK REF" 120; then
+ capture_screen "readyshell_cat_failure"
+ echo "READYOS_READYSHELL_CAT_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+
+ type_text $'VER\r'
+ if ! wait_for_screen "readyshell_ver_after_cat_wait" "VERSION 0.2" 90; then
+ capture_screen "readyshell_ver_after_cat_failure"
+ echo "READYOS_READYSHELL_VER_AFTER_CAT_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+
+ capture_screen "readyshell_overlay_final"
+}
+
+echo "host=${host}" >> "$log"
+echo "connect_wait_s=${connect_wait_s}" >> "$log"
+echo "skip_upload=${skip_upload}" >> "$log"
+echo "skip_config=${skip_config}" >> "$log"
+echo "clear_reu=${clear_reu}" >> "$log"
+echo "clear_reu_only=${clear_reu_only}" >> "$log"
+echo "machine_reboot=${machine_reboot}" >> "$log"
+if [[ "$skip_upload" == "1" ]]; then
+ wait_for_http
+else
+ wait_for_ftp
+ delete_remote_image
+ run curl --fail --silent --show-error --ftp-create-dirs \
+ -T "$image" "ftp://${host}/${remote}" --user anonymous:anonymous@
+ verify_remote_image
+ wait_for_http
+fi
+
+if [[ "$skip_config" != "1" ]]; then
+ cat > "${tmp_dir}/config_a.json" <> "$log"
+ exit 1
+ fi
+ echo "READYOS_CLEAR_REU_ONLY_OK" | tee "${out_dir}/status"
+ exit 0
+fi
+
+reset_machine "pre-mount"
+run curl --fail --silent --show-error --max-time 10 \
+ -X PUT "${api}/drives/a:mount?image=%2F${remote_root}%2F${remote_name}&type=d81&mode=readwrite"
+reset_machine "post-mount"
+wait_for_screen "basic_after_reset" "READY" 30
+
+type_text $'LOAD"BOOT",8\r'
+sleep 45
+capture_screen "after_boot_load"
+type_text $'RUN\r'
+sleep "${READYOS_BOOT_INITIAL_WAIT_S:-90}"
+
+if [[ "${READYOS_BOOT_ACTION:-}" == "autorun-editor" ]]; then
+ if ! wait_for_screen "editor_wait" "EDITOR:" 240; then
+ capture_screen "editor_failure"
+ echo "READYOS_AUTORUN_EDITOR_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ type_key 2
+ if ! wait_for_screen "launcher_after_editor_wait" "READY OS" 120; then
+ capture_screen "launcher_after_editor_failure"
+ echo "READYOS_AUTORUN_EDITOR_RETURN_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ if [[ "${READYOS_EXPECT_DMA:-1}" != "0" ]]; then
+ if ! wait_for_screen "dma_on_wait" "DMA:ON" 60; then
+ capture_screen "dma_on_failure"
+ echo "READYOS_AUTORUN_EDITOR_DMA_ON_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ fi
+ capture_screen "autorun_editor_final"
+ echo "READYOS_AUTORUN_EDITOR_PASS" | tee "${out_dir}/status"
+ exit 0
+fi
+
+if wait_for_screen "launcher_wait" "READY OS" 180; then
+ capture_screen "launcher_final"
+ if [[ "${READYOS_EXPECT_DMA_READY:-0}" != "0" ]]; then
+ if ! wait_for_screen_re "launcher_dma_ready_wait" "DMA:(YES|ON)" 60; then
+ capture_screen "launcher_dma_ready_failure"
+ echo "READYOS_DMA_READY_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ fi
+ if [[ "${READYOS_EXPECT_DMA_OFF:-0}" != "0" ]]; then
+ if ! wait_for_screen "launcher_dma_off_wait" "DMA:NO" 60; then
+ capture_screen "launcher_dma_off_failure"
+ echo "READYOS_DMA_OFF_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ fi
+ if [[ -n "${READYOS_EXPECT_NOTICE_RE:-}" ]]; then
+ if ! wait_for_screen_re "launcher_notice_wait" "${READYOS_EXPECT_NOTICE_RE}" 60; then
+ capture_screen "launcher_notice_failure"
+ echo "READYOS_NOTICE_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ fi
+ if [[ "${READYOS_BOOT_ACTION:-}" == "editor-direct" ]]; then
+ select_editor
+ type_key 13
+ # C64U REST screen/memory polling can stall active KERNAL disk loads.
+ if [[ -n "${READYOS_QUIET_AFTER_APP_ENTER_S:-}" ]]; then
+ sleep "${READYOS_QUIET_AFTER_APP_ENTER_S}"
+ fi
+ if ! wait_for_screen "editor_wait" "EDITOR:" 120; then
+ capture_screen "editor_failure"
+ echo "READYOS_EDITOR_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ capture_screen "editor_final"
+ echo "READYOS_EDITOR_DIRECT_PASS" | tee "${out_dir}/status"
+ exit 0
+ fi
+
+ if [[ "${READYOS_BOOT_ACTION:-}" == "editor-direct-dma-return" ]]; then
+ select_editor
+ type_key 13
+ # C64U REST screen/memory polling can stall active KERNAL disk loads.
+ if [[ -n "${READYOS_QUIET_AFTER_APP_ENTER_S:-}" ]]; then
+ sleep "${READYOS_QUIET_AFTER_APP_ENTER_S}"
+ fi
+ fail_on_disk=0
+ if [[ "${READYOS_EXPECT_DMA:-1}" != "0" ]]; then
+ fail_on_disk="${READYOS_FAIL_ON_DISK_LOADING_WHEN_DMA:-1}"
+ fi
+ if wait_for_app_or_disk "editor_direct_watch" "EDITOR:" 180 "$fail_on_disk" \
+ "editor-direct" "editor_direct_disk_loading_failure.txt"; then
+ editor_direct_watch_rc=0
+ else
+ editor_direct_watch_rc=$?
+ fi
+ if [[ "$editor_direct_watch_rc" == "2" ]]; then
+ capture_screen "editor_direct_disk_loading_failure"
+ echo "READYOS_EDITOR_DIRECT_DISK_LOADING_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ if [[ "$editor_direct_watch_rc" != "0" ]]; then
+ capture_screen "editor_failure"
+ echo "READYOS_EDITOR_DIRECT_DMA_RETURN_EDITOR_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ type_key 2
+ if ! wait_for_screen "launcher_after_editor_wait" "READY OS" 120; then
+ capture_screen "launcher_after_editor_failure"
+ echo "READYOS_EDITOR_DIRECT_DMA_RETURN_LAUNCHER_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ if [[ "${READYOS_EXPECT_DMA:-1}" != "0" ]]; then
+ if ! wait_for_screen "dma_on_wait" "DMA:ON" 60; then
+ capture_screen "dma_on_failure"
+ echo "READYOS_EDITOR_DIRECT_DMA_RETURN_DMA_ON_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ if ! wait_for_loaded_marker "editor_direct_loaded_marker_wait" "EDITOR" 30; then
+ capture_screen "editor_direct_loaded_marker_failure"
+ echo "READYOS_EDITOR_DIRECT_LOADED_MARKER_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ fi
+ capture_screen "editor_direct_dma_return_final"
+ echo "READYOS_EDITOR_DIRECT_DMA_RETURN_PASS" | tee "${out_dir}/status"
+ exit 0
+ fi
+
+ if [[ "${READYOS_BOOT_ACTION:-}" == "loadall-editor" ||
+ "${READYOS_BOOT_ACTION:-}" == "loadall-editor-any" ||
+ "${READYOS_BOOT_ACTION:-}" == "loadall-readyshell-overlay-smoke" ]]; then
+ type_key 133
+ fail_on_disk=0
+ if [[ "${READYOS_EXPECT_DMA:-1}" != "0" ]]; then
+ fail_on_disk="${READYOS_FAIL_ON_DISK_LOADING_WHEN_DMA:-1}"
+ fi
+ if wait_for_loadall_done "loadall_watch" "${READYOS_LOADALL_WATCH_POLLS:-360}" "$fail_on_disk"; then
+ loadall_watch_rc=0
+ else
+ loadall_watch_rc=$?
+ fi
+ if [[ "$loadall_watch_rc" == "2" ]]; then
+ capture_screen "loadall_disk_loading_failure"
+ echo "READYOS_LOADALL_DISK_LOADING_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ if [[ "$loadall_watch_rc" == "3" ]]; then
+ capture_screen "loadall_reported_failure"
+ echo "READYOS_LOADALL_REPORTED_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ if [[ "$loadall_watch_rc" != "0" ]]; then
+ capture_screen "loadall_failure"
+ echo "READYOS_LOADALL_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ type_key 13
+ if [[ "${READYOS_BOOT_ACTION:-}" == "loadall-editor" ||
+ "${READYOS_BOOT_ACTION:-}" == "loadall-readyshell-overlay-smoke" ]]; then
+ if ! wait_for_screen "dma_on_wait" "DMA:ON" 60; then
+ capture_screen "dma_on_failure"
+ echo "READYOS_DMA_ON_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ if ! wait_for_loaded_marker "editor_loaded_marker_wait" "EDITOR" 30; then
+ capture_screen "editor_loaded_marker_failure"
+ echo "READYOS_EDITOR_LOADED_MARKER_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ else
+ if ! wait_for_screen "loadall_done_wait" "READY OS" 60; then
+ capture_screen "loadall_done_failure"
+ echo "READYOS_LOADALL_DONE_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ fi
+ if [[ "${READYOS_BOOT_ACTION:-}" == "loadall-readyshell-overlay-smoke" ]]; then
+ select_menu_downs "${READYOS_SELECT_DOWNS:-3}"
+ type_key 13
+ if ! wait_for_screen "readyshell_wait" "READYOS READYSHELL" 180; then
+ capture_screen "readyshell_failure"
+ echo "READYOS_LOADALL_READYSHELL_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ readyshell_overlay_smoke
+ capture_screen "readyshell_final"
+ echo "READYOS_LOADALL_READYSHELL_OVERLAY_PASS" | tee "${out_dir}/status"
+ exit 0
+ fi
+ select_editor
+ type_key 13
+ if ! wait_for_screen "editor_wait" "EDITOR:" 120; then
+ capture_screen "editor_failure"
+ echo "READYOS_EDITOR_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ capture_screen "editor_final"
+ if [[ "${READYOS_BOOT_ACTION:-}" == "loadall-editor" ]]; then
+ echo "READYOS_LOADALL_EDITOR_PASS" | tee "${out_dir}/status"
+ else
+ echo "READYOS_LOADALL_EDITOR_ANY_PASS" | tee "${out_dir}/status"
+ fi
+ exit 0
+ fi
+
+ if [[ "${READYOS_BOOT_ACTION:-}" == "manifest-sidetris" ]]; then
+ type_key 135
+ # Repeated REST screen reads can stall active KERNAL directory I/O on the
+ # Ultimate. Allow hardware acceptance callers to give the drive an
+ # entirely quiet interval before polling the completed dialog.
+ if [[ -n "${READYOS_QUIET_AFTER_MANIFEST_OPEN_S:-}" ]]; then
+ sleep "${READYOS_QUIET_AFTER_MANIFEST_OPEN_S}"
+ fi
+ if ! wait_for_screen "manifest_dialog_wait" "BROWSE APP MANIFEST" \
+ "${READYOS_MANIFEST_DIALOG_WAIT_S:-120}"; then
+ capture_screen "manifest_dialog_failure"
+ echo "READYOS_MANIFEST_DIALOG_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ select_relative_downs "${READYOS_MANIFEST_DOWNS:-4}"
+ type_key 13
+ fail_on_disk=0
+ if [[ "${READYOS_EXPECT_DMA:-1}" != "0" ]]; then
+ fail_on_disk="${READYOS_FAIL_ON_DISK_LOADING_WHEN_DMA:-1}"
+ fi
+ if wait_for_loader_done "manifest_load_watch" 180 "$fail_on_disk" \
+ "manifest-load" "manifest_disk_loading_failure.txt"; then
+ manifest_load_watch_rc=0
+ else
+ manifest_load_watch_rc=$?
+ fi
+ if [[ "$manifest_load_watch_rc" == "2" ]]; then
+ capture_screen "manifest_disk_loading_failure"
+ echo "READYOS_MANIFEST_DISK_LOADING_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ if [[ "$manifest_load_watch_rc" != "0" ]]; then
+ capture_screen "manifest_load_failure"
+ echo "READYOS_MANIFEST_LOAD_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ if ! grep -ERq "OK|LOADED TO REU" "${out_dir}"/manifest_load_watch_*/screen.txt 2>/dev/null; then
+ capture_screen "manifest_load_not_ok"
+ echo "READYOS_MANIFEST_LOAD_NOT_OK" | tee "${out_dir}/status"
+ exit 1
+ fi
+ type_key 13
+ if [[ "${READYOS_EXPECT_DMA:-1}" != "0" ]]; then
+ if ! wait_for_screen "manifest_dma_on_wait" "DMA:ON" 60; then
+ capture_screen "manifest_dma_on_failure"
+ echo "READYOS_MANIFEST_DMA_ON_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ fi
+ type_key 13
+ if ! wait_for_screen "sidetris_wait" "SIDETRIS" 120; then
+ capture_screen "sidetris_failure"
+ echo "READYOS_MANIFEST_SIDETRIS_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ capture_screen "sidetris_final"
+ echo "READYOS_MANIFEST_SIDETRIS_PASS" | tee "${out_dir}/status"
+ exit 0
+ fi
+
+ if [[ "${READYOS_BOOT_ACTION:-}" == "editor-load-selected" ]]; then
+ select_editor
+ type_key 134
+ fail_on_disk=0
+ if [[ "${READYOS_EXPECT_DMA:-1}" != "0" ]]; then
+ fail_on_disk="${READYOS_FAIL_ON_DISK_LOADING_WHEN_DMA:-1}"
+ fi
+ if wait_for_loader_done "load_selected_watch" "${READYOS_LOAD_SELECTED_WATCH_POLLS:-120}" "$fail_on_disk" \
+ "editor-load-selected" "load_selected_disk_loading_failure.txt"; then
+ load_selected_watch_rc=0
+ else
+ load_selected_watch_rc=$?
+ fi
+ if [[ "$load_selected_watch_rc" == "2" ]]; then
+ capture_screen "load_selected_disk_loading_failure"
+ echo "READYOS_LOAD_SELECTED_DISK_LOADING_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ if [[ "$load_selected_watch_rc" == "3" ]]; then
+ capture_screen "load_selected_reported_failure"
+ echo "READYOS_LOAD_SELECTED_REPORTED_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ if [[ "$load_selected_watch_rc" != "0" ]]; then
+ capture_screen "load_selected_failure"
+ echo "READYOS_LOAD_SELECTED_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ if ! grep -R -q "OK" "${out_dir}"/load_selected_watch_*/screen.txt 2>/dev/null; then
+ capture_screen "load_selected_not_ok"
+ echo "READYOS_LOAD_SELECTED_NOT_OK" | tee "${out_dir}/status"
+ exit 1
+ fi
+ type_key 13
+ if [[ "${READYOS_EXPECT_DMA:-1}" != "0" ]]; then
+ if ! wait_for_screen "dma_on_wait" "DMA:ON" 60; then
+ capture_screen "dma_on_failure"
+ echo "READYOS_DMA_ON_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ if ! wait_for_loaded_marker "editor_loaded_marker_wait" "EDITOR" 30; then
+ capture_screen "editor_loaded_marker_failure"
+ echo "READYOS_EDITOR_LOADED_MARKER_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ else
+ if ! wait_for_screen "load_selected_done_wait" "READY OS" 60; then
+ capture_screen "load_selected_done_failure"
+ echo "READYOS_LOAD_SELECTED_DONE_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ fi
+ type_key 13
+ if ! wait_for_screen "editor_wait" "EDITOR:" 120; then
+ capture_screen "editor_failure"
+ echo "READYOS_EDITOR_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ capture_screen "editor_final"
+ echo "READYOS_EDITOR_LOAD_SELECTED_PASS" | tee "${out_dir}/status"
+ exit 0
+ fi
+
+ if [[ "${READYOS_BOOT_ACTION:-}" == "app-load-selected-marker" ]]; then
+ selected_downs="${READYOS_SELECT_DOWNS:-2}"
+ selected_marker="${READYOS_EXPECT_MARKER:-EDITOR}"
+ select_menu_downs "$selected_downs"
+ type_key 134
+ fail_on_disk=0
+ if [[ "${READYOS_EXPECT_DMA:-1}" != "0" ]]; then
+ fail_on_disk="${READYOS_FAIL_ON_DISK_LOADING_WHEN_DMA:-1}"
+ fi
+ if wait_for_loader_done "load_selected_watch" 180 "$fail_on_disk" \
+ "app-load-selected-marker" "load_selected_disk_loading_failure.txt"; then
+ load_selected_watch_rc=0
+ else
+ load_selected_watch_rc=$?
+ fi
+ if [[ "$load_selected_watch_rc" == "2" ]]; then
+ capture_screen "load_selected_disk_loading_failure"
+ echo "READYOS_LOAD_SELECTED_DISK_LOADING_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ if [[ "$load_selected_watch_rc" == "3" ]]; then
+ capture_screen "load_selected_reported_failure"
+ echo "READYOS_LOAD_SELECTED_REPORTED_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ if [[ "$load_selected_watch_rc" != "0" ]]; then
+ capture_screen "load_selected_failure"
+ echo "READYOS_LOAD_SELECTED_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ if ! grep -R -q "OK" "${out_dir}"/load_selected_watch_*/screen.txt 2>/dev/null; then
+ capture_screen "load_selected_not_ok"
+ echo "READYOS_LOAD_SELECTED_NOT_OK" | tee "${out_dir}/status"
+ exit 1
+ fi
+ type_key 13
+ if [[ "${READYOS_EXPECT_DMA:-1}" != "0" ]]; then
+ if ! wait_for_screen "dma_on_wait" "DMA:ON" 60; then
+ capture_screen "dma_on_failure"
+ echo "READYOS_DMA_ON_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ fi
+ if ! wait_for_loaded_marker "loaded_marker_wait" "$selected_marker" 30; then
+ capture_screen "loaded_marker_failure"
+ echo "READYOS_LOADED_MARKER_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ capture_screen "load_selected_marker_final"
+ echo "READYOS_LOAD_SELECTED_MARKER_PASS" | tee "${out_dir}/status"
+ exit 0
+ fi
+
+ if [[ "${READYOS_BOOT_ACTION:-}" == "readyshell-enter-smoke" ]]; then
+ select_menu_downs "${READYOS_SELECT_DOWNS:-3}"
+ type_key 13
+ fail_on_disk=0
+ if [[ "${READYOS_EXPECT_DMA:-1}" != "0" ]]; then
+ fail_on_disk="${READYOS_FAIL_ON_DISK_LOADING_WHEN_DMA:-1}"
+ fi
+ if wait_for_app_or_disk "enter_watch" "${READYOS_EXPECT_TEXT:-READYOS READYSHELL}" 180 \
+ "$fail_on_disk" "readyshell-enter" "enter_disk_loading_failure.txt"; then
+ enter_watch_rc=0
+ else
+ enter_watch_rc=$?
+ fi
+ if [[ "$enter_watch_rc" == "2" ]]; then
+ capture_screen "enter_disk_loading_failure"
+ echo "READYOS_READYSHELL_ENTER_DISK_LOADING_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ if [[ "$enter_watch_rc" != "0" ]]; then
+ capture_screen "app_failure"
+ echo "READYOS_READYSHELL_ENTER_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ readyshell_overlay_smoke
+ capture_screen "app_final"
+ echo "READYOS_READYSHELL_ENTER_SMOKE_PASS" | tee "${out_dir}/status"
+ exit 0
+ fi
+
+ if [[ "${READYOS_BOOT_ACTION:-}" == "readyshell-load-selected" || "${READYOS_BOOT_ACTION:-}" == "readyshell-overlay-smoke" || "${READYOS_BOOT_ACTION:-}" == "readybasic-load-selected" ]]; then
+ if [[ "${READYOS_BOOT_ACTION:-}" == "readyshell-load-selected" || "${READYOS_BOOT_ACTION:-}" == "readyshell-overlay-smoke" ]]; then
+ select_menu_downs "${READYOS_SELECT_DOWNS:-3}"
+ expected_text="${READYOS_EXPECT_TEXT:-READYOS READYSHELL}"
+ if [[ "${READYOS_BOOT_ACTION:-}" == "readyshell-overlay-smoke" ]]; then
+ pass_status="READYOS_READYSHELL_OVERLAY_SMOKE_PASS"
+ else
+ pass_status="READYOS_READYSHELL_LOAD_SELECTED_PASS"
+ fi
+ else
+ select_menu_downs "${READYOS_SELECT_DOWNS:-6}"
+ expected_text="${READYOS_EXPECT_TEXT:-READYBASIC}"
+ pass_status="READYOS_READYBASIC_LOAD_SELECTED_PASS"
+ fi
+ type_key 134
+ fail_on_disk=0
+ if [[ "${READYOS_EXPECT_DMA:-1}" != "0" ]]; then
+ fail_on_disk="${READYOS_FAIL_ON_DISK_LOADING_WHEN_DMA:-1}"
+ fi
+ if wait_for_loader_done "load_selected_watch" 180 "$fail_on_disk" \
+ "${READYOS_BOOT_ACTION:-load-selected}" "load_selected_disk_loading_failure.txt"; then
+ load_selected_watch_rc=0
+ else
+ load_selected_watch_rc=$?
+ fi
+ if [[ "$load_selected_watch_rc" == "2" ]]; then
+ capture_screen "load_selected_disk_loading_failure"
+ echo "READYOS_LOAD_SELECTED_DISK_LOADING_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ if [[ "$load_selected_watch_rc" != "0" ]]; then
+ capture_screen "load_selected_failure"
+ echo "READYOS_LOAD_SELECTED_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ if ! grep -R -q "OK" "${out_dir}"/load_selected_watch_*/screen.txt 2>/dev/null; then
+ capture_screen "load_selected_not_ok"
+ echo "READYOS_LOAD_SELECTED_NOT_OK" | tee "${out_dir}/status"
+ exit 1
+ fi
+ type_key 13
+ if [[ "${READYOS_EXPECT_DMA:-1}" != "0" ]]; then
+ if ! wait_for_screen "dma_on_wait" "DMA:ON" 60; then
+ capture_screen "dma_on_failure"
+ echo "READYOS_DMA_ON_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ else
+ if ! wait_for_screen "load_selected_done_wait" "READY OS" 60; then
+ capture_screen "load_selected_done_failure"
+ echo "READYOS_LOAD_SELECTED_DONE_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ fi
+ type_key 13
+ if ! wait_for_screen "app_wait" "$expected_text" 180; then
+ capture_screen "app_failure"
+ echo "READYOS_APP_FAIL" | tee "${out_dir}/status"
+ exit 1
+ fi
+ if [[ "${READYOS_BOOT_ACTION:-}" == "readyshell-overlay-smoke" ]]; then
+ readyshell_overlay_smoke
+ fi
+ capture_screen "app_final"
+ echo "$pass_status" | tee "${out_dir}/status"
+ exit 0
+ fi
+ echo "READYOS_BOOT_PASS" | tee "${out_dir}/status"
+ exit 0
+fi
+
+capture_screen "failure_final"
+curl --fail --silent --show-error --max-time 10 \
+ "${api}/machine:readmem?address=0&length=65536" -o "${out_dir}/mem_failure.bin" >> "$log" 2>&1 || true
+echo "READYOS_BOOT_FAIL" | tee "${out_dir}/status"
+exit 1
diff --git a/build_support/run_readyshell_cross_app_resume_c64u.sh b/build_support/run_readyshell_cross_app_resume_c64u.sh
new file mode 100755
index 0000000..0cff140
--- /dev/null
+++ b/build_support/run_readyshell_cross_app_resume_c64u.sh
@@ -0,0 +1,457 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+READYOS_ROOT="${READYOS_ROOT:-$(cd "$SCRIPT_DIR/.." && pwd)}"
+if [ -n "${VICE_TASKS_ROOT:-}" ]; then
+ VICE_TOOL_ROOT="$(cd "$VICE_TASKS_ROOT" && pwd)"
+ HARNESS_REPO="$(cd "$VICE_TOOL_ROOT/../.." && pwd)"
+else
+ HARNESS_REPO="${VICE_TASKS_REPO:-$READYOS_ROOT/../agenticdevharness}"
+ HARNESS_REPO="$(cd "$HARNESS_REPO" && pwd)"
+ VICE_TOOL_ROOT="$HARNESS_REPO/tools/vice_tasks_dotnet"
+fi
+PROJECT="$VICE_TOOL_ROOT/src/ViceTasks.Binary/ViceTasks.Binary.csproj"
+PLAN="${READYSHELL_C64U_PLAN:-$SCRIPT_DIR/readyshell_cross_app_resume_c64u.generated.yaml}"
+CONFIG_SRC="${READYSHELL_C64U_CONFIG_SRC:-$SCRIPT_DIR/readyshell_cross_app_resume_c64u.generated.ini}"
+REPEAT_COUNT="${READYSHELL_CROSS_APP_REPEAT:-1}"
+C64U_HOST="${C64U_HOST:-10.0.0.79}"
+C64U_REMOTE_ROOT="${C64U_REMOTE_ROOT:-USB1/automation/vice_tasks_dotnet}"
+C64U_REMOTE_D81="${C64U_REMOTE_D81:-readyos-readyshell-c64u.d81}"
+C64U_IMAGE_PATH_CONFIG="${C64U_IMAGE_PATH_CONFIG:-}"
+C64U_CAPTURE_VIDEO="${C64U_CAPTURE_VIDEO:-false}"
+C64U_CONNECT_WAIT_S="${C64U_CONNECT_WAIT_S:-300}"
+READYSHELL_C64U_PREMOUNT_REST="${READYSHELL_C64U_PREMOUNT_REST:-1}"
+READYSHELL_C64U_ASSUME_MOUNTED="${READYSHELL_C64U_ASSUME_MOUNTED:-0}"
+READYSHELL_C64U_BOOT_LOAD_WAIT_S="${READYSHELL_C64U_BOOT_LOAD_WAIT_S:-45}"
+READYSHELL_C64U_KEY_DELAY_S="${READYSHELL_C64U_KEY_DELAY_S:-0.25}"
+READYSHELL_C64U_POLL_S="${READYSHELL_C64U_POLL_S:-1.0}"
+READYSHELL_C64U_POST_RUN_QUIET_S="${READYSHELL_C64U_POST_RUN_QUIET_S:-120}"
+READYSHELL_C64U_APP_LOAD_QUIET_S="${READYSHELL_C64U_APP_LOAD_QUIET_S:-90}"
+
+keys() {
+ python3 - "$1" <<'PY'
+import sys
+s = sys.argv[1]
+out = []
+for ch in s:
+ code = ord(ch)
+ if 0x61 <= code <= 0x7a:
+ code -= 0x20
+ out.append(str(code))
+print(",".join(out))
+PY
+}
+
+emit_type_step() {
+ local id="$1"
+ local text="$2"
+ local post="${3:-0.8}"
+ cat >>"$PLAN" <>"$PLAN" <>"$PLAN" <>"$PLAN" <>"$PLAN" <>"$PLAN" <>"$PLAN" </dev/null 2>&1; then
+ rm -f "$probe"
+ return 0
+ fi
+ sleep 3
+ done
+ rm -f "$probe"
+ echo "C64U REST not reachable after ${C64U_CONNECT_WAIT_S}s at ${C64U_HOST}" >&2
+ return 1
+}
+
+wait_for_c64u_ftp() {
+ local deadline
+ local probe
+ if [ "${READYSHELL_C64U_WAIT_FOR_DEVICE:-1}" = "0" ]; then
+ return 0
+ fi
+ probe="$(mktemp)"
+ deadline=$((SECONDS + C64U_CONNECT_WAIT_S))
+ while (( SECONDS <= deadline )); do
+ if curl --fail --silent --show-error --max-time 8 \
+ "ftp://${C64U_HOST}/${C64U_REMOTE_ROOT}/" \
+ --user anonymous:anonymous@ -o "$probe" >/dev/null 2>&1; then
+ rm -f "$probe"
+ return 0
+ fi
+ sleep 3
+ done
+ rm -f "$probe"
+ echo "C64U FTP not reachable after ${C64U_CONNECT_WAIT_S}s at ${C64U_HOST}" >&2
+ return 1
+}
+
+cd "$READYOS_ROOT"
+PROFILE_CATALOG_SRC="$(python3 build_support/readyos_profiles.py catalog-source --profile precog-d81)"
+if [ -z "$C64U_IMAGE_PATH_CONFIG" ]; then
+ C64U_IMAGE_PATH_CONFIG="$(python3 - "$C64U_REMOTE_ROOT" "$C64U_REMOTE_D81" <<'PY'
+import sys
+root = sys.argv[1].strip().strip("/")
+name = sys.argv[2].strip().strip("/")
+print(("/" + "/".join(part for part in (root, name) if part)).lower())
+PY
+)"
+fi
+python3 - "$PROFILE_CATALOG_SRC" "$CONFIG_SRC" "$C64U_IMAGE_PATH_CONFIG" <<'PY'
+import pathlib
+import sys
+
+src = pathlib.Path(sys.argv[1])
+dst = pathlib.Path(sys.argv[2])
+image_path = sys.argv[3]
+lines = src.read_text(encoding="utf-8").splitlines()
+out = []
+for line in lines:
+ if line.startswith("c64u_image_path="):
+ out.append(f"c64u_image_path={image_path}")
+ else:
+ out.append(line)
+dst.write_text("\n".join(out) + "\n", encoding="utf-8")
+PY
+PUBLIC_VERSION_TEXT="$(python3 build_support/update_build_version.py --current)"
+PUBLIC_VERSION="${PUBLIC_VERSION_TEXT%[A-Z]}"
+if [ "${READYSHELL_C64U_SKIP_BUILD:-0}" != "1" ]; then
+ RUN_VERSION_TEXT="$(python3 build_support/update_build_version.py --next)"
+ make -B \
+ BUILD_SUPPORT_DIR=build_support \
+ PROFILE=precog-d81 \
+ LAUNCHER_DMA_LOAD=1 \
+ READYOS_VERSION_TEXT="$RUN_VERSION_TEXT" \
+ READYOS_CONFIG_SRC="$CONFIG_SRC" \
+ profile
+fi
+
+if [ -n "${READYSHELL_C64U_D81:-}" ]; then
+ D81="$READYSHELL_C64U_D81"
+else
+ D81="$(ls -t Releases/$PUBLIC_VERSION/precog-d81/*.d81 | head -1)"
+fi
+
+PLAN_D81="$D81"
+PLAN_REMOTE_D81="$C64U_REMOTE_ROOT/$C64U_REMOTE_D81"
+if [ "$READYSHELL_C64U_ASSUME_MOUNTED" = "1" ]; then
+ PLAN_D81=""
+ PLAN_REMOTE_D81=""
+elif [ "$READYSHELL_C64U_PREMOUNT_REST" = "1" ]; then
+ wait_for_c64u_ftp
+ curl --fail --silent --show-error --ftp-create-dirs \
+ -T "$D81" "ftp://${C64U_HOST}/${PLAN_REMOTE_D81}" \
+ --user anonymous:anonymous@
+ wait_for_c64u_rest
+ curl --fail --silent --show-error --max-time 10 \
+ -H "Content-Type: application/json" \
+ --data-binary '{"Drive A Settings":{"Drive":"Enabled","Drive Type":"1581","Drive Bus ID":8}}' \
+ "http://${C64U_HOST}/v1/configs" >/dev/null
+ curl --fail --silent --show-error --max-time 10 -X PUT \
+ "http://${C64U_HOST}/v1/machine:reset" >/dev/null
+ sleep 2
+ curl --fail --silent --show-error --max-time 10 -X PUT \
+ "http://${C64U_HOST}/v1/drives/a:mount?image=%2F${PLAN_REMOTE_D81//\//%2F}&type=d81&mode=readwrite" >/dev/null
+ PLAN_D81=""
+ PLAN_REMOTE_D81=""
+fi
+
+cat >"$PLAN" <>"$PLAN" <>"$PLAN" <<'YAML'
+ - id: dump_final_state
+ type: dump.memory_ranges
+ params:
+ ranges:
+ - { label: launcher_shim_c600, start: 0xC600, end: 0xCA00 }
+ - { label: app_work_1000, start: 0x1000, end: 0x1800 }
+ - { label: upper_app_a000, start: 0xA000, end: 0xC600 }
+YAML
+
+if [ "${READYSHELL_C64U_GENERATE_PLAN_ONLY:-0}" = "1" ]; then
+ echo "wrote $PLAN"
+ exit 0
+fi
+
+dotnet build "$PROJECT"
+wait_for_c64u_rest
+dotnet run --project "$PROJECT" -- run-ultimate-plan --plan "$PLAN" --host "$C64U_HOST" --no-tui
diff --git a/build_support/run_readyshell_cross_app_resume_probe.sh b/build_support/run_readyshell_cross_app_resume_probe.sh
index 4685568..93cd328 100755
--- a/build_support/run_readyshell_cross_app_resume_probe.sh
+++ b/build_support/run_readyshell_cross_app_resume_probe.sh
@@ -122,6 +122,8 @@ emit_readyshell_cat_overlay() {
}
cd "$READYOS_ROOT"
+PUBLIC_VERSION_TEXT="$(python3 build_support/update_build_version.py --current)"
+PUBLIC_VERSION="${PUBLIC_VERSION_TEXT%[A-Z]}"
if [ "${READYSHELL_SKIP_BUILD:-0}" != "1" ]; then
RUN_VERSION_TEXT="$(python3 build_support/update_build_version.py --next)"
make -B \
@@ -132,8 +134,8 @@ if [ "${READYSHELL_SKIP_BUILD:-0}" != "1" ]; then
profile
fi
-D81_REL="$(ls -t Releases/0.2.4/precog-d81/*.d81 | head -1)"
-PREBOOT_REL="$(ls -t Releases/0.2.4/precog-d81/*-preboot.prg | head -1)"
+D81_REL="$(ls -t Releases/$PUBLIC_VERSION/precog-d81/*.d81 | head -1)"
+PREBOOT_REL="$(ls -t Releases/$PUBLIC_VERSION/precog-d81/*-preboot.prg | head -1)"
D81="$D81_REL"
PREBOOT="$PREBOOT_REL"
@@ -176,9 +178,14 @@ steps:
- id: wait_editor_initial
type: screen.wait_contains
params:
- text: "editor"
+ text: "EDITOR:"
wait_timeout_s: 180
capture_label: editor_initial
+ - id: clear_keyboard_buffer_before_editor_entry
+ type: memory.write
+ params:
+ start: 198
+ bytes_hex: "00"
YAML
for i in $(seq 1 "$REPEAT_COUNT"); do
@@ -236,13 +243,28 @@ cat >>"$PLAN" <>"$PLAN" <<'YAML'
type: dump.memory_ranges
params:
ranges:
- - { label: launcher_shim_c800, start: 0xC800, end: 0xCA00 }
+ - { label: launcher_shim_c600, start: 0xC600, end: 0xCA00 }
- { label: app_work_1000, start: 0x1000, end: 0x1800 }
- { label: upper_app_a000, start: 0xA000, end: 0xC600 }
YAML
diff --git a/build_support/run_uci_dma_probe_c64u_ram.sh b/build_support/run_uci_dma_probe_c64u_ram.sh
new file mode 100755
index 0000000..2e41cf5
--- /dev/null
+++ b/build_support/run_uci_dma_probe_c64u_ram.sh
@@ -0,0 +1,151 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+repo="$(cd "$(dirname "$0")/.." && pwd)"
+host="${C64U_HOST:-10.0.0.79}"
+remote_dir="${C64U_REMOTE_DIR:-USB1}"
+image_type="${PROBE_IMAGE_TYPE:-d64}"
+log="${1:-/tmp/uci_dma_probe_c64u_ram.log}"
+status="${2:-/tmp/uci_dma_probe_c64u_ram.status}"
+
+case "$remote_dir" in
+ USB0|USB1) ;;
+ *) echo "C64U_REMOTE_DIR must be USB0 or USB1" >&2; exit 64 ;;
+esac
+
+case "$image_type" in
+ d64)
+ image_name="UCI40.D64"
+ expected_version="40"
+ expected_title="UCI DOS REU PROBE V40"
+ ;;
+ d81)
+ image_name="UCI41.D81"
+ expected_version="41"
+ expected_title="UCI DOS REU PROBE V41"
+ ;;
+ *) echo "PROBE_IMAGE_TYPE must be d64 or d81" >&2; exit 64 ;;
+esac
+
+api="http://${host}/v1"
+remote_image="${remote_dir}/${image_name}"
+build_image="${repo}/build/uci_dma_probe/uci_dma_probe.${image_type}"
+build_prg="${repo}/build/uci_dma_probe/uci_dma_probe.prg"
+capture_dir="/tmp/uci_dma_probe_c64u_ram_${image_type}_capture"
+tmp_dir="/tmp/uci_dma_probe_c64u_ram_${image_type}_tmp"
+
+rm -f "$log" "$status"
+rm -rf "$capture_dir" "$tmp_dir"
+mkdir -p "$tmp_dir"
+
+finish() {
+ local rc=$?
+ echo "$rc" > "$status"
+ echo "EXIT $rc" >> "$log"
+ exit "$rc"
+}
+trap finish EXIT
+
+run() {
+ echo "+ $*" >> "$log"
+ "$@" >> "$log" 2>&1
+}
+
+post_hex() {
+ local address="$1"
+ local data="$2"
+ run curl --fail --silent --show-error --max-time 10 \
+ -X PUT \
+ "${api}/machine:writemem?address=${address}&data=${data}"
+}
+
+type_text() {
+ python3 - "$tmp_dir/type.hex" "$1" <<'PY'
+import pathlib
+import sys
+
+text = sys.argv[2]
+data = bytes(0x0D if ch in "\r\n" else ord(ch.upper()) for ch in text)
+pathlib.Path(sys.argv[1]).write_text(data.hex())
+PY
+ local hex
+ hex="$(cat "$tmp_dir/type.hex")"
+ post_hex "00C5" "0000"
+ post_hex "0277" "$hex"
+ printf "%02x" $(( ${#hex} / 2 )) > "$tmp_dir/type_count.hex"
+ post_hex "00C6" "$(cat "$tmp_dir/type_count.hex")"
+}
+
+write_probe_prg() {
+ python3 - "$build_prg" "$tmp_dir/chunks.tsv" "$tmp_dir/basic_ptrs.hex" <<'PY'
+import pathlib
+import sys
+
+prg = pathlib.Path(sys.argv[1]).read_bytes()
+load = prg[0] | (prg[1] << 8)
+body = prg[2:]
+end = load + len(body)
+chunk = 64
+lines = []
+for offset in range(0, len(body), chunk):
+ address = load + offset
+ data = body[offset : offset + chunk].hex()
+ lines.append(f"{address:04X}\t{data}")
+pathlib.Path(sys.argv[2]).write_text("\n".join(lines) + "\n")
+ptr = bytes([end & 0xFF, end >> 8])
+pathlib.Path(sys.argv[3]).write_text((ptr * 4).hex())
+print(f"PRG load=${load:04X} end=${end:04X} bytes={len(body)}")
+PY
+
+ while IFS=$'\t' read -r address data; do
+ [[ -n "$address" ]] || continue
+ post_hex "$address" "$data"
+ done < "$tmp_dir/chunks.tsv"
+ post_hex "002D" "$(cat "$tmp_dir/basic_ptrs.hex")"
+}
+
+{
+ date
+ echo "C64U host: ${host}"
+ echo "Image type: ${image_type}"
+ echo "Remote image: /${remote_image}"
+} > "$log"
+
+cd "$repo"
+run env PROBE_IMAGE_TYPE="$image_type" /bin/bash probes/uci_dma/build.sh
+run curl --ftp-create-dirs --max-time 90 \
+ -T "$build_image" \
+ "ftp://anonymous:anonymous%40@${host}/${remote_image}"
+
+run curl --fail --silent --show-error --max-time 10 -X PUT "${api}/machine:reset"
+sleep 3
+run curl --fail --silent --show-error --max-time 10 -X PUT "${api}/machine:resume"
+sleep 8
+
+write_probe_prg >> "$log" 2>&1
+type_text $'RUN\r'
+
+for _ in $(seq 1 120); do
+ if C64U_HOST="$host" /bin/bash "$repo/build_support/capture_uci_dma_probe_c64u.sh" "$capture_dir" >> "$log" 2>&1; then
+ if grep -q "PROBE DONE" "$capture_dir/screen.txt"; then
+ break
+ fi
+ if grep -q "$expected_title" "$capture_dir/screen.txt"; then
+ echo "Probe visible, waiting for completion" >> "$log"
+ fi
+ fi
+ sleep 1
+done
+
+cat "$capture_dir/screen.txt" >> "$log" 2>/dev/null || true
+
+if ! grep -q "PROBE DONE" "$capture_dir/screen.txt"; then
+ echo "Probe did not reach PROBE DONE" >> "$log"
+ exit 3
+fi
+
+run python3 "$repo/build_support/analyze_uci_dma_probe_run.py" \
+ "$capture_dir" --expect success --version "$expected_version"
+
+echo "Capture: $capture_dir" >> "$log"
+echo "OK ${image_type}" >> "$log"
diff --git a/build_support/run_uci_dma_probe_c64u_rest.sh b/build_support/run_uci_dma_probe_c64u_rest.sh
new file mode 100755
index 0000000..32d6d93
--- /dev/null
+++ b/build_support/run_uci_dma_probe_c64u_rest.sh
@@ -0,0 +1,223 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+repo="$(cd "$(dirname "$0")/.." && pwd)"
+host="${C64U_HOST:-10.0.0.79}"
+remote_dir="${C64U_REMOTE_DIR:-USB1}"
+image_type="${PROBE_IMAGE_TYPE:-d64}"
+log="${1:-/tmp/uci_dma_probe_c64u_rest.log}"
+status="${2:-/tmp/uci_dma_probe_c64u_rest.status}"
+
+case "$remote_dir" in
+ USB0|USB1) ;;
+ *) echo "C64U_REMOTE_DIR must be USB0 or USB1" >&2; exit 64 ;;
+esac
+
+case "$image_type" in
+ d64)
+ image_upper="D64"
+ image_name="UCI40.D64"
+ drive_type="1541"
+ expected_version="40"
+ expected_title="UCI DOS REU PROBE V40"
+ ;;
+ d81)
+ image_upper="D81"
+ image_name="UCI41.D81"
+ drive_type="1581"
+ expected_version="41"
+ expected_title="UCI DOS REU PROBE V41"
+ ;;
+ *) echo "PROBE_IMAGE_TYPE must be d64 or d81" >&2; exit 64 ;;
+esac
+
+api="http://${host}/v1"
+remote_image="${remote_dir}/${image_name}"
+build_image="${repo}/build/uci_dma_probe/uci_dma_probe.${image_type}"
+capture_dir="/tmp/uci_dma_probe_c64u_rest_${image_type}_capture"
+tmp_dir="/tmp/uci_dma_probe_c64u_rest_${image_type}_tmp"
+screen_probe_dir="/tmp/uci_dma_probe_c64u_rest_${image_type}_screen"
+
+rm -f "$log" "$status"
+rm -rf "$capture_dir" "$tmp_dir"
+mkdir -p "$tmp_dir"
+
+finish() {
+ local rc=$?
+ echo "$rc" > "$status"
+ echo "EXIT $rc" >> "$log"
+ exit "$rc"
+}
+trap finish EXIT
+
+run() {
+ echo "+ $*" >> "$log"
+ "$@" >> "$log" 2>&1
+}
+
+post_bytes() {
+ local address="$1"
+ local file="$2"
+ local hex
+ hex="$(xxd -p -c 256 "$file" | tr -d '\n')"
+ run curl --fail --silent --show-error --max-time 10 \
+ -X PUT \
+ "${api}/machine:writemem?address=${address}&data=${hex}"
+}
+
+write_byte_file() {
+ python3 - "$1" "$2" <<'PY'
+import pathlib
+import sys
+
+pathlib.Path(sys.argv[1]).write_bytes(bytes([int(sys.argv[2], 0) & 0xFF]))
+PY
+}
+
+wait_keyboard_empty() {
+ local sample value
+ for _ in $(seq 1 200); do
+ sample="$tmp_dir/kb_count.bin"
+ if curl --fail --silent --show-error --max-time 5 \
+ "${api}/machine:readmem?address=C6&length=1" -o "$sample" >> "$log" 2>&1; then
+ value="$(od -An -tu1 "$sample" | tr -d ' ')"
+ if [[ "$value" == "0" ]]; then
+ return 0
+ fi
+ fi
+ sleep 0.03
+ done
+ echo "Keyboard buffer did not drain" >> "$log"
+ return 1
+}
+
+type_text() {
+ python3 - "$tmp_dir/type.bin" "$1" <<'PY'
+import pathlib
+import sys
+
+text = sys.argv[2]
+pathlib.Path(sys.argv[1]).write_bytes(
+ bytes(0x0D if ch in "\r\n" else ord(ch.upper()) for ch in text)
+)
+PY
+
+ local size offset byte_hex
+ size="$(wc -c < "$tmp_dir/type.bin" | tr -d ' ')"
+ offset=0
+ while (( offset < size )); do
+ dd if="$tmp_dir/type.bin" of="$tmp_dir/chunk.bin" bs=1 skip="$offset" count=1 status=none
+ byte_hex="$(xxd -p -c 1 "$tmp_dir/chunk.bin" | tr -d '\n')"
+ printf '\000\000' > "$tmp_dir/kbclear.bin"
+ wait_keyboard_empty
+ post_bytes "C5" "$tmp_dir/kbclear.bin"
+ run curl --fail --silent --show-error --max-time 10 \
+ -X PUT \
+ "${api}/machine:writemem?address=277&data=${byte_hex}"
+ write_byte_file "$tmp_dir/count.bin" 1
+ post_bytes "C6" "$tmp_dir/count.bin"
+ wait_keyboard_empty
+ offset=$(( offset + 1 ))
+ done
+}
+
+capture_screen_probe() {
+ rm -rf "$screen_probe_dir"
+ C64U_HOST="$host" /bin/bash "$repo/build_support/capture_uci_dma_probe_c64u.sh" "$screen_probe_dir" >> "$log" 2>&1
+}
+
+wait_for_basic() {
+ local label="$1"
+ local allow_stale_load="${2:-0}"
+ for _ in $(seq 1 30); do
+ if capture_screen_probe; then
+ if grep -q "READY" "$screen_probe_dir/screen.txt"; then
+ if [[ "$allow_stale_load" == "1" ]] \
+ || { ! grep -q "SEARCHING" "$screen_probe_dir/screen.txt" \
+ && ! grep -q "LOADING" "$screen_probe_dir/screen.txt"; }; then
+ echo "BASIC ready after ${label}" >> "$log"
+ return 0
+ fi
+ fi
+ fi
+ sleep 1
+ done
+ echo "BASIC did not become ready after ${label}" >> "$log"
+ cat "$screen_probe_dir/screen.txt" >> "$log" 2>/dev/null || true
+ return 1
+}
+
+reboot_to_basic() {
+ local label="$1"
+ run curl --fail --silent --show-error --max-time 10 -X PUT "${api}/machine:reset"
+ sleep 3
+ run curl --fail --silent --show-error --max-time 10 -X PUT "${api}/machine:resume"
+ sleep 7
+ wait_for_basic "$label"
+}
+
+{
+ date
+ echo "C64U host: ${host}"
+ echo "Image type: ${image_type}"
+ echo "Remote image: /${remote_image}"
+} > "$log"
+
+cd "$repo"
+run env PROBE_IMAGE_TYPE="$image_type" /bin/bash probes/uci_dma/build.sh
+
+run curl --ftp-create-dirs --max-time 60 \
+ -T "$build_image" \
+ "ftp://anonymous:anonymous%40@${host}/${remote_image}"
+
+reboot_to_basic "pre-mount reset"
+
+cat > "$tmp_dir/config_a.json" <> "$log"
+fi
+
+run curl --fail --silent --show-error --max-time 10 \
+ -X PUT \
+ "${api}/drives/a:mount?image=%2F${remote_image//\//%2F}&type=${image_type}&mode=readwrite"
+
+reboot_to_basic "post-mount reset"
+
+type_text $'LOAD"PROBE",8\r'
+echo "Quiet wait for disk LOAD to finish" >> "$log"
+sleep 45
+wait_for_basic "after LOAD" 1
+type_text $'RUN\r'
+
+for _ in $(seq 1 90); do
+ if C64U_HOST="$host" /bin/bash "$repo/build_support/capture_uci_dma_probe_c64u.sh" "$capture_dir" >> "$log" 2>&1; then
+ if grep -q "PROBE DONE" "$capture_dir/screen.txt"; then
+ break
+ fi
+ if grep -q "$expected_title" "$capture_dir/screen.txt"; then
+ echo "Probe visible, waiting for completion" >> "$log"
+ fi
+ fi
+ sleep 1
+done
+
+cat "$capture_dir/screen.txt" >> "$log"
+
+if ! grep -q "PROBE DONE" "$capture_dir/screen.txt"; then
+ echo "Probe did not reach PROBE DONE" >> "$log"
+ exit 3
+fi
+
+run python3 "$repo/build_support/analyze_uci_dma_probe_run.py" \
+ "$capture_dir" --expect success --version "$expected_version" \
+ --expect-plain fail --expect-copy-ui fail
+
+echo "Capture: $capture_dir" >> "$log"
+echo "OK ${image_upper}" >> "$log"
diff --git a/build_support/run_uci_dma_probe_ultimate.sh b/build_support/run_uci_dma_probe_ultimate.sh
new file mode 100644
index 0000000..48ccab7
--- /dev/null
+++ b/build_support/run_uci_dma_probe_ultimate.sh
@@ -0,0 +1,187 @@
+#!/usr/bin/env bash
+set -uo pipefail
+
+repo="/Users/karlprosserpp/dev/c64projects/readyosprecog"
+harness="/Users/karlprosserpp/dev/c64projects/agenticdevharness/tools/vice_tasks_dotnet"
+log="${1:-/tmp/uci_dma_probe_ultimate.log}"
+status="${2:-/tmp/uci_dma_probe_ultimate.status}"
+
+host="${C64U_HOST:-10.0.0.79}"
+image_type="${PROBE_IMAGE_TYPE:-d81}"
+case "$image_type" in
+ d64)
+ image_upper="D64"
+ drive_type="1541"
+ expected_title="UCI DOS REU PROBE V40"
+ expected_version="40"
+ ;;
+ d81)
+ image_upper="D81"
+ drive_type="1581"
+ expected_title="UCI DOS REU PROBE V41"
+ expected_version="41"
+ ;;
+ *)
+ echo "PROBE_IMAGE_TYPE must be d64 or d81" > "$log"
+ echo 64 > "$status"
+ exit 64
+ ;;
+esac
+requested_host="$host"
+if [[ -n "${C64U_REMOTE_DIR:-}" ]]; then
+ case "$C64U_REMOTE_DIR" in
+ USB0|USB1) candidate_dirs=("$C64U_REMOTE_DIR") ;;
+ *)
+ echo "C64U_REMOTE_DIR must be USB0 or USB1" > "$log"
+ echo 64 > "$status"
+ exit 64
+ ;;
+ esac
+else
+ candidate_dirs=("USB1" "USB0")
+fi
+remote_dir=""
+remote_image=""
+plan=""
+rc=99
+
+rm -f "$log" "$status"
+
+finish() {
+ rc=$?
+ echo "$rc" > "$status"
+ echo "EXIT $rc" >> "$log"
+ exit "$rc"
+}
+trap finish EXIT
+
+run() {
+ echo "+ $*" >> "$log"
+ "$@" >> "$log" 2>&1
+}
+
+probe_endpoint() {
+ echo "+ $*" >> "$log"
+ "$@" >> "$log" 2>&1
+ local probe_rc=$?
+ echo "endpoint rc=${probe_rc}" >> "$log"
+ return 0
+}
+
+{
+ date
+ echo "Requested C64U host: ${requested_host}"
+ echo "Discovery mode: ${C64U_DISCOVER:-0}"
+} > "$log"
+
+if [[ "$requested_host" == "auto" || "${C64U_DISCOVER:-0}" == "1" ]]; then
+ discovery_log="${C64U_DISCOVERY_LOG:-${log}.discover}"
+ echo "Running C64U discovery, log: ${discovery_log}" >> "$log"
+ if discovered_host="$(
+ C64U_DISCOVERY_LOG="$discovery_log" \
+ C64U_HOST="$requested_host" \
+ C64U_PASSWORD="${C64U_PASSWORD:-}" \
+ C64U_HOSTS="${C64U_HOSTS:-}" \
+ C64U_SCAN_SUBNET="${C64U_SCAN_SUBNET:-}" \
+ /bin/bash "$repo/build_support/discover_c64u_host.sh" 2>>"$log"
+ )"; then
+ host="$discovered_host"
+ echo "Discovered C64U host: ${host}" >> "$log"
+ else
+ echo "C64U discovery found no reachable Ultimate REST host" >> "$log"
+ if [[ "$requested_host" == "auto" ]]; then
+ exit 6
+ fi
+ echo "Falling back to requested host: ${host}" >> "$log"
+ fi
+fi
+
+{
+ echo "C64U host: ${host}"
+ echo "Remote candidates: ${candidate_dirs[*]}"
+ echo "REST preflight"
+} >> "$log"
+
+probe_endpoint curl --max-time 5 --silent --show-error --head "http://${host}/"
+echo "FTP preflight" >> "$log"
+probe_endpoint curl --max-time 5 --silent --show-error \
+ "ftp://anonymous:anonymous%40@${host}/"
+
+echo "Building Ultimate DOS REU probe ${image_upper} and payloads" >> "$log"
+
+cd "$repo" || exit 1
+if ! run env PROBE_IMAGE_TYPE="$image_type" /bin/bash probes/uci_dma/build.sh; then
+ exit 1
+fi
+
+for candidate in "${candidate_dirs[@]}"; do
+ candidate_image="${candidate}/UCI.${image_upper}"
+ candidate_url="ftp://anonymous:anonymous%40@${host}/${candidate_image}"
+ candidate_plan="/tmp/uci_dma_probe_ultimate_${candidate}.yaml"
+
+ sed \
+ -e "s#remote_root: USB1#remote_root: ${candidate}#g" \
+ -e "s#remote_disk: USB1/UCI.D81#remote_disk: ${candidate_image}#g" \
+ -e "s#uci_dma_probe.d81#uci_dma_probe.${image_type}#g" \
+ -e "s#drive_a_type: '1581'#drive_a_type: '${drive_type}'#g" \
+ -e "s#drive_b_type: '1581'#drive_b_type: '${drive_type}'#g" \
+ -e "s#drive_type: '1581'#drive_type: '${drive_type}'#g" \
+ -e "s#UCI DOS REU PROBE V41#${expected_title}#g" \
+ "$repo/build_support/uci_dma_probe_ultimate.generated.yaml" > "$candidate_plan"
+
+ echo "Replacing /${candidate_image}" >> "$log"
+ run curl --max-time 20 --quote "DELE /${candidate_image}" \
+ "ftp://anonymous:anonymous%40@${host}/" || true
+
+ if run curl --ftp-create-dirs --max-time 60 \
+ -T "$repo/build/uci_dma_probe/uci_dma_probe.${image_type}" \
+ "$candidate_url"; then
+ remote_dir="$candidate"
+ remote_image="$candidate_image"
+ plan="$candidate_plan"
+ break
+ fi
+
+ echo "FTP upload failed for /${candidate_image}" >> "$log"
+done
+
+if [[ -z "$remote_dir" ]]; then
+ echo "FTP upload failed for all candidate roots" >> "$log"
+ exit 2
+fi
+
+echo "Using remote image: /${remote_image}" >> "$log"
+
+cd "$harness" || exit 1
+if ! /usr/local/share/dotnet/dotnet run \
+ --project src/ViceTasks.Binary/ViceTasks.Binary.csproj \
+ -- run-ultimate-plan \
+ --plan "$plan" \
+ --no-tui >> "$log" 2>&1; then
+ echo "Ultimate plan failed" >> "$log"
+ exit 3
+fi
+
+manifest="$(
+ python3 - "$log" <<'PY'
+import re
+import sys
+
+text = open(sys.argv[1], "r", encoding="utf-8-sig", errors="ignore").read()
+matches = re.findall(r'"Manifest"\s*:\s*"([^"]+)"', text)
+print(matches[-1] if matches else "")
+PY
+)"
+if [[ -z "$manifest" ]]; then
+ echo "Ultimate plan manifest not found in log" >> "$log"
+ exit 4
+fi
+
+run_dir="$(dirname "$manifest")"
+if ! run python3 "$repo/build_support/analyze_uci_dma_probe_run.py" \
+ "$run_dir" --expect success --version "$expected_version"; then
+ echo "Ultimate probe artifact analysis failed" >> "$log"
+ exit 5
+fi
+
+exit 0
diff --git a/build_support/run_uci_dma_probe_vice.sh b/build_support/run_uci_dma_probe_vice.sh
new file mode 100755
index 0000000..7b086ee
--- /dev/null
+++ b/build_support/run_uci_dma_probe_vice.sh
@@ -0,0 +1,74 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+READYOS_ROOT="${READYOS_ROOT:-$(cd "$SCRIPT_DIR/.." && pwd)}"
+if [ -n "${VICE_TASKS_ROOT:-}" ]; then
+ VICE_TOOL_ROOT="$(cd "$VICE_TASKS_ROOT" && pwd)"
+else
+ HARNESS_REPO="${VICE_TASKS_REPO:-$READYOS_ROOT/../agenticdevharness}"
+ VICE_TOOL_ROOT="$(cd "$HARNESS_REPO/tools/vice_tasks_dotnet" && pwd)"
+fi
+
+PROJECT="$VICE_TOOL_ROOT/src/ViceTasks.Binary/ViceTasks.Binary.csproj"
+PLAN="${UCI_DMA_VICE_PLAN:-$SCRIPT_DIR/uci_dma_probe_vice.generated.yaml}"
+LOG="${UCI_DMA_VICE_LOG:-/tmp/uci_dma_probe_vice.log}"
+STATUS="${UCI_DMA_VICE_STATUS:-/tmp/uci_dma_probe_vice.status}"
+RUN_DIR_FILE="${UCI_DMA_VICE_RUN_DIR_FILE:-/tmp/uci_dma_probe_vice.run_dir}"
+
+rm -f "$LOG" "$STATUS" "$RUN_DIR_FILE"
+
+cd "$READYOS_ROOT"
+PROBE_IMAGE_TYPE=d81 /bin/bash probes/uci_dma/build.sh >>"$LOG" 2>&1
+
+set +e
+dotnet run --project "$PROJECT" -- run-plan --plan "$PLAN" --close-vice --no-tui \
+ >>"$LOG" 2>&1
+rc=$?
+set -e
+if [ "$rc" -ne 0 ]; then
+ echo "$rc" >"$STATUS"
+ exit "$rc"
+fi
+
+python3 - "$LOG" "$RUN_DIR_FILE" <<'PY'
+import json
+import pathlib
+import re
+import sys
+
+text = pathlib.Path(sys.argv[1]).read_text(encoding="utf-8-sig", errors="ignore")
+run_dir = ""
+for line in reversed(text.splitlines()):
+ line = line.strip()
+ if not line:
+ continue
+ try:
+ obj = json.loads(line)
+ except Exception:
+ obj = None
+ if isinstance(obj, dict):
+ run_dir = str(obj.get("RunDir") or obj.get("run_dir") or "")
+ if not run_dir and isinstance(obj.get("artifacts"), dict):
+ run_dir = str(obj["artifacts"].get("run_dir") or "")
+ if run_dir:
+ break
+matches = re.findall(r"run_dir[=:] ?`?([^`\"\\s,}]+)", text, re.IGNORECASE)
+if not run_dir and matches:
+ run_dir = matches[-1]
+if not run_dir:
+ matches = re.findall(r'"(?:run_dir|RunDir)"\s*:\s*"([^"]+)"', text)
+ if matches:
+ run_dir = matches[-1]
+if not run_dir:
+ raise SystemExit("could not find VICE run_dir in log")
+pathlib.Path(sys.argv[2]).write_text(run_dir + "\n", encoding="utf-8")
+print(run_dir)
+PY
+
+run_dir="$(cat "$RUN_DIR_FILE")"
+python3 build_support/analyze_uci_dma_probe_run.py \
+ "$run_dir" --expect no-uci --version 41 >>"$LOG" 2>&1
+
+echo 0 >"$STATUS"
+echo "OK VICE $run_dir" >>"$LOG"
diff --git a/build_support/run_uci_timing_probe_c64u_rest.sh b/build_support/run_uci_timing_probe_c64u_rest.sh
new file mode 100755
index 0000000..ab109bb
--- /dev/null
+++ b/build_support/run_uci_timing_probe_c64u_rest.sh
@@ -0,0 +1,237 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+repo="$(cd "$(dirname "$0")/.." && pwd)"
+host="${C64U_HOST:-10.0.0.79}"
+remote_image="${C64U_REMOTE_IMAGE:-USB1/readyos.d81}"
+log="${1:-/tmp/uci_timing_probe_c64u_rest.log}"
+status="${2:-/tmp/uci_timing_probe_c64u_rest.status}"
+
+case "$remote_image" in
+ USB0/*|USB1/*) ;;
+ *) echo "C64U_REMOTE_IMAGE must start with USB0/ or USB1/" >&2; exit 64 ;;
+esac
+
+api="http://${host}/v1"
+remote_root="${remote_image%%/*}"
+build_image="${repo}/build/uci_timing/readyos.d81"
+capture_dir="/tmp/uci_timing_probe_c64u_rest_capture"
+tmp_dir="/tmp/uci_timing_probe_c64u_rest_tmp"
+
+rm -f "$log" "$status"
+rm -rf "$capture_dir" "$tmp_dir"
+mkdir -p "$tmp_dir"
+
+finish() {
+ local rc=$?
+ echo "$rc" > "$status"
+ echo "EXIT $rc" >> "$log"
+ exit "$rc"
+}
+trap finish EXIT
+
+run() {
+ echo "+ $*" >> "$log"
+ "$@" >> "$log" 2>&1
+}
+
+post_bytes() {
+ local address="$1"
+ local file="$2"
+ local hex
+ hex="$(xxd -p -c 256 "$file" | tr -d '\n')"
+ run curl --fail --silent --show-error --max-time 10 \
+ -X PUT \
+ "${api}/machine:writemem?address=${address}&data=${hex}"
+}
+
+write_byte_file() {
+ python3 - "$1" "$2" <<'PY'
+import pathlib
+import sys
+
+pathlib.Path(sys.argv[1]).write_bytes(bytes([int(sys.argv[2], 0) & 0xFF]))
+PY
+}
+
+wait_for_url() {
+ local label="$1"
+ local url="$2"
+ local deadline=$((SECONDS + 300))
+ echo "Waiting for ${label}: ${url}" >> "$log"
+ while [ "$SECONDS" -lt "$deadline" ]; do
+ if curl --fail --silent --show-error --max-time 5 "$url" >/dev/null 2>>"$log"; then
+ echo "${label} reachable" >> "$log"
+ return 0
+ fi
+ sleep 3
+ done
+ echo "${label} not reachable" >> "$log"
+ return 1
+}
+
+wait_keyboard_empty() {
+ local sample value
+ for _ in $(seq 1 200); do
+ sample="$tmp_dir/kb_count.bin"
+ if curl --fail --silent --show-error --max-time 5 \
+ "${api}/machine:readmem?address=C6&length=1" -o "$sample" >> "$log" 2>&1; then
+ value="$(od -An -tu1 "$sample" | tr -d ' ')"
+ if [[ "$value" == "0" ]]; then
+ return 0
+ fi
+ fi
+ sleep 0.03
+ done
+ echo "Keyboard buffer did not drain" >> "$log"
+ return 1
+}
+
+type_text() {
+ python3 - "$tmp_dir/type.bin" "$1" <<'PY'
+import pathlib
+import sys
+
+text = sys.argv[2]
+pathlib.Path(sys.argv[1]).write_bytes(
+ bytes(0x0D if ch in "\r\n" else ord(ch.upper()) for ch in text)
+)
+PY
+
+ local size offset byte_hex
+ size="$(wc -c < "$tmp_dir/type.bin" | tr -d ' ')"
+ offset=0
+ while (( offset < size )); do
+ dd if="$tmp_dir/type.bin" of="$tmp_dir/chunk.bin" bs=1 skip="$offset" count=1 status=none
+ byte_hex="$(xxd -p -c 1 "$tmp_dir/chunk.bin" | tr -d '\n')"
+ printf '\000\000' > "$tmp_dir/kbclear.bin"
+ wait_keyboard_empty
+ post_bytes "C5" "$tmp_dir/kbclear.bin"
+ run curl --fail --silent --show-error --max-time 10 \
+ -X PUT \
+ "${api}/machine:writemem?address=277&data=${byte_hex}"
+ write_byte_file "$tmp_dir/count.bin" 1
+ post_bytes "C6" "$tmp_dir/count.bin"
+ wait_keyboard_empty
+ offset=$(( offset + 1 ))
+ done
+}
+
+capture_probe() {
+ rm -rf "$capture_dir"
+ mkdir -p "$capture_dir"
+ run curl --fail --silent --show-error --max-time 10 \
+ "${api}/machine:readmem?address=0400&length=1000" \
+ -o "$capture_dir/screen_0400.bin"
+ run curl --fail --silent --show-error --max-time 10 \
+ "${api}/machine:readmem?address=3000&length=192" \
+ -o "$capture_dir/probe_results_3000.bin"
+ run curl --fail --silent --show-error --max-time 10 \
+ "${api}/drives" \
+ -o "$capture_dir/drives.json"
+ python3 "$repo/build_support/decode_c64_screen.py" \
+ "$capture_dir/screen_0400.bin" \
+ --output "$capture_dir/screen.txt" >> "$log" 2>&1
+ xxd -g 1 -c 16 "$capture_dir/probe_results_3000.bin" \
+ > "$capture_dir/probe_results_3000.hex.txt"
+}
+
+wait_for_basic_ready() {
+ local label="$1"
+ local allow_loading="${2:-0}"
+ for _ in $(seq 1 30); do
+ if capture_probe; then
+ if grep -q "READY" "$capture_dir/screen.txt"; then
+ if [[ "$allow_loading" == "1" ]] \
+ || { ! grep -q "SEARCHING" "$capture_dir/screen.txt" \
+ && ! grep -q "LOADING" "$capture_dir/screen.txt"; }; then
+ echo "BASIC ready after ${label}" >> "$log"
+ return 0
+ fi
+ fi
+ fi
+ sleep 1
+ done
+ echo "BASIC did not become ready after ${label}" >> "$log"
+ cat "$capture_dir/screen.txt" >> "$log" 2>/dev/null || true
+ return 1
+}
+
+reboot_to_basic() {
+ local label="$1"
+ run curl --fail --silent --show-error --max-time 10 -X PUT "${api}/machine:reset"
+ sleep 3
+ run curl --fail --silent --show-error --max-time 10 -X PUT "${api}/machine:resume"
+ sleep 7
+ wait_for_basic_ready "$label"
+}
+
+{
+ date
+ echo "C64U host: ${host}"
+ echo "Remote image: /${remote_image}"
+} > "$log"
+
+cd "$repo"
+run /bin/bash probes/uci_timing/build.sh
+
+wait_for_url "C64U FTP" "ftp://anonymous:anonymous%40@${host}/${remote_root}/"
+run curl --max-time 20 --quote "DELE /${remote_image}" \
+ "ftp://anonymous:anonymous%40@${host}/" || true
+run curl --ftp-create-dirs --max-time 90 \
+ -T "$build_image" \
+ "ftp://anonymous:anonymous%40@${host}/${remote_image}"
+
+wait_for_url "C64U REST" "${api}/drives"
+reboot_to_basic "pre-mount reset"
+
+cat > "$tmp_dir/config_a.json" <> "$log"
+fi
+
+run curl --fail --silent --show-error --max-time 10 \
+ -X PUT \
+ "${api}/drives/a:mount?image=%2F${remote_image//\//%2F}&type=d81&mode=readwrite"
+
+reboot_to_basic "post-mount reset"
+
+type_text $'LOAD"UTIME",8\r'
+echo "Quiet wait for UTIME disk LOAD to finish" >> "$log"
+sleep "${UTIME_LOAD_WAIT_S:-120}"
+wait_for_basic_ready "after UTIME LOAD" 1
+type_text $'RUN\r'
+
+for _ in $(seq 1 "${UTIME_RUN_WAIT_S:-240}"); do
+ if capture_probe; then
+ if grep -q "PROBE DONE" "$capture_dir/screen.txt"; then
+ break
+ fi
+ if grep -q "config .*failed" "$capture_dir/screen.txt"; then
+ break
+ fi
+ if grep -q "uci timing probe" "$capture_dir/screen.txt"; then
+ echo "Timing probe visible, waiting for completion" >> "$log"
+ fi
+ fi
+ sleep 1
+done
+
+cat "$capture_dir/screen.txt" >> "$log" 2>/dev/null || true
+cat "$capture_dir/probe_results_3000.hex.txt" >> "$log" 2>/dev/null || true
+
+if ! run python3 "$repo/build_support/analyze_uci_timing_probe_run.py" \
+ "$capture_dir" --json-output "$repo/build/uci_timing/latest_result.json"; then
+ echo "Timing probe did not report success" >> "$log"
+ exit 4
+fi
+
+echo "Capture: $capture_dir" >> "$log"
+echo "OK UCI timing" >> "$log"
diff --git a/build_support/run_uci_timing_probe_ultimate.sh b/build_support/run_uci_timing_probe_ultimate.sh
new file mode 100644
index 0000000..c8eaab6
--- /dev/null
+++ b/build_support/run_uci_timing_probe_ultimate.sh
@@ -0,0 +1,93 @@
+#!/usr/bin/env bash
+set -uo pipefail
+
+repo="/Users/karlprosserpp/dev/c64projects/readyosprecog"
+harness="/Users/karlprosserpp/dev/c64projects/agenticdevharness/tools/vice_tasks_dotnet"
+log="${1:-/tmp/uci_timing_probe_ultimate.log}"
+status="${2:-/tmp/uci_timing_probe_ultimate.status}"
+host="${C64U_HOST:-10.0.0.79}"
+remote_image="${C64U_REMOTE_IMAGE:-USB1/readyos.d81}"
+plan="/tmp/uci_timing_probe_ultimate.yaml"
+connect_wait_s="${C64U_CONNECT_WAIT_S:-300}"
+
+rm -f "$log" "$status"
+
+finish() {
+ rc=$?
+ echo "$rc" > "$status"
+ echo "EXIT $rc" >> "$log"
+ exit "$rc"
+}
+trap finish EXIT
+
+run() {
+ echo "+ $*" >> "$log"
+ "$@" >> "$log" 2>&1
+}
+
+wait_for_url() {
+ local label="$1"
+ local url="$2"
+ local deadline=$((SECONDS + connect_wait_s))
+ echo "Waiting for ${label}: ${url}" >> "$log"
+ while [ "$SECONDS" -lt "$deadline" ]; do
+ if curl --fail --silent --show-error --max-time 5 "$url" >/dev/null 2>>"$log"; then
+ echo "${label} reachable" >> "$log"
+ return 0
+ fi
+ sleep 3
+ done
+ echo "${label} not reachable after ${connect_wait_s}s" >> "$log"
+ return 1
+}
+
+{
+ date
+ echo "C64U host: $host"
+ echo "Remote image: /$remote_image"
+} > "$log"
+
+cd "$repo" || exit 1
+if ! run /bin/bash probes/uci_timing/build.sh; then
+ exit 1
+fi
+
+remote_root="${remote_image%%/*}"
+sed \
+ -e "s#remote_root: USB1#remote_root: ${remote_root}#g" \
+ -e "s#remote_disk: USB1/readyos.d81#remote_disk: ${remote_image}#g" \
+ -e "s#host: 10.0.0.79#host: ${host}#g" \
+ "$repo/build_support/uci_timing_probe_ultimate.generated.yaml" > "$plan"
+
+echo "Replacing /$remote_image" >> "$log"
+if ! wait_for_url "C64U FTP" "ftp://anonymous:anonymous%40@${host}/${remote_root}/"; then
+ exit 2
+fi
+run curl --max-time 20 --quote "DELE /${remote_image}" \
+ "ftp://anonymous:anonymous%40@${host}/" || true
+if ! run curl --ftp-create-dirs --max-time 90 \
+ -T "$repo/build/uci_timing/readyos.d81" \
+ "ftp://anonymous:anonymous%40@${host}/${remote_image}"; then
+ exit 2
+fi
+if ! wait_for_url "C64U REST" "http://${host}/v1/drives"; then
+ exit 2
+fi
+
+cd "$harness" || exit 1
+if ! /usr/local/share/dotnet/dotnet run \
+ --project src/ViceTasks.Binary/ViceTasks.Binary.csproj \
+ -- run-ultimate-plan \
+ --plan "$plan" \
+ --no-tui >> "$log" 2>&1; then
+ echo "Ultimate plan failed" >> "$log"
+ exit 3
+fi
+
+if ! run python3 "$repo/build_support/analyze_uci_timing_probe_run.py" \
+ "$log" --json-output "$repo/build/uci_timing/latest_result.json"; then
+ echo "Timing probe reported failure" >> "$log"
+ exit 4
+fi
+
+exit 0
diff --git a/build_support/start_uci_dma_probe_ultimate_screen.sh b/build_support/start_uci_dma_probe_ultimate_screen.sh
new file mode 100644
index 0000000..4d9aa8c
--- /dev/null
+++ b/build_support/start_uci_dma_probe_ultimate_screen.sh
@@ -0,0 +1,36 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+repo="/Users/karlprosserpp/dev/c64projects/readyosprecog"
+stamp="$(date +%Y%m%d_%H%M%S)"
+session="${UCI_DMA_SCREEN_SESSION:-uci_dma_probe_${stamp}}"
+log="${UCI_DMA_LOG:-/tmp/uci_dma_probe_ultimate_${stamp}.log}"
+status="${UCI_DMA_STATUS:-/tmp/uci_dma_probe_ultimate_${stamp}.status}"
+host="${C64U_HOST:-10.0.0.79}"
+remote_dir="${C64U_REMOTE_DIR:-}"
+
+if [[ -n "$remote_dir" ]]; then
+ case "$remote_dir" in
+ USB0|USB1) ;;
+ *)
+ echo "C64U_REMOTE_DIR must be USB0 or USB1" >&2
+ exit 64
+ ;;
+ esac
+fi
+
+rm -f "$log" "$status"
+
+screen -dmS "$session" /bin/bash -lc \
+ "cd '$repo' && C64U_HOST='$host' C64U_REMOTE_DIR='$remote_dir' /bin/bash build_support/run_uci_dma_probe_ultimate.sh '$log' '$status'"
+
+echo "session=$session"
+echo "log=$log"
+echo "status=$status"
+echo "host=$host"
+echo "discover=${C64U_DISCOVER:-0}"
+if [[ -n "$remote_dir" ]]; then
+ echo "remote_dir=$remote_dir"
+else
+ echo "remote_dir=auto"
+fi
diff --git a/build_support/sync_shim_documentation.py b/build_support/sync_shim_documentation.py
new file mode 100644
index 0000000..08f50d1
--- /dev/null
+++ b/build_support/sync_shim_documentation.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python3
+"""Refresh every complete Markdown/HTML shim appendix from the canonical source.
+
+Historical reports are intentionally preserved, but an appendix claiming to
+contain the current complete shim must be exact. This script changes only the
+marked code block/preformatted block and leaves the surrounding report intact.
+"""
+
+from __future__ import annotations
+
+import html
+from pathlib import Path
+
+
+ROOT = Path(__file__).resolve().parents[1]
+SOURCE = ROOT / "src/boot/readyos_shim.inc"
+MARKERS = (
+ "Shared ReadyOS shim image ($C600-$C9FF, 1024 bytes)",
+ "Shared ReadyOS shim image ($C800-$C9FF, 512 bytes)",
+)
+
+
+def marker_offset(text: str) -> int:
+ offsets = [text.index(marker) for marker in MARKERS if marker in text]
+ return min(offsets) if offsets else -1
+
+
+def sync_markdown(path: Path, source: str) -> bool:
+ text = path.read_text(encoding="utf-8")
+ marker = marker_offset(text)
+ if marker < 0:
+ return False
+ opening = text.rfind("```", 0, marker)
+ closing = text.find("```", marker)
+ if opening < 0 or closing < 0:
+ raise SystemExit(f"marked shim listing is not fenced: {path}")
+ opening_end = text.find("\n", opening)
+ updated = text[: opening_end + 1] + source.rstrip() + "\n" + text[closing:]
+ path.write_text(updated, encoding="utf-8")
+ return True
+
+
+def sync_html(path: Path, source: str) -> bool:
+ text = path.read_text(encoding="utf-8")
+ marker = marker_offset(text)
+ if marker < 0:
+ return False
+ opening = text.rfind("", opening)
+ closing = text.find(" ", marker)
+ if opening < 0 or opening_end < 0 or closing < 0:
+ raise SystemExit(f"marked shim listing is not in a pre block: {path}")
+ escaped = html.escape(source.rstrip(), quote=False)
+ updated = text[: opening_end + 1] + escaped + "\n" + text[closing:]
+ path.write_text(updated, encoding="utf-8")
+ return True
+
+
+def main() -> None:
+ source = SOURCE.read_text(encoding="utf-8")
+ changed = []
+ for path in ROOT.rglob("*"):
+ if not path.is_file() or ".git" in path.parts or "third_party" in path.parts:
+ continue
+ if path.suffix.lower() == ".md" and sync_markdown(path, source):
+ changed.append(path)
+ elif path.suffix.lower() in {".html", ".htm"} and sync_html(path, source):
+ changed.append(path)
+ print(f"refreshed {len(changed)} complete shim appendices")
+ for path in changed:
+ print(path.relative_to(ROOT))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/build_support/uci_dma_probe_ultimate.generated.yaml b/build_support/uci_dma_probe_ultimate.generated.yaml
new file mode 100644
index 0000000..f0da50e
--- /dev/null
+++ b/build_support/uci_dma_probe_ultimate.generated.yaml
@@ -0,0 +1,102 @@
+version: 1
+kind: ultimate_task_plan
+plan_id: uci_dma_probe
+run_mode: ultimate64
+global_defaults:
+ retry_policy:
+ max_attempts: 1
+ backoff_ms: 500
+ jitter: false
+ timeouts:
+ launch_s: 60
+ step_s: 180
+ read_s: 60
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: true
+ ultimate:
+ host: 10.0.0.79
+ password: null
+ ftp_user: anonymous
+ ftp_password: anonymous@
+ remote_root: USB1
+ disk8: /Users/karlprosserpp/dev/c64projects/readyosprecog/build/uci_dma_probe/uci_dma_probe.d81
+ disk9: null
+ autostart_prg: null
+ drive_a_bus_id: 8
+ drive_b_bus_id: 11
+ drive_a_type: '1581'
+ drive_b_type: '1581'
+ drive_a_enabled: true
+ drive_b_enabled: false
+ mount_mode: readwrite
+ boot_drive: 8
+ capture_video_stream: true
+ stream_port: 11000
+ stream_timeout_s: 4.0
+ default_speed_mhz: 1
+ warp_equivalent_mhz: 8
+steps:
+- id: launch_probe_d81
+ type: ultimate.launch
+ params:
+ boot_mode: disk
+ drives:
+ - slot: a
+ bus_id: 8
+ drive_type: '1581'
+ enabled: true
+ disk: /Users/karlprosserpp/dev/c64projects/readyosprecog/build/uci_dma_probe/uci_dma_probe.d81
+ remote_disk: USB1/UCI.D81
+ mount_mode: readwrite
+ - slot: b
+ bus_id: 11
+ drive_type: '1581'
+ enabled: false
+ disk: /Users/karlprosserpp/dev/c64projects/readyosprecog/build/uci_dma_probe/uci_dma_probe.d81
+ remote_disk: USB1/UCI.D81
+ mount_mode: readwrite
+ boot_drive: 8
+ boot_command: "load\"probe\",8\nrun\n"
+ reset_before_boot: true
+ post_reset_delay_s: 2.0
+- id: wait_probe_started
+ type: screen.wait_contains
+ params:
+ text: "UCI DOS REU PROBE V41"
+ wait_timeout_s: 90
+ capture_label: uci_dma_probe_started
+- id: wait_probe_done
+ type: screen.wait_contains
+ criticality: observe
+ params:
+ text: "PROBE DONE"
+ wait_timeout_s: 45
+ capture_label: uci_dma_probe_done
+- id: wait_success_summary
+ type: screen.wait_contains
+ criticality: observe
+ params:
+ text: "F1:55 F2:55 F3:55"
+ wait_timeout_s: 5
+ capture_label: uci_dma_probe_success_summary
+- id: capture_done_screen
+ type: screen.capture
+ criticality: observe
+ params:
+ label: uci_dma_probe_final
+ note: Final UCI DOS REU probe screen
+ capture_state: true
+- id: dump_probe_state
+ type: dump.memory_ranges
+ criticality: observe
+ params:
+ ranges:
+ - { label: probe_results_3000, start: 0x3000, end: 0x307F }
+ - { label: dma_load_buf_4000, start: 0x4000, end: 0x40FF }
+ - { label: reu_fetch_buf_5000, start: 0x5000, end: 0x50FF }
+ - { label: reu_snap_udma1_6000, start: 0x6000, end: 0x60FF }
+ - { label: reu_snap_udma2_6100, start: 0x6100, end: 0x61FF }
+ - { label: reu_snap_udma3_6200, start: 0x6200, end: 0x62FF }
+ - { label: screen_0400, start: 0x0400, end: 0x07E7 }
diff --git a/build_support/uci_dma_probe_vice.generated.yaml b/build_support/uci_dma_probe_vice.generated.yaml
new file mode 100644
index 0000000..cce8df3
--- /dev/null
+++ b/build_support/uci_dma_probe_vice.generated.yaml
@@ -0,0 +1,81 @@
+version: 1
+kind: vice_task_plan
+plan_id: uci_dma_probe_vice
+run_mode: gui_vice
+global_defaults:
+ monitor_host: 127.0.0.1
+ monitor_port_start: 6502
+ monitor_port_span: 40
+ dump_reu_mode: sampled
+ retry_policy:
+ max_attempts: 1
+ backoff_ms: 250
+ jitter: false
+ timeouts:
+ launch_s: 30
+ step_s: 90
+ read_s: 2
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: true
+ vice:
+ disk8: build/uci_dma_probe/uci_dma_probe.d81
+ disk9: build/uci_dma_probe/uci_dma_probe.d81
+ autostart_prg: build/uci_dma_probe/uci_dma_probe.prg
+ autostart_enabled: false
+ drive8_enabled: true
+ drive9_enabled: false
+ drive8_type: 1581
+ drive9_type: 1581
+ true_drive: false
+ close_vice: true
+ headless: true
+ speed_percent: 800
+steps:
+- id: launch
+ type: vice.launch
+ params:
+ kill_stale: true
+ launch_attempts: 1
+- id: set_initial_speed
+ type: warp.set
+ params:
+ enabled: true
+ mhz: 8
+ capture_after: false
+- id: load_and_run_probe
+ type: input.sequence
+ params:
+ keys: [76,79,65,68,34,80,82,79,66,69,34,44,56,44,49,13,82,85,78,13]
+ inter_key_delay_s: 0.03
+ post_delay_s: 2.0
+- id: wait_probe_started
+ type: screen.wait_contains
+ params:
+ text: "UCI DOS REU PROBE V41"
+ wait_timeout_s: 30
+ capture_label: vice_uci_dma_probe_started
+- id: wait_probe_done
+ type: screen.wait_contains
+ params:
+ text: "PROBE DONE"
+ wait_timeout_s: 45
+ capture_label: vice_uci_dma_probe_done
+- id: assert_no_uci
+ type: assert.screen
+ params:
+ contains: "NOT FOUND"
+- id: dump_probe_state
+ type: dump.memory_ranges
+ criticality: observe
+ params:
+ ranges:
+ - { label: probe_results_3000, start: 0x3000, end: 0x307F }
+ - { label: screen_0400, start: 0x0400, end: 0x07E7 }
+- id: restore_speed
+ type: warp.set
+ params:
+ enabled: false
+ mhz: 1
+ capture_after: true
diff --git a/build_support/uci_timing_probe_ultimate.generated.yaml b/build_support/uci_timing_probe_ultimate.generated.yaml
new file mode 100644
index 0000000..d3dfdd9
--- /dev/null
+++ b/build_support/uci_timing_probe_ultimate.generated.yaml
@@ -0,0 +1,88 @@
+version: 1
+kind: ultimate_task_plan
+plan_id: uci_timing_probe
+run_mode: ultimate64
+global_defaults:
+ retry_policy:
+ max_attempts: 1
+ backoff_ms: 500
+ jitter: false
+ timeouts:
+ launch_s: 60
+ step_s: 360
+ read_s: 60
+ artifact_policy:
+ capture_screen: true
+ capture_state: true
+ capture_dump: true
+ ultimate:
+ host: 10.0.0.79
+ password: null
+ ftp_user: anonymous
+ ftp_password: anonymous@
+ remote_root: USB1
+ disk8: /Users/karlprosserpp/dev/c64projects/readyosprecog/build/uci_timing/readyos.d81
+ disk9: null
+ autostart_prg: null
+ drive_a_bus_id: 8
+ drive_b_bus_id: 11
+ drive_a_type: '1581'
+ drive_b_type: '1581'
+ drive_a_enabled: true
+ drive_b_enabled: false
+ mount_mode: readwrite
+ boot_drive: 8
+ capture_video_stream: true
+ stream_port: 11000
+ stream_timeout_s: 4.0
+ default_speed_mhz: 1
+ warp_equivalent_mhz: 8
+steps:
+- id: launch_probe
+ type: ultimate.launch
+ params:
+ boot_mode: prg
+ prg: /Users/karlprosserpp/dev/c64projects/readyosprecog/build/uci_timing/uci_timing_probe.prg
+ drives:
+ - slot: a
+ bus_id: 8
+ drive_type: '1581'
+ enabled: true
+ disk: /Users/karlprosserpp/dev/c64projects/readyosprecog/build/uci_timing/readyos.d81
+ remote_disk: USB1/readyos.d81
+ mount_mode: readwrite
+ - slot: b
+ bus_id: 11
+ drive_type: '1581'
+ enabled: false
+ disk: /Users/karlprosserpp/dev/c64projects/readyosprecog/build/uci_timing/readyos.d81
+ remote_disk: USB1/readyos.d81
+ mount_mode: readwrite
+ boot_drive: 8
+- id: wait_probe_started
+ type: screen.wait_contains
+ params:
+ text: "uci timing probe"
+ wait_timeout_s: 360
+ capture_label: uci_timing_started
+- id: wait_probe_done
+ type: screen.wait_contains
+ criticality: observe
+ params:
+ text: "PROBE DONE"
+ wait_timeout_s: 420
+ capture_label: uci_timing_done
+- id: capture_final
+ type: screen.capture
+ criticality: observe
+ params:
+ label: uci_timing_final
+ note: Final UCI timing probe screen
+ capture_state: true
+- id: dump_results
+ type: dump.memory_ranges
+ criticality: observe
+ params:
+ ranges:
+ - { label: uci_timing_results_3000, start: 0x3000, end: 0x306F }
+ - { label: screen_0400, start: 0x0400, end: 0x07E7 }
diff --git a/build_support/update_build_version.py b/build_support/update_build_version.py
index da2beb9..83f73ed 100644
--- a/build_support/update_build_version.py
+++ b/build_support/update_build_version.py
@@ -18,7 +18,7 @@
HEADER_PATH = GEN_DIR / "build_version.h"
ASM_PATH = GEN_DIR / "msg_version.inc"
STATE_PATH = Path("/tmp/readyos_run_version_suffix.txt")
-BASE_VERSION = "0.2.4"
+BASE_VERSION = "0.2.5"
def read_current_version() -> str:
diff --git a/build_support/update_documentation_html_status.py b/build_support/update_documentation_html_status.py
new file mode 100644
index 0000000..aebbca0
--- /dev/null
+++ b/build_support/update_documentation_html_status.py
@@ -0,0 +1,149 @@
+#!/usr/bin/env python3
+"""Add or refresh visible current/historical status banners in documentation HTML.
+
+The HTML reports include both live generated documentation and intentionally
+preserved design/evidence snapshots. Keeping the classification here makes it
+possible to audit the complete HTML corpus without deleting or silently
+rewriting historical measurements.
+"""
+
+import argparse
+from pathlib import Path
+
+
+ROOT = Path(__file__).resolve().parents[1]
+START = ""
+END = ""
+
+CURRENT = {
+ "docs/DOCUMENTATION_INDEX.html": "Current documentation index, audited against the 0.2.5 development tree on 2026-08-02.",
+ "docs/ReadyOS_SHIM_ARCHITECTURE_0.2.5.html": "Current 0.2.5 schema-v5 shim/ReadyOS-bank architecture, including the resident-versus-REU authority split and live token lookup.",
+ "docs/ultimate_dos_dma_loading.html": "Current C64 Ultimate DOS DMA behavior. The launcher path is opt-in and disk fallback remains part of the contract.",
+ "docs/ReadyShellArchitecture.html": "Current ReadyShell architecture counterpart generated from ReadyShellArchitecture.md.",
+ "docs/ReadyShellHostTesting.html": "Current ReadyShell host-testing counterpart generated from ReadyShellHostTesting.md.",
+ "docs/readybasic_memory_diagrams.html": "Current generated ReadyBASIC memory visualization. Regenerate after linker or module-layout changes.",
+ "docs/readyshell_overlay_inventory.html": "Current artifact-backed ReadyShell overlay inventory for the version/profile named in the report.",
+ "docs/reports/easyflash_boot_flow.html": "Current EasyFlash boot-flow counterpart generated from easyflash_boot_flow.md.",
+ "privatedocs/reports/readyshell_overlay_inventory.html": "Current private counterpart of the artifact-backed ReadyShell overlay inventory.",
+ "src/apps/readybasic/readybasic_current_design.html": "Current ReadyBASIC implementation and custom assembler/linker-shape contract generated from READYBASIC_CURRENT_DESIGN.md.",
+ "src/apps/readybasic/readybasic_lifecycle_visual_guide.html": "Current ReadyBASIC lifecycle and REU architecture counterpart generated from READYBASIC_LIFECYCLE_AND_REU_ARCHITECTURE.md.",
+ "src/apps/readybasic/readybasic_making_command_guide.html": "Current ReadyBASIC command-authoring counterpart generated from READYBASIC_MAKING_COMMAND_GUIDE.md.",
+}
+
+HISTORICAL = {
+ "ReadyOSREUPhase1Completed.html": "Preserved completed-phase record. Its full commented shim appendix is byte-verified current; other values describe the phase at the time and are not a live 0.2.5 memory contract.",
+ "docs/ReadyOS SHIM Architecture Report (0.2).html": "Preserved 0.2.4 shim report with its full commented source appendix refreshed and byte-verified against the current shim. ReadyOS_SHIM_ARCHITECTURE_0.2.5.html is the current architecture contract.",
+ "docs/reports/ReadyOSREUPhase1Completed.html": "Preserved completed-phase record. Its full commented shim appendix is byte-verified current; other values describe the phase at the time and are not a live 0.2.5 memory contract.",
+ "docs/reports/function_key_audit.html": "Preserved function-key audit snapshot. Revalidate profile/app coverage before treating counts as current.",
+ "docs/reports/readyos_memory_size_comparison_0_1_5_vs_now.html": "Preserved 0.1.5-to-0.2.4 comparison. Sections saying “current” mean the 0.2.4 audit point, not the present 0.2.5 tree.",
+ "docs/reports/readyos_shim_architecture_report_v3.html": "Preserved 0.2.4 v3 report with its full commented source appendix refreshed and byte-verified current. Use ReadyOS_SHIM_ARCHITECTURE_0.2.5.html for current architecture.",
+ "docs/reports/simplefiles_once_bss_resume_headroom_0_1_8w.html": "Preserved 0.1.8W measurement report; it is evidence from that build, not current headroom.",
+ "privatedocs/reports/easyflash_boot_flow.html": "Preserved older styled EasyFlash report. The current public Markdown/HTML boot-flow pair supersedes its fixed-slot and app-count measurements.",
+ "privatedocs/reports/function_key_audit.html": "Preserved function-key audit snapshot. Revalidate profile/app coverage before treating counts as current.",
+ "privatedocs/reports/future_petscii_control_character_options_for_readyos_and_readyshell.html": "Design exploration retained for reference; it is not a current runtime contract.",
+ "privatedocs/reports/non_ignored_file_inventory.html": "Point-in-time repository inventory retained for reference; filenames and generated artifacts may have changed.",
+ "privatedocs/reports/old_readybasic_memory_rearrangement_implemented.html": "Historical ReadyBASIC implementation record. READYBASIC_CURRENT_DESIGN.md and the generated memory diagrams are authoritative now.",
+ "privatedocs/reports/potential_future_readyos_ram_maximization_plan.html": "Future design exploration retained for reference; no proposed memory move is current unless reflected in the canonical memory map.",
+ "privatedocs/reports/readybasic_design_ideas.html": "Pre/current-design exploration retained for provenance. READYBASIC_CURRENT_DESIGN.md supersedes it.",
+ "privatedocs/reports/readyos_c64os_interop_design.html": "Historical interop proposal. Fixed-slot and schema-4 control-bank descriptions are superseded by the schema-v5 combined ReadyOS bank.",
+ "privatedocs/reports/readyos_c64os_interop_design_v2.html": "Versioned interop proposal retained for reference; it is not a current ReadyOS memory or compatibility contract.",
+ "privatedocs/reports/readyos_memory_layout_print.html": "Historical memory-layout options report. Use the canonical private MEMORY_MAP.md for current spatial layout and sizes.",
+ "privatedocs/reports/readyos_memory_size_comparison_0_1_5_vs_now.html": "Preserved 0.1.5-to-0.2.4 comparison. “Current” values refer to that audit point, not the present 0.2.5 tree.",
+ "privatedocs/reports/readyos_shim_architecture_report.html": "Historical shim report retained for ABI evolution context; its fixed app-slot REU layout is superseded by the current public 0.2.5 shim report.",
+ "privatedocs/reports/readyos_shim_architecture_report_v2.html": "Historical shim v2 report retained for ABI evolution context; use docs/ReadyOS_SHIM_ARCHITECTURE_0.2.5.html for current behavior.",
+ "privatedocs/reports/readyos_shim_architecture_report_v3 copy.html": "Preserved intermediate v3 copy. It is intentionally not normalized into the current contract; use the current public 0.2.5 shim report.",
+ "privatedocs/reports/readyos_shim_architecture_report_v3.html": "Historical 0.2.4 report with its full commented source appendix refreshed and byte-verified current. Other fixed-slot and ReadyShell measurements are superseded.",
+ "privatedocs/reports/readyshell_command_overlay_experiment_2026-04-10.html": "Dated experiment record retained unchanged apart from this status notice; it is not the current overlay contract.",
+ "privatedocs/reports/readyshell_overlay_bss_resume_headroom_0_1_8a.html": "Preserved 0.1.8A overlay/headroom measurement report; current values are in the generated overlay inventory.",
+ "privatedocs/reports/readyshell_variable_memory_ram_reu_flow.html": "Preserved ReadyShell variable-flow analysis from the older 2246-byte-heap build. The current heap/map values are in the generated overlay inventory.",
+ "privatedocs/reports/true_end_pipeline_design.html": "Design report retained for pipeline evolution context; implementation status must be checked against current source and tests.",
+}
+
+
+def banner(kind: str, message: str) -> str:
+ current = kind == "current"
+ bg = "#e7f7ec" if current else "#fff4d6"
+ border = "#238636" if current else "#9a6700"
+ label = "CURRENT DOCUMENT" if current else "PRESERVED SNAPSHOT / DESIGN"
+ return (
+ f"{START}\n"
+ f'\n"
+ f"{END}"
+ )
+
+
+def update(path_text: str, kind: str, message: str) -> None:
+ path = ROOT / path_text
+ if not path.exists():
+ raise SystemExit(f"missing classified HTML document: {path_text}")
+ text = path.read_text(encoding="utf-8")
+ block = banner(kind, message)
+ if START in text:
+ before, rest = text.split(START, 1)
+ _old, after = rest.split(END, 1)
+ text = before + block + after
+ else:
+ body_end = text.find(">", text.lower().find(" None:
+ parser = argparse.ArgumentParser(
+ description="Update or verify ReadyOS documentation HTML status banners."
+ )
+ parser.add_argument(
+ "--check", action="store_true",
+ help="verify classification and exact banners without writing files",
+ )
+ args = parser.parse_args()
+ classified = set(CURRENT) | set(HISTORICAL)
+ actual = {
+ str(path.relative_to(ROOT))
+ for tree in (ROOT / "docs", ROOT / "privatedocs")
+ for path in tree.rglob("*")
+ if path.is_file() and path.suffix.lower() in {".html", ".htm"}
+ }
+ actual.update({
+ "ReadyOSREUPhase1Completed.html",
+ "src/apps/readybasic/readybasic_current_design.html",
+ "src/apps/readybasic/readybasic_lifecycle_visual_guide.html",
+ "src/apps/readybasic/readybasic_making_command_guide.html",
+ })
+ missing = sorted(actual - classified)
+ extra = sorted(classified - actual)
+ if missing or extra:
+ raise SystemExit(
+ "HTML classification mismatch\n"
+ + ("unclassified: " + ", ".join(missing) + "\n" if missing else "")
+ + ("missing: " + ", ".join(extra) if extra else "")
+ )
+ if args.check:
+ failures = []
+ for path_text, message in CURRENT.items():
+ text = (ROOT / path_text).read_text(encoding="utf-8")
+ if banner("current", message) not in text:
+ failures.append(path_text)
+ for path_text, message in HISTORICAL.items():
+ text = (ROOT / path_text).read_text(encoding="utf-8")
+ if banner("historical", message) not in text:
+ failures.append(path_text)
+ if failures:
+ raise SystemExit("missing/stale status banner: " + ", ".join(failures))
+ print(f"verified {len(classified)} classified HTML documents")
+ else:
+ for path, message in CURRENT.items():
+ update(path, "current", message)
+ for path, message in HISTORICAL.items():
+ update(path, "historical", message)
+ print(f"updated {len(classified)} classified HTML documents")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/build_support/verify_documentation_contract.py b/build_support/verify_documentation_contract.py
new file mode 100644
index 0000000..012d425
--- /dev/null
+++ b/build_support/verify_documentation_contract.py
@@ -0,0 +1,175 @@
+#!/usr/bin/env python3
+"""Verify the live documentation against the schema-v5 memory contract.
+
+Historical reports deliberately retain their original measurements, so this
+gate checks their supersession markers while applying exact current-value
+checks only to documents that claim to describe the live tree.
+"""
+
+from __future__ import annotations
+
+import subprocess
+import sys
+from pathlib import Path
+
+import annotate_historical_memory_contracts as historical
+
+
+ROOT = Path(__file__).resolve().parents[1]
+
+REQUIRED: dict[str, tuple[str, ...]] = {
+ "README.md": (
+ "app runtime window: `$1000-$C5FF` (`$B600` bytes)",
+ "resident shim: `$C600-$C9FF` (1 KB)",
+ "physical `Skip`: the ReadyOS bank",
+ "physical `Skip+1` and above: dynamic allocation pool",
+ ),
+ "Releases/0.2.5/README.md": (
+ "active app snapshot is `$1000-$C5FF` (`$B600` bytes)",
+ "Physical REU bank `Skip` is the **ReadyOS bank**",
+ "Physical `Skip+1` is the first dynamic bank",
+ ),
+ "docs/release_root_readme_template.md": (
+ "active app snapshot is `$1000-$C5FF` (`$B600` bytes)",
+ "Physical REU bank `Skip` is the **ReadyOS bank**",
+ ),
+ "docs/ReadyOS_SHIM_ARCHITECTURE_0.2.5.md": (
+ "Physical `Skip` is the ReadyOS bank",
+ "Physical `Skip+1` is the first dynamic app/resource bank",
+ "full shim region is restored to 1 KB at `$C600-$C9FF`",
+ "ReadyOS:$B740 + token",
+ "token validity/loaded/resumable state | ReadyOS `$B840-$B93F`",
+ ),
+ "docs/ReadyOS_SHIM_ARCHITECTURE_0.2.5.html": (
+ "Physical Skip is the ReadyOS bank",
+ "$C600-$C9FF",
+ "ReadyOS:$B740 + token",
+ ),
+ "docs/ultimate_dos_dma_loading.md": (
+ "`$1000-$C5FF`",
+ "`$B600` REU\nstash/fetch operations",
+ "exact-size `LOAD_REU`",
+ ),
+ "docs/ultimate_dos_dma_loading.html": (
+ "$1000-$C5FF",
+ "$B600 REU stash/fetch",
+ "exact-size LOAD_REU",
+ ),
+ "docs/reports/easyflash_boot_flow.md": (
+ "full app window `$1000-$C5FF` (`$B600` bytes)",
+ "full `46,592` byte app window",
+ "Physical `Skip` is the\nsingle source of truth",
+ ),
+ "docs/reports/easyflash_boot_flow.html": (
+ "full 46,592 byte app window",
+ "Physical\nSkip is the single source of truth",
+ ),
+ "privatedocs/top_level_md/MEMORY_MAP.md": (
+ "Skip (ReadyOS bank)",
+ "`$B940` | `$0090` | clipboard count plus 16 item records",
+ "clipboard metadata lives in ReadyOS `$B940-$B9CF`",
+ "agentworking/readyos-1kb-shim-skip-bank/headroom_comparison.md",
+ ),
+ "privatedocs/top_level_md/SHIM_PLAN.md": (
+ "`Skip` | ReadyOS bank: launcher snapshot + `RCB5` schema 5",
+ "`Skip+1..detected end` | dynamic pool",
+ "`$C600-$C9FF`; `$C600-$C7FF` is resident expansion reserve",
+ ),
+ "src/apps/readybasic/readyBASICrefactorguidelines.md": (
+ "`$C600-$C7FF` | Reserved resident ReadyOS shim expansion capacity",
+ ),
+ "src/apps/readyshell/README.md": (
+ "ReadyOS snapshot window: `$1000-$C5FF` (`46592` bytes)",
+ "Overlay execution window: `$8E00-$C5FF` (`14336` bytes)",
+ ),
+ "Releases/0.2.5/precog-kung-fu-flash-2-d81/README.md": (
+ "Fresh launcher state uses `1` bank by default",
+ "That leaves `15` banks",
+ "about `6/16` banks in use including the ReadyOS bank",
+ "about `4/16` banks in use including the ReadyOS bank",
+ "about `9/16` banks including the ReadyOS bank",
+ ),
+}
+
+FORBIDDEN: dict[str, tuple[str, ...]] = {
+ "docs/ultimate_dos_dma_loading.md": ("`$B800` REU\nstash/fetch operations",),
+ "docs/ultimate_dos_dma_loading.html": ("$B800 REU stash/fetch",),
+ "docs/reports/easyflash_boot_flow.md": ("full `47,104` byte app window",),
+ "docs/reports/easyflash_boot_flow.html": ("full 47,104 byte app window",),
+ "privatedocs/top_level_md/MEMORY_MAP.md": (
+ "clipboard metadata lives in ReadyOS `$BB40-$BBCF`",
+ "agentworking/readyos-bank-refactor/headroom_comparison.md",
+ ),
+ "Releases/0.2.5/precog-kung-fu-flash-2-d81/README.md": (
+ "Fresh launcher state uses `2` banks by default",
+ "That leaves `14` banks",
+ "about `7/16` banks in use",
+ "about `5/16` banks in use",
+ "about `10/16` banks",
+ ),
+ "build_support/readyos_profiles.py": (
+ "Fresh launcher state uses `2` banks by default",
+ "That leaves `14` banks",
+ ),
+}
+
+
+def main() -> int:
+ failures: list[str] = []
+ checked = 0
+ for rel, snippets in REQUIRED.items():
+ path = ROOT / rel
+ if not path.exists():
+ failures.append(f"missing current document: {rel}")
+ continue
+ text = path.read_text(encoding="utf-8", errors="replace")
+ checked += 1
+ for snippet in snippets:
+ if snippet not in text:
+ failures.append(f"{rel}: missing current contract text {snippet!r}")
+
+ for rel, snippets in FORBIDDEN.items():
+ path = ROOT / rel
+ if not path.exists():
+ failures.append(f"missing checked file: {rel}")
+ continue
+ text = path.read_text(encoding="utf-8", errors="replace")
+ for snippet in snippets:
+ if snippet in text:
+ failures.append(f"{rel}: stale current-contract text {snippet!r}")
+
+ for rel in (*historical.MARKDOWN_PATHS, *historical.HTML_PATHS):
+ path = ROOT / rel
+ if not path.exists():
+ failures.append(f"missing retained historical document: {rel}")
+ continue
+ if historical.MARKER not in path.read_text(encoding="utf-8", errors="replace"):
+ failures.append(f"{rel}: missing current-contract supersession marker")
+
+ status = subprocess.run(
+ [sys.executable, str(ROOT / "build_support/update_documentation_html_status.py"), "--check"],
+ cwd=ROOT,
+ text=True,
+ capture_output=True,
+ )
+ if status.returncode != 0:
+ failures.append("HTML classification check failed: " + (status.stderr or status.stdout).strip())
+
+ if failures:
+ print("DOCUMENTATION CONTRACT VERIFICATION FAILED")
+ for failure in failures:
+ print(f" [FAIL] {failure}")
+ return 1
+
+ print(
+ "DOCUMENTATION CONTRACT VERIFICATION PASSED: "
+ f"{checked} current documents, "
+ f"{len(historical.MARKDOWN_PATHS) + len(historical.HTML_PATHS)} historical markers"
+ )
+ if status.stdout.strip():
+ print(status.stdout.strip())
+ return 0
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/build_support/verify_dynamic_launcher.py b/build_support/verify_dynamic_launcher.py
index 5765206..6f0c083 100644
--- a/build_support/verify_dynamic_launcher.py
+++ b/build_support/verify_dynamic_launcher.py
@@ -41,6 +41,9 @@ def main() -> int:
encoding="utf-8", errors="replace"
)
makefile = (ROOT / "Makefile").read_text(encoding="utf-8", errors="replace")
+ tui_alias = (ROOT / "src/lib/tui_readyos_alias.s").read_text(
+ encoding="utf-8", errors="replace"
+ )
check("launcher exposes 64 app capacity",
"#define APP_SLOT_CAPACITY 64" in launcher)
@@ -48,9 +51,10 @@ def main() -> int:
"app_banks[idx] = 0u;" in launcher)
check("launcher has lazy snapshot allocator",
"launcher_alloc_snapshot_bank" in launcher and
- "REU_ALLOC_TABLE[physical] == REU_FREE" in launcher)
- check("low shim-bitmap banks no longer require reserved placeholders",
- "bank < 24u && REU_ALLOC_TABLE[physical] == REU_RESERVED" not in launcher)
+ "launcher_bank_type(physical) == REU_FREE" in launcher and
+ "launcher_bind_snapshot_token" in launcher)
+ check("C64 allocation mirror is absent",
+ "REU_ALLOC_TABLE" not in launcher)
reu_mgr = (ROOT / "src/lib/reu_mgr.h").read_text(
encoding="utf-8", errors="replace"
)
@@ -60,37 +64,40 @@ def main() -> int:
shim = (ROOT / "src/boot/readyos_shim.inc").read_text(
encoding="utf-8", errors="replace"
)
- check("allocator dynamic pool starts after ReadyOS system banks",
+ check("physical Skip is the ReadyOS bank and Skip+1 is first dynamic",
"#define REU_FIRST_DYNAMIC 1" in reu_mgr and
- "*SHIM_REU_BANK_SKIP + 2u" in reu_mgr)
- check("REU bank 0 publishes shim token lookup page",
- "REUCB_SHIM_LOOKUP_OFF" in reu_control and
- "REUCB_SHIM_LOOKUP_SIZE" in reu_control and
- "reucb_write_shim_lookup" in reu_control)
- check("shim resolves app tokens through REU bank 0 lookup",
+ "*SHIM_READYOS_BANK + 1u" in reu_mgr)
+ check("ReadyOS bank owns authoritative mapping and status pages",
+ "REUCB_SHIM_LOOKUP_OFF" in
+ (ROOT / "src/lib/reu_control_bank.h").read_text() and
+ "REUCB_TOKEN_STATUS_OFF" in
+ (ROOT / "src/lib/reu_control_bank.h").read_text() and
+ "REU_ALLOC_TABLE" not in reu_control)
+ check("shim resolves app tokens through ReadyOS-bank lookup",
"lookup_app_bank" in shim and
- "STA $DF05 (REU offset hi = lookup page)" in shim and
+ "LDA #>$B740" in shim and
"LDA $C83D (resolved physical bank)" in shim)
- check("launcher tracks banks above shim bitmap",
- "bank >= 24u && last_saved == bank" in launcher)
- check("launcher validates extended loaded state",
- "app_banks[i] == 0u || !apps_loaded[i]" in launcher)
+ check("shim commits token loaded/resumable state",
+ "mark_loaded" in shim and "LDA #VALID|LOADED|RESUMABLE" in shim)
+ check("launcher validates ReadyOS token loaded state",
+ "REUCB_TOKEN_LOADED" in launcher and "required_slots_loaded" in launcher)
check("load-all progress rows wrap for 64-app catalogs",
"#define LOAD_ALL_LIST_ROWS 19" in launcher and
"loaded_count % LOAD_ALL_LIST_ROWS" in launcher)
- check("cartridge preloads can be tracked above shim bitmap",
+ check("cartridge preloads publish explicit token mappings",
"launcher_mark_embedded_preloads_loaded" in launcher and
+ "readyos_easyflash_app_physical_banks" in launcher and
"app_sizes[i] = APP_SAVE_SIZE;" in launcher)
check("launcher has unload command",
"unload_selected_from_reu" in launcher and "case TUI_KEY_F7" in launcher)
- check("launcher invalidates stale last-saved bank on unload",
+ check("launcher invalidates stale last-saved token on unload",
"*SHIM_LAST_SAVED == bank" in launcher and
"*SHIM_LAST_SAVED = 0xFFu;" in launcher and
- "last_saved < 24 && launcher_catalog_uses_bank(last_saved, 0xFFu)" in launcher)
+ "launcher_set_snapshot_loaded(bank, 0u)" in launcher)
check("launcher unload frees owner-recorded app allocations",
"launcher_free_app_owned_alloc_records" in launcher and
"REUCB_DEP_KIND_APP_ALLOC" in launcher and
- "REU_ALLOC_TABLE[bank] == REU_APP_ALLOC" in launcher)
+ "launcher_bank_type(bank) == REU_APP_ALLOC" in launcher)
check("launcher owns ReadyShell overlay resource banks",
"APP_RESOURCE_READYSHELL_OVL" in launcher and
"launcher_load_readyshell_resources" in launcher and
@@ -118,6 +125,10 @@ def main() -> int:
"RS_REU_OVL_CACHE_META_VERSION 4u" in rs_state and
"g_overlay_cache_offsets" in rs_overlay and
"rs_cmd_registry_apply_overlay_cache" in rs_overlay)
+ check("ReadyShell diagnostics have no C64-RAM mirror",
+ "RS_RAM_DBG" not in rs_overlay and
+ "RS_REU_DBG_DATA_OFF" in rs_overlay and
+ "RS_REU_DBG_HEAD_OFF" in rs_overlay)
check("ReadyShell overlay metadata does not overlap UI flags or value arena",
"RS_REU_UI_FLAGS_REL 0x8114u" in rs_state and
"RS_REU_UI_FLAGS_OFF rs_reu_state_abs(RS_REU_UI_FLAGS_REL)" in rs_state and
@@ -136,7 +147,16 @@ def main() -> int:
"len(apps) > 64" in catalog)
check("global hotkeys allow dynamic logical banks",
"#define APP_BANK_MAX TUI_APP_BANK_MAX" in hotkeys and
- "#define TUI_APP_BANK_MAX 223" in tui_header)
+ "#define TUI_APP_BANK_MAX 64" in tui_header and
+ "REUCB_TOKEN_STATUS_OFF" in hotkeys)
+ check("TUI ReadyOS access avoids duplicate DMA micromodules",
+ "TUI_READYOS_SRC = $(LIB_DIR)/tui_readyos_alias.s" in makefile and
+ "TUI_READYOS_LITE_SRC = $(LIB_DIR)/tui_readyos.c" in makefile and
+ "LIB_SYSINFO = $(TUI_BASE_NAV_MISC) $(TUI_HOTKEY_LITE_SRC)" in makefile and
+ "LIB_UCITEST = $(TUI_UCITEST) $(TUI_HOTKEY_LITE_SRC)" in makefile and
+ "jmp _readyos_bank_read_byte" in tui_alias and
+ "jmp _readyos_bank_write_byte" in tui_alias and
+ not (ROOT / "src/lib/tui_readyos_alias.c").exists())
check("verify target includes dynamic launcher check",
"verify_dynamic_launcher.py" in makefile)
diff --git a/build_support/verify_launcher_dma_gate.py b/build_support/verify_launcher_dma_gate.py
new file mode 100644
index 0000000..b2e1ceb
--- /dev/null
+++ b/build_support/verify_launcher_dma_gate.py
@@ -0,0 +1,141 @@
+#!/usr/bin/env python3
+"""Verify the experimental launcher UCI DMA path stays gated off by default."""
+
+from __future__ import annotations
+
+import pathlib
+import re
+import sys
+
+
+ROOT = pathlib.Path(__file__).resolve().parents[1]
+
+
+def read(path: str) -> str:
+ return (ROOT / path).read_text(encoding="utf-8", errors="replace")
+
+
+def ok(message: str) -> None:
+ print(f"[OK] {message}")
+
+
+def fail(message: str) -> int:
+ print(f"[FAIL] {message}")
+ return 1
+
+
+def note(message: str) -> None:
+ print(f"[NOTE] {message}")
+
+
+def require(condition: bool, message: str, failures: list[str]) -> None:
+ if condition:
+ ok(message)
+ else:
+ print(f"[FAIL] {message}")
+ failures.append(message)
+
+
+def make_var(makefile: str, name: str) -> str | None:
+ match = re.search(rf"^{re.escape(name)}\s*\?=\s*(.+)$", makefile, re.M)
+ if match:
+ return match.group(1).strip()
+ match = re.search(rf"^{re.escape(name)}\s*=\s*(.+)$", makefile, re.M)
+ if match:
+ return match.group(1).strip()
+ return None
+
+
+def main() -> int:
+ failures: list[str] = []
+ makefile = read("Makefile")
+ launcher = read("src/apps/launcher/launcher.c")
+ dma_asm = read("src/apps/launcher/launcher_uci_dma.s")
+ lessons = read("ULTIMATEDOS_DMA_LOADING_LESSONS_LEARNT.md")
+
+ require(
+ make_var(makefile, "LAUNCHER_DMA_LOAD") == "0",
+ "Makefile defaults LAUNCHER_DMA_LOAD to 0",
+ failures,
+ )
+ require(
+ "ifeq ($(LAUNCHER_DMA_LOAD),1)" in makefile
+ and "$(APPS_DIR)/launcher/launcher_uci_dma.s" in makefile,
+ "launcher_uci_dma.s is linked only by the LAUNCHER_DMA_LOAD make gate",
+ failures,
+ )
+ require(
+ "-DLAUNCHER_DMA_LOAD=$(LAUNCHER_DMA_LOAD)" in makefile,
+ "launcher compile flags carry the DMA gate into C",
+ failures,
+ )
+ require(
+ "#if !READYOS_LAUNCHER_VARIANT_EASYFLASH && LAUNCHER_DMA_LOAD" in launcher,
+ "launcher C code keeps DMA logic behind variant and DMA guards",
+ failures,
+ )
+ require(
+ '"DMA:"' in launcher and "launcher_dma_used" in launcher,
+ "experimental DMA UI indicator remains explicit when enabled",
+ failures,
+ )
+ require(
+ "SUM USB:01 P:42 C:51 F1:55 F2:55 F3:55" in lessons,
+ "lessons record the current successful D81 probe summary",
+ failures,
+ )
+ require(
+ "A pathless, production-safe Ultimate DOS load" in lessons
+ and "not proven" in lessons,
+ "lessons preserve the pathless mounted-drive blocker",
+ failures,
+ )
+ require(
+ "DOS_CMD_LOAD_REU" in lessons
+ and "CTRL_CMD_LOAD_REU" in lessons
+ and "CTRL_CMD_GET_DRVINFO" in lessons,
+ "lessons distinguish DOS LOAD_REU, Control LOAD_REU, and drive info limits",
+ failures,
+ )
+ require(
+ "jsr dos_file_info" in dma_asm
+ and "lda data_buf" in dma_asm
+ and "sbc #$02" in dma_asm
+ and "sta remaining_lo" in dma_asm
+ and "sta remaining_hi" in dma_asm,
+ "DMA loader derives LOAD_REU length from Ultimate DOS FILE_INFO minus PRG header",
+ failures,
+ )
+ require(
+ "lda _launcher_uci_dma_max_len\n sta remaining_lo" not in dma_asm,
+ "DMA loader no longer uses destination slot size as the transfer length",
+ failures,
+ )
+ require(
+ "FILE_INFO" in lessons
+ and "exactly that payload length" in lessons,
+ "lessons document exact-size LOAD_REU requirement for ReadyShell overlays",
+ failures,
+ )
+
+ map_path = ROOT / "obj" / "launcher.map"
+ if map_path.exists():
+ map_text = map_path.read_text(encoding="utf-8", errors="replace")
+ if "launcher_uci_dma" in map_text:
+ note(
+ "current launcher.map contains launcher_uci_dma symbols; "
+ "the workspace was last built with LAUNCHER_DMA_LOAD=1"
+ )
+ else:
+ ok("current launcher.map has no launcher_uci_dma symbols")
+ else:
+ ok("obj/launcher.map not present; skipped default map symbol check")
+
+ if failures:
+ return fail(f"{len(failures)} launcher DMA gate check(s) failed")
+ ok("launcher DMA gate verification passed")
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/build_support/verify_memory_map.py b/build_support/verify_memory_map.py
index 126380d..e2a8760 100755
--- a/build_support/verify_memory_map.py
+++ b/build_support/verify_memory_map.py
@@ -4,7 +4,7 @@
Hard memory-map contract checks for ReadyOS:
- app/runtime RAM windows
-- shim/REU-reserved boundary discipline
+- shim boundary discipline and ReadyOS-bank schema constants
- cc65 ONCE/BSS disjointness for warm-resumed apps
- ReadyShell overlay window + overlay fit
- REU and resume constants
@@ -179,6 +179,8 @@ def collect_fixed_addresses():
if path.suffix not in (".c", ".h", ".s"):
continue
txt = path.read_text(encoding="utf-8", errors="replace")
+ if "RETIRED" in txt[:512]:
+ continue
for m in pat.finditer(txt):
addr = int(m.group(0), 16)
if 0xC000 <= addr <= 0xDFFF:
@@ -206,8 +208,6 @@ def main():
app_start = parse_int(spec["ram_windows"]["app_runtime"]["start"])
app_end = parse_int(spec["ram_windows"]["app_runtime"]["end"])
- reu_meta_start = parse_int(spec["ram_windows"]["reu_metadata"]["start"])
- reu_meta_end = parse_int(spec["ram_windows"]["reu_metadata"]["end"])
shim_start = parse_int(spec["ram_windows"]["shim"]["start"])
shim_end = parse_int(spec["ram_windows"]["shim"]["end"])
io_start = parse_int(spec["ram_windows"]["io"]["start"])
@@ -289,11 +289,6 @@ def main():
start >= app_start and end <= app_end,
f"{hex(start)}..{hex(end)}",
)
- ok &= check(
- f"{rel}:{seg_name} avoids REU meta",
- not intersects(start, end, reu_meta_start, reu_meta_end),
- f"{hex(start)}..{hex(end)} vs {hex(reu_meta_start)}..{hex(reu_meta_end)}",
- )
ok &= check(
f"{rel}:{seg_name} avoids shim",
not intersects(start, end, shim_start, shim_end),
@@ -321,7 +316,7 @@ def main():
f"ONCE={once_range} BSS={bss_range}",
)
- if rel.endswith("readyshell.map"):
+ if "readyshell" in Path(rel).stem:
try:
overlay_start = parse_map_symbol(txt, "__OVERLAYSTART__")
overlay_loadaddr = parse_map_symbol(txt, "__OVERLAY_LOADADDR__")
@@ -431,29 +426,24 @@ def main():
load >= app_start and end <= app_end,
f"{fmt_range(load, end)} payload=${payload_len:04X}",
)
- ok &= check(
- f"{rel} compact load span avoids REU meta",
- not intersects(load, end, reu_meta_start, reu_meta_end),
- f"{fmt_range(load, end)} vs {fmt_range(reu_meta_start, reu_meta_end)}",
- )
print("\n=== REU/Resume Constants ===")
try:
reu_total = parse_define(ROOT / "src" / "lib" / "reu_mgr.h", "REU_TOTAL_BANKS")
reu_first = parse_define(ROOT / "src" / "lib" / "reu_mgr.h", "REU_FIRST_DYNAMIC")
- reu_skip_addr = parse_pointer_define(ROOT / "src" / "lib" / "reu_mgr.h", "SHIM_REU_BANK_SKIP")
+ readyos_addr = parse_pointer_define(ROOT / "src" / "lib" / "reu_mgr.h", "SHIM_READYOS_BANK")
reu_mgr_h = (ROOT / "src" / "lib" / "reu_mgr.h").read_text(encoding="utf-8", errors="replace")
ok &= check("REU total banks", reu_total == int(spec["reu_contract"]["total_banks"]), str(reu_total))
ok &= check("REU first dynamic logical", reu_first == int(spec["reu_contract"]["first_dynamic_logical"]), str(reu_first))
ok &= check("REU physical dynamic offset macro",
- "*SHIM_REU_BANK_SKIP + 2u" in reu_mgr_h,
- "expect skip + 2")
- ok &= check("REU logical-to-physical macro",
- "? 1u : (1u + (unsigned char)(bank))" in reu_mgr_h,
- "expect logical 0 -> skip + 1, apps -> skip + 1 + logical")
- ok &= check("SHIM_REU_BANK_SKIP address",
- reu_skip_addr == parse_int(spec["reu_contract"]["shim_reu_bank_skip_addr"]),
- hex(reu_skip_addr))
+ "*SHIM_READYOS_BANK + 1u" in reu_mgr_h,
+ "physical Skip+1 is the first dynamic bank")
+ ok &= check("arithmetic token mapping removed",
+ "REU_LOGICAL_TO_PHYSICAL" not in reu_mgr_h,
+ "tokens resolve through schema-v5 lookup")
+ ok &= check("SHIM_READYOS_BANK address",
+ readyos_addr == parse_int(spec["reu_contract"]["shim_readyos_bank_addr"]),
+ hex(readyos_addr))
ok &= check("REU ReadyShell cache banks dynamic",
"REU_BANK_RS_CACHE" not in reu_mgr_h,
"cache bank constants must not be fixed")
@@ -467,20 +457,17 @@ def main():
ok &= check("reu_mgr.h constants", False, str(ex))
try:
- bank_system = parse_define(ROOT / "src" / "shim" / "reu.h", "REU_BANK_SYSTEM")
- bank_launcher = parse_define(ROOT / "src" / "shim" / "reu.h", "REU_BANK_LAUNCHER")
- bank_base = parse_define(ROOT / "src" / "shim" / "reu.h", "REU_BANK_APP_BASE")
- bank_count = parse_define(ROOT / "src" / "shim" / "reu.h", "REU_BANK_APP_COUNT")
- bank_free_base = parse_define(ROOT / "src" / "shim" / "reu.h", "REU_BANK_FREE_BASE")
- ok &= check("shim REU bank system", bank_system == int(spec["reu_contract"]["bank_system"]), str(bank_system))
- ok &= check("shim REU bank launcher", bank_launcher == int(spec["reu_contract"]["bank_launcher"]), str(bank_launcher))
- ok &= check("shim REU bank app base", bank_base == int(spec["reu_contract"]["bank_app_base"]), str(bank_base))
- ok &= check("shim REU bank app count", bank_count == int(spec["reu_contract"]["bank_app_count"]), str(bank_count))
- ok &= check("shim REU bank free base",
- bank_free_base == int(spec["reu_contract"]["first_dynamic_physical_offset"]),
- str(bank_free_base))
+ schema = parse_define(ROOT / "src" / "lib" / "reu_control_bank.h",
+ "REUCB_SCHEMA_VERSION")
+ lookup = parse_define(ROOT / "src" / "lib" / "reu_control_bank.h",
+ "REUCB_SHIM_LOOKUP_OFF")
+ status = parse_define(ROOT / "src" / "lib" / "reu_control_bank.h",
+ "REUCB_TOKEN_STATUS_OFF")
+ ok &= check("ReadyOS-bank schema version", schema == 5, str(schema))
+ ok &= check("token mapping offset", lookup == 0xB740, hex(lookup))
+ ok &= check("token status offset", status == 0xB840, hex(status))
except ValueError as ex:
- ok &= check("shim/reu.h constants", False, str(ex))
+ ok &= check("ReadyOS-bank schema constants", False, str(ex))
try:
snapshot = parse_define(ROOT / "src" / "lib" / "resume_state.h", "REU_APP_SNAPSHOT_SIZE")
diff --git a/build_support/verify_quicknotes_owned_reu_dump.py b/build_support/verify_quicknotes_owned_reu_dump.py
new file mode 100644
index 0000000..ae2a06e
--- /dev/null
+++ b/build_support/verify_quicknotes_owned_reu_dump.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python3
+"""Verify QuickNotes-owned allocation types in a full VICE REU dump."""
+
+from __future__ import annotations
+
+import argparse
+import json
+from pathlib import Path
+
+HEADER_OFF = 0xB600
+BANK_TYPES_OFF = 0xB640
+BANK_TYPES_SIZE = 0x100
+MAGIC = b"RCB5\x05"
+REU_APP_ALLOC = 3
+
+
+def main() -> int:
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--index", required=True, type=Path)
+ parser.add_argument("--expect", required=True, choices=("present", "absent"))
+ args = parser.parse_args()
+
+ payload = json.loads(args.index.read_text(encoding="utf-8-sig"))
+ readyos_image = None
+ for chunk in payload.get("chunks", []):
+ path = Path(chunk["file"])
+ data = path.read_bytes()
+ if len(data) == 0x10000 and data[HEADER_OFF:HEADER_OFF + len(MAGIC)] == MAGIC:
+ if readyos_image is not None:
+ raise SystemExit("FAIL: more than one full REU bank contains the RCB5 header")
+ readyos_image = data
+ if readyos_image is None:
+ raise SystemExit("FAIL: no full REU bank contains the RCB5 schema header")
+
+ types = readyos_image[BANK_TYPES_OFF:BANK_TYPES_OFF + BANK_TYPES_SIZE]
+ owned = [bank for bank, value in enumerate(types) if value == REU_APP_ALLOC]
+ if args.expect == "present" and len(owned) < 2:
+ raise SystemExit(f"FAIL: expected at least two QuickNotes app-owned banks, found {owned}")
+ if args.expect == "absent" and owned:
+ raise SystemExit(f"FAIL: app-owned banks survived launcher unload: {owned}")
+ print(f"PASS: ReadyOS bank app-owned types are {owned} ({args.expect})")
+ return 0
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/build_support/verify_readybasic_plugin.py b/build_support/verify_readybasic_plugin.py
index f753183..87b090b 100644
--- a/build_support/verify_readybasic_plugin.py
+++ b/build_support/verify_readybasic_plugin.py
@@ -9,10 +9,35 @@
ROOT = Path(__file__).resolve().parents[1]
ASM = ROOT / "src/apps/readybasic/readybasic.s"
+CFG = ROOT / "cfg/ready_app_readybasic.cfg"
MAP = ROOT / "obj/readybasic.map"
REU_HDR = ROOT / "src/lib/reu_mgr.h"
PRG = ROOT / "bin/readybasic.prg"
MODULE_DIR = ROOT / "obj/readybasic_modules"
+MAKEFILE = ROOT / "Makefile"
+
+READYBASIC_VICE_TARGETS = {
+ "readybasic-demo-vice", "readybasic-repeat-label-vice",
+ "readybasic-lifecycle-vice", "readybasic-module-overlay-vice",
+ "readybasic-plugin-command-vice", "readybasic-program-vice",
+ "readybasic-rbtest1-vice", "readybasic-resume-min-vice",
+ "readybasic-screen-reu-temp-vice", "readybasic-state-vice",
+ "readybasic-large-vars-vice", "readybasic-hotkey-vice",
+ "readybasic-keyboard-regression-vice", "readybasic-reuviewer-f2-chain-vice",
+ "readybasic-cross-app-resume-vice", "readybasic-second-entry-editor-vice",
+ "readybasic-gfx-phase1-vice", "readybasic-sprite-steps-vice",
+ "readybasic-gfx-phase2-vice", "readybasic-gfx-phase3-vice",
+ "readybasic-gfx-mbitmap-vice", "readybasic-gfx-phase4-vice",
+ "readybasic-gfx-phase5-vice", "readybasic-sound-phase1-vice",
+ "readybasic-readyos-loaded-apps-vice", "readybasic-full-vice",
+}
+
+READYBASIC_VICE_PLAN_SCRIPTS = {
+ "run_readybasic_gfx_phase5_demo.sh",
+ "run_readybasic_sprite_steps_demo.sh",
+ "run_readybasic_resume_min_probe.sh",
+ "run_readybasic_screen_reu_temp_probe.sh",
+}
def fail(message: str) -> None:
@@ -24,6 +49,154 @@ def require(pattern: str, text: str, description: str) -> None:
fail(description)
+REMOVED_COMMAND_NAMES = {
+ "BUFNEW",
+ "BUFFREE",
+ "FREEMEM",
+ "GFXTARGET",
+ "POINT",
+ "FRECT",
+ "SPRCOLOR",
+ "SPREXPAND",
+ "SPRMCOLOR",
+ "SPRMCLR",
+ "PBUFNEW",
+ "PBUFFREE",
+ "DLCLR",
+ "DLFRECT",
+ "SIDCLR",
+ "SILENCE",
+ "FREQ",
+ "NOTE",
+ "SND",
+ "ENV",
+ "CTRL",
+ "FILT",
+ "SPRMULTI",
+}
+
+BASIC_V2_EMBEDDED_TOKENS = (
+ "RESTORE",
+ "RETURN",
+ "VERIFY",
+ "PRINT#",
+ "PRINT",
+ "INPUT#",
+ "INPUT",
+ "CLOSE",
+ "GOSUB",
+ "GOTO",
+ "NEXT",
+ "DATA",
+ "READ",
+ "LOAD",
+ "SAVE",
+ "POKE",
+ "CONT",
+ "LIST",
+ "OPEN",
+ "THEN",
+ "STEP",
+ "STOP",
+ "WAIT",
+ "PEEK",
+ "LEFT$",
+ "RIGHT$",
+ "MID$",
+ "STR$",
+ "CHR$",
+ "TAB(",
+ "SPC(",
+ "END",
+ "FOR",
+ "DIM",
+ "LET",
+ "RUN",
+ "REM",
+ "NEW",
+ "CLR",
+ "CMD",
+ "SYS",
+ "GET",
+ "NOT",
+ "AND",
+ "SGN",
+ "INT",
+ "ABS",
+ "USR",
+ "FRE",
+ "POS",
+ "SQR",
+ "RND",
+ "LOG",
+ "EXP",
+ "COS",
+ "SIN",
+ "TAN",
+ "ATN",
+ "LEN",
+ "VAL",
+ "ASC",
+ "DEF",
+ "FN",
+ "IF",
+ "ON",
+ "TO",
+ "OR",
+ "GO",
+)
+
+
+def parse_command_names(asm: str) -> list[str]:
+ names: list[str] = []
+ for line in asm.splitlines():
+ if not line.strip().startswith("CMD_"):
+ continue
+ match = re.search(r'"([A-Z0-9]+)"', line)
+ if match:
+ names.append(match.group(1))
+ return names
+
+
+def token_unsafe_reason(name: str) -> str | None:
+ for i in range(len(name)):
+ tail = name[i:]
+ for token in BASIC_V2_EMBEDDED_TOKENS:
+ if token.endswith("$") or token.endswith("("):
+ literal = token
+ else:
+ literal = token
+ if tail.startswith(literal):
+ return token
+ return None
+
+
+def check_command_descriptor_layout(asm: str) -> None:
+ start = asm.find("rb_command_descriptors:")
+ if start < 0:
+ fail("command descriptor table label is missing")
+ hidden = asm.find('; ---------------------------------------------------------------------------\n; Hidden helper code', start)
+ if hidden < 0:
+ fail("command descriptor table end marker is missing")
+ block = asm[start:hidden]
+ command_lines = [line for line in block.splitlines() if line.strip().startswith("CMD_")]
+ fill_match = re.search(r"\.res\s+\(RB_CMD_DESC_COUNT\s*-\s*(\d+)\)\s*\*\s*RB_CMD_DESC_SIZE", block)
+ if not fill_match:
+ fail("command descriptor table must use RB_CMD_DESC_COUNT-based filler")
+ declared_real_descriptors = int(fill_match.group(1))
+ actual_real_descriptors = len(command_lines)
+ if actual_real_descriptors != declared_real_descriptors:
+ fail(
+ "command descriptor filler is out of sync: "
+ f"filler declares {declared_real_descriptors} real descriptors, "
+ f"but table has {actual_real_descriptors}"
+ )
+ if actual_real_descriptors > 128:
+ fail(f"command descriptor table exceeds 128 entries: {actual_real_descriptors}")
+ if not any('"SCRPUT"' in line for line in command_lines):
+ fail("SCRPUT descriptor must remain in the searchable command table")
+
+
def parse_segments(map_text: str) -> dict[str, tuple[int, int, int]]:
segments: dict[str, tuple[int, int, int]] = {}
for line in map_text.splitlines():
@@ -36,13 +209,45 @@ def parse_segments(map_text: str) -> dict[str, tuple[int, int, int]]:
def main() -> None:
asm = ASM.read_text()
+ cfg = CFG.read_text()
reu_hdr = REU_HDR.read_text()
+ makefile = MAKEFILE.read_text()
if not MAP.exists():
fail("obj/readybasic.map is missing; build bin/readybasic.prg first")
if not PRG.exists():
fail("bin/readybasic.prg is missing; build it first")
segments = parse_segments(MAP.read_text())
+ aggregate = re.search(r"^readybasic-vice-suites:\s*(.+)$", makefile, re.MULTILINE)
+ if not aggregate:
+ fail("readybasic-vice-suites aggregate is missing")
+ aggregate_targets = aggregate.group(1).split()
+ if len(aggregate_targets) != len(set(aggregate_targets)):
+ fail("readybasic-vice-suites contains duplicate targets")
+ if set(aggregate_targets) != READYBASIC_VICE_TARGETS:
+ missing = sorted(READYBASIC_VICE_TARGETS - set(aggregate_targets))
+ extra = sorted(set(aggregate_targets) - READYBASIC_VICE_TARGETS)
+ fail(f"26-target VICE aggregate drifted; missing={missing}, extra={extra}")
+ for script_name in READYBASIC_VICE_PLAN_SCRIPTS:
+ if f"$(BUILD_SUPPORT_DIR)/{script_name}" not in makefile:
+ fail(f"READYBASIC_VICE_SCRIPTS is missing {script_name}")
+
+ # The custom ca65/ld65 image is not a conventional contiguous cc65 app.
+ # These checks couple the assembler's run addresses to the linker's exact
+ # cold-load seed shape so either side cannot drift silently.
+ require(r"ENTRY:\s+file\s*=\s*%O,\s*start\s*=\s*\$1000,\s*size\s*=\s*\$0200", cfg,
+ "custom ReadyBASIC ENTRY shape must remain $1000/$0200")
+ require(r"SLOT0:\s+file\s*=\s*\"\",\s*start\s*=\s*\$A800,\s*size\s*=\s*\$0800", cfg,
+ "custom ReadyBASIC slot 0 must remain $A800/$0800")
+ require(r"SLOT1:\s+file\s*=\s*\"\",\s*start\s*=\s*\$B000,\s*size\s*=\s*\$0800", cfg,
+ "custom ReadyBASIC slot 1 must remain $B000/$0800")
+ require(r"SLOT2:\s+file\s*=\s*\"\",\s*start\s*=\s*\$B800,\s*size\s*=\s*\$0800", cfg,
+ "custom ReadyBASIC slot 2 must remain $B800/$0800")
+ require(r"SHARED:\s+file\s*=\s*\"\",\s*start\s*=\s*\$C200,\s*size\s*=\s*\$0400", cfg,
+ "custom ReadyBASIC shared-frame shape must remain $C200-$C5FF")
+ require(r"BRIDGE:\s+file\s*=\s*\"\",\s*start\s*=\s*\$C000,\s*size\s*=\s*\$0600", cfg,
+ "custom ReadyBASIC bridge window must remain $C000-$C5FF")
+
require(r"^BASIC_START\s*=\s*\$2AC1\b", asm, "BASIC_START must be $2AC1")
require(r"^BASIC_LIMIT\s*=\s*\$A000\b", asm, "BASIC_LIMIT must be $A000")
require(r"^rb_resolve_reu_banks_hidden:", asm,
@@ -73,6 +278,99 @@ def main() -> None:
require(r"^SIG_SCRPUT\s*=\s*15\b", asm, "SCRPUT signature must be registered")
require(r"^SIG_FADD\s*=\s*16\b", asm, "FADD signature must be registered")
require(r"^SIG_ZPAUSE\s*=\s*SIG_BUFFREE\b", asm, "ZPAUSE must reuse the one-integer parser signature")
+ require(r"^RB_MODULE_GFX\s*=\s*3\b", asm, "graphics commands must use module id 3")
+ require(r"^RB_MODULE_SID\s*=\s*4\b", asm, "sound commands must use module id 4")
+ require(r"^RB_SUBMOD_GFXCORE\s*=\s*16\b", asm, "GFXCORE submodule must be registered")
+ require(r"^RB_SUBMOD_GFXPRIM\s*=\s*17\b", asm, "GFXPRIM submodule must be registered")
+ require(r"^RB_SUBMOD_GFXSPR\s*=\s*18\b", asm, "GFXSPR submodule must be registered")
+ require(r"^RB_SUBMOD_INPUTEV\s*=\s*19\b", asm, "INPUTEV submodule must be registered")
+ require(r"^RB_SUBMOD_GFXPOLY\s*=\s*20\b", asm, "GFXPOLY submodule must be registered")
+ require(r"^RB_SUBMOD_GFXDL\s*=\s*21\b", asm, "GFXDL submodule must be registered")
+ require(r"^RB_SUBMOD_GFXTILE\s*=\s*22\b", asm, "GFXTILE submodule must be registered")
+ require(r"^RB_SUBMOD_SIDCORE\s*=\s*23\b", asm, "SIDCORE submodule must be registered")
+ require(r"^SIG_GFXMODE\s*=\s*19\b", asm, "GFXMODE signature must be registered")
+ require(r"^SIG_GFXSURF\s*=\s*20\b", asm, "GFXSURF signature must be registered")
+ require(r"^SIG_PLOT\s*=\s*21\b", asm, "PLOT signature must be registered")
+ require(r"^SIG_LINE\s*=\s*22\b", asm, "LINE signature must be registered")
+ require(r"^SIG_SPRSET\s*=\s*23\b", asm, "SPRSET signature must be registered")
+ require(r"^SIG_KEYNONE\s*=\s*24\b", asm, "zero-argument input signature must be registered")
+ require(r"^SIG_POLY\s*=\s*25\b", asm, "polygon array signature must be registered")
+ require(r"^RB_HANDLE_TYPE_GFXSURF\s*=\s*3\b", asm, "graphics surfaces must use typed handle 3")
+ require(r"^RB_HANDLE_TYPE_POINTBUF\s*=\s*4\b", asm, "point buffers must use typed handle 4")
+ require(r"^RB_HANDLE_TYPE_DLIST\s*=\s*5\b", asm, "display lists must use typed handle 5")
+ require(r"^RB_HANDLE_TYPE_CHARSET\s*=\s*6\b", asm, "charsets must use typed handle 6")
+ require(r"^RB_HANDLE_TYPE_TILESET\s*=\s*7\b", asm, "tilesets must use typed handle 7")
+ require(r"^RB_HANDLE_TYPE_TILEMAP\s*=\s*8\b", asm, "tilemaps must use typed handle 8")
+ require(r"^RB_GFX_SCREEN\s*=\s*\$CC00\b", asm, "Bank D graphics screen RAM must start at $CC00")
+ require(r"^RB_GFX_SPRITES\s*=\s*\$CA00\b", asm, "Bank D sprite data must start at $CA00")
+ require(r"^RB_GFX_BITMAP\s*=\s*\$E000\b", asm, "Bank D bitmap RAM must start at $E000")
+ require(r"^RB_GFX_COLOR\s*=\s*\$D800\b", asm, "graphics color RAM must be $D800")
+ require(r"^RB_GFX_SPR_PTRS\s*=\s*\$CFF8\b", asm, "sprite pointer table must stay in the $CC00 screen page")
+ require(r"CMD_GFXCORE\s+CMD_GFXMODE,\s+SIG_GFXMODE,\s+cmd_gfxmode,\s+\"GFXMODE\"", asm,
+ "GFXMODE must be a built-in GFXCORE command")
+ require(r"CMD_LOW_ALL\s+CMD_BUFNEW,\s+SIG_BUFNEW,\s+cmd_bufnew_low,\s+\"BUFMAKE\"", asm,
+ "BUFMAKE must be the only public buffer allocation command")
+ require(r"CMD_LOW_ALL\s+CMD_BUFFREE,\s+SIG_BUFFREE,\s+cmd_buffree_low,\s+\"BUFDROP\"", asm,
+ "BUFDROP must be the only public buffer release command")
+ require(r"CMD_LOW\s+CMD_FREEMEM,\s+SIG_FREEMEM,\s+cmd_freemem_low,\s+cmd_freemem_low_end,\s+\"MEMAVL\"", asm,
+ "MEMAVL must be the only public BASIC free-memory probe")
+ require(r"CMD_LOW_ALL\s+CMD_GFXTARGET,\s+SIG_BUFFREE,\s+cmd_gfxtarget_low,\s+\"GFXTGT\"", asm,
+ "GFXTGT must be the only public graphics target command")
+ require(r"CMD_GFXPRIM\s+CMD_PLOT,\s+SIG_PLOT,\s+cmd_plot,\s+\"PLOT\"", asm,
+ "PLOT must be a built-in GFXPRIM command")
+ require(r"CMD_GFXPRIM\s+CMD_FRECT,\s+SIG_LINE,\s+cmd_frect,\s+\"FBOX\"", asm,
+ "FBOX must be the only public filled-rectangle command")
+ require(r"CMD_GFXSPR\s+CMD_SPRSET,\s+SIG_SPRSET,\s+cmd_sprset,\s+\"SPRSET\"", asm,
+ "SPRSET must be a built-in GFXSPR overlay command")
+ require(r"CMD_INPUTEV\s+CMD_JOY,\s+SIG_ZFAIL,\s+cmd_joy,\s+\"JOY\"", asm,
+ "JOY must be a built-in INPUTEV overlay command")
+ require(r"CMD_GFXPOLY\s+CMD_POLY,\s+SIG_POLY,\s+cmd_poly,\s+\"POLY\"", asm,
+ "POLY must be a built-in GFXPOLY overlay command")
+ require(r"CMD_GFXPOLY\s+CMD_POLYH,\s+SIG_PLOT,\s+cmd_poly,\s+\"POLYH\"", asm,
+ "POLYH must be a built-in GFXPOLY overlay command")
+ require(r"CMD_GFXPOLY\s+CMD_PBUFNEW,\s+SIG_BUFNEW,\s+cmd_pbufnew,\s+\"PBMAKE\"", asm,
+ "PBMAKE must be the only public point-buffer allocation command")
+ require(r"CMD_GFXPOLY\s+CMD_PBUFFREE,\s+SIG_BUFFREE,\s+cmd_pbuffree,\s+\"PBDROP\"", asm,
+ "PBDROP must be the only public point-buffer release command")
+ require(r"CMD_GFXDL\s+CMD_DLNEW,\s+SIG_BUFNEW,\s+cmd_dlnew,\s+\"DLMAKE\"", asm,
+ "DLMAKE must be a built-in GFXDL overlay command")
+ require(r"CMD_GFXDL\s+CMD_DLCLR,\s+SIG_BUFFREE,\s+cmd_dlclr,\s+\"DLRST\"", asm,
+ "DLRST must be the only public display-list reset command")
+ require(r"CMD_GFXDL\s+CMD_DLFRECT,\s+SIG_LINE,\s+cmd_dlfrect,\s+\"DLFBOX\"", asm,
+ "DLFBOX must be the only public display-list filled-rectangle command")
+ require(r"CMD_GFXDL\s+CMD_DLDRAW,\s+SIG_BUFFREE,\s+cmd_dldraw,\s+\"DLDRAW\"", asm,
+ "DLDRAW must be a built-in GFXDL overlay command")
+ require(r"CMD_GFXTILE\s+CMD_TMDRAW,\s+SIG_BUFFILL,\s+cmd_tmdraw,\s+\"TMDRAW\"", asm,
+ "TMDRAW must be a built-in GFXTILE overlay command")
+ require(r"CMD_SIDCORE\s+CMD_SIDCLR,\s+SIG_KEYNONE,\s+cmd_sidclr,\s+\"SIDRST\"", asm,
+ "SIDRST must be the only public SID reset command")
+ require(r"CMD_SIDCORE\s+CMD_SILENCE,\s+SIG_KEYNONE,\s+cmd_sidclr,\s+\"SIDOFF\"", asm,
+ "SIDOFF must be the only public SID silence command")
+ require(r"CMD_SIDCORE\s+CMD_FREQ,\s+SIG_BUFFILL,\s+cmd_freq,\s+\"FRQ\"", asm,
+ "FRQ must be the only public raw SID frequency command")
+ require(r"CMD_SIDCORE\s+CMD_NOTE,\s+SIG_PLOT,\s+cmd_note,\s+\"PITCH\"", asm,
+ "PITCH must be the only public note-to-frequency command")
+ require(r"CMD_SIDCORE\s+CMD_VOICE,\s+SIG_LINE,\s+cmd_voice,\s+\"VOICE\"", asm,
+ "VOICE must use the existing five-number signature to avoid resident parser growth")
+ require(r"CMD_SIDCORE\s+CMD_SOUND,\s+SIG_SPRSET,\s+cmd_sound,\s+\"SOUND\"", asm,
+ "SOUND must be a built-in SIDCORE overlay command")
+ if re.search(r"^\s*RB_GFX_[A-Za-z0-9_]+\s*=\s*\$C[6789][0-9A-Fa-f]{2}\b", asm, re.MULTILINE):
+ fail("graphics-owned Bank D state must not live in the resident $C600-$C9FF shim range")
+ command_names = parse_command_names(asm)
+ removed_present = sorted(set(command_names) & REMOVED_COMMAND_NAMES)
+ if removed_present:
+ fail("removed alpha command aliases must not be registered: " + ", ".join(removed_present))
+ unsafe_names = []
+ for name in command_names:
+ reason = token_unsafe_reason(name)
+ if reason:
+ unsafe_names.append(f"{name} ({reason})")
+ if unsafe_names:
+ fail(
+ "command names must avoid embedded BASIC V2 token words: "
+ + ", ".join(unsafe_names)
+ )
+ check_command_descriptor_layout(asm)
require(r"^CMD_ZMODLOAD\s*=\s*28\b", asm, "ZMODLOAD loader command id must stay stable")
require(r"CMD_SLOT1\s+CMD_ZMODLOAD,\s+SIG_ZHIDDENRAM,\s+cmd_zmodload,\s+\"ZMODLD\"", asm, "ZMODLD loader command must live in module 2 slot 1")
require(r"^K_OPEN\s*=\s*\$FFC0\b", asm, "ZMODLD must use streamed KERNAL file I/O")
@@ -84,7 +382,7 @@ def main() -> None:
if "REU_BANK_RB_CORE" in reu_hdr or "REU_BANK_RB_CODE" in reu_hdr:
fail("ReadyBASIC core/code banks must not be fixed in reu_mgr.h")
- for name in ("ENTRY", "RESIDENT", "LOWPACK", "SLOTPACK1", "SLOTPACK2", "SPANPACK", "OVL1PACK", "OVL2PACK", "HIDDEN", "BRIDGE", "REGSEED"):
+ for name in ("ENTRY", "RESIDENT", "LOWPACK", "SLOTPACK1", "SLOTPACK2", "SPANPACK", "OVL1PACK", "OVL2PACK", "OVL3PACK", "OVL4PACK", "OVL5PACK", "OVL6PACK", "HIDDEN", "BRIDGE", "REGSEED"):
if name not in segments:
fail(f"map is missing segment {name}")
@@ -95,6 +393,10 @@ def main() -> None:
spanpack = segments["SPANPACK"]
ovl1pack = segments["OVL1PACK"]
ovl2pack = segments["OVL2PACK"]
+ ovl3pack = segments["OVL3PACK"]
+ ovl4pack = segments["OVL4PACK"]
+ ovl5pack = segments["OVL5PACK"]
+ ovl6pack = segments["OVL6PACK"]
hidden = segments["HIDDEN"]
bridge = segments["BRIDGE"]
regseed = segments["REGSEED"]
@@ -105,22 +407,30 @@ def main() -> None:
fail(f"RESIDENT grew past command-module slot budget $18C0, got ${resident[2]:04X}")
if lowpack[0] != 0xA800 or lowpack[1] > 0xAFFF:
fail(f"command slot 0 must fit under BASIC ROM at $A800-$AFFF, got ${lowpack[0]:04X}-${lowpack[1]:04X}")
- if lowpack[2] != 0x06D1:
- fail(f"command slot 0 size changed from measured $06D1, got ${lowpack[2]:04X}")
+ if lowpack[2] > 0x0800:
+ fail(f"command slot 0 grew past 2KB budget, got ${lowpack[2]:04X}")
if slotpack1[0] != 0xB000 or slotpack1[1] > 0xB7FF:
fail(f"command slot 1 must fit under BASIC ROM at $B000-$B7FF, got ${slotpack1[0]:04X}-${slotpack1[1]:04X}")
- if slotpack1[2] != 0x023B:
- fail(f"command slot 1 size changed from measured $023B, got ${slotpack1[2]:04X}")
+ if slotpack1[2] > 0x0800:
+ fail(f"command slot 1 grew past 2KB budget, got ${slotpack1[2]:04X}")
if slotpack2[0] != 0xB800 or slotpack2[1] > 0xBFFF:
fail(f"command slot 2 must fit under BASIC ROM at $B800-$BFFF, got ${slotpack2[0]:04X}-${slotpack2[1]:04X}")
- if slotpack2[2] != 0x0015:
- fail(f"command slot 2 size changed from measured $0015, got ${slotpack2[2]:04X}")
- if spanpack[0] != 0xB000 or spanpack[1] > 0xBFFF or spanpack[2] != 0x0015:
- fail(f"two-slot proof payload must fit at $B000-$BFFF with measured size $0015, got ${spanpack[0]:04X}-${spanpack[1]:04X} size ${spanpack[2]:04X}")
- if ovl1pack[0] < 0xB800 or ovl1pack[1] > 0xBFFF or ovl1pack[2] != 0x0015:
- fail(f"overlay 1 proof payload must fit in slot 2 with measured size $0015, got ${ovl1pack[0]:04X}-${ovl1pack[1]:04X} size ${ovl1pack[2]:04X}")
- if ovl2pack[0] < 0xB800 or ovl2pack[1] > 0xBFFF or ovl2pack[2] != 0x0015:
- fail(f"overlay 2 proof payload must fit in slot 2 with measured size $0015, got ${ovl2pack[0]:04X}-${ovl2pack[1]:04X} size ${ovl2pack[2]:04X}")
+ if slotpack2[2] > 0x0800:
+ fail(f"command slot 2 grew past 2KB budget, got ${slotpack2[2]:04X}")
+ if spanpack[0] != 0xB000 or spanpack[1] > 0xBFFF or spanpack[2] > 0x1000:
+ fail(f"two-slot payload must fit at $B000-$BFFF, got ${spanpack[0]:04X}-${spanpack[1]:04X} size ${spanpack[2]:04X}")
+ if ovl1pack[0] < 0xB800 or ovl1pack[1] > 0xBFFF or ovl1pack[2] > 0x0800:
+ fail(f"overlay 1 payload must fit in slot 2, got ${ovl1pack[0]:04X}-${ovl1pack[1]:04X} size ${ovl1pack[2]:04X}")
+ if ovl2pack[0] < 0xB800 or ovl2pack[1] > 0xBFFF or ovl2pack[2] > 0x0800:
+ fail(f"overlay 2 payload must fit in slot 2, got ${ovl2pack[0]:04X}-${ovl2pack[1]:04X} size ${ovl2pack[2]:04X}")
+ if ovl3pack[0] < 0xB800 or ovl3pack[1] > 0xBFFF or ovl3pack[2] > 0x0800:
+ fail(f"overlay 3 payload must fit in slot 2, got ${ovl3pack[0]:04X}-${ovl3pack[1]:04X} size ${ovl3pack[2]:04X}")
+ if ovl4pack[0] < 0xB800 or ovl4pack[1] > 0xBFFF or ovl4pack[2] > 0x0800:
+ fail(f"overlay 4 payload must fit in slot 2, got ${ovl4pack[0]:04X}-${ovl4pack[1]:04X} size ${ovl4pack[2]:04X}")
+ if ovl5pack[0] < 0xB800 or ovl5pack[1] > 0xBFFF or ovl5pack[2] > 0x0800:
+ fail(f"overlay 5 payload must fit in slot 2, got ${ovl5pack[0]:04X}-${ovl5pack[1]:04X} size ${ovl5pack[2]:04X}")
+ if ovl6pack[0] < 0xB800 or ovl6pack[1] > 0xBFFF or ovl6pack[2] > 0x0800:
+ fail(f"overlay 6 payload must fit in slot 2, got ${ovl6pack[0]:04X}-${ovl6pack[1]:04X} size ${ovl6pack[2]:04X}")
if hidden[0] != 0xA000 or hidden[1] > 0xA7FF:
fail(f"HIDDEN helper/common area must fit in $A000-$A7FF, got ${hidden[0]:04X}-${hidden[1]:04X}")
if hidden[2] > 0x0800:
@@ -142,6 +452,18 @@ def main() -> None:
require(r"^RUNTIME_STACK_BUF\s*=\s*\$C500\b", asm, "RUNTIME_STACK_BUF must be $C500")
require(r"^RB_REU_HIDDEN_SHADOW_OFF\s*=\s*\$3000\b",
asm, "hidden helper shadow must live in ReadyBASIC core REU offset $3000")
+ require(r"^RB_CODE_GFXSPR_OFF\s*=\s*\$5000\b",
+ asm, "built-in GFXSPR overlay must be stashed at REU code offset $5000")
+ require(r"^RB_CODE_INPUTEV_OFF\s*=\s*\$5800\b",
+ asm, "built-in INPUTEV overlay must be stashed at REU code offset $5800")
+ require(r"^RB_CODE_GFXPOLY_OFF\s*=\s*\$6000\b",
+ asm, "built-in GFXPOLY overlay must be stashed at REU code offset $6000")
+ require(r"^RB_CODE_GFXDL_OFF\s*=\s*\$6800\b",
+ asm, "built-in GFXDL overlay must be stashed at REU code offset $6800")
+ require(r"^RB_CODE_GFXTILE_OFF\s*=\s*\$7000\b",
+ asm, "built-in GFXTILE overlay must be stashed at REU code offset $7000")
+ require(r"^RB_CODE_SIDCORE_OFF\s*=\s*\$7800\b",
+ asm, "built-in SIDCORE overlay must be stashed at REU code offset $7800")
if re.search(r"^HIDDEN_SHADOW\s*=", asm, re.MULTILINE):
fail("ReadyBASIC hidden helper shadow must not consume C64 RAM")
hidden_shadow_end = 0x3000 + hidden[2] - 1
@@ -149,12 +471,36 @@ def main() -> None:
fail(f"HIDDEN shadow copy must stay inside REU common area, got $3000-${hidden_shadow_end:04X}")
if regseed[0] != 0x5000 or regseed[2] > 0x1200:
fail(f"REGSEED must stay within cold seed $5000-$61FF, got ${regseed[0]:04X} size ${regseed[2]:04X}")
- expected_payload = 0x6200 - 0x1000
+ if ovl1pack[0] != 0xB800:
+ fail(f"overlay 1 must run as a replacement slot-2 overlay at $B800, got ${ovl1pack[0]:04X}")
+ if ovl2pack[0] != 0xB800:
+ fail(f"overlay 2 must run as a replacement slot-2 overlay at $B800, got ${ovl2pack[0]:04X}")
+ if ovl3pack[0] != 0xB800:
+ fail(f"overlay 3 must run as a replacement slot-2 overlay at $B800, got ${ovl3pack[0]:04X}")
+ if ovl4pack[0] != 0xB800:
+ fail(f"overlay 4 must run as a replacement slot-2 overlay at $B800, got ${ovl4pack[0]:04X}")
+ if ovl5pack[0] != 0xB800:
+ fail(f"overlay 5 must run as a replacement slot-2 overlay at $B800, got ${ovl5pack[0]:04X}")
+ if ovl6pack[0] != 0xB800:
+ fail(f"overlay 6 must run as a replacement slot-2 overlay at $B800, got ${ovl6pack[0]:04X}")
+ if 0x5000 + ovl1pack[2] > 0x5800:
+ fail(f"GFXSPR built-in overlay overflowed its reserved 2KB REU code range, size ${ovl1pack[2]:04X}")
+ if 0x5800 + ovl2pack[2] > 0x6000:
+ fail(f"INPUTEV built-in overlay overflowed its reserved 2KB REU code range, size ${ovl2pack[2]:04X}")
+ if 0x6000 + ovl3pack[2] > 0x6800:
+ fail(f"GFXPOLY built-in overlay overflowed its reserved 2KB REU code range, size ${ovl3pack[2]:04X}")
+ if 0x6800 + ovl4pack[2] > 0x7000:
+ fail(f"GFXDL built-in overlay overflowed its reserved 2KB REU code range, size ${ovl4pack[2]:04X}")
+ if 0x7000 + ovl5pack[2] > 0x7800:
+ fail(f"GFXTILE built-in overlay overflowed its reserved 2KB REU code range, size ${ovl5pack[2]:04X}")
+ if 0x7800 + ovl6pack[2] > 0x8000:
+ fail(f"SIDCORE built-in overlay overflowed its reserved 2KB REU code range, size ${ovl6pack[2]:04X}")
+ expected_payload = 0x8000 - 0x1000
actual_payload = PRG.stat().st_size - 2
if actual_payload < expected_payload:
fail(
"PRG payload does not cover the load-image seed span "
- f"$1000-$61FF: got ${actual_payload:04X}, need ${expected_payload:04X}"
+ f"$1000-$7FFF: got ${actual_payload:04X}, need ${expected_payload:04X}"
)
for module_name in ("rbm.sample1.seq", "rbm.sample2.seq", "rbm.sample3.seq"):
diff --git a/build_support/verify_readyos_shim.py b/build_support/verify_readyos_shim.py
index d25c7e1..0e3b86f 100644
--- a/build_support/verify_readyos_shim.py
+++ b/build_support/verify_readyos_shim.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
"""
-Verify that the shared ReadyOS shim remains 512 bytes, preserves ABI anchor
+Verify that the shared ReadyOS shim remains 1024 bytes, preserves ABI anchor
locations, and that cartridge packaging consumes the configured image.
"""
@@ -19,24 +19,27 @@
SHIM_INC = ROOT / "src" / "boot" / "readyos_shim.inc"
EASYFLASH_SHIM_BIN = ROOT / "bin" / "easyflash_shim.bin"
-EXPECTED_SIZE = 512
+SHIM_START = 0xC600
+ABI_BASE = 0x0200
+EXPECTED_SIZE = 1024
ABI_CHECKS = (
- ("jt_load_disk", 0x000, bytes.fromhex("4c40c8")),
- ("jt_load_reu", 0x003, bytes.fromhex("4c60c8")),
- ("jt_run_app", 0x006, bytes.fromhex("4c0010")),
- ("jt_preload", 0x009, bytes.fromhex("4c80c8")),
- ("jt_return", 0x00C, bytes.fromhex("4c00c9")),
- ("jt_switch", 0x00F, bytes.fromhex("4c40c9")),
- ("jt_stash_cur", 0x012, bytes.fromhex("4cc0c8")),
- ("jt_fetch_bank", 0x015, bytes.fromhex("4cf0c8")),
- ("jt_log_byte", 0x018, bytes.fromhex("4ce0c9")),
- ("data_filename_len", 0x021, bytes([0x08])),
- ("storage_drive_default", 0x039, bytes([0x08])),
- ("stash_uses_logical_setup", 0x0E0, bytes.fromhex("2060c9")),
- ("fetch_uses_logical_setup", 0x0F0, bytes.fromhex("2060c9")),
- ("logical_setup_entry", 0x160, bytes.fromhex("c900d009ad3b")),
- ("raw_setup_entry", 0x1A0, bytes.fromhex("8d06df")),
+ ("jt_load_disk", ABI_BASE + 0x000, bytes.fromhex("4c40c8")),
+ ("jt_load_reu", ABI_BASE + 0x003, bytes.fromhex("4c60c8")),
+ ("jt_run_app", ABI_BASE + 0x006, bytes.fromhex("4c0010")),
+ ("jt_preload", ABI_BASE + 0x009, bytes.fromhex("4c80c8")),
+ ("jt_return", ABI_BASE + 0x00C, bytes.fromhex("4c00c9")),
+ ("jt_switch", ABI_BASE + 0x00F, bytes.fromhex("4c40c9")),
+ ("jt_reserved_noop", ABI_BASE + 0x012, bytes.fromhex("4cffc9")),
+ ("jt_fetch_bank", ABI_BASE + 0x015, bytes.fromhex("4cf0c8")),
+ ("jt_deprecated_log", ABI_BASE + 0x018, bytes.fromhex("4cffc9")),
+ ("jt_mark_loaded", ABI_BASE + 0x01B, bytes.fromhex("4cc0c9")),
+ ("data_filename_len", ABI_BASE + 0x021, bytes([0x08])),
+ ("storage_drive_default", ABI_BASE + 0x039, bytes([0x08])),
+ ("stash_uses_logical_setup", ABI_BASE + 0x0E0, bytes.fromhex("2060c9")),
+ ("fetch_uses_logical_setup", ABI_BASE + 0x0F0, bytes.fromhex("2060c9")),
+ ("logical_setup_entry", ABI_BASE + 0x160, bytes.fromhex("c900d006ad3b")),
+ ("raw_setup_entry", ABI_BASE + 0x1A0, bytes.fromhex("8d06df")),
)
@@ -91,6 +94,9 @@ def parse_byte_token(token: str, constants: dict[str, int]) -> bytes:
return bytes([int(token[1:], 16)])
if token in constants:
return bytes([constants[token] & 0xFF])
+ m = re.fullmatch(r"([A-Za-z_][A-Za-z0-9_]*)\s*\+\s*(\d+)", token)
+ if m and m.group(1) in constants:
+ return bytes([(constants[m.group(1)] + int(m.group(2))) & 0xFF])
return bytes([int(token, 0)])
@@ -114,6 +120,14 @@ def parse_shim_bytes(text: str, *, start_label: str, constants: dict[str, int] |
continue
if stripped.startswith(".include"):
continue
+ if stripped.startswith(".res"):
+ payload = stripped.split(".res", 1)[1]
+ tokens = split_tokens(payload)
+ count_raw = tokens[0]
+ count = int(count_raw[1:], 16) if count_raw.startswith("$") else int(count_raw, 0)
+ value = parse_byte_token(tokens[1], constants)[0] if len(tokens) > 1 else 0
+ data.extend(bytes([value]) * count)
+ continue
if ".byte" not in stripped:
continue
payload = stripped.split(".byte", 1)[1]
@@ -164,13 +178,40 @@ def verify_exact_image(label: str, data: bytes, *, reu_bank_skip: int = 0) -> No
actual = data[offset:offset + len(expected)]
if actual != expected:
fail(
- f"{label} ABI field {name} changed at ${0xC800 + offset:04X} "
+ f"{label} ABI field {name} changed at ${SHIM_START + offset:04X} "
f"({actual.hex()} != {expected.hex()})"
)
- skip_actual = data[0x03B]
- if skip_actual != (reu_bank_skip & 0xFF):
- fail(f"{label} reu_bank_skip changed at $C83B ({skip_actual} != {reu_bank_skip})")
+ readyos_actual = data[ABI_BASE + 0x03B]
+ readyos_expected = reu_bank_skip & 0xFF
+ if readyos_actual != readyos_expected:
+ fail(f"{label} ReadyOS bank changed at $C83B ({readyos_actual} != {readyos_expected})")
+ if bytes.fromhex("a9b68d08df") not in data[ABI_BASE + 0x1A0:ABI_BASE + 0x1C0]:
+ fail(f"{label} snapshot length is not $B600")
+ for address_lo in (0x07, 0x08, 0x09, 0x0B, 0x0C):
+ if bytes((0x8D, address_lo, 0xC0)) in data[ABI_BASE:]:
+ fail(f"{label} reintroduced an obsolete preload trace store to $C0{address_lo:02X}")
+
+ padding_ranges = (
+ (0x05C, 0x060), (0x069, 0x080), (0x0B6, 0x0E0),
+ (0x0E9, 0x0F0), (0x0F9, 0x100), (0x11F, 0x140),
+ (0x15B, 0x160), (0x19E, 0x1A0), (0x1BE, 0x1C0),
+ (0x1FB, 0x1FF),
+ )
+ padding_bytes = sum(end - start for start, end in padding_ranges)
+ if padding_bytes != 129:
+ fail(f"internal shim padding accounting changed ({padding_bytes} != 129)")
+ for start, end in padding_ranges:
+ if any(data[ABI_BASE + start:ABI_BASE + end]):
+ fail(
+ f"{label} executable padding is no longer clear at "
+ f"${0xC800 + start:04X}-${0xC800 + end - 1:04X}"
+ )
+ if any(data[:ABI_BASE]):
+ fail(f"{label} lower 512-byte expansion reserve is not clear")
ok(f"{label} ABI anchor bytes match expected layout")
+ ok(f"{label} has no obsolete preload trace stores in app RAM")
+ ok(f"{label} has 129 verified executable-padding bytes")
+ ok(f"{label} has 512 clear resident expansion bytes at $C600-$C7FF")
def main() -> int:
@@ -188,8 +229,13 @@ def main() -> int:
require_include_pattern(
BOOT_ASM,
- r"(?m)^shim_data:\s*\n\.include \"readyos_shim\.inc\"$",
- "boot shim include handoff",
+ r"(?m)^shim_data:\s*\nREADYOS_SHIM_ABI_ONLY\s*=\s*1\s*\n\.include \"readyos_shim\.inc\"$",
+ "boot optimized ABI-only shim include handoff",
+ )
+ require_include_pattern(
+ BOOT_ASM,
+ r"(?s)sta \$C600,x.*sta \$C700,x.*sta \$C800,x.*sta \$C900,x",
+ "boot clears the reserve and copies both ABI pages",
)
require_include_pattern(
EASYFLASH_SHIM_SRC,
diff --git a/build_support/verify_resume_contract.py b/build_support/verify_resume_contract.py
index 7db0f7d..33f3700 100755
--- a/build_support/verify_resume_contract.py
+++ b/build_support/verify_resume_contract.py
@@ -128,6 +128,27 @@ def main():
all_ok &= check("shared shim sets REU length low", has_len_lo, shim_path)
all_ok &= check("shared shim sets REU length high to $B6", has_len_hi_b6, shim_path)
+ print("\n=== Launcher ReadyOS-bank Resume Contract ===")
+ try:
+ with open(os.path.join(ROOT, "src", "lib", "resume_state_priv.h"),
+ "r", encoding="utf-8", errors="replace") as f:
+ resume_priv = f.read()
+ with open(os.path.join(ROOT, "src", "apps", "launcher", "launcher.c"),
+ "r", encoding="utf-8", errors="replace") as f:
+ launcher_src = f.read()
+ except FileNotFoundError as ex:
+ all_ok &= check("launcher resume sources exist", False, str(ex))
+ else:
+ all_ok &= check("token 0 resume uses ReadyOS runtime block",
+ "REUCB_RUNTIME_OFF" in resume_priv and
+ "REUCB_RUNTIME_SIZE" in resume_priv)
+ all_ok &= check("launcher resume payload contains only compact UI state",
+ "LAUNCHER_RESUME_SEG_COUNT 1" in launcher_src and
+ "LauncherResumeV1" in launcher_src)
+ all_ok &= check("selection is validated after registry restore",
+ "if (out_selected != 0)" in launcher_src and
+ "if (saved_selected < launcher_menu_count())" in launcher_src)
+
print()
if all_ok:
print("RESUME CONTRACT CHECKS PASSED")
diff --git a/build_support/verify_reu_control_bank.py b/build_support/verify_reu_control_bank.py
index 3722e11..4fe6bce 100644
--- a/build_support/verify_reu_control_bank.py
+++ b/build_support/verify_reu_control_bank.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-"""Static checks for the ReadyOS logical REU bank 0 control mirror."""
+"""Static checks for the authoritative schema-v5 ReadyOS bank."""
from __future__ import annotations
@@ -48,56 +48,64 @@ def main() -> int:
reuviewer = read("src/apps/reuviewer/reuviewer.c")
makefile = read("Makefile")
- require(define_int(hdr, "REUCB_SCHEMA_VERSION") == 4, "schema version is 4")
- require(define_int(hdr, "REUCB_HEADER_OFF") == 0x0000, "header starts at $0000")
+ require(define_int(hdr, "REUCB_SCHEMA_VERSION") == 5, "schema version is 5")
+ require(define_int(hdr, "REUCB_LAUNCHER_SNAPSHOT_SIZE") == 0xB600,
+ "ReadyOS bank begins with the $B600 launcher snapshot")
+ require(define_int(hdr, "REUCB_HEADER_OFF") == 0xB600, "header starts at $B600")
require(define_int(hdr, "REUCB_HEADER_SIZE") == 0x0040, "header is 64 bytes")
- require(define_int(hdr, "REUCB_BANK_TYPE_OFF") == 0x0100, "bank table mirror starts at $0100")
- require(define_int(hdr, "REUCB_BANK_TYPE_SIZE") == 0x0100, "bank table mirror is 256 bytes")
- require(define_int(hdr, "REUCB_RESOURCE_OFF") == 0x0200, "resource records start at $0200")
- require(define_int(hdr, "REUCB_RESOURCE_SIZE") == 8, "resource records are 8 bytes")
- require(define_int(hdr, "REUCB_RESOURCE_COUNT") == 10, "fixed resource record count is 10")
- require(define_int(hdr, "REUCB_APP_REG_OFF") == 0x0300, "64-app registry starts at $0300")
- require(define_int(hdr, "REUCB_APP_REG_SIZE") == 8, "app registry records are 8 bytes")
+ require(define_int(hdr, "REUCB_BANK_TYPE_OFF") == 0xB640, "bank types start at $B640")
+ require(define_int(hdr, "REUCB_SHIM_LOOKUP_OFF") == 0xB740,
+ "token-to-physical map starts at $B740")
+ require(define_int(hdr, "REUCB_TOKEN_STATUS_OFF") == 0xB840,
+ "token status starts at $B840")
+ require(define_int(hdr, "REUCB_CLIPBOARD_OFF") == 0xB940,
+ "clipboard metadata starts at $B940")
+ require(define_int(hdr, "REUCB_HOTKEY_OFF") == 0xB9D0,
+ "hotkeys start at $B9D0")
+ require(define_int(hdr, "REUCB_SETTINGS_OFF") == 0xB9D9,
+ "launcher settings start at $B9D9")
+ require(define_int(hdr, "REUCB_SETTINGS_SIZE") == 39,
+ "launcher settings fill the pre-registry gap")
+ require(define_int(hdr, "REUCB_RUNTIME_OFF") == 0xFC40,
+ "launcher UI resume state starts at $FC40")
+ require(define_int(hdr, "REUCB_RUNTIME_SIZE") == 0x0080,
+ "launcher UI resume state has a 128-byte envelope")
+ require(define_int(hdr, "REUCB_APP_REG_OFF") == 0xBA00, "64-app registry starts at $BA00")
+ require(define_int(hdr, "REUCB_APP_REG_SIZE") == 16, "app registry records are 16 bytes")
require(define_int(hdr, "REUCB_APP_REG_COUNT") == 64, "app registry has 64 entries")
- require(define_int(hdr, "REUCB_APP_META_OFF") == 0x0500, "app metadata starts at $0500")
+ require(define_int(hdr, "REUCB_TOKEN_APP_OFF") == 0xBE00,
+ "token-to-app index starts at $BE00")
+ require(define_int(hdr, "REUCB_APP_META_OFF") == 0xBF00, "app metadata starts at $BF00")
require(define_int(hdr, "REUCB_APP_META_SIZE") == 13, "app filename records are 13 bytes")
- require(define_int(hdr, "REUCB_DEP_OFF") == 0x0900, "dependency records start at $0900")
- require(define_int(hdr, "REUCB_DEP_COUNT") == 128, "dependency record capacity is 128")
- require(define_int(hdr, "REUCB_RSRC_REC_OFF") == 0x0A00, "rich resource records start at $0A00")
+ require(define_int(hdr, "REUCB_RSRC_REC_OFF") == 0xC240, "rich resource records start at $C240")
require(define_int(hdr, "REUCB_RSRC_REC_SIZE") == 16, "rich resource records are 16 bytes")
require(define_int(hdr, "REUCB_RSRC_REC_COUNT") == 64, "rich resource record capacity is 64")
- require(define_int(hdr, "REUCB_DEP_LINE_OFF") == 0x0E00, "dependency lines start at $0E00")
+ require(define_int(hdr, "REUCB_DEP_LINE_OFF") == 0xC640, "dependency lines start at $C640")
require(define_int(hdr, "REUCB_DEP_LINE_SIZE") == 128, "dependency line records are 128 bytes")
- require(define_int(hdr, "REUCB_CATALOG_TEXT_OFF") == 0x3000, "cold catalog text starts at $3000")
- require(define_int(hdr, "REUCB_CATALOG_NAME_OFF") == 0x3000, "catalog names start at $3000")
+ require(define_int(hdr, "REUCB_CATALOG_NAME_OFF") == 0xE640, "catalog names start at $E640")
require(define_int(hdr, "REUCB_CATALOG_NAME_SIZE") == 32, "catalog name records are 32 bytes")
- require(define_int(hdr, "REUCB_CATALOG_DESC_OFF") == 0x3800, "catalog descriptions start at $3800")
+ require(define_int(hdr, "REUCB_CATALOG_DESC_OFF") == 0xEE40, "catalog descriptions start at $EE40")
require(define_int(hdr, "REUCB_CATALOG_DESC_SIZE") == 39, "catalog description records are 39 bytes")
- require(define_int(hdr, "REUCB_CATALOG_FILE_OFF") == 0x4200, "catalog file tokens start at $4200")
+ require(define_int(hdr, "REUCB_CATALOG_FILE_OFF") == 0xF800, "catalog file tokens start at $F800")
require(define_int(hdr, "REUCB_CATALOG_FILE_SIZE") == 13, "catalog file token records are 13 bytes")
require(define_int(hdr, "REUCB_HEADER_PHYS_BANKS") == 44, "header records physical bank count")
require(define_int(hdr, "REUCB_HEADER_FIRST_UNAVAIL") == 45, "header records first unavailable bank")
- require("REU_READYOS_GLOBAL_PHYSICAL()" in src, "control mirror records ReadyOS global bank")
- require("REU_LAUNCHER_PHYSICAL()" in src, "control mirror records launcher bank")
- require("REU_LAUNCHER_OVERLAY_PHYSICAL()" not in src,
- "control mirror does not reserve a launcher overlay bank")
+ require("REU_READYOS_GLOBAL_PHYSICAL()" in src, "schema records direct ReadyOS bank")
+ require("readyos_bank_write_byte" in src, "schema writes bank types directly in REU")
+ require("REU_ALLOC_TABLE" not in src, "schema has no C64-RAM allocation mirror")
require("REU_BANK_RS_CACHE" not in src, "control mirror no longer records fixed ReadyShell cache banks")
require("REU_BANK_RS_SCRATCH" not in src, "control mirror no longer records fixed ReadyShell scratch bank")
require("REU_BANK_RS_DEBUG" not in src, "control mirror no longer records fixed ReadyShell debug bank")
require("REU_BANK_RB_CORE" not in src and "REU_BANK_RB_CODE" not in src,
"control mirror must not record fixed ReadyBASIC core/code banks")
- require("reu_dma_stash((unsigned int)REU_ALLOC_TABLE" in src,
- "control mirror stashes resident bank table")
- require("reu_phys_count_from_alloc_table()" in src and
- "REUCB_HEADER_PHYS_BANKS" in src,
- "control mirror publishes physical REU size")
+ require("REUCB_HEADER_PHYS_BANKS" in src, "schema publishes physical REU size")
require("reu_control_bank_write_launcher_registry" in registry,
"control mirror writes launcher 64-app registry")
- require("app_rs_bank1 + first_app_index" in registry and
- "app_rs_bank3 + first_app_index" in registry and
- "app_rs_bank4 + first_app_index" in registry,
- "control mirror records loader-owned dependency/resource bank arrays")
+ require("REUCB_TOKEN_STATUS_OFF" in registry and "REUCB_TOKEN_APP_OFF" in registry,
+ "registry publishes authoritative token status and token-to-app index")
+ require("REUCB_APP_REC_SIZE_LO" in registry and "app_sizes" in registry,
+ "registry publishes app snapshot sizes")
require("REU_CONTROL_BANK_SRC = $(LIB_DIR)/reu_control_bank.c" in makefile,
"Makefile defines REU_CONTROL_BANK_SRC")
@@ -126,16 +134,20 @@ def main() -> int:
"normal REU DMA/stats library does not link control bank module")
require("launcher_mirror_reu_control();" in launcher,
- "launcher refreshes control mirror")
+ "launcher refreshes ReadyOS-bank registry")
+ require("launcher_publish_settings" in launcher and
+ "REUCB_SETTINGS_MAGIC0" in launcher and
+ "launcher_restore_registry_from_readyos" in launcher,
+ "launcher publishes and restores its settings and registry from the ReadyOS bank")
require("reu_phys_apply_to_alloc_table(reu_phys_detect_bank_count())" in launcher,
"launcher probes physical REU size before allocation")
require("reu_control_bank_write_launcher_registry(" in launcher,
- "launcher mirrors app registry into control bank")
+ "launcher publishes app registry into ReadyOS bank")
require("catalog_store_entry" in launcher and
"REUCB_CATALOG_NAME_OFF" in launcher and
"REUCB_CATALOG_DESC_OFF" in launcher and
"REUCB_CATALOG_FILE_OFF" in launcher,
- "launcher stores cold catalog strings in logical REU bank 0")
+ "launcher stores cold catalog strings in the ReadyOS bank")
require("catalog_name_cache[APPS_HEIGHT]" in launcher and
"catalog_text_buf[MAX_DESC_LEN + 1]" in launcher,
"launcher keeps only visible catalog-name cache and one text scratch buffer")
@@ -152,7 +164,7 @@ def main() -> int:
"launcher writes rich resource/dependency metadata")
require("launcher_free_app_owned_alloc_records" in launcher and
"REUCB_DEP_KIND_APP_ALLOC" in launcher and
- "REU_ALLOC_TABLE[bank] == REU_APP_ALLOC" in launcher,
+ "launcher_bank_type(bank) == REU_APP_ALLOC" in launcher,
"launcher unload frees owner-recorded app allocation banks")
require("readyshell_overlay_names" not in launcher and
"readyshell_overlay_offsets" not in launcher,
@@ -161,10 +173,23 @@ def main() -> int:
"launcher has snapshot-bank resolver")
require("bank = launcher_resolve_snapshot_bank(index);" in launcher,
"launcher preload/REU launch paths use resolver")
+ load_app = re.search(
+ r"static unsigned int load_app_to_reu\(unsigned char index\) \{(.*?)\n\}",
+ launcher,
+ re.DOTALL,
+ )
+ require(load_app is not None, "launcher preload implementation is available for ordering checks")
+ if load_app is not None:
+ body = load_app.group(1)
+ require(body.find("bank = launcher_resolve_snapshot_bank(index);") <
+ body.find("filename = catalog_file_for_index(index);"),
+ "snapshot allocation publishes metadata before taking a catalog scratch pointer")
+ require("filename = catalog_file_for_index(index);\n set_shim_name(filename);" in body,
+ "DMA fallback reacquires its catalog filename after metadata publication")
require("*SHIM_CURRENT_BANK = bank;" in launcher,
"launcher disk path writes resolved bank to shim current bank")
require("reu_control_bank_sync_and_mirror(REUCB_WRITER_REUVIEWER)" in reuviewer,
- "reuviewer refreshes control mirror")
+ "reuviewer refreshes ReadyOS-bank header")
require("reuviewer_read_control_bank_header" in reuviewer and '"CB:"' in reuviewer and
"control_bank_generation" in reuviewer,
"reuviewer displays compact control-bank header status")
@@ -177,7 +202,7 @@ def main() -> int:
require("REUCB_DEP_KIND_APP_ALLOC" in reuviewer and '"TAG"' in reuviewer,
"reuviewer displays app-owned allocation record tags")
- print("REU control bank static checks passed.")
+ print("ReadyOS bank schema-v5 static checks passed.")
return 0
diff --git a/build_support/verify_shim_html_source.py b/build_support/verify_shim_html_source.py
new file mode 100644
index 0000000..39f71cb
--- /dev/null
+++ b/build_support/verify_shim_html_source.py
@@ -0,0 +1,123 @@
+#!/usr/bin/env python3
+"""Verify every HTML full-shim listing against the canonical byte image.
+
+Styled reports may add explanatory comments, so this checker compares every
+`.byte` directive (including directive boundaries and operands) and separately
+requires the current control-bank lookup annotations.
+"""
+
+from html.parser import HTMLParser
+from pathlib import Path
+import re
+
+
+ROOT = Path(__file__).resolve().parents[1]
+SOURCE = ROOT / "src/boot/readyos_shim.inc"
+MARKER = "Shared ReadyOS shim image ($C600-$C9FF, 1024 bytes)"
+
+REQUIRED_ANNOTATIONS = (
+ "$C83B: readyos_bank",
+ "Resolve token via the ReadyOS bank",
+ "lookup_app_bank",
+ "ADC #<$B740",
+ "fetch physical bank byte",
+ "Padding to $C9A0",
+ "mark_loaded",
+ "len hi = $B6",
+)
+
+RETIRED_ANNOTATIONS = (
+ "$C83D-$C83F: reserved",
+ "BNE app_bank",
+ "JMP store_physical_bank",
+ "global + launcher overlay reserve",
+ "Start+3..Start+25: physical backing banks",
+ "Resolve logical token via REU bank 0",
+ "ADC #<$2F00",
+)
+
+
+class PreBlocks(HTMLParser):
+ def __init__(self) -> None:
+ super().__init__()
+ self.in_pre = False
+ self.current = []
+ self.blocks = []
+
+ def handle_starttag(self, tag, attrs) -> None:
+ if tag == "pre":
+ self.in_pre = True
+ self.current = []
+
+ def handle_endtag(self, tag) -> None:
+ if tag == "pre" and self.in_pre:
+ self.blocks.append("".join(self.current))
+ self.current = []
+ self.in_pre = False
+
+ def handle_data(self, data) -> None:
+ if self.in_pre:
+ self.current.append(data)
+
+
+def byte_directives(text: str) -> list[str]:
+ result = []
+ for line in text.splitlines():
+ stripped = line.strip()
+ if not stripped.startswith(".byte"):
+ continue
+ operation = stripped.split(";", 1)[0].strip()
+ result.append(re.sub(r"\s+", " ", operation))
+ return result
+
+
+def main() -> None:
+ canonical = byte_directives(SOURCE.read_text(encoding="utf-8"))
+ checked = []
+ failures = []
+
+ for tree_name in ("docs", "privatedocs"):
+ for path in (ROOT / tree_name).rglob("*"):
+ if not path.is_file() or path.suffix.lower() not in {".html", ".htm"}:
+ continue
+ parser = PreBlocks()
+ parser.feed(path.read_text(encoding="utf-8"))
+ for block_index, block in enumerate(parser.blocks, start=1):
+ if MARKER not in block:
+ continue
+ label = f"{path.relative_to(ROOT)} pre#{block_index}"
+ checked.append(label)
+ embedded = byte_directives(block)
+ if embedded != canonical:
+ mismatch = next(
+ (
+ index
+ for index, pair in enumerate(zip(canonical, embedded), start=1)
+ if pair[0] != pair[1]
+ ),
+ min(len(canonical), len(embedded)) + 1,
+ )
+ failures.append(
+ f"{label}: byte directives differ at #{mismatch} "
+ f"(canonical {len(canonical)}, embedded {len(embedded)})"
+ )
+ for annotation in REQUIRED_ANNOTATIONS:
+ if annotation not in block:
+ failures.append(f"{label}: missing annotation: {annotation}")
+ for annotation in RETIRED_ANNOTATIONS:
+ if annotation in block:
+ failures.append(f"{label}: retired annotation remains: {annotation}")
+
+ if not checked:
+ raise SystemExit("no full commented shim listing found in documentation HTML")
+ if failures:
+ raise SystemExit("\n".join(failures))
+
+ print(
+ f"verified {len(checked)} full HTML shim listings: "
+ f"{len(canonical)} canonical .byte directives each"
+ )
+
+
+if __name__ == "__main__":
+ main()
diff --git a/build_support/vice_easyflash_smoke.py b/build_support/vice_easyflash_smoke.py
index b803de2..ccc338a 100644
--- a/build_support/vice_easyflash_smoke.py
+++ b/build_support/vice_easyflash_smoke.py
@@ -42,18 +42,6 @@ def payload_bytes_from_prg(path: Path) -> bytes:
return raw[2:]
-def expected_bitmap(layout: Dict[str, object]) -> bytes:
- bitmap = [0, 0, 0]
- for entry in layout["apps"]:
- bank = int(entry["bank"])
- if bank >= 24:
- fail(f"unsupported launcher bank for smoke bitmap: {bank}")
- byte_index = bank // 8
- bit_index = bank % 8
- bitmap[byte_index] |= 1 << bit_index
- return bytes(bitmap + [0x08])
-
-
def parse_monitor_log(path: Path) -> Dict[int, bytes]:
dumps: Dict[int, bytes] = {}
for line in path.read_text(encoding="utf-8", errors="replace").splitlines():
@@ -100,6 +88,14 @@ def marker_present(ring: bytes, marker: bytes) -> bool:
return value in ring or (value | 0x80) in ring
+def generated_readyos_bank() -> int:
+ text = (ROOT / "src/generated/easyflash_layout.inc").read_text(encoding="ascii")
+ match = re.search(r"(?m)^READYOS_REU_BANK_SKIP\s*=\s*(\d+)\s*$", text)
+ if not match:
+ fail("READYOS_REU_BANK_SKIP missing from generated EasyFlash layout")
+ return (int(match.group(1)) + 1) & 0xFF
+
+
def symbol_value_from_map(path: Path, symbol: str) -> int:
pattern = re.compile(rf"(?:^|\s){re.escape(symbol)}\s+([0-9A-Fa-f]{{6}})\s+RLA", re.M)
text = path.read_text(encoding="utf-8", errors="replace")
@@ -125,145 +121,37 @@ def write_monitor(output_path: Path,
output_path.parent.mkdir(parents=True, exist_ok=True)
main_addr = symbol_value_from_map(launcher_map_path, "_main")
keyloop_addr = symbol_value_from_map(launcher_map_path, "_tui_getkey")
- callmain_addr = symbol_value_from_map(launcher_map_path, "callmain")
- initlib_addr = symbol_value_from_map(launcher_map_path, "initlib")
- zerobss_addr = symbol_value_from_map(launcher_map_path, "zerobss")
- optional_launcher_breaks = [
- optional_symbol_value_from_map(launcher_map_path, "_ef_linit_entry"),
- optional_symbol_value_from_map(launcher_map_path, "_ef_linit_before_bootstrap"),
- optional_symbol_value_from_map(launcher_map_path, "_ef_linit_after_bootstrap"),
- optional_symbol_value_from_map(launcher_map_path, "_ef_linit_before_catalog_defaults"),
- optional_symbol_value_from_map(launcher_map_path, "_ef_linit_after_catalog_defaults"),
- ]
lines = []
if include_preload:
if boot_map_path is None:
fail("--include-preload requires --boot-map")
- shim_addr = symbol_value_from_map(boot_map_path, "easyflash_shim_copy_done")
preload_addr = symbol_value_from_map(boot_map_path, "easyflash_preload_verify_done")
- kernal_addr = symbol_value_from_map(boot_map_path, "easyflash_after_kernal_init")
- restore_addr = symbol_value_from_map(boot_map_path, "easyflash_after_launcher_restore")
- jump_addr = symbol_value_from_map(boot_map_path, "easyflash_before_launcher_jump")
- lines.append(f"break {shim_addr:04x}")
lines.append(f"break {preload_addr:04x}")
- lines.append(f"break {kernal_addr:04x}")
- lines.append(f"break {restore_addr:04x}")
- lines.append(f"break {jump_addr:04x}")
lines.extend([
- "break 1000",
- "break 890d",
- f"break {initlib_addr:04x}",
- f"break {zerobss_addr:04x}",
- f"break {callmain_addr:04x}",
f"break {main_addr:04x}",
f"break {keyloop_addr:04x}",
"x",
])
- for addr in optional_launcher_breaks:
- if addr is not None:
- lines.insert(-1, f"break {addr:04x}")
if include_preload:
lines.extend([
- "m 0f20 112f",
"m c800 c9ff",
- "x",
- "m 1000 107f",
"m ca00 cb1f",
- "m c600 c9ff",
- "m c760 c783",
- "m de00 de02",
- "m df01 df08",
- "x",
- "m c7a0 c7ef",
- "m 0000 001b",
- "m de00 de02",
- "m df01 df08",
- "x",
- "m 1000 107f",
- "m c7a0 c7ef",
- "m c836 c839",
- "m 0000 001b",
- "m de00 de02",
- "m df01 df08",
- "x",
- "m 1000 107f",
- "m c7a0 c7ef",
- "m c836 c839",
- "m 0000 001b",
- "m de00 de02",
- "m df01 df08",
- "x",
- "m 1000 107f",
- "m 88e0 892f",
- "m c7a0 c7ef",
- "m 0000 001b",
- "m de00 de02",
- "m df01 df08",
- "x",
- "m 88e0 892f",
- "m c7a0 c7ef",
- "m 0000 001b",
- "m de00 de02",
- "m df01 df08",
- "x",
- "m 88e0 892f",
- "m c7a0 c7ef",
- "m 0000 001b",
- "m de00 de02",
- "m df01 df08",
- "x",
- "m 8927 89a6",
- "m c7a0 c7ef",
- "m 0000 001b",
- "m de00 de02",
- "m df01 df08",
- "x",
- "m 7c50 7c7f",
- "m c7a0 c7ef",
- "m 0000 001b",
- "m de00 de02",
- "m df01 df08",
- "x",
- "m 0400 047f",
- "m d800 d87f",
- "m c7a0 c7ef",
- "m 0000 001b",
- "m de00 de02",
- "m df01 df08",
- "x",
- "m c7a0 c7ef",
- "m 0000 001b",
- "m de00 de02",
- "m df01 df08",
- "x",
- "m c7a0 c7ef",
- "m 0000 001b",
- "m de00 de02",
- "m df01 df08",
- "x",
- "m c7a0 c7ef",
- "m 0000 001b",
- "m de00 de02",
- "m df01 df08",
- "x",
- "m c7a0 c7ef",
- "m 0000 001b",
+ "m cb20 cb6f",
+ "m cb60 cb83",
"m de00 de02",
"m df01 df08",
"x",
])
lines.extend([
+ # Launcher C entry. Resume until the first UI key wait, after schema
+ # initialization, embedded preload publication, and the initial draw.
"m 1000 101f",
- "m c7a0 c7ef",
- "m c600 c9ff",
- "m de00 de02",
- "m df01 df08",
"x",
"m 0400 047f",
"m d800 d87f",
- "m c7a0 c7ef",
- "m c700 c700",
- "m c836 c839",
+ "m 1000 101f",
+ "m cb20 cb6f",
+ "m c800 c9ff",
"m de00 de02",
"m df01 df08",
"q",
@@ -319,35 +207,64 @@ def verify_preload_diagnostics(dumps: Dict[int, bytes], layout: Dict[str, object
)
return
- # Current boot ROM no longer writes the transient EFV checksum block at
- # $CA00. Fall back to the persistent preload state that survives into the
- # launcher handoff: REU init magic, app bitmap, overlay cache metadata, and
- # boot-stage debug markers up through V(erify).
- if 0xC700 not in dumps:
- fail("missing REU magic memory dump at $C700")
- if 0xC836 not in dumps:
- fail("missing launcher bitmap memory dump at $C836")
- if 0xC760 not in dumps:
- fail("missing ReadyShell overlay metadata dump at $C760")
- if 0xC7A0 not in dumps:
- fail("missing launcher debug ring dump at $C7A0")
-
- bitmap = expected_bitmap(layout)
- check_prefix(dumps[0xC700], bytes([0xA5]), "REU magic")
- check_prefix(dumps[0xC836], bitmap, "app preload bitmap/storage drive")
- check_prefix(region_bytes(dumps, 0xC760, len(expected_overlay_meta(layout))),
- expected_overlay_meta(layout), "overlay metadata")
- ring = region_bytes(dumps, 0xC7A0, 0x50)
+ # Compact/production loader builds may omit the extended $CA00 diagnostic
+ # records. In that case the loader ring is the preload-stage contract;
+ # full smoke runs independently validate schema v5 from VICE's REU image
+ # after the launcher has initialized it.
+ ring = region_bytes(dumps, 0xCB20, 0x50)
for marker in (b"R", b"L", b"A", b"O", b"M", b"V"):
if not marker_present(ring, marker):
fail(f"preload debug ring missing marker {marker.decode('ascii')}")
+def verify_readyos_schema(dumps: Dict[int, bytes], layout: Dict[str, object]) -> None:
+ schema = region_bytes(dumps, 0x0800, 0x300)
+ if len(schema) != 0x300:
+ fail("missing ReadyOS-bank schema dump at $0800-$0AFF")
+ check_prefix(schema, b"RCB5\x05", "ReadyOS-bank schema header")
+ readyos_bank = int(layout["reu_bank_skip"]) & 0xFF
+ if schema[9] != readyos_bank or schema[10] != readyos_bank:
+ fail("ReadyOS/launcher physical bank header fields do not name Skip")
+ if schema[0x40 + readyos_bank] != 7:
+ fail("ReadyOS physical bank is not marked REU_GLOBAL")
+ for entry in layout["apps"]:
+ token = int(entry["bank"])
+ physical = int(entry["reu_bank"])
+ if schema[0x140 + token] != physical:
+ fail(f"token {token} maps to {schema[0x140 + token]}, expected {physical}")
+ if schema[0x240 + token] & 0x07 != 0x07:
+ fail(f"token {token} is not valid, loaded, and resumable")
+
+
+def verify_readyos_schema_image(path: Path, layout: Dict[str, object]) -> None:
+ if not path.exists():
+ fail(f"missing VICE REU image: {path}")
+ readyos_bank = int(layout["reu_bank_skip"]) & 0xFF
+ raw = path.read_bytes()
+ start = readyos_bank * 0x10000 + 0xB600
+ schema = raw[start:start + 0x300]
+ if len(schema) != 0x300:
+ fail("VICE REU image is too short for the ReadyOS-bank schema")
+ check_prefix(schema, b"RCB5\x05", "ReadyOS-bank schema header")
+ if schema[9] != readyos_bank or schema[10] != readyos_bank:
+ fail("ReadyOS/launcher physical bank header fields do not name Skip")
+ if schema[0x40 + readyos_bank] != 7:
+ fail("ReadyOS physical bank is not marked REU_GLOBAL")
+ for entry in layout["apps"]:
+ token = int(entry["bank"])
+ physical = int(entry["reu_bank"])
+ if schema[0x140 + token] != physical:
+ fail(f"token {token} maps to {schema[0x140 + token]}, expected {physical}")
+ if schema[0x240 + token] & 0x07 != 0x07:
+ fail(f"token {token} is not valid, loaded, and resumable")
+
+
def verify_log(output_dir: Path,
layout_path: Path,
log_path: Path,
vice_rc: int,
launcher_map_path: Path,
+ reu_image_path: Path | None = None,
verify_preload: bool = False,
preload_only: bool = False) -> None:
crt_path = output_dir / "readyos_easyflash.crt"
@@ -371,7 +288,6 @@ def verify_log(output_dir: Path,
return
launcher_prefix = payload_bytes_from_prg(BIN_DIR / "launcher_easyflash.prg")[:32]
- bitmap = expected_bitmap(layout)
main_addr = symbol_value_from_map(launcher_map_path, "_main")
keyloop_addr = symbol_value_from_map(launcher_map_path, "_tui_getkey")
@@ -384,21 +300,14 @@ def verify_log(output_dir: Path,
fail("missing launcher memory dump at $1000")
if 0x0400 not in dumps:
fail("missing launcher screen dump at $0400")
- if 0xC7A0 not in dumps:
- fail("missing launcher debug ring dump at $C7A0")
- if 0xC700 not in dumps:
- fail("missing REU magic memory dump at $C700")
- if 0xC836 not in dumps:
- fail("missing launcher bitmap memory dump at $C836")
- if 0xC760 not in dumps:
- fail("missing ReadyShell overlay metadata dump at $C760")
+ if 0xCB20 not in dumps:
+ fail("missing EasyFlash loader debug ring dump at $CB20")
check_prefix(region_bytes(dumps, 0x1000, len(launcher_prefix)), launcher_prefix, "launcher RAM prefix")
- check_prefix(dumps[0xC700], bytes([0xA5]), "REU magic")
- check_prefix(dumps[0xC836], bitmap, "app preload bitmap/storage drive")
- check_prefix(region_bytes(dumps, 0xC760, len(expected_overlay_meta(layout))),
- expected_overlay_meta(layout), "overlay metadata")
- ring = region_bytes(dumps, 0xC7A0, 0x50)
+ if reu_image_path is None:
+ fail("full EasyFlash smoke verification requires --reu-image")
+ verify_readyos_schema_image(reu_image_path, layout)
+ ring = region_bytes(dumps, 0xCB20, 0x50)
for marker in (b"R", b"L", b"A", b"O", b"M", b"V", b"T", b"J", b"K"):
if not marker_present(ring, marker):
fail(f"launcher debug ring missing marker {marker.decode('ascii')}")
@@ -408,8 +317,7 @@ def verify_log(output_dir: Path,
print("easyflash smoke passed")
print(f" launcher main breakpoint: ${main_addr:04X}")
print(f" launcher key-loop breakpoint: ${keyloop_addr:04X}")
- print(f" preload bitmap: {bitmap[:3].hex(' ')}")
- print(f" storage drive: {bitmap[3]}")
+ print(" ReadyOS bank: schema v5 and explicit token mappings verified")
if vice_rc != 0:
print(f" note: VICE exited with rc={vice_rc}, but the monitor log verified successfully")
@@ -429,6 +337,7 @@ def main() -> int:
verify_parser.add_argument("--layout", required=True)
verify_parser.add_argument("--log", required=True)
verify_parser.add_argument("--launcher-map", required=True)
+ verify_parser.add_argument("--reu-image")
verify_parser.add_argument("--vice-rc", type=int, default=0)
verify_parser.add_argument("--verify-preload", action="store_true")
verify_parser.add_argument("--preload-only", action="store_true")
@@ -450,6 +359,7 @@ def main() -> int:
layout_path=Path(args.layout),
log_path=Path(args.log),
launcher_map_path=Path(args.launcher_map),
+ reu_image_path=Path(args.reu_image) if args.reu_image else None,
vice_rc=args.vice_rc,
verify_preload=bool(args.verify_preload),
preload_only=bool(args.preload_only),
diff --git a/build_support/vice_readybasic_repeat_label_probe.sh b/build_support/vice_readybasic_repeat_label_probe.sh
index aace53c..a583d83 100755
--- a/build_support/vice_readybasic_repeat_label_probe.sh
+++ b/build_support/vice_readybasic_repeat_label_probe.sh
@@ -41,6 +41,8 @@ PY
}
cd "$ROOT"
+PUBLIC_VERSION_TEXT="$(python3 build_support/update_build_version.py --current)"
+PUBLIC_VERSION="${PUBLIC_VERSION_TEXT%[A-Z]}"
if [ "${READYBASIC_SKIP_BUILD:-0}" != "1" ]; then
RUN_VERSION_TEXT="$(python3 build_support/update_build_version.py --next)"
make -B \
@@ -51,8 +53,8 @@ if [ "${READYBASIC_SKIP_BUILD:-0}" != "1" ]; then
profile
fi
-D81_REL="$(ls -t Releases/0.2.4/precog-d81/*.d81 | head -1)"
-PREBOOT_REL="$(ls -t Releases/0.2.4/precog-d81/*-preboot.prg | head -1)"
+D81_REL="$(ls -t Releases/$PUBLIC_VERSION/precog-d81/*.d81 | head -1)"
+PREBOOT_REL="$(ls -t Releases/$PUBLIC_VERSION/precog-d81/*-preboot.prg | head -1)"
D81="$D81_REL"
PREBOOT="$PREBOOT_REL"
diff --git a/cfg/easyflash_shim.cfg b/cfg/easyflash_shim.cfg
index 55f3cc9..cae5d66 100644
--- a/cfg/easyflash_shim.cfg
+++ b/cfg/easyflash_shim.cfg
@@ -1,6 +1,6 @@
MEMORY {
ZP: file = "", start = $0002, size = $001A, type = rw, define = yes;
- SHIM: file = %O, start = $C800, size = $0200, type = ro, fill = yes, fillval = $FF;
+ SHIM: file = %O, start = $C600, size = $0400, type = ro, fill = yes, fillval = $FF;
}
SEGMENTS {
diff --git a/cfg/profiles/precog-d81-rsdebug.json b/cfg/profiles/precog-d81-rsdebug.json
index aa37b79..b538383 100644
--- a/cfg/profiles/precog-d81-rsdebug.json
+++ b/cfg/profiles/precog-d81-rsdebug.json
@@ -56,6 +56,32 @@
{ "artifact": "obj/rscopy.prg", "name": "rscopy", "type": "prg" },
{ "artifact": "obj/rsedit.prg", "name": "rsedit", "type": "prg" },
{ "artifact": "obj/rbtest1.prg", "name": "rbtest1", "type": "prg" },
+ { "artifact": "obj/rbgfx01_modes.prg", "name": "rbgfx01", "type": "prg" },
+ { "artifact": "obj/rbgfx02_hires_plot.prg", "name": "rbgfx02", "type": "prg" },
+ { "artifact": "obj/rbgfx03_hires_lines.prg", "name": "rbgfx03", "type": "prg" },
+ { "artifact": "obj/rbgfx04_rects.prg", "name": "rbgfx04", "type": "prg" },
+ { "artifact": "obj/rbgfx05_point_read.prg", "name": "rbgfx05", "type": "prg" },
+ { "artifact": "obj/rbgfx06_reu_surface.prg", "name": "rbgfx06", "type": "prg" },
+ { "artifact": "obj/rbgfx07_mbitmap.prg", "name": "rbgfx07", "type": "prg" },
+ { "artifact": "obj/rbgfx08_tile.prg", "name": "rbgfx08", "type": "prg" },
+ { "artifact": "obj/rbgfx09_sprites.prg", "name": "rbgfx09", "type": "prg" },
+ { "artifact": "obj/rbgfx10_collision.prg", "name": "rbgfx10", "type": "prg" },
+ { "artifact": "obj/rbgfx11_input.prg", "name": "rbgfx11", "type": "prg" },
+ { "artifact": "obj/rbgfx12_showcase.prg", "name": "rbgfx12", "type": "prg" },
+ { "artifact": "obj/rbgfx13_sprite_steps.prg", "name": "rbgfx13", "type": "prg" },
+ { "artifact": "obj/rbgfx14_phase2_prims.prg", "name": "rbgfx14", "type": "prg" },
+ { "artifact": "obj/rbgfx15_phase2_tiles.prg", "name": "rbgfx15", "type": "prg" },
+ { "artifact": "obj/rbgfx16_phase2_sprite_ctrl.prg", "name": "rbgfx16", "type": "prg" },
+ { "artifact": "obj/rbgfx17_poly_array.prg", "name": "rbgfx17", "type": "prg" },
+ { "artifact": "obj/rbgfx18_fpoly_array.prg", "name": "rbgfx18", "type": "prg" },
+ { "artifact": "obj/rbgfx19_poly_reu.prg", "name": "rbgfx19", "type": "prg" },
+ { "artifact": "obj/rbgfx20_fpoly_reu_showcase.prg", "name": "rbgfx20", "type": "prg" },
+ { "artifact": "obj/rbsnd01_sid_basics.prg", "name": "rbsnd01", "type": "prg" },
+ { "artifact": "obj/rbsnd02_voice_state.prg", "name": "rbsnd02", "type": "prg" },
+ { "artifact": "obj/rbsnd03_notes.prg", "name": "rbsnd03", "type": "prg" },
+ { "artifact": "obj/rbsnd04_filter.prg", "name": "rbsnd04", "type": "prg" },
+ { "artifact": "obj/rbsnd05_voice_batch.prg", "name": "rbsnd05", "type": "prg" },
+ { "artifact": "obj/rbsnd06_three_voice.prg", "name": "rbsnd06", "type": "prg" },
{ "artifact": "obj/apps_cfg_petscii.seq", "name": "apps.cfg", "type": "seq" },
{ "artifact": "obj/app_sidetris.seq", "name": "app.sidetris", "type": "seq" }
],
diff --git a/cfg/profiles/precog-d81.ini b/cfg/profiles/precog-d81.ini
index ad09713..bf83c9b 100644
--- a/cfg/profiles/precog-d81.ini
+++ b/cfg/profiles/precog-d81.ini
@@ -6,6 +6,7 @@ reu_bank_skip=32
[launcher]
load_all_to_reu=0
runappfirst=
+c64u_image_path=/usb1/readyos.d81
[apps]
8:editor:editor:1
diff --git a/cfg/profiles/precog-d81.json b/cfg/profiles/precog-d81.json
index 439af72..9b1ff65 100644
--- a/cfg/profiles/precog-d81.json
+++ b/cfg/profiles/precog-d81.json
@@ -57,6 +57,44 @@
{ "artifact": "obj/rbtest1.prg", "name": "rbtest1", "type": "prg" },
{ "artifact": "obj/rbproc1.prg", "name": "rbproc1", "type": "prg" },
{ "artifact": "obj/rbprocerr.prg", "name": "rbprocerr", "type": "prg" },
+ { "artifact": "obj/rbgfx01_modes.prg", "name": "rbgfx01", "type": "prg" },
+ { "artifact": "obj/rbgfx02_hires_plot.prg", "name": "rbgfx02", "type": "prg" },
+ { "artifact": "obj/rbgfx03_hires_lines.prg", "name": "rbgfx03", "type": "prg" },
+ { "artifact": "obj/rbgfx04_rects.prg", "name": "rbgfx04", "type": "prg" },
+ { "artifact": "obj/rbgfx05_point_read.prg", "name": "rbgfx05", "type": "prg" },
+ { "artifact": "obj/rbgfx06_reu_surface.prg", "name": "rbgfx06", "type": "prg" },
+ { "artifact": "obj/rbgfx07_mbitmap.prg", "name": "rbgfx07", "type": "prg" },
+ { "artifact": "obj/rbgfx08_tile.prg", "name": "rbgfx08", "type": "prg" },
+ { "artifact": "obj/rbgfx09_sprites.prg", "name": "rbgfx09", "type": "prg" },
+ { "artifact": "obj/rbgfx10_collision.prg", "name": "rbgfx10", "type": "prg" },
+ { "artifact": "obj/rbgfx11_input.prg", "name": "rbgfx11", "type": "prg" },
+ { "artifact": "obj/rbgfx12_showcase.prg", "name": "rbgfx12", "type": "prg" },
+ { "artifact": "obj/rbgfx13_sprite_steps.prg", "name": "rbgfx13", "type": "prg" },
+ { "artifact": "obj/rbgfx14_phase2_prims.prg", "name": "rbgfx14", "type": "prg" },
+ { "artifact": "obj/rbgfx15_phase2_tiles.prg", "name": "rbgfx15", "type": "prg" },
+ { "artifact": "obj/rbgfx16_phase2_sprite_ctrl.prg", "name": "rbgfx16", "type": "prg" },
+ { "artifact": "obj/rbgfx17_poly_array.prg", "name": "rbgfx17", "type": "prg" },
+ { "artifact": "obj/rbgfx18_fpoly_array.prg", "name": "rbgfx18", "type": "prg" },
+ { "artifact": "obj/rbgfx19_poly_reu.prg", "name": "rbgfx19", "type": "prg" },
+ { "artifact": "obj/rbgfx20_fpoly_reu_showcase.prg", "name": "rbgfx20", "type": "prg" },
+ { "artifact": "obj/rbgfx21_mbitmap_prims.prg", "name": "rbgfx21", "type": "prg" },
+ { "artifact": "obj/rbgfx22_mbitmap_point.prg", "name": "rbgfx22", "type": "prg" },
+ { "artifact": "obj/rbgfx23_dlist.prg", "name": "rbgfx23", "type": "prg" },
+ { "artifact": "obj/rbgfx24_tilemap.prg", "name": "rbgfx24", "type": "prg" },
+ { "artifact": "obj/rbgfx25_mbcells.prg", "name": "rbgfx25", "type": "prg" },
+ { "artifact": "obj/rbgfx26_mode_matrix.prg", "name": "rbgfx26", "type": "prg" },
+ { "artifact": "obj/rbgfx27_target_blit.prg", "name": "rbgfx27", "type": "prg" },
+ { "artifact": "obj/rbgfx28_tile_visible.prg", "name": "rbgfx28", "type": "prg" },
+ { "artifact": "obj/rbgfx29_mtile_visible.prg", "name": "rbgfx29", "type": "prg" },
+ { "artifact": "obj/rbgfx30_mbitmap_dlist.prg", "name": "rbgfx30", "type": "prg" },
+ { "artifact": "obj/rbgfx31_sync_blit.prg", "name": "rbgfx31", "type": "prg" },
+ { "artifact": "obj/rbgfx32_convex_poly.prg", "name": "rbgfx32", "type": "prg" },
+ { "artifact": "obj/rbsnd01_sid_basics.prg", "name": "rbsnd01", "type": "prg" },
+ { "artifact": "obj/rbsnd02_voice_state.prg", "name": "rbsnd02", "type": "prg" },
+ { "artifact": "obj/rbsnd03_notes.prg", "name": "rbsnd03", "type": "prg" },
+ { "artifact": "obj/rbsnd04_filter.prg", "name": "rbsnd04", "type": "prg" },
+ { "artifact": "obj/rbsnd05_voice_batch.prg", "name": "rbsnd05", "type": "prg" },
+ { "artifact": "obj/rbsnd06_three_voice.prg", "name": "rbsnd06", "type": "prg" },
{ "artifact": "obj/apps_cfg_petscii.seq", "name": "apps.cfg", "type": "seq" },
{ "artifact": "obj/app_sidetris.seq", "name": "app.sidetris", "type": "seq" }
],
diff --git a/cfg/profiles/precog-dual-d71.ini b/cfg/profiles/precog-dual-d71.ini
index 8e44056..0b9f127 100644
--- a/cfg/profiles/precog-dual-d71.ini
+++ b/cfg/profiles/precog-dual-d71.ini
@@ -57,6 +57,3 @@ fizzy inspired kanban app
9:readyirc:readyirc
ultimate tcp irc client
-
-9:ucitest:uci tester
-ultimate command interface lab
diff --git a/cfg/profiles/precog-kung-fu-flash-2-d81.json b/cfg/profiles/precog-kung-fu-flash-2-d81.json
index 3f997cf..cca2480 100644
--- a/cfg/profiles/precog-kung-fu-flash-2-d81.json
+++ b/cfg/profiles/precog-kung-fu-flash-2-d81.json
@@ -59,6 +59,44 @@
{ "artifact": "obj/rbtest1.prg", "name": "rbtest1", "type": "prg" },
{ "artifact": "obj/rbproc1.prg", "name": "rbproc1", "type": "prg" },
{ "artifact": "obj/rbprocerr.prg", "name": "rbprocerr", "type": "prg" },
+ { "artifact": "obj/rbgfx01_modes.prg", "name": "rbgfx01", "type": "prg" },
+ { "artifact": "obj/rbgfx02_hires_plot.prg", "name": "rbgfx02", "type": "prg" },
+ { "artifact": "obj/rbgfx03_hires_lines.prg", "name": "rbgfx03", "type": "prg" },
+ { "artifact": "obj/rbgfx04_rects.prg", "name": "rbgfx04", "type": "prg" },
+ { "artifact": "obj/rbgfx05_point_read.prg", "name": "rbgfx05", "type": "prg" },
+ { "artifact": "obj/rbgfx06_reu_surface.prg", "name": "rbgfx06", "type": "prg" },
+ { "artifact": "obj/rbgfx07_mbitmap.prg", "name": "rbgfx07", "type": "prg" },
+ { "artifact": "obj/rbgfx08_tile.prg", "name": "rbgfx08", "type": "prg" },
+ { "artifact": "obj/rbgfx09_sprites.prg", "name": "rbgfx09", "type": "prg" },
+ { "artifact": "obj/rbgfx10_collision.prg", "name": "rbgfx10", "type": "prg" },
+ { "artifact": "obj/rbgfx11_input.prg", "name": "rbgfx11", "type": "prg" },
+ { "artifact": "obj/rbgfx12_showcase.prg", "name": "rbgfx12", "type": "prg" },
+ { "artifact": "obj/rbgfx13_sprite_steps.prg", "name": "rbgfx13", "type": "prg" },
+ { "artifact": "obj/rbgfx14_phase2_prims.prg", "name": "rbgfx14", "type": "prg" },
+ { "artifact": "obj/rbgfx15_phase2_tiles.prg", "name": "rbgfx15", "type": "prg" },
+ { "artifact": "obj/rbgfx16_phase2_sprite_ctrl.prg", "name": "rbgfx16", "type": "prg" },
+ { "artifact": "obj/rbgfx17_poly_array.prg", "name": "rbgfx17", "type": "prg" },
+ { "artifact": "obj/rbgfx18_fpoly_array.prg", "name": "rbgfx18", "type": "prg" },
+ { "artifact": "obj/rbgfx19_poly_reu.prg", "name": "rbgfx19", "type": "prg" },
+ { "artifact": "obj/rbgfx20_fpoly_reu_showcase.prg", "name": "rbgfx20", "type": "prg" },
+ { "artifact": "obj/rbgfx21_mbitmap_prims.prg", "name": "rbgfx21", "type": "prg" },
+ { "artifact": "obj/rbgfx22_mbitmap_point.prg", "name": "rbgfx22", "type": "prg" },
+ { "artifact": "obj/rbgfx23_dlist.prg", "name": "rbgfx23", "type": "prg" },
+ { "artifact": "obj/rbgfx24_tilemap.prg", "name": "rbgfx24", "type": "prg" },
+ { "artifact": "obj/rbgfx25_mbcells.prg", "name": "rbgfx25", "type": "prg" },
+ { "artifact": "obj/rbgfx26_mode_matrix.prg", "name": "rbgfx26", "type": "prg" },
+ { "artifact": "obj/rbgfx27_target_blit.prg", "name": "rbgfx27", "type": "prg" },
+ { "artifact": "obj/rbgfx28_tile_visible.prg", "name": "rbgfx28", "type": "prg" },
+ { "artifact": "obj/rbgfx29_mtile_visible.prg", "name": "rbgfx29", "type": "prg" },
+ { "artifact": "obj/rbgfx30_mbitmap_dlist.prg", "name": "rbgfx30", "type": "prg" },
+ { "artifact": "obj/rbgfx31_sync_blit.prg", "name": "rbgfx31", "type": "prg" },
+ { "artifact": "obj/rbgfx32_convex_poly.prg", "name": "rbgfx32", "type": "prg" },
+ { "artifact": "obj/rbsnd01_sid_basics.prg", "name": "rbsnd01", "type": "prg" },
+ { "artifact": "obj/rbsnd02_voice_state.prg", "name": "rbsnd02", "type": "prg" },
+ { "artifact": "obj/rbsnd03_notes.prg", "name": "rbsnd03", "type": "prg" },
+ { "artifact": "obj/rbsnd04_filter.prg", "name": "rbsnd04", "type": "prg" },
+ { "artifact": "obj/rbsnd05_voice_batch.prg", "name": "rbsnd05", "type": "prg" },
+ { "artifact": "obj/rbsnd06_three_voice.prg", "name": "rbsnd06", "type": "prg" },
{ "artifact": "obj/apps_cfg_petscii.seq", "name": "apps.cfg", "type": "seq" },
{ "artifact": "obj/app_sidetris.seq", "name": "app.sidetris", "type": "seq" }
],
diff --git a/cfg/profiles/precog-solo-d64-c.json b/cfg/profiles/precog-solo-d64-c.json
index b5d3594..a57dbe5 100644
--- a/cfg/profiles/precog-solo-d64-c.json
+++ b/cfg/profiles/precog-solo-d64-c.json
@@ -18,7 +18,6 @@
"true_drive": true,
"contents": [
{ "artifact": "preboot.prg", "name": "preboot", "type": "prg" },
- { "artifact": "showcfg.prg", "name": "showcfg", "type": "prg" },
{ "artifact": "boot.prg", "name": "boot", "type": "prg" },
{ "artifact": "launcher.prg", "name": "launcher", "type": "prg" },
{ "artifact": "tasklist.prg", "name": "tasklist", "type": "prg" },
diff --git a/cfg/ready_app.cfg b/cfg/ready_app.cfg
index 4bc3980..a9d7897 100644
--- a/cfg/ready_app.cfg
+++ b/cfg/ready_app.cfg
@@ -1,6 +1,7 @@
# Linker configuration for Ready OS Applications
# Runtime window is $1000-$C5FF ($B600 = 46,592 bytes).
-# $C600-$C7FF is reserved for REU metadata, $C800-$C9FF for shim.
+# ReadyOS metadata is authoritative in the ReadyOS REU bank. The complete
+# resident shim area occupies $C600-$C9FF; its public ABI remains at $C800.
SYMBOLS {
__LOADADDR__: type = import;
diff --git a/cfg/ready_app_overlay.cfg b/cfg/ready_app_overlay.cfg
index 26fac25..8d591e2 100644
--- a/cfg/ready_app_overlay.cfg
+++ b/cfg/ready_app_overlay.cfg
@@ -1,5 +1,6 @@
# Linker configuration for Ready OS overlay-capable apps.
-# Runtime window is $1000-$C5FF. Overlays execute in a carved-out window below $C600.
+# The ReadyOS snapshot and ReadyShell's proven overlay ABI both end at $C5FF.
+# The $C600-$C9FF resident shim area is never overlay payload.
SYMBOLS {
__LOADADDR__: type = import;
diff --git a/cfg/ready_app_readybasic.cfg b/cfg/ready_app_readybasic.cfg
index 9c7d772..6ffad49 100644
--- a/cfg/ready_app_readybasic.cfg
+++ b/cfg/ready_app_readybasic.cfg
@@ -5,6 +5,13 @@
# seed image lives in cold-load regions beginning at $2B00. BASIC owns
# $2AC1-$9FFF. Hidden helpers, shared buffers, and the bridge stay outside that
# BASIC workspace.
+#
+# This file and readybasic.s form one assembler/linker ABI: the file-backed
+# seed regions must contain every run-at-$A000-$C5FF segment in the order the
+# startup copier expects. The static ReadyBASIC plugin verifier enforces the
+# slot, bridge, shared-frame, compact-PRG, and REU relocation shape. Do not
+# substitute the generic ReadyOS app config. $C600-$C9FF is the resident shim
+# area and remains outside this custom image.
MEMORY {
LOADADDR: file = %O, start = $0FFE, size = $0002;
@@ -14,12 +21,19 @@ MEMORY {
SLOT0: file = "", start = $A800, size = $0800, type = rw, define = yes;
SLOT1: file = "", start = $B000, size = $0800, type = rw, define = yes;
SLOT2: file = "", start = $B800, size = $0800, type = rw, define = yes;
+ SLOT2OVL1:file = "", start = $B800, size = $0800, type = rw, define = yes;
+ SLOT2OVL2:file = "", start = $B800, size = $0800, type = rw, define = yes;
+ SLOT2OVL3:file = "", start = $B800, size = $0800, type = rw, define = yes;
+ SLOT2OVL4:file = "", start = $B800, size = $0800, type = rw, define = yes;
+ SLOT2OVL5:file = "", start = $B800, size = $0800, type = rw, define = yes;
+ SLOT2OVL6:file = "", start = $B800, size = $0800, type = rw, define = yes;
SPAN12: file = "", start = $B000, size = $1000, type = rw, define = yes;
SHARED: file = "", start = $C200, size = $0400, type = rw, define = yes;
CMDPACK: file = %O, start = $2B00, size = $1500, type = ro, define = yes, fill = yes;
HIDLOAD: file = %O, start = $4000, size = $0800, type = ro, define = yes, fill = yes;
BRLOAD: file = %O, start = $4800, size = $0800, type = ro, define = yes, fill = yes;
REGSEED: file = %O, start = $5000, size = $1200, type = ro, define = yes, fill = yes;
+ CMDPACK2: file = %O, start = $6200, size = $1E00, type = ro, define = yes, fill = yes;
HIDDEN: file = "", start = $A000, size = $0800, type = ro;
BRIDGE: file = "", start = $C000, size = $0600, type = rw;
}
@@ -33,8 +47,12 @@ SEGMENTS {
SLOTPACK1: load = CMDPACK, run = SLOT1, type = ro, define = yes;
SLOTPACK2: load = CMDPACK, run = SLOT2, type = ro, define = yes;
SPANPACK: load = CMDPACK, run = SPAN12, type = ro, define = yes;
- OVL1PACK: load = CMDPACK, run = SLOT2, type = ro, define = yes;
- OVL2PACK: load = CMDPACK, run = SLOT2, type = ro, define = yes;
+ OVL1PACK: load = CMDPACK2, run = SLOT2OVL1, type = ro, define = yes;
+ OVL2PACK: load = CMDPACK2, run = SLOT2OVL2, type = ro, define = yes;
+ OVL3PACK: load = CMDPACK2, run = SLOT2OVL3, type = ro, define = yes;
+ OVL4PACK: load = CMDPACK2, run = SLOT2OVL4, type = ro, define = yes;
+ OVL5PACK: load = CMDPACK2, run = SLOT2OVL5, type = ro, define = yes;
+ OVL6PACK: load = CMDPACK2, run = SLOT2OVL6, type = ro, define = yes;
HIDDEN: load = HIDLOAD, run = HIDDEN, type = ro, define = yes;
BRIDGE: load = BRLOAD, run = BRIDGE, type = rw, define = yes;
REGSEED: load = REGSEED, type = ro;
diff --git a/cfg/ready_app_simplefiles.cfg b/cfg/ready_app_simplefiles.cfg
index d45796a..58ca0cc 100644
--- a/cfg/ready_app_simplefiles.cfg
+++ b/cfg/ready_app_simplefiles.cfg
@@ -1,6 +1,6 @@
# Linker configuration for Simple Files.
# Keeps the standard ReadyOS app window and reserves an explicit C stack
-# below $C600 so BSS cannot grow into the stack area.
+# below $C600 so BSS cannot grow into the stack or resident shim area.
SYMBOLS {
__LOADADDR__: type = import;
diff --git a/docs/DOCUMENTATION_INDEX.html b/docs/DOCUMENTATION_INDEX.html
new file mode 100644
index 0000000..3c78795
--- /dev/null
+++ b/docs/DOCUMENTATION_INDEX.html
@@ -0,0 +1,348 @@
+
+
+
+
+
+
+ DOCUMENTATION_INDEX
+
+
+
+
+CURRENT DOCUMENT Current documentation index, audited against the 0.2.5 development tree on 2026-08-02.
+
+ReadyOS Documentation Index
+This index separates current contracts from historical records. It
+was audited against the 0.2.5 development tree on
+2026-08-02.
+An HTML counterpart is generated as
+DOCUMENTATION_INDEX.html. Every HTML file under
+docs/ and privatedocs/, the root
+completed-phase HTML report, and the three ReadyBASIC HTML guides are
+classified by
+build_support/update_documentation_html_status.py and carry
+a visible CURRENT DOCUMENT or
+PRESERVED SNAPSHOT / DESIGN banner. The classification
+changes presentation only: historical report bodies and measurements are
+not deleted or rewritten into claims about a version they did not
+describe.
+Start Here
+
+../README.md : project
+overview, current SKUs, app catalog, runtime summary, and supported
+build/run entry points.
+ultimate_dos_dma_loading.md :
+opt-in C64 Ultimate DOS DMA loading, fallback behavior, configuration,
+and verification.
+ReadyOS_SHIM_ARCHITECTURE_0.2.5.md :
+current resident-shim and schema-v5 ReadyOS-bank architecture, including
+which state remains resident, which state lives in physical
+Skip, and which copy is authoritative for each
+operation.
+../privatedocs/top_level_md/MEMORY_MAP.md :
+canonical detailed RAM, REU, shim, and per-app memory contract.
+../privatedocs/top_level_md/SHIM_PLAN.md :
+current resident-shim ABI and switching flow (the historical filename is
+retained).
+
+Current Subsystem
+Documentation
+
+Generated Reports
+
+make readyshell-overlay-report refreshes the
+public/private ReadyShell overlay Markdown and HTML reports from maps
+and profile metadata.
+make readybasic-memory-report refreshes the ReadyBASIC
+proportional memory report and diagrams.
+make easyflash-report reports the generated cartridge
+layout.
+python3 build_support/report_app_headroom.py emits
+current per-app segment endpoints and free bytes from
+obj/*.map.
+
+Generated reports are current only for the artifacts in the working
+tree. A dated stability report or an agentworking/ log is
+evidence from that run, not a live architecture contract.
+After changing Markdown/HTML documentation, regenerate current HTML
+counterparts and run:
+python3 build_support/update_documentation_html_status.py
+python3 build_support/sync_shim_documentation.py
+python3 build_support/verify_documentation_contract.py
+python3 build_support/verify_shim_html_source.py
+The documentation-contract verifier checks the current RAM/REU
+statements, the 1 MB SKU bank budget, retained-history supersession
+markers, and the HTML classification. Classification fails if any
+covered HTML document is not explicitly categorized, preventing a new
+report from silently appearing without freshness status. The shim-source
+verifier discovers every HTML <pre> block containing
+the complete resident shim, compares all .byte directives
+with src/boot/readyos_shim.inc, and rejects retired lookup
+annotations.
+Historical Material Policy
+
+Releases/<version>/ documents describe the
+artifacts shipped in that version and are intentionally not rewritten to
+match later source.
+agentworking/, dated stability reports, files
+explicitly named OLD_*, and completed/refactor lessons
+retain their original observations. New notes may mark a claim as
+superseded, but the evidence itself is preserved.
+Current decisions belong in the root README, docs/, the
+canonical private memory/shim documents, or the relevant app’s
+current-design document.
+
+
+
diff --git a/docs/DOCUMENTATION_INDEX.md b/docs/DOCUMENTATION_INDEX.md
new file mode 100644
index 0000000..3f30c3b
--- /dev/null
+++ b/docs/DOCUMENTATION_INDEX.md
@@ -0,0 +1,85 @@
+# ReadyOS Documentation Index
+
+This index separates current contracts from historical records. It was audited
+against the `0.2.5` development tree on 2026-08-02.
+
+An HTML counterpart is generated as `DOCUMENTATION_INDEX.html`. Every HTML file
+under `docs/` and `privatedocs/`, the root completed-phase HTML report, and the
+three ReadyBASIC HTML guides are classified by
+`build_support/update_documentation_html_status.py` and carry a visible
+`CURRENT DOCUMENT` or `PRESERVED SNAPSHOT / DESIGN` banner. The classification
+changes presentation only: historical report bodies and measurements are not
+deleted or rewritten into claims about a version they did not describe.
+
+## Start Here
+
+- [`../README.md`](../README.md): project overview, current SKUs, app catalog,
+ runtime summary, and supported build/run entry points.
+- [`ultimate_dos_dma_loading.md`](ultimate_dos_dma_loading.md): opt-in C64
+ Ultimate DOS DMA loading, fallback behavior, configuration, and verification.
+- [`ReadyOS_SHIM_ARCHITECTURE_0.2.5.md`](ReadyOS_SHIM_ARCHITECTURE_0.2.5.md):
+ current resident-shim and schema-v5 ReadyOS-bank architecture, including which
+ state remains resident, which state lives in physical `Skip`, and which copy is
+ authoritative for each operation.
+- [`../privatedocs/top_level_md/MEMORY_MAP.md`](../privatedocs/top_level_md/MEMORY_MAP.md):
+ canonical detailed RAM, REU, shim, and per-app memory contract.
+- [`../privatedocs/top_level_md/SHIM_PLAN.md`](../privatedocs/top_level_md/SHIM_PLAN.md):
+ current resident-shim ABI and switching flow (the historical filename is
+ retained).
+
+## Current Subsystem Documentation
+
+- ReadyShell: [`ReadyShellArchitecture.md`](ReadyShellArchitecture.md),
+ [`ReadyShellHostTesting.md`](ReadyShellHostTesting.md), and the generated
+ [`readyshell_overlay_inventory.md`](readyshell_overlay_inventory.md).
+- ReadyBASIC: [`../src/apps/readybasic/READYBASIC_CURRENT_DESIGN.md`](../src/apps/readybasic/READYBASIC_CURRENT_DESIGN.md),
+ graphics and sound command designs, lifecycle/REU architecture, module-making
+ guide, and the examples listed in the root README.
+- EasyFlash: [`reports/easyflash_boot_flow.md`](reports/easyflash_boot_flow.md).
+- File formats: the `*_format.md` and `*_seq_format.md` documents in this
+ directory.
+- C64 Ultimate DMA research evidence:
+ [`../ULTIMATEDOS_DMA_LOADING_LESSONS_LEARNT.md`](../ULTIMATEDOS_DMA_LOADING_LESSONS_LEARNT.md)
+ and [`../probes/uci_dma/README.md`](../probes/uci_dma/README.md).
+
+## Generated Reports
+
+- `make readyshell-overlay-report` refreshes the public/private ReadyShell
+ overlay Markdown and HTML reports from maps and profile metadata.
+- `make readybasic-memory-report` refreshes the ReadyBASIC proportional memory
+ report and diagrams.
+- `make easyflash-report` reports the generated cartridge layout.
+- `python3 build_support/report_app_headroom.py` emits current per-app segment
+ endpoints and free bytes from `obj/*.map`.
+
+Generated reports are current only for the artifacts in the working tree. A
+dated stability report or an `agentworking/` log is evidence from that run, not
+a live architecture contract.
+
+After changing Markdown/HTML documentation, regenerate current HTML
+counterparts and run:
+
+```sh
+python3 build_support/update_documentation_html_status.py
+python3 build_support/sync_shim_documentation.py
+python3 build_support/verify_documentation_contract.py
+python3 build_support/verify_shim_html_source.py
+```
+
+The documentation-contract verifier checks the current RAM/REU statements,
+the 1 MB SKU bank budget, retained-history supersession markers, and the HTML
+classification. Classification fails if any covered HTML document is not
+explicitly categorized, preventing a new report from silently appearing
+without freshness status. The shim-source verifier discovers every HTML `` block containing
+the complete resident shim, compares all `.byte` directives with
+`src/boot/readyos_shim.inc`, and rejects retired lookup annotations.
+
+## Historical Material Policy
+
+- `Releases//` documents describe the artifacts shipped in that
+ version and are intentionally not rewritten to match later source.
+- `agentworking/`, dated stability reports, files explicitly named `OLD_*`, and
+ completed/refactor lessons retain their original observations. New notes may
+ mark a claim as superseded, but the evidence itself is preserved.
+- Current decisions belong in the root README, `docs/`, the canonical private
+ memory/shim documents, or the relevant app's current-design document.
diff --git a/docs/ReadyOS SHIM Architecture Report (0.2).html b/docs/ReadyOS SHIM Architecture Report (0.2).html
index 09094b9..a280afc 100644
--- a/docs/ReadyOS SHIM Architecture Report (0.2).html
+++ b/docs/ReadyOS SHIM Architecture Report (0.2).html
@@ -205,6 +205,9 @@
+
+PRESERVED SNAPSHOT / DESIGN Preserved 0.2.4 shim report with its full commented source appendix refreshed and byte-verified against the current shim. ReadyOS_SHIM_ARCHITECTURE_0.2.5.html is the current architecture contract.
+
ReadyOS SHIM Architecture: 0.2.4 Runtime Reality
@@ -221,12 +224,13 @@
ReadyOS SHIM Architecture: 0.2.4 Runtime Reality
+ Current 0.2.5 contract: The full resident shim owns $C600-$C9FF (1024 bytes), with 512 bytes of expansion reserve below the stable ABI at $C800 . Physical Skip is the ReadyOS bank; Skip+1 is the first dynamic bank. The app snapshot is $1000-$C5FF ($B600 ), and schema v5 begins at ReadyOS offset $B600 . Historical 0.2.4 discussion below is retained as version history.
Executive Snapshot
@@ -266,7 +270,7 @@ Canonical C64 RAM Map
@@ -365,7 +369,8 @@
Shim data ABI
$C83A log_index legacy ring head; $C980-$C99F is no longer safe ring storage
$C83B reu_bank_skip compiled physical REU bank offset for the ReadyOS region
$C83C launcher_flags launcher-owned one-shot state flags
-
$C83D-$C83F reserved unused padding
+
$C83D reu_lookup_scratch one-byte physical bank fetched from control bank 0
+
$C83E-$C83F reserved unused padding
$C84D device immediate load_disk launcher-patched drive byte
$C89C device immediate preload launcher-patched drive byte
@@ -383,20 +388,31 @@
Shim data ABI
Annotated Resident Shim Walkthrough
- This is a complete report-local annotation of the resident shim byte image.
- The comments here use the clearer 0.2.4 Start-relative terminology; the
- emitted byte sequence is checked against src/boot/readyos_shim.inc
- and still covers the jump table, every data ABI byte, all live routines,
- and all padding bytes in the 512-byte $C800-$C9FF image.
+ This is a complete commented copy of the current resident shim byte image.
+ The source appendix was refreshed against src/boot/readyos_shim.inc
+ for the 0.2.5 documentation audit. It covers the jump table, every data
+ ABI byte, all live routines, and all padding bytes in the 1024-byte
+ $C600-$C9FF image. The surrounding report remains
+ a preserved 0.2.4 architecture snapshot.
;-----------------------------------------------------------------------------
-; Shared ReadyOS shim image ($C800-$C9FF, 512 bytes)
+; Shared ReadyOS shim image ($C600-$C9FF, 1024 bytes)
; This file is the canonical shim byte layout used by both the disk boot path
; and the EasyFlash cartridge flavor. Keep it identical across all variants.
;-----------------------------------------------------------------------------
;-----------------------------------------------------------------------------
-; Page 1: $C800-$C8FF - Jump table, data, and helper routines
+; Pages 1-2: $C600-$C7FF - reserved resident expansion space
+;-----------------------------------------------------------------------------
+; This space used to contain the C64-RAM REU allocation/metadata mirror. The
+; authoritative state now lives in the ReadyOS REU bank, but the RAM remains
+; resident shim-owned capacity rather than becoming app snapshot memory.
+.ifndef READYOS_SHIM_ABI_ONLY
+.res $0200, $00
+.endif
+
+;-----------------------------------------------------------------------------
+; Page 3: $C800-$C8FF - Jump table, data, and helper routines
;-----------------------------------------------------------------------------
; $C800-$C817: Jump Table (24 bytes, 8 entries)
@@ -406,7 +422,7 @@ Annotated Resident Shim Walkthrough
jt_preload = $C809 ; Preload to REU, return
jt_return = $C80C ; Return to launcher
jt_switch = $C80F ; Switch to another app
-jt_stash_cur = $C812 ; Helper: stash current app
+jt_reserved = $C812 ; Reserved compatibility slot (safe no-op)
jt_fetch_bank = $C815 ; Helper: fetch from bank in A
.byte $4C, $40, $C8 ; $C800: JMP load_disk ($C840)
@@ -415,52 +431,51 @@ Annotated Resident Shim Walkthrough
.byte $4C, $80, $C8 ; $C809: JMP preload ($C880)
.byte $4C, $00, $C9 ; $C80C: JMP return_to_launcher ($C900)
.byte $4C, $40, $C9 ; $C80F: JMP switch_app ($C940)
-.byte $4C, $C0, $C8 ; $C812: JMP stash_current ($C8C0) - placeholder
+.byte $4C, $FF, $C9 ; $C812: reserved helper -> safe RTS
.byte $4C, $F0, $C8 ; $C815: JMP fetch_bank ($C8F0)
-; $C818: JMP log_byte ($C9E0)
-; Legacy diagnostic entry. The old $C980-$C99F ring now overlaps active
-; reu_setup_logical bytes, so callers must not use this unless the ring moves.
-.byte $4C, $E0, $C9 ; $C818: JMP log_byte
-.byte $00,$00,$00,$00,$00 ; $C81B-$C81F: Padding
+; $C818: deprecated logger compatibility slot
+.byte $4C, $FF, $C9 ; $C818: deprecated logger -> safe RTS
+.byte $4C, $C0, $C9 ; $C81B: JMP mark_loaded (token in A)
+.byte $00,$00 ; $C81E-$C81F: reserved
; $C820-$C83F: Data Area (32 bytes)
-; $C820: target_bank - logical bank to load/switch to
+; $C820: target_bank - bank to load/switch to
; $C821: filename_len
-; $C822-$C823: unused
+; $C822-$C823: launcher-side app-size scratch (not consumed by the shim)
; $C824-$C82F: filename (12 bytes)
; $C830: load_end_lo (KERNAL LOAD end addr low byte, saved by preload)
; $C831: load_end_hi (KERNAL LOAD end addr high byte, saved by preload)
; $C832-$C833: unused
-; $C834: current_bank - currently running logical bank
+; $C834: current_bank - currently running app
; $C835: last_saved
-; $C836: reu_bitmap_lo (logical banks 0-7)
-; $C837: reu_bitmap_hi (logical banks 8-15)
-; $C838: reu_bitmap_xhi (logical banks 16-23)
+; $C836-$C838: retired bitmap bytes (reserved; authoritative state is in REU)
; $C839: storage_drive - shim-global default storage drive for D8/D9 app dialogs
; This persists across app switches and is shared by apps that use the
; common file-dialog default-drive contract.
-; $C83A: log_index - legacy debug byte ring head
-; $C83B: reu_bank_skip - physical 64K banks reserved before ReadyOS bank start
- ; $C83C: launcher_flags - launcher-owned one-shot state flags
- ; $C83D-$C83F: reserved
+; $C83A: reserved (formerly log_index)
+; $C83B: readyos_bank - direct physical ReadyOS bank number (Skip)
+; $C83C: launcher_flags - launcher-owned one-shot state flags
+; $C83D: reu_lookup_scratch - one-byte ReadyOS-bank DMA scratch
+; $C83E: token_scratch; $C83F: reserved
.byte $00 ; $C820: target_bank
.byte $08 ; $C821: filename_len
-.byte $00, $00 ; $C822-$C823: unused
-.byte "LAUNCHER " ; $C824-$C82F: filename (12 bytes)
+.byte $00, $00 ; $C822-$C823: launcher app-size scratch
+.byte "LAUNCHER " ; $C824-$C82F: filename (12 bytes)
.byte $00,$00 ; $C830-$C831: load_end_lo, load_end_hi
.byte $00,$00 ; $C832-$C833: unused
.byte $00 ; $C834: current_bank
.byte $FF ; $C835: last_saved
-.byte $00 ; $C836: reu_bitmap_lo
-.byte $00 ; $C837: reu_bitmap_hi
-.byte $00 ; $C838: reu_bitmap_xhi
+.byte $00 ; $C836: reserved (retired bitmap byte)
+.byte $00 ; $C837: reserved (retired bitmap byte)
+.byte $00 ; $C838: reserved (retired bitmap byte)
.byte $08 ; $C839: storage_drive (default drive 8)
-.byte $00 ; $C83A: log_index (legacy debug buffer)
-.byte READYOS_REU_BANK_SKIP ; $C83B: reu_bank_skip (compiled into boot image)
- .byte $00 ; $C83C: launcher_flags
- .byte $00,$00,$00 ; $C83D-$C83F: reserved
+.byte $00 ; $C83A: reserved (retired debug-ring head)
+.byte READYOS_REU_BANK_SKIP ; $C83B: readyos_bank (physical Skip)
+.byte $00 ; $C83C: launcher_flags
+.byte $00 ; $C83D: reu_lookup_scratch
+.byte $00,$00 ; $C83E-$C83F: reserved
;-----------------------------------------------------------------------------
; $C840: load_disk - Load app from disk and run (32 bytes)
@@ -470,13 +485,13 @@ Annotated Resident Shim Walkthrough
.byte $A0, $C8 ; LDY #$C8 (filename at $C824)
.byte $20, $BD, $FF ; JSR $FFBD (SETNAM)
.byte $A9, $00 ; LDA #0
-.byte $A2, $08 ; LDX #8
+.byte $AE, $39, $C8 ; LDX $C839 (storage drive)
.byte $A0, $01 ; LDY #1
.byte $20, $BA, $FF ; JSR $FFBA (SETLFS)
.byte $A9, $00 ; LDA #0
.byte $20, $D5, $FF ; JSR $FFD5 (LOAD)
.byte $4C, $00, $10 ; JMP $1000
-.byte $00,$00,$00,$00,$00 ; Padding to $C860
+.byte $00,$00,$00,$00 ; Padding to $C860
;-----------------------------------------------------------------------------
; $C860: load_reu - Fetch app from REU and run (32 bytes)
@@ -491,30 +506,20 @@ Annotated Resident Shim Walkthrough
;-----------------------------------------------------------------------------
; $C880: preload - Load to REU, return to launcher
; Called via JSR $C809
-; DEBUG: writes markers to $C007-$C00C
;-----------------------------------------------------------------------------
-.byte $A9, $AA ; LDA #$AA (170 = "preload entered")
-.byte $8D, $07, $C0 ; STA $C007
-
-.byte $A9, $00 ; LDA #0 (select launcher bank at Start+1)
+.byte $A9, $00 ; LDA #0 (launcher token -> ReadyOS bank)
.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
-.byte $A9, $BB ; LDA #$BB (187 = "launcher stashed")
-.byte $8D, $08, $C0 ; STA $C008
-
.byte $AD, $21, $C8 ; LDA $C821 (len)
.byte $A2, $24 ; LDX #$24
.byte $A0, $C8 ; LDY #$C8 (filename at $C824)
.byte $20, $BD, $FF ; JSR SETNAM
.byte $A9, $00 ; LDA #0
-.byte $A2, $08 ; LDX #8
+.byte $AE, $39, $C8 ; LDX $C839 (storage drive)
.byte $A0, $01 ; LDY #1
.byte $20, $BA, $FF ; JSR SETLFS
-.byte $A9, $CC ; LDA #$CC (204 = "about to LOAD")
-.byte $8D, $09, $C0 ; STA $C009
-
.byte $A9, $00 ; LDA #0
.byte $20, $D5, $FF ; JSR LOAD
@@ -524,25 +529,23 @@ Annotated Resident Shim Walkthrough
.byte $AD, $20, $C8 ; LDA $C820 (target bank)
.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
-.byte $A9, $EE ; LDA #$EE (238 = "app stashed")
-.byte $8D, $0B, $C0 ; STA $C00B
-
.byte $AD, $20, $C8 ; LDA $C820 (target bank)
-.byte $20, $C0, $C9 ; JSR set_bitmap ($C9C0)
+.byte $20, $C0, $C9 ; JSR mark_loaded ($C9C0)
-.byte $A9, $00 ; LDA #0 (select launcher bank at Start+1)
+.byte $A9, $00 ; LDA #0
.byte $20, $F0, $C8 ; JSR fetch_bank ($C8F0)
-.byte $A9, $FF ; LDA #$FF (255 = "launcher restored")
-.byte $8D, $0C, $C0 ; STA $C00C
-
.byte $60 ; RTS
-.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00
;-----------------------------------------------------------------------------
-; $C8E0: stash_to_bank - Stash $1000-$C5FF to logical REU bank in A (16 bytes)
+; $C8E0: stash_to_bank - Stash $1000-$C5FF to REU bank in A (16 bytes)
;-----------------------------------------------------------------------------
.byte $20, $60, $C9 ; JSR reu_setup_logical ($C960)
.byte $A9, $90 ; LDA #$90 (STASH command)
@@ -551,7 +554,7 @@ Annotated Resident Shim Walkthrough
.byte $00,$00,$00,$00,$00,$00,$00
;-----------------------------------------------------------------------------
-; $C8F0: fetch_bank - Fetch logical REU bank in A to $1000-$C5FF (16 bytes)
+; $C8F0: fetch_bank - Fetch from REU bank in A to $1000-$C5FF (16 bytes)
;-----------------------------------------------------------------------------
.byte $20, $60, $C9 ; JSR reu_setup_logical ($C960)
.byte $A9, $91 ; LDA #$91 (FETCH command)
@@ -560,21 +563,21 @@ Annotated Resident Shim Walkthrough
.byte $00,$00,$00,$00,$00,$00,$00
;-----------------------------------------------------------------------------
-; Page 2: $C900-$C9FF - Main routines
+; Page 4: $C900-$C9FF - Main routines
;-----------------------------------------------------------------------------
;-----------------------------------------------------------------------------
; $C900: return_to_launcher (64 bytes)
;-----------------------------------------------------------------------------
-.byte $AD, $34, $C8 ; LDA $C834 (current logical bank)
+.byte $AD, $34, $C8 ; LDA $C834 (current bank)
.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
-.byte $AD, $34, $C8 ; LDA $C834 (current logical bank)
-.byte $20, $C0, $C9 ; JSR set_bitmap ($C9C0)
+.byte $AD, $34, $C8 ; LDA $C834 (current bank)
+.byte $20, $C0, $C9 ; JSR mark_loaded ($C9C0)
.byte $AD, $34, $C8 ; LDA $C834
.byte $8D, $35, $C8 ; STA $C835
-.byte $A9, $00 ; LDA #0 (select launcher bank at Start+1)
+.byte $A9, $00 ; LDA #0
.byte $20, $F0, $C8 ; JSR fetch_bank ($C8F0)
-.byte $A9, $00 ; LDA #0 (select launcher bank at Start+1)
+.byte $A9, $00 ; LDA #0
.byte $8D, $34, $C8 ; STA $C834
.byte $4C, $00, $10 ; JMP $1000
.byte $00,$00,$00,$00,$00,$00,$00,$00
@@ -586,11 +589,11 @@ Annotated Resident Shim Walkthrough
;-----------------------------------------------------------------------------
; $C940: switch_app (64 bytes)
;-----------------------------------------------------------------------------
-.byte $AD, $34, $C8 ; LDA $C834 (current logical bank)
+.byte $AD, $34, $C8 ; LDA $C834 (current bank)
.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
-.byte $AD, $34, $C8 ; LDA $C834 (current logical bank)
-.byte $20, $C0, $C9 ; JSR set_bitmap ($C9C0)
-.byte $AD, $20, $C8 ; LDA $C820 (target logical bank)
+.byte $AD, $34, $C8 ; LDA $C834 (current bank)
+.byte $20, $C0, $C9 ; JSR mark_loaded ($C9C0)
+.byte $AD, $20, $C8 ; LDA $C820 (target bank)
.byte $20, $F0, $C8 ; JSR fetch_bank ($C8F0)
.byte $AD, $20, $C8 ; LDA $C820
.byte $8D, $34, $C8 ; STA $C834
@@ -598,40 +601,38 @@ Annotated Resident Shim Walkthrough
.byte $00,$00,$00,$00,$00
;-----------------------------------------------------------------------------
-; $C960: reu_setup_logical - Map logical bank to physical, then setup REU regs
-;
-; Current note:
-; this older listing's retired fixed app-slot description has
-; been superseded by logical REU bank 0 token -> physical-bank lookup.
-; See ReadyOSREUPhase1Completed.html for the completed Phase 1 shim contract.
+; $C960: reu_setup_logical - Resolve token via the ReadyOS bank, then setup regs
;-----------------------------------------------------------------------------
-.byte $C9, $00 ; CMP #0 (select launcher bank at Start+1?)
-.byte $D0, $09 ; BNE app_bank
-.byte $AD, $3B, $C8 ; LDA $C83B (reu_bank_skip)
+.byte $C9, $00 ; CMP #0 (logical launcher bank?)
+.byte $D0, $06 ; BNE lookup_app_bank
+.byte $AD, $3B, $C8 ; LDA $C83B (ReadyOS bank contains launcher)
+.byte $4C, $A0, $C9 ; JMP reu_setup ($C9A0)
+.byte $AA ; lookup_app_bank: TAX (preserve logical token)
+.byte $A9, $3D ; LDA #<$C83D
+.byte $8D, $02, $DF ; STA $DF02 (C64 addr lo)
+.byte $A9, $C8 ; LDA #>$C83D
+.byte $8D, $03, $DF ; STA $DF03 (C64 addr hi)
+.byte $8A ; TXA
.byte $18 ; CLC
-.byte $69, $01 ; ADC #$01 (launcher is Start+1)
-.byte $4C, $74, $C9 ; JMP store_physical_bank
-.byte $18 ; app_bank: CLC
-.byte $6D, $3B, $C8 ; ADC $C83B (logical app bank + skip)
-.byte $18 ; CLC
-.byte $69, $01 ; ADC #$01 (global + launcher snapshot only)
-.byte $8D, $06, $DF ; STA $DF06 (physical bank)
-.byte $A9, $00 ; LDA #$00
-.byte $8D, $02, $DF ; STA $DF02 (C64 addr lo = $00)
-.byte $A9, $10 ; LDA #$10
-.byte $8D, $03, $DF ; STA $DF03 (C64 addr hi = $10, so $1000)
-.byte $A9, $00 ; LDA #$00
-.byte $8D, $04, $DF ; STA $DF04 (REU addr lo)
-.byte $8D, $05, $DF ; STA $DF05 (REU addr hi)
-.byte $8D, $07, $DF ; STA $DF07 (len lo = $00)
-.byte $A9, $B6 ; LDA #$B6
-.byte $8D, $08, $DF ; STA $DF08 (len hi = $B6, so $B600 bytes)
-.byte $60 ; RTS
-
-.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+.byte $69, $40 ; ADC #<$B740 (mapping offset + token)
+.byte $8D, $04, $DF ; STA $DF04 (REU offset lo)
+.byte $A9, $B7 ; LDA #>$B740
+.byte $69, $00 ; ADC #0 (include low-byte carry)
+.byte $8D, $05, $DF ; STA $DF05 (REU offset hi)
+.byte $AD, $3B, $C8 ; LDA $C83B (ReadyOS global physical bank)
+.byte $8D, $06, $DF ; STA $DF06
+.byte $A9, $01 ; LDA #1
+.byte $8D, $07, $DF ; STA $DF07 (length lo)
+.byte $A9, $00 ; LDA #0
+.byte $8D, $08, $DF ; STA $DF08 (length hi)
+.byte $A9, $91 ; LDA #$91 (FETCH command)
+.byte $8D, $01, $DF ; STA $DF01 - fetch physical bank byte
+.byte $AD, $3D, $C8 ; LDA $C83D (resolved physical bank)
+.byte $4C, $A0, $C9 ; JMP reu_setup ($C9A0)
+.byte $00,$00 ; Padding to $C9A0
;-----------------------------------------------------------------------------
-; $C9A0: reu_setup - Set up REU registers for a physical bank in A
+; $C9A0: reu_setup - Set up REU registers for $B600 transfer at $1000
;-----------------------------------------------------------------------------
.byte $8D, $06, $DF ; STA $DF06 (bank)
.byte $A9, $00 ; LDA #$00
@@ -648,46 +649,35 @@ Annotated Resident Shim Walkthrough
.byte $00,$00
;-----------------------------------------------------------------------------
-; $C9C0: set_bitmap - Set bit for bank in A in reu_bitmap ($C836-$C838)
+; $C9C0: mark_loaded - Commit token status after a successful snapshot stash
+; A = logical token. Status $07 means valid, loaded, and resumable.
;-----------------------------------------------------------------------------
-.byte $C9, $18 ; CMP #$18 (only logical banks 0-23 are tracked)
-.byte $B0, $17 ; BCS done
-.byte $AA ; TAX - preserve full bank
-.byte $29, $07 ; AND #$07 - bit index within byte
-.byte $A8 ; TAY - Y = bit index
-.byte $8A ; TXA - restore full bank
-.byte $4A ; LSR A
-.byte $4A ; LSR A
-.byte $4A ; LSR A
-.byte $AA ; TAX - X = byte offset 0..2
-.byte $A9, $01 ; LDA #$01
-.byte $88 ; DEY
-.byte $30, $03 ; BMI store_bit
-.byte $0A ; ASL A
-.byte $10, $FA ; BPL shift_loop
-.byte $1D, $36, $C8 ; ORA $C836,X
-.byte $9D, $36, $C8 ; STA $C836,X
-.byte $60 ; RTS
-.byte $00,$00,$00,$00
-
-;-----------------------------------------------------------------------------
-; $C9E0: log_byte - Legacy debug marker writer
-; WARNING: $C980-$C99F now overlaps active reu_setup_logical code bytes.
-; This entry is kept for ABI shape only; do not call it unless the ring moves.
-;-----------------------------------------------------------------------------
-.byte $48 ; PHA - save the byte to log
-.byte $8E, $FC, $00 ; STX $00FC - save X to ZP temp
-.byte $AE, $3A, $C8 ; LDX $C83A - get log_index
-.byte $68 ; PLA - get byte back
-.byte $9D, $80, $C9 ; STA $C980,X - write to buffer
-.byte $E8 ; INX - increment index
-.byte $E0, $20 ; CPX #$20 - wrap at 32
-.byte $D0, $02 ; BNE +2 (skip reset)
-.byte $A2, $00 ; LDX #$00 - reset to 0
-.byte $8E, $3A, $C8 ; STX $C83A - store new index
-.byte $AE, $FC, $00 ; LDX $00FC - restore X
+.byte $8D, $3E, $C8 ; STA $C83E (preserve token)
+.byte $A9, $07 ; LDA #VALID|LOADED|RESUMABLE
+.byte $8D, $3D, $C8 ; STA $C83D
+.byte $A9, $3D ; C64 source = $C83D
+.byte $8D, $02, $DF
+.byte $A9, $C8
+.byte $8D, $03, $DF
+.byte $AD, $3E, $C8 ; token
+.byte $18 ; CLC
+.byte $69, $40 ; + <$B840 (token status table)
+.byte $8D, $04, $DF
+.byte $A9, $B8 ; >$B840
+.byte $69, $00 ; include low-byte carry
+.byte $8D, $05, $DF
+.byte $AD, $3B, $C8 ; ReadyOS physical bank
+.byte $8D, $06, $DF
+.byte $A9, $01 ; one byte
+.byte $8D, $07, $DF
+.byte $A9, $00
+.byte $8D, $08, $DF
+.byte $A9, $90 ; STASH C64 byte to ReadyOS bank
+.byte $8D, $01, $DF
+.byte $AD, $3E, $C8 ; preserve caller-visible token in A
.byte $60 ; RTS
-.byte $00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00 ; reserved through $C9FE
+.byte $60 ; $C9FF: compatibility no-op RTS
diff --git a/docs/ReadyOS_SHIM_ARCHITECTURE_0.2.5.html b/docs/ReadyOS_SHIM_ARCHITECTURE_0.2.5.html
new file mode 100644
index 0000000..7919d29
--- /dev/null
+++ b/docs/ReadyOS_SHIM_ARCHITECTURE_0.2.5.html
@@ -0,0 +1,1079 @@
+
+
+
+
+
+
+
ReadyOS_SHIM_ARCHITECTURE_0.2.5
+
+
+
+
+
CURRENT DOCUMENT Current 0.2.5 schema-v5 shim/ReadyOS-bank architecture, including the resident-versus-REU authority split and live token lookup.
+
+
ReadyOS 0.2.5
+Shim and ReadyOS-Bank Architecture
+
This is the current implementation-backed explanation of the resident
+shim and the combined ReadyOS bank. It was audited against the
+0.2.5 development tree on 2026-08-01.
+
The most important correction to older descriptions is that
+physical Skip is the ReadyOS bank and is the single
+source of truth . It combines the launcher snapshot and
+schema-v5 operating-system state:
+
C64 RAM
+$1000 $C5FF $C600 $C9FF
+|<--------------- active app snapshot: $B600 bytes -------------->|<-- 1 KB shim ------>|
+
+ReadyOS physical REU region
+Skip (ReadyOS bank) Skip+1 ... detected end
+| launcher $0000-$B5FF | dynamic app/resource pool |
+| schema v5 $B600-$FFFF | explicit token mappings |
+
The configured skip is compiled into the build; resident shim byte
+$C83B stores the direct physical ReadyOS bank number
+(Skip).
+
What Changed
+
The older shim calculated every app snapshot’s physical bank from a
+fixed layout. A nonzero logical app bank N was tied to a
+reserved physical slot after the global, launcher, and launcher-overlay
+reservations. That made the resident shim depend on a fixed block of app
+slots and prevented the allocator from using the REU as one flexible
+pool.
+
The current implementation makes these changes:
+
+Physical Skip is the ReadyOS bank. It is skipped by the
+dynamic allocator, but it is not unused.
+Physical Skip+1 is the first dynamic app/resource
+bank.
+Token 0 resolves directly to the ReadyOS bank; its
+first $B600 bytes are the launcher snapshot.
+Schema-v5 state occupies the same ReadyOS bank at
+$B600-$FFFF, including bank types, token mappings/status,
+clipboard metadata, hotkeys, settings, app/resource records, catalog
+text, audit data, and launcher runtime state.
+For a nonzero token, the shim fetches one byte from
+ReadyOS:$B740 + token. That byte is the physical snapshot
+bank to use.
+The old $C600-$C7FF allocation/clipboard/hotkey mirrors
+and the three-byte loaded bitmap are retired; $C600-$C7FF
+remains resident as contiguous shim expansion capacity rather than
+becoming app RAM.
+The snapshot is $1000-$C5FF ($B600 bytes),
+leaving a $4A00 per-app resume tail at REU offsets
+$B600-$FFFF.
+The full shim region is restored to 1 KB at
+$C600-$C9FF; the stable 512-byte ABI and entry addresses
+remain at $C800-$C9FF. $C81B is the
+mark_loaded entry; $C818 is a safe deprecated
+RTS target.
+
+
Mappings are explicitly allocated and published. No app or shim path
+may infer a physical bank from a logical token arithmetically.
+
Version-history
+clarification
+
The earlier 0.2.5 design used a separate control bank at
+Skip and launcher bank at Skip+1. Schema v5
+deliberately supersedes that split while preserving the established
+transition entry points in the upper 512-byte ABI. Ultimate DOS DMA
+remains launcher-side cold-load transport and publishes the same
+explicit mappings as the KERNAL path.
+
The State Was Split, Not
+Simply Moved
+
Only values required while $1000-$C5FF is being
+overwritten remain resident. All scalable state is authoritative in the
+ReadyOS bank.
+
+
+
+
+
+
+
+
+State
+Current location
+Operational role / authority
+
+
+
+
+transition target, current token, last-saved hint, bank skip, drive,
+flags
+shim $C820-$C83F
+resident transition state; available while app RAM is replaced
+
+
+$C836-$C838, $C83A
+resident reserved bytes
+retired bitmap/log-index storage; never authoritative
+
+
+active physical bank allocation types
+ReadyOS $B640-$B73F
+allocator authority used through direct byte/block DMA helpers
+
+
+token-to-physical mapping
+ReadyOS $B740-$B83F
+live source read by shim, launcher, apps, and tools
+
+
+token validity/loaded/resumable state
+ReadyOS $B840-$B93F
+authoritative transition status; committed only after a successful
+stash
+
+
+clipboard metadata
+ReadyOS $B940-$B9CF
+authoritative 16-item table; payload banks remain dynamically
+allocated
+
+
+global hotkeys
+ReadyOS $B9D0-$B9D8
+shared state read directly by focused TUI micromodules
+
+
+launcher catalog-shape settings
+ReadyOS $B9D9-$B9FF
+LS v1 record used to reconstruct launcher arrays from
+the authoritative registry
+
+
+app/resource/dependency/catalog records
+ReadyOS $BA00-$FB3F
+normalized 64-app registry and cold metadata
+
+
+launcher executable snapshot
+ReadyOS $0000-$B5FF
+restored for token 0
+
+
+launcher runtime/resume record
+ReadyOS $FC40-$FCBF
+RSM1-validated UI state (selection, scroll, one-shot
+flag, and DMA-use flag/path when enabled)
+
+
+
+
The ReadyOS bank is the source of truth. Resident shim bytes carry
+only the minimum transition operands and one-byte DMA scratch needed
+while app RAM is being replaced.
+
Resident Shim
+($C600-$C9FF) and ABI ($C800-$C9FF)
+
The resident shim owns exactly 1 KB outside the app snapshot window.
+Its lower 512 bytes are clear contiguous expansion reserve; its public
+ABI remains in the upper 512 bytes at the same addresses as before.
+
Measured shim room
+
The current image has 512 contiguous reserved bytes
+at $C600-$C7FF, plus 129 bytes of executable
+padding within the established ABI, all verified as zero by
+verify_readyos_shim.py. That space is fragmented: the
+largest single run is 42 bytes at $C8B6-$C8DF; the other
+runs are 33, 23, 7, 7, 5, 4, 4, 2, and 2 bytes. There are another 11
+resident ABI/data bytes currently marked scratch/retired/reserved
+($C81E-$C81F, $C822-$C823,
+$C832-$C833, $C836-$C838, $C83A,
+and $C83F), but they should not be counted as general code
+room because existing callers may rely on their addresses or zero value.
+So the practical extension budget is 512 contiguous bytes plus 129
+fragmented ABI padding bytes. Moving duplicate loaded/map/catalog
+authority into the ReadyOS bank is what makes this budget possible; ABI
+padding still requires extra caution because callers may depend on
+established addresses.
+
The 25-byte increase came from retiring five preload trace writes to
+$C007-$C00C. No runtime or test consumed them, and app
+snapshot RAM is no longer used as a shim diagnostic side channel. The
+reserved $C812 entry now jumps to the safe
+$C9FF RTS instead of into the middle of
+preload code.
+
Stable entry block
+
+
+
+Address
+Entry
+
+
+
+
+$C800
+load from disk and run
+
+
+$C803
+fetch from REU and run
+
+
+$C806
+run app at $1000
+
+
+$C809
+preload app to REU and return
+
+
+$C80C
+return to launcher
+
+
+$C80F
+switch directly to another app
+
+
+$C812
+reserved compatibility slot; safe no-op jump to
+$C9FF
+
+
+$C815
+fetch-bank helper
+
+
+$C818
+deprecated logger entry; jumps to safe RTS at
+$C9FF
+
+
+$C81B
+mark token loaded/resumable after a successful stash
+
+
+
+
Resident data bytes
+
+
+
+
+
+
+
+
+Address
+Field
+Current meaning
+
+
+
+
+$C820
+target_bank
+target logical snapshot token
+
+
+$C821
+filename_len
+filename length for KERNAL load paths
+
+
+$C822-$C823
+app-size scratch ABI bytes
+launcher uses them; shim does not consume them
+
+
+$C824-$C82F
+filename[12]
+disk-load filename buffer
+
+
+$C830-$C831
+load_end
+actual end returned by KERNAL LOAD during preload
+
+
+$C832-$C833
+unused
+reserved
+
+
+$C834
+current_bank
+currently running logical snapshot token
+
+
+$C835
+last_saved
+recovery/resilience hint
+
+
+$C836-$C838
+reserved
+retired loaded bitmap bytes
+
+
+$C839
+storage_drive
+shared default file-dialog drive
+
+
+$C83A
+reserved
+retired debug-ring index
+
+
+$C83B
+readyos_bank
+direct physical ReadyOS bank (Skip)
+
+
+$C83C
+launcher_flags
+launcher-owned one-shot flags
+
+
+$C83D
+reu_lookup_scratch
+physical/status byte DMA scratch
+
+
+$C83E
+token_scratch
+token preserved by mark_loaded
+
+
+$C83F
+reserved
+future ABI space
+
+
+
+
Lookup flow at $C960
+
For shim token 0:
+
+read $C83B
+use that direct physical ReadyOS-bank number
+
+
For any nonzero token N:
+
+configure a one-byte REU fetch into $C83D
+fetch from the ReadyOS bank at offset $B740 + N
+load the fetched physical bank byte
+configure the normal $B600 stash or fetch at C64
+address $1000
+
+
The small one-byte preliminary DMA is why the shim can resolve a
+scalable logical token without carrying a large resident table.
+
ReadyOS Bank (Skip,
+Schema 5)
+
+
+
+
+
+
+
+
+Offset
+Size
+Contents
+
+
+
+
+$0000
+$B600
+launcher snapshot of C64 $1000-$C5FF
+
+
+$B600
+$0040
+RCB5 header: schema, writer, skip/count/availability
+and offsets
+
+
+$B640
+$0100
+authoritative 256-entry physical bank-type table
+
+
+$B740
+$0100
+token-to-physical snapshot map
+
+
+$B840
+$0100
+token valid/loaded/resumable status
+
+
+$B940
+$0090
+clipboard count and 16 item records
+
+
+$B9D0
+9
+global hotkeys
+
+
+$B9D9
+$0027
+active LS v1 launcher settings: first-app index, app
+count, load-all policy, and 32-byte variant name
+
+
+$BA00
+$0400
+64 app records (64 x 16)
+
+
+$BE00
+$0100
+token-to-app-index table
+
+
+$BF00
+$0340
+64 app filename records (64 x 13)
+
+
+$C240
+$0400
+64 rich resource records (64 x 16)
+
+
+$C640
+$2000
+64 dependency/source lines (64 x 128)
+
+
+$E640
+$0800
+catalog names (64 x 32)
+
+
+$EE40
+$09C0
+catalog descriptions (64 x 39)
+
+
+$F800
+$0340
+catalog file tokens (64 x 13)
+
+
+$FB40
+$0100
+audit page
+
+
+$FC40
+$0080
+launcher RSM1 envelope: 16-byte header plus compact UI
+payload; DMA builds also persist the bounded image path
+
+
+$FCC0
+$0340
+reserved for compatible schema growth
+
+
+
+
reu_control_bank_sync_and_mirror() writes bank types
+directly to the ReadyOS bank; there is no resident mirror to reconcile.
+The launcher registry writer publishes the catalog, explicit token
+maps/status, physical snapshot sizes, and resource ownership. Banks
+beyond the detected physical size are marked REU_UNAVAIL
+and are never eligible for allocation.
+
The launcher deliberately does not persist its former full set of
+parallel arrays in the resume tail. On return, it validates the small
+RSM1 UI record, then rebuilds app_banks,
+drives, hotkeys, resource-bank assignments, loaded flags, and snapshot
+sizes from the LS settings record plus the 64 app records
+at $BA00. Selection bounds are checked only after that
+registry has restored the menu shape. Catalog strings remain in their
+ReadyOS-bank tables and are fetched through a small visible-row cache
+and one shared scratch buffer.
+
Because that scratch buffer is also used for ReadyOS DMA publication,
+code may not retain a pointer returned by a catalog accessor across a
+metadata write. The preload path resolves/allocates its token first and
+only then fetches the filename; the DMA fallback reacquires the filename
+after republishing state.
+
App Switching With the Split
+State
+
Preload
+
+Launcher assigns a logical snapshot token and physical slot.
+Launcher publishes the allocation, map, and status directly to
+ReadyOS.
+Shim stashes the launcher using token 0 to the ReadyOS
+bank.
+The app is loaded into $1000, then stashed using its
+nonzero token.
+Shim reads that token’s physical bank from ReadyOS
+$B740 and performs the transfer.
+Shim restores the launcher from the ReadyOS bank.
+
+
Return or direct switch
+
+Shim uses resident $C834/$C820 to know the
+current and target tokens.
+Each nonzero token is resolved through ReadyOS
+$B740.
+Shim stashes/fetches exactly $B600 bytes.
+Returning to the launcher resolves token 0 directly to
+$C83B.
+
+
The shim never needs the launcher’s normal app RAM structures to
+survive this sequence; that is the reason the small resident state
+remains resident.
+
Relationship to
+0.2.5 Ultimate DOS DMA Loading
+
The opt-in Ultimate DOS/UCI DMA path changes how a cold PRG payload
+reaches an already allocated REU snapshot bank. It does
+not enlarge or relocate the resident shim and does not
+change the later switch contract:
+
+the destination snapshot is still launcher-allocated;
+ReadyOS-bank metadata, mapping, and status are still
+republished;
+later app launches, returns, and direct switches still use the
+resident shim and its $B600 transfer;
+the KERNAL/disk preload path remains the fallback.
+
+
The current non-DMA and DMA launchers therefore share the same
+resident shim/ReadyOS-bank switching architecture.
+
Source of Truth
+
+resident byte image: src/boot/readyos_shim.inc
+ReadyOS-bank schema and publisher (retaining the source module’s
+historical filename): src/lib/reu_control_bank.h and
+src/lib/reu_control_bank.c
+normalized app registry publisher:
+src/lib/reu_control_registry.c
+active allocator and mapping helpers:
+src/lib/reu_mgr*.c, src/lib/reu_mgr.h, and
+src/apps/launcher/launcher.c
+canonical detailed map:
+privatedocs/top_level_md/MEMORY_MAP.md
+
+
Older shim HTML reports are retained as historical architecture
+evidence. They must not be read as current when they show a separate
+control bank, a resident allocation/bitmap mirror, fixed app slots,
+$2F00 lookup, or $B800 snapshots.
+
+
This appendix is synchronized from
+src/boot/readyos_shim.inc; both the disk and EasyFlash
+builds use that same canonical 1024-byte definition. The disk bootstrap
+clears the lower reserve in place and embeds only the upper ABI half to
+stay below $1000; EasyFlash packages the complete image.
+The documentation verifier compares every directive and ABI
+annotation.
+
;-----------------------------------------------------------------------------
+; Shared ReadyOS shim image ($C600-$C9FF, 1024 bytes)
+; This file is the canonical shim byte layout used by both the disk boot path
+; and the EasyFlash cartridge flavor. Keep it identical across all variants.
+;-----------------------------------------------------------------------------
+
+;-----------------------------------------------------------------------------
+; Pages 1-2: $C600-$C7FF - reserved resident expansion space
+;-----------------------------------------------------------------------------
+; This space used to contain the C64-RAM REU allocation/metadata mirror. The
+; authoritative state now lives in the ReadyOS REU bank, but the RAM remains
+; resident shim-owned capacity rather than becoming app snapshot memory.
+.ifndef READYOS_SHIM_ABI_ONLY
+.res $0200, $00
+.endif
+
+;-----------------------------------------------------------------------------
+; Page 3: $C800-$C8FF - Jump table, data, and helper routines
+;-----------------------------------------------------------------------------
+
+; $C800-$C817: Jump Table (24 bytes, 8 entries)
+jt_load_disk = $C800 ; Load from disk, run
+jt_load_reu = $C803 ; Fetch from REU, run
+jt_run_app = $C806 ; Just run app
+jt_preload = $C809 ; Preload to REU, return
+jt_return = $C80C ; Return to launcher
+jt_switch = $C80F ; Switch to another app
+jt_reserved = $C812 ; Reserved compatibility slot (safe no-op)
+jt_fetch_bank = $C815 ; Helper: fetch from bank in A
+
+.byte $4C, $40, $C8 ; $C800: JMP load_disk ($C840)
+.byte $4C, $60, $C8 ; $C803: JMP load_reu ($C860)
+.byte $4C, $00, $10 ; $C806: JMP $1000 (run app)
+.byte $4C, $80, $C8 ; $C809: JMP preload ($C880)
+.byte $4C, $00, $C9 ; $C80C: JMP return_to_launcher ($C900)
+.byte $4C, $40, $C9 ; $C80F: JMP switch_app ($C940)
+.byte $4C, $FF, $C9 ; $C812: reserved helper -> safe RTS
+.byte $4C, $F0, $C8 ; $C815: JMP fetch_bank ($C8F0)
+
+; $C818: deprecated logger compatibility slot
+.byte $4C, $FF, $C9 ; $C818: deprecated logger -> safe RTS
+.byte $4C, $C0, $C9 ; $C81B: JMP mark_loaded (token in A)
+.byte $00,$00 ; $C81E-$C81F: reserved
+
+; $C820-$C83F: Data Area (32 bytes)
+; $C820: target_bank - bank to load/switch to
+; $C821: filename_len
+; $C822-$C823: launcher-side app-size scratch (not consumed by the shim)
+; $C824-$C82F: filename (12 bytes)
+; $C830: load_end_lo (KERNAL LOAD end addr low byte, saved by preload)
+; $C831: load_end_hi (KERNAL LOAD end addr high byte, saved by preload)
+; $C832-$C833: unused
+; $C834: current_bank - currently running app
+; $C835: last_saved
+; $C836-$C838: retired bitmap bytes (reserved; authoritative state is in REU)
+; $C839: storage_drive - shim-global default storage drive for D8/D9 app dialogs
+; This persists across app switches and is shared by apps that use the
+; common file-dialog default-drive contract.
+; $C83A: reserved (formerly log_index)
+; $C83B: readyos_bank - direct physical ReadyOS bank number (Skip)
+; $C83C: launcher_flags - launcher-owned one-shot state flags
+; $C83D: reu_lookup_scratch - one-byte ReadyOS-bank DMA scratch
+; $C83E: token_scratch; $C83F: reserved
+
+.byte $00 ; $C820: target_bank
+.byte $08 ; $C821: filename_len
+.byte $00, $00 ; $C822-$C823: launcher app-size scratch
+.byte "LAUNCHER " ; $C824-$C82F: filename (12 bytes)
+.byte $00,$00 ; $C830-$C831: load_end_lo, load_end_hi
+.byte $00,$00 ; $C832-$C833: unused
+.byte $00 ; $C834: current_bank
+.byte $FF ; $C835: last_saved
+.byte $00 ; $C836: reserved (retired bitmap byte)
+.byte $00 ; $C837: reserved (retired bitmap byte)
+.byte $00 ; $C838: reserved (retired bitmap byte)
+.byte $08 ; $C839: storage_drive (default drive 8)
+.byte $00 ; $C83A: reserved (retired debug-ring head)
+.byte READYOS_REU_BANK_SKIP ; $C83B: readyos_bank (physical Skip)
+.byte $00 ; $C83C: launcher_flags
+.byte $00 ; $C83D: reu_lookup_scratch
+.byte $00,$00 ; $C83E-$C83F: reserved
+
+;-----------------------------------------------------------------------------
+; $C840: load_disk - Load app from disk and run (32 bytes)
+;-----------------------------------------------------------------------------
+.byte $AD, $21, $C8 ; LDA $C821 (filename len)
+.byte $A2, $24 ; LDX #$24
+.byte $A0, $C8 ; LDY #$C8 (filename at $C824)
+.byte $20, $BD, $FF ; JSR $FFBD (SETNAM)
+.byte $A9, $00 ; LDA #0
+.byte $AE, $39, $C8 ; LDX $C839 (storage drive)
+.byte $A0, $01 ; LDY #1
+.byte $20, $BA, $FF ; JSR $FFBA (SETLFS)
+.byte $A9, $00 ; LDA #0
+.byte $20, $D5, $FF ; JSR $FFD5 (LOAD)
+.byte $4C, $00, $10 ; JMP $1000
+.byte $00,$00,$00,$00 ; Padding to $C860
+
+;-----------------------------------------------------------------------------
+; $C860: load_reu - Fetch app from REU and run (32 bytes)
+;-----------------------------------------------------------------------------
+.byte $AD, $20, $C8 ; LDA $C820 (target bank)
+.byte $20, $F0, $C8 ; JSR fetch_bank ($C8F0)
+.byte $4C, $00, $10 ; JMP $1000
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00
+
+;-----------------------------------------------------------------------------
+; $C880: preload - Load to REU, return to launcher
+; Called via JSR $C809
+;-----------------------------------------------------------------------------
+.byte $A9, $00 ; LDA #0 (launcher token -> ReadyOS bank)
+.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
+
+.byte $AD, $21, $C8 ; LDA $C821 (len)
+.byte $A2, $24 ; LDX #$24
+.byte $A0, $C8 ; LDY #$C8 (filename at $C824)
+.byte $20, $BD, $FF ; JSR SETNAM
+
+.byte $A9, $00 ; LDA #0
+.byte $AE, $39, $C8 ; LDX $C839 (storage drive)
+.byte $A0, $01 ; LDY #1
+.byte $20, $BA, $FF ; JSR SETLFS
+
+.byte $A9, $00 ; LDA #0
+.byte $20, $D5, $FF ; JSR LOAD
+
+.byte $8E, $30, $C8 ; STX $C830 (end addr lo)
+.byte $8C, $31, $C8 ; STY $C831 (end addr hi)
+
+.byte $AD, $20, $C8 ; LDA $C820 (target bank)
+.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
+
+.byte $AD, $20, $C8 ; LDA $C820 (target bank)
+.byte $20, $C0, $C9 ; JSR mark_loaded ($C9C0)
+
+.byte $A9, $00 ; LDA #0
+.byte $20, $F0, $C8 ; JSR fetch_bank ($C8F0)
+
+.byte $60 ; RTS
+
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00
+
+;-----------------------------------------------------------------------------
+; $C8E0: stash_to_bank - Stash $1000-$C5FF to REU bank in A (16 bytes)
+;-----------------------------------------------------------------------------
+.byte $20, $60, $C9 ; JSR reu_setup_logical ($C960)
+.byte $A9, $90 ; LDA #$90 (STASH command)
+.byte $8D, $01, $DF ; STA $DF01 - execute transfer
+.byte $60 ; RTS
+.byte $00,$00,$00,$00,$00,$00,$00
+
+;-----------------------------------------------------------------------------
+; $C8F0: fetch_bank - Fetch from REU bank in A to $1000-$C5FF (16 bytes)
+;-----------------------------------------------------------------------------
+.byte $20, $60, $C9 ; JSR reu_setup_logical ($C960)
+.byte $A9, $91 ; LDA #$91 (FETCH command)
+.byte $8D, $01, $DF ; STA $DF01 - execute transfer
+.byte $60 ; RTS
+.byte $00,$00,$00,$00,$00,$00,$00
+
+;-----------------------------------------------------------------------------
+; Page 4: $C900-$C9FF - Main routines
+;-----------------------------------------------------------------------------
+
+;-----------------------------------------------------------------------------
+; $C900: return_to_launcher (64 bytes)
+;-----------------------------------------------------------------------------
+.byte $AD, $34, $C8 ; LDA $C834 (current bank)
+.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
+.byte $AD, $34, $C8 ; LDA $C834 (current bank)
+.byte $20, $C0, $C9 ; JSR mark_loaded ($C9C0)
+.byte $AD, $34, $C8 ; LDA $C834
+.byte $8D, $35, $C8 ; STA $C835
+.byte $A9, $00 ; LDA #0
+.byte $20, $F0, $C8 ; JSR fetch_bank ($C8F0)
+.byte $A9, $00 ; LDA #0
+.byte $8D, $34, $C8 ; STA $C834
+.byte $4C, $00, $10 ; JMP $1000
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00
+
+;-----------------------------------------------------------------------------
+; $C940: switch_app (64 bytes)
+;-----------------------------------------------------------------------------
+.byte $AD, $34, $C8 ; LDA $C834 (current bank)
+.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
+.byte $AD, $34, $C8 ; LDA $C834 (current bank)
+.byte $20, $C0, $C9 ; JSR mark_loaded ($C9C0)
+.byte $AD, $20, $C8 ; LDA $C820 (target bank)
+.byte $20, $F0, $C8 ; JSR fetch_bank ($C8F0)
+.byte $AD, $20, $C8 ; LDA $C820
+.byte $8D, $34, $C8 ; STA $C834
+.byte $4C, $00, $10 ; JMP $1000
+.byte $00,$00,$00,$00,$00
+
+;-----------------------------------------------------------------------------
+; $C960: reu_setup_logical - Resolve token via the ReadyOS bank, then setup regs
+;-----------------------------------------------------------------------------
+.byte $C9, $00 ; CMP #0 (logical launcher bank?)
+.byte $D0, $06 ; BNE lookup_app_bank
+.byte $AD, $3B, $C8 ; LDA $C83B (ReadyOS bank contains launcher)
+.byte $4C, $A0, $C9 ; JMP reu_setup ($C9A0)
+.byte $AA ; lookup_app_bank: TAX (preserve logical token)
+.byte $A9, $3D ; LDA #<$C83D
+.byte $8D, $02, $DF ; STA $DF02 (C64 addr lo)
+.byte $A9, $C8 ; LDA #>$C83D
+.byte $8D, $03, $DF ; STA $DF03 (C64 addr hi)
+.byte $8A ; TXA
+.byte $18 ; CLC
+.byte $69, $40 ; ADC #<$B740 (mapping offset + token)
+.byte $8D, $04, $DF ; STA $DF04 (REU offset lo)
+.byte $A9, $B7 ; LDA #>$B740
+.byte $69, $00 ; ADC #0 (include low-byte carry)
+.byte $8D, $05, $DF ; STA $DF05 (REU offset hi)
+.byte $AD, $3B, $C8 ; LDA $C83B (ReadyOS global physical bank)
+.byte $8D, $06, $DF ; STA $DF06
+.byte $A9, $01 ; LDA #1
+.byte $8D, $07, $DF ; STA $DF07 (length lo)
+.byte $A9, $00 ; LDA #0
+.byte $8D, $08, $DF ; STA $DF08 (length hi)
+.byte $A9, $91 ; LDA #$91 (FETCH command)
+.byte $8D, $01, $DF ; STA $DF01 - fetch physical bank byte
+.byte $AD, $3D, $C8 ; LDA $C83D (resolved physical bank)
+.byte $4C, $A0, $C9 ; JMP reu_setup ($C9A0)
+.byte $00,$00 ; Padding to $C9A0
+
+;-----------------------------------------------------------------------------
+; $C9A0: reu_setup - Set up REU registers for $B600 transfer at $1000
+;-----------------------------------------------------------------------------
+.byte $8D, $06, $DF ; STA $DF06 (bank)
+.byte $A9, $00 ; LDA #$00
+.byte $8D, $02, $DF ; STA $DF02 (C64 addr lo = $00)
+.byte $A9, $10 ; LDA #$10
+.byte $8D, $03, $DF ; STA $DF03 (C64 addr hi = $10, so $1000)
+.byte $A9, $00 ; LDA #$00
+.byte $8D, $04, $DF ; STA $DF04 (REU addr lo)
+.byte $8D, $05, $DF ; STA $DF05 (REU addr hi)
+.byte $8D, $07, $DF ; STA $DF07 (len lo = $00)
+.byte $A9, $B6 ; LDA #$B6
+.byte $8D, $08, $DF ; STA $DF08 (len hi = $B6, so $B600 bytes)
+.byte $60 ; RTS
+.byte $00,$00
+
+;-----------------------------------------------------------------------------
+; $C9C0: mark_loaded - Commit token status after a successful snapshot stash
+; A = logical token. Status $07 means valid, loaded, and resumable.
+;-----------------------------------------------------------------------------
+.byte $8D, $3E, $C8 ; STA $C83E (preserve token)
+.byte $A9, $07 ; LDA #VALID|LOADED|RESUMABLE
+.byte $8D, $3D, $C8 ; STA $C83D
+.byte $A9, $3D ; C64 source = $C83D
+.byte $8D, $02, $DF
+.byte $A9, $C8
+.byte $8D, $03, $DF
+.byte $AD, $3E, $C8 ; token
+.byte $18 ; CLC
+.byte $69, $40 ; + <$B840 (token status table)
+.byte $8D, $04, $DF
+.byte $A9, $B8 ; >$B840
+.byte $69, $00 ; include low-byte carry
+.byte $8D, $05, $DF
+.byte $AD, $3B, $C8 ; ReadyOS physical bank
+.byte $8D, $06, $DF
+.byte $A9, $01 ; one byte
+.byte $8D, $07, $DF
+.byte $A9, $00
+.byte $8D, $08, $DF
+.byte $A9, $90 ; STASH C64 byte to ReadyOS bank
+.byte $8D, $01, $DF
+.byte $AD, $3E, $C8 ; preserve caller-visible token in A
+.byte $60 ; RTS
+.byte $00,$00,$00,$00 ; reserved through $C9FE
+.byte $60 ; $C9FF: compatibility no-op RTS
+
+
+
diff --git a/docs/ReadyOS_SHIM_ARCHITECTURE_0.2.5.md b/docs/ReadyOS_SHIM_ARCHITECTURE_0.2.5.md
new file mode 100644
index 0000000..fdc50d9
--- /dev/null
+++ b/docs/ReadyOS_SHIM_ARCHITECTURE_0.2.5.md
@@ -0,0 +1,554 @@
+# ReadyOS 0.2.5 Shim and ReadyOS-Bank Architecture
+
+This is the current implementation-backed explanation of the resident shim
+and the combined ReadyOS bank. It was audited
+against the `0.2.5` development tree on 2026-08-01.
+
+The most important correction to older descriptions is that **physical
+`Skip` is the ReadyOS bank and is the single source of truth**. It combines
+the launcher snapshot and schema-v5 operating-system state:
+
+```text
+C64 RAM
+$1000 $C5FF $C600 $C9FF
+|<--------------- active app snapshot: $B600 bytes -------------->|<-- 1 KB shim ------>|
+
+ReadyOS physical REU region
+Skip (ReadyOS bank) Skip+1 ... detected end
+| launcher $0000-$B5FF | dynamic app/resource pool |
+| schema v5 $B600-$FFFF | explicit token mappings |
+```
+
+The configured skip is compiled into the build; resident shim byte `$C83B`
+stores the direct physical ReadyOS bank number (`Skip`).
+
+## What Changed
+
+The older shim calculated every app snapshot's physical bank from a fixed
+layout. A nonzero logical app bank `N` was tied to a reserved physical slot
+after the global, launcher, and launcher-overlay reservations. That made the
+resident shim depend on a fixed block of app slots and prevented the allocator
+from using the REU as one flexible pool.
+
+The current implementation makes these changes:
+
+1. Physical `Skip` is the ReadyOS bank. It is skipped by the dynamic allocator,
+ but it is not unused.
+2. Physical `Skip+1` is the first dynamic app/resource bank.
+3. Token `0` resolves directly to the ReadyOS bank;
+ its first `$B600` bytes are the launcher snapshot.
+4. Schema-v5 state occupies the same ReadyOS bank at `$B600-$FFFF`, including
+ bank types, token mappings/status, clipboard metadata, hotkeys, settings,
+ app/resource records, catalog text, audit data, and launcher runtime state.
+5. For a nonzero token, the shim fetches one byte from
+ `ReadyOS:$B740 + token`. That byte is the physical snapshot bank to use.
+6. The old `$C600-$C7FF` allocation/clipboard/hotkey mirrors and the three-byte
+ loaded bitmap are retired; `$C600-$C7FF` remains resident as contiguous shim
+ expansion capacity rather than becoming app RAM.
+7. The snapshot is `$1000-$C5FF` (`$B600` bytes), leaving a `$4A00`
+ per-app resume tail at REU offsets `$B600-$FFFF`.
+8. The full shim region is restored to 1 KB at `$C600-$C9FF`; the stable
+ 512-byte ABI and entry addresses remain at `$C800-$C9FF`. `$C81B` is the
+ `mark_loaded` entry; `$C818` is a safe deprecated `RTS` target.
+
+Mappings are explicitly allocated and published. No app or shim path may infer
+a physical bank from a logical token arithmetically.
+
+### Version-history clarification
+
+The earlier 0.2.5 design used a separate control bank at `Skip` and launcher
+bank at `Skip+1`. Schema v5 deliberately supersedes that split while preserving
+the established transition entry points in the upper 512-byte ABI.
+Ultimate DOS DMA remains launcher-side cold-load transport and publishes the
+same explicit mappings as the KERNAL path.
+
+## The State Was Split, Not Simply Moved
+
+Only values required while `$1000-$C5FF` is being overwritten remain resident.
+All scalable state is authoritative in the ReadyOS bank.
+
+| State | Current location | Operational role / authority |
+|---|---|---|
+| transition target, current token, last-saved hint, bank skip, drive, flags | shim `$C820-$C83F` | resident transition state; available while app RAM is replaced |
+| `$C836-$C838`, `$C83A` | resident reserved bytes | retired bitmap/log-index storage; never authoritative |
+| active physical bank allocation types | ReadyOS `$B640-$B73F` | allocator authority used through direct byte/block DMA helpers |
+| token-to-physical mapping | ReadyOS `$B740-$B83F` | live source read by shim, launcher, apps, and tools |
+| token validity/loaded/resumable state | ReadyOS `$B840-$B93F` | authoritative transition status; committed only after a successful stash |
+| clipboard metadata | ReadyOS `$B940-$B9CF` | authoritative 16-item table; payload banks remain dynamically allocated |
+| global hotkeys | ReadyOS `$B9D0-$B9D8` | shared state read directly by focused TUI micromodules |
+| launcher catalog-shape settings | ReadyOS `$B9D9-$B9FF` | `LS` v1 record used to reconstruct launcher arrays from the authoritative registry |
+| app/resource/dependency/catalog records | ReadyOS `$BA00-$FB3F` | normalized 64-app registry and cold metadata |
+| launcher executable snapshot | ReadyOS `$0000-$B5FF` | restored for token `0` |
+| launcher runtime/resume record | ReadyOS `$FC40-$FCBF` | `RSM1`-validated UI state (selection, scroll, one-shot flag, and DMA-use flag/path when enabled) |
+
+The ReadyOS bank is the source of truth. Resident shim bytes carry only the
+minimum transition operands and one-byte DMA scratch needed while app RAM is
+being replaced.
+
+## Resident Shim (`$C600-$C9FF`) and ABI (`$C800-$C9FF`)
+
+The resident shim owns exactly 1 KB outside the app snapshot window. Its lower
+512 bytes are clear contiguous expansion reserve; its public ABI remains in the
+upper 512 bytes at the same addresses as before.
+
+### Measured shim room
+
+The current image has **512 contiguous reserved bytes** at `$C600-$C7FF`, plus
+**129 bytes of executable padding** within the established ABI, all verified as zero by
+`verify_readyos_shim.py`. That space is fragmented: the largest single run is
+42 bytes at `$C8B6-$C8DF`; the other runs are 33, 23, 7, 7, 5, 4, 4, 2, and 2
+bytes. There are another 11 resident ABI/data bytes currently marked
+scratch/retired/reserved (`$C81E-$C81F`, `$C822-$C823`, `$C832-$C833`,
+`$C836-$C838`, `$C83A`, and `$C83F`), but they should not be counted as general
+code room because existing callers may rely on their addresses or zero value.
+So the practical extension budget is 512 contiguous bytes plus 129 fragmented
+ABI padding bytes. Moving duplicate loaded/map/catalog authority into the
+ReadyOS bank is what makes this budget possible; ABI padding still requires
+extra caution because callers may depend on established addresses.
+
+The 25-byte increase came from retiring five preload trace writes to
+`$C007-$C00C`. No runtime or test consumed them, and app snapshot RAM is no
+longer used as a shim diagnostic side channel. The reserved `$C812` entry now
+jumps to the safe `$C9FF` `RTS` instead of into the middle of preload code.
+
+### Stable entry block
+
+| Address | Entry |
+|---:|---|
+| `$C800` | load from disk and run |
+| `$C803` | fetch from REU and run |
+| `$C806` | run app at `$1000` |
+| `$C809` | preload app to REU and return |
+| `$C80C` | return to launcher |
+| `$C80F` | switch directly to another app |
+| `$C812` | reserved compatibility slot; safe no-op jump to `$C9FF` |
+| `$C815` | fetch-bank helper |
+| `$C818` | deprecated logger entry; jumps to safe `RTS` at `$C9FF` |
+| `$C81B` | mark token loaded/resumable after a successful stash |
+
+### Resident data bytes
+
+| Address | Field | Current meaning |
+|---:|---|---|
+| `$C820` | `target_bank` | target logical snapshot token |
+| `$C821` | `filename_len` | filename length for KERNAL load paths |
+| `$C822-$C823` | app-size scratch ABI bytes | launcher uses them; shim does not consume them |
+| `$C824-$C82F` | `filename[12]` | disk-load filename buffer |
+| `$C830-$C831` | `load_end` | actual end returned by KERNAL `LOAD` during preload |
+| `$C832-$C833` | unused | reserved |
+| `$C834` | `current_bank` | currently running logical snapshot token |
+| `$C835` | `last_saved` | recovery/resilience hint |
+| `$C836-$C838` | reserved | retired loaded bitmap bytes |
+| `$C839` | `storage_drive` | shared default file-dialog drive |
+| `$C83A` | reserved | retired debug-ring index |
+| `$C83B` | `readyos_bank` | direct physical ReadyOS bank (`Skip`) |
+| `$C83C` | `launcher_flags` | launcher-owned one-shot flags |
+| `$C83D` | `reu_lookup_scratch` | physical/status byte DMA scratch |
+| `$C83E` | `token_scratch` | token preserved by `mark_loaded` |
+| `$C83F` | reserved | future ABI space |
+
+### Lookup flow at `$C960`
+
+For shim token `0`:
+
+1. read `$C83B`
+2. use that direct physical ReadyOS-bank number
+
+For any nonzero token `N`:
+
+1. configure a one-byte REU fetch into `$C83D`
+2. fetch from the ReadyOS bank at offset `$B740 + N`
+3. load the fetched physical bank byte
+4. configure the normal `$B600` stash or fetch at C64 address `$1000`
+
+The small one-byte preliminary DMA is why the shim can resolve a scalable
+logical token without carrying a large resident table.
+
+## ReadyOS Bank (`Skip`, Schema 5)
+
+| Offset | Size | Contents |
+|---:|---:|---|
+| `$0000` | `$B600` | launcher snapshot of C64 `$1000-$C5FF` |
+| `$B600` | `$0040` | `RCB5` header: schema, writer, skip/count/availability and offsets |
+| `$B640` | `$0100` | authoritative 256-entry physical bank-type table |
+| `$B740` | `$0100` | token-to-physical snapshot map |
+| `$B840` | `$0100` | token valid/loaded/resumable status |
+| `$B940` | `$0090` | clipboard count and 16 item records |
+| `$B9D0` | `9` | global hotkeys |
+| `$B9D9` | `$0027` | active `LS` v1 launcher settings: first-app index, app count, load-all policy, and 32-byte variant name |
+| `$BA00` | `$0400` | 64 app records (`64 x 16`) |
+| `$BE00` | `$0100` | token-to-app-index table |
+| `$BF00` | `$0340` | 64 app filename records (`64 x 13`) |
+| `$C240` | `$0400` | 64 rich resource records (`64 x 16`) |
+| `$C640` | `$2000` | 64 dependency/source lines (`64 x 128`) |
+| `$E640` | `$0800` | catalog names (`64 x 32`) |
+| `$EE40` | `$09C0` | catalog descriptions (`64 x 39`) |
+| `$F800` | `$0340` | catalog file tokens (`64 x 13`) |
+| `$FB40` | `$0100` | audit page |
+| `$FC40` | `$0080` | launcher `RSM1` envelope: 16-byte header plus compact UI payload; DMA builds also persist the bounded image path |
+| `$FCC0` | `$0340` | reserved for compatible schema growth |
+
+`reu_control_bank_sync_and_mirror()` writes bank types directly to the ReadyOS
+bank; there is no resident mirror to reconcile. The launcher registry writer
+publishes the catalog, explicit token maps/status, physical snapshot sizes, and
+resource ownership. Banks beyond the detected physical size are marked
+`REU_UNAVAIL` and are never eligible for allocation.
+
+The launcher deliberately does not persist its former full set of parallel
+arrays in the resume tail. On return, it validates the small `RSM1` UI record,
+then rebuilds `app_banks`, drives, hotkeys, resource-bank assignments,
+loaded flags, and snapshot sizes from the `LS` settings record plus the 64 app
+records at `$BA00`. Selection bounds are checked only after that registry has
+restored the menu shape. Catalog strings remain in their ReadyOS-bank tables
+and are fetched through a small visible-row cache and one shared scratch
+buffer.
+
+Because that scratch buffer is also used for ReadyOS DMA publication, code may
+not retain a pointer returned by a catalog accessor across a metadata write.
+The preload path resolves/allocates its token first and only then fetches the
+filename; the DMA fallback reacquires the filename after republishing state.
+
+## App Switching With the Split State
+
+### Preload
+
+1. Launcher assigns a logical snapshot token and physical slot.
+2. Launcher publishes the allocation, map, and status directly to ReadyOS.
+3. Shim stashes the launcher using token `0` to the ReadyOS bank.
+4. The app is loaded into `$1000`, then stashed using its nonzero token.
+5. Shim reads that token's physical bank from ReadyOS `$B740` and performs the transfer.
+6. Shim restores the launcher from the ReadyOS bank.
+
+### Return or direct switch
+
+1. Shim uses resident `$C834`/`$C820` to know the current and target tokens.
+2. Each nonzero token is resolved through ReadyOS `$B740`.
+3. Shim stashes/fetches exactly `$B600` bytes.
+4. Returning to the launcher resolves token `0` directly to `$C83B`.
+
+The shim never needs the launcher's normal app RAM structures to survive this
+sequence; that is the reason the small resident state remains resident.
+
+## Relationship to 0.2.5 Ultimate DOS DMA Loading
+
+The opt-in Ultimate DOS/UCI DMA path changes how a cold PRG payload reaches an
+already allocated REU snapshot bank. It does **not** enlarge or relocate the
+resident shim and does not change the later switch contract:
+
+- the destination snapshot is still launcher-allocated;
+- ReadyOS-bank metadata, mapping, and status are still republished;
+- later app launches, returns, and direct switches still use the resident shim
+ and its `$B600` transfer;
+- the KERNAL/disk preload path remains the fallback.
+
+The current non-DMA and DMA launchers therefore share the same resident
+shim/ReadyOS-bank switching architecture.
+
+## Source of Truth
+
+- resident byte image: `src/boot/readyos_shim.inc`
+- ReadyOS-bank schema and publisher (retaining the source module's historical
+ filename): `src/lib/reu_control_bank.h` and
+ `src/lib/reu_control_bank.c`
+- normalized app registry publisher: `src/lib/reu_control_registry.c`
+- active allocator and mapping helpers: `src/lib/reu_mgr*.c`,
+ `src/lib/reu_mgr.h`, and `src/apps/launcher/launcher.c`
+- canonical detailed map: `privatedocs/top_level_md/MEMORY_MAP.md`
+
+Older shim HTML reports are retained as historical architecture evidence. They
+must not be read as current when they show a separate control bank, a resident
+allocation/bitmap mirror, fixed app slots, `$2F00` lookup, or `$B800` snapshots.
+
+## Full Commented Resident Shim Source
+
+This appendix is synchronized from `src/boot/readyos_shim.inc`; both the disk
+and EasyFlash builds use that same canonical 1024-byte definition. The disk
+bootstrap clears the lower reserve in place and embeds only the upper ABI half
+to stay below `$1000`; EasyFlash packages the complete image. The documentation
+verifier compares every directive and ABI annotation.
+
+```asm
+;-----------------------------------------------------------------------------
+; Shared ReadyOS shim image ($C600-$C9FF, 1024 bytes)
+; This file is the canonical shim byte layout used by both the disk boot path
+; and the EasyFlash cartridge flavor. Keep it identical across all variants.
+;-----------------------------------------------------------------------------
+
+;-----------------------------------------------------------------------------
+; Pages 1-2: $C600-$C7FF - reserved resident expansion space
+;-----------------------------------------------------------------------------
+; This space used to contain the C64-RAM REU allocation/metadata mirror. The
+; authoritative state now lives in the ReadyOS REU bank, but the RAM remains
+; resident shim-owned capacity rather than becoming app snapshot memory.
+.ifndef READYOS_SHIM_ABI_ONLY
+.res $0200, $00
+.endif
+
+;-----------------------------------------------------------------------------
+; Page 3: $C800-$C8FF - Jump table, data, and helper routines
+;-----------------------------------------------------------------------------
+
+; $C800-$C817: Jump Table (24 bytes, 8 entries)
+jt_load_disk = $C800 ; Load from disk, run
+jt_load_reu = $C803 ; Fetch from REU, run
+jt_run_app = $C806 ; Just run app
+jt_preload = $C809 ; Preload to REU, return
+jt_return = $C80C ; Return to launcher
+jt_switch = $C80F ; Switch to another app
+jt_reserved = $C812 ; Reserved compatibility slot (safe no-op)
+jt_fetch_bank = $C815 ; Helper: fetch from bank in A
+
+.byte $4C, $40, $C8 ; $C800: JMP load_disk ($C840)
+.byte $4C, $60, $C8 ; $C803: JMP load_reu ($C860)
+.byte $4C, $00, $10 ; $C806: JMP $1000 (run app)
+.byte $4C, $80, $C8 ; $C809: JMP preload ($C880)
+.byte $4C, $00, $C9 ; $C80C: JMP return_to_launcher ($C900)
+.byte $4C, $40, $C9 ; $C80F: JMP switch_app ($C940)
+.byte $4C, $FF, $C9 ; $C812: reserved helper -> safe RTS
+.byte $4C, $F0, $C8 ; $C815: JMP fetch_bank ($C8F0)
+
+; $C818: deprecated logger compatibility slot
+.byte $4C, $FF, $C9 ; $C818: deprecated logger -> safe RTS
+.byte $4C, $C0, $C9 ; $C81B: JMP mark_loaded (token in A)
+.byte $00,$00 ; $C81E-$C81F: reserved
+
+; $C820-$C83F: Data Area (32 bytes)
+; $C820: target_bank - bank to load/switch to
+; $C821: filename_len
+; $C822-$C823: launcher-side app-size scratch (not consumed by the shim)
+; $C824-$C82F: filename (12 bytes)
+; $C830: load_end_lo (KERNAL LOAD end addr low byte, saved by preload)
+; $C831: load_end_hi (KERNAL LOAD end addr high byte, saved by preload)
+; $C832-$C833: unused
+; $C834: current_bank - currently running app
+; $C835: last_saved
+; $C836-$C838: retired bitmap bytes (reserved; authoritative state is in REU)
+; $C839: storage_drive - shim-global default storage drive for D8/D9 app dialogs
+; This persists across app switches and is shared by apps that use the
+; common file-dialog default-drive contract.
+; $C83A: reserved (formerly log_index)
+; $C83B: readyos_bank - direct physical ReadyOS bank number (Skip)
+; $C83C: launcher_flags - launcher-owned one-shot state flags
+; $C83D: reu_lookup_scratch - one-byte ReadyOS-bank DMA scratch
+; $C83E: token_scratch; $C83F: reserved
+
+.byte $00 ; $C820: target_bank
+.byte $08 ; $C821: filename_len
+.byte $00, $00 ; $C822-$C823: launcher app-size scratch
+.byte "LAUNCHER " ; $C824-$C82F: filename (12 bytes)
+.byte $00,$00 ; $C830-$C831: load_end_lo, load_end_hi
+.byte $00,$00 ; $C832-$C833: unused
+.byte $00 ; $C834: current_bank
+.byte $FF ; $C835: last_saved
+.byte $00 ; $C836: reserved (retired bitmap byte)
+.byte $00 ; $C837: reserved (retired bitmap byte)
+.byte $00 ; $C838: reserved (retired bitmap byte)
+.byte $08 ; $C839: storage_drive (default drive 8)
+.byte $00 ; $C83A: reserved (retired debug-ring head)
+.byte READYOS_REU_BANK_SKIP ; $C83B: readyos_bank (physical Skip)
+.byte $00 ; $C83C: launcher_flags
+.byte $00 ; $C83D: reu_lookup_scratch
+.byte $00,$00 ; $C83E-$C83F: reserved
+
+;-----------------------------------------------------------------------------
+; $C840: load_disk - Load app from disk and run (32 bytes)
+;-----------------------------------------------------------------------------
+.byte $AD, $21, $C8 ; LDA $C821 (filename len)
+.byte $A2, $24 ; LDX #$24
+.byte $A0, $C8 ; LDY #$C8 (filename at $C824)
+.byte $20, $BD, $FF ; JSR $FFBD (SETNAM)
+.byte $A9, $00 ; LDA #0
+.byte $AE, $39, $C8 ; LDX $C839 (storage drive)
+.byte $A0, $01 ; LDY #1
+.byte $20, $BA, $FF ; JSR $FFBA (SETLFS)
+.byte $A9, $00 ; LDA #0
+.byte $20, $D5, $FF ; JSR $FFD5 (LOAD)
+.byte $4C, $00, $10 ; JMP $1000
+.byte $00,$00,$00,$00 ; Padding to $C860
+
+;-----------------------------------------------------------------------------
+; $C860: load_reu - Fetch app from REU and run (32 bytes)
+;-----------------------------------------------------------------------------
+.byte $AD, $20, $C8 ; LDA $C820 (target bank)
+.byte $20, $F0, $C8 ; JSR fetch_bank ($C8F0)
+.byte $4C, $00, $10 ; JMP $1000
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00
+
+;-----------------------------------------------------------------------------
+; $C880: preload - Load to REU, return to launcher
+; Called via JSR $C809
+;-----------------------------------------------------------------------------
+.byte $A9, $00 ; LDA #0 (launcher token -> ReadyOS bank)
+.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
+
+.byte $AD, $21, $C8 ; LDA $C821 (len)
+.byte $A2, $24 ; LDX #$24
+.byte $A0, $C8 ; LDY #$C8 (filename at $C824)
+.byte $20, $BD, $FF ; JSR SETNAM
+
+.byte $A9, $00 ; LDA #0
+.byte $AE, $39, $C8 ; LDX $C839 (storage drive)
+.byte $A0, $01 ; LDY #1
+.byte $20, $BA, $FF ; JSR SETLFS
+
+.byte $A9, $00 ; LDA #0
+.byte $20, $D5, $FF ; JSR LOAD
+
+.byte $8E, $30, $C8 ; STX $C830 (end addr lo)
+.byte $8C, $31, $C8 ; STY $C831 (end addr hi)
+
+.byte $AD, $20, $C8 ; LDA $C820 (target bank)
+.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
+
+.byte $AD, $20, $C8 ; LDA $C820 (target bank)
+.byte $20, $C0, $C9 ; JSR mark_loaded ($C9C0)
+
+.byte $A9, $00 ; LDA #0
+.byte $20, $F0, $C8 ; JSR fetch_bank ($C8F0)
+
+.byte $60 ; RTS
+
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00
+
+;-----------------------------------------------------------------------------
+; $C8E0: stash_to_bank - Stash $1000-$C5FF to REU bank in A (16 bytes)
+;-----------------------------------------------------------------------------
+.byte $20, $60, $C9 ; JSR reu_setup_logical ($C960)
+.byte $A9, $90 ; LDA #$90 (STASH command)
+.byte $8D, $01, $DF ; STA $DF01 - execute transfer
+.byte $60 ; RTS
+.byte $00,$00,$00,$00,$00,$00,$00
+
+;-----------------------------------------------------------------------------
+; $C8F0: fetch_bank - Fetch from REU bank in A to $1000-$C5FF (16 bytes)
+;-----------------------------------------------------------------------------
+.byte $20, $60, $C9 ; JSR reu_setup_logical ($C960)
+.byte $A9, $91 ; LDA #$91 (FETCH command)
+.byte $8D, $01, $DF ; STA $DF01 - execute transfer
+.byte $60 ; RTS
+.byte $00,$00,$00,$00,$00,$00,$00
+
+;-----------------------------------------------------------------------------
+; Page 4: $C900-$C9FF - Main routines
+;-----------------------------------------------------------------------------
+
+;-----------------------------------------------------------------------------
+; $C900: return_to_launcher (64 bytes)
+;-----------------------------------------------------------------------------
+.byte $AD, $34, $C8 ; LDA $C834 (current bank)
+.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
+.byte $AD, $34, $C8 ; LDA $C834 (current bank)
+.byte $20, $C0, $C9 ; JSR mark_loaded ($C9C0)
+.byte $AD, $34, $C8 ; LDA $C834
+.byte $8D, $35, $C8 ; STA $C835
+.byte $A9, $00 ; LDA #0
+.byte $20, $F0, $C8 ; JSR fetch_bank ($C8F0)
+.byte $A9, $00 ; LDA #0
+.byte $8D, $34, $C8 ; STA $C834
+.byte $4C, $00, $10 ; JMP $1000
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00
+
+;-----------------------------------------------------------------------------
+; $C940: switch_app (64 bytes)
+;-----------------------------------------------------------------------------
+.byte $AD, $34, $C8 ; LDA $C834 (current bank)
+.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
+.byte $AD, $34, $C8 ; LDA $C834 (current bank)
+.byte $20, $C0, $C9 ; JSR mark_loaded ($C9C0)
+.byte $AD, $20, $C8 ; LDA $C820 (target bank)
+.byte $20, $F0, $C8 ; JSR fetch_bank ($C8F0)
+.byte $AD, $20, $C8 ; LDA $C820
+.byte $8D, $34, $C8 ; STA $C834
+.byte $4C, $00, $10 ; JMP $1000
+.byte $00,$00,$00,$00,$00
+
+;-----------------------------------------------------------------------------
+; $C960: reu_setup_logical - Resolve token via the ReadyOS bank, then setup regs
+;-----------------------------------------------------------------------------
+.byte $C9, $00 ; CMP #0 (logical launcher bank?)
+.byte $D0, $06 ; BNE lookup_app_bank
+.byte $AD, $3B, $C8 ; LDA $C83B (ReadyOS bank contains launcher)
+.byte $4C, $A0, $C9 ; JMP reu_setup ($C9A0)
+.byte $AA ; lookup_app_bank: TAX (preserve logical token)
+.byte $A9, $3D ; LDA #<$C83D
+.byte $8D, $02, $DF ; STA $DF02 (C64 addr lo)
+.byte $A9, $C8 ; LDA #>$C83D
+.byte $8D, $03, $DF ; STA $DF03 (C64 addr hi)
+.byte $8A ; TXA
+.byte $18 ; CLC
+.byte $69, $40 ; ADC #<$B740 (mapping offset + token)
+.byte $8D, $04, $DF ; STA $DF04 (REU offset lo)
+.byte $A9, $B7 ; LDA #>$B740
+.byte $69, $00 ; ADC #0 (include low-byte carry)
+.byte $8D, $05, $DF ; STA $DF05 (REU offset hi)
+.byte $AD, $3B, $C8 ; LDA $C83B (ReadyOS global physical bank)
+.byte $8D, $06, $DF ; STA $DF06
+.byte $A9, $01 ; LDA #1
+.byte $8D, $07, $DF ; STA $DF07 (length lo)
+.byte $A9, $00 ; LDA #0
+.byte $8D, $08, $DF ; STA $DF08 (length hi)
+.byte $A9, $91 ; LDA #$91 (FETCH command)
+.byte $8D, $01, $DF ; STA $DF01 - fetch physical bank byte
+.byte $AD, $3D, $C8 ; LDA $C83D (resolved physical bank)
+.byte $4C, $A0, $C9 ; JMP reu_setup ($C9A0)
+.byte $00,$00 ; Padding to $C9A0
+
+;-----------------------------------------------------------------------------
+; $C9A0: reu_setup - Set up REU registers for $B600 transfer at $1000
+;-----------------------------------------------------------------------------
+.byte $8D, $06, $DF ; STA $DF06 (bank)
+.byte $A9, $00 ; LDA #$00
+.byte $8D, $02, $DF ; STA $DF02 (C64 addr lo = $00)
+.byte $A9, $10 ; LDA #$10
+.byte $8D, $03, $DF ; STA $DF03 (C64 addr hi = $10, so $1000)
+.byte $A9, $00 ; LDA #$00
+.byte $8D, $04, $DF ; STA $DF04 (REU addr lo)
+.byte $8D, $05, $DF ; STA $DF05 (REU addr hi)
+.byte $8D, $07, $DF ; STA $DF07 (len lo = $00)
+.byte $A9, $B6 ; LDA #$B6
+.byte $8D, $08, $DF ; STA $DF08 (len hi = $B6, so $B600 bytes)
+.byte $60 ; RTS
+.byte $00,$00
+
+;-----------------------------------------------------------------------------
+; $C9C0: mark_loaded - Commit token status after a successful snapshot stash
+; A = logical token. Status $07 means valid, loaded, and resumable.
+;-----------------------------------------------------------------------------
+.byte $8D, $3E, $C8 ; STA $C83E (preserve token)
+.byte $A9, $07 ; LDA #VALID|LOADED|RESUMABLE
+.byte $8D, $3D, $C8 ; STA $C83D
+.byte $A9, $3D ; C64 source = $C83D
+.byte $8D, $02, $DF
+.byte $A9, $C8
+.byte $8D, $03, $DF
+.byte $AD, $3E, $C8 ; token
+.byte $18 ; CLC
+.byte $69, $40 ; + <$B840 (token status table)
+.byte $8D, $04, $DF
+.byte $A9, $B8 ; >$B840
+.byte $69, $00 ; include low-byte carry
+.byte $8D, $05, $DF
+.byte $AD, $3B, $C8 ; ReadyOS physical bank
+.byte $8D, $06, $DF
+.byte $A9, $01 ; one byte
+.byte $8D, $07, $DF
+.byte $A9, $00
+.byte $8D, $08, $DF
+.byte $A9, $90 ; STASH C64 byte to ReadyOS bank
+.byte $8D, $01, $DF
+.byte $AD, $3E, $C8 ; preserve caller-visible token in A
+.byte $60 ; RTS
+.byte $00,$00,$00,$00 ; reserved through $C9FE
+.byte $60 ; $C9FF: compatibility no-op RTS
+```
diff --git a/docs/ReadyShellArchitecture.html b/docs/ReadyShellArchitecture.html
index 7760a0f..42a09ff 100644
--- a/docs/ReadyShellArchitecture.html
+++ b/docs/ReadyShellArchitecture.html
@@ -1,3 +1,180 @@
+
+
+
+
+
+
+
ReadyShellArchitecture
+
+
+
+
+
CURRENT DOCUMENT Current ReadyShell architecture counterpart generated from ReadyShellArchitecture.md.
+
ReadyShell Architecture
This document describes the current ReadyShell implementation in
ReadyOS as it exists in the local build, not an aspirational future
@@ -68,9 +245,9 @@
2. Runtime Memory Model
-Resident app window
+ReadyOS snapshot window
$1000-$C5FF
-ReadyShell-owned app RAM
+ReadyShell-owned app RAM captured by the shim
Overlay load bytes
@@ -83,13 +260,18 @@ 2. Runtime Memory Model
Shared live window for whichever overlay is active
+Resident shim expansion reserve
+$C600-$C7FF
+ReadyOS-owned capacity outside ReadyShell’s proven overlay ABI
+
+
Resident BSS
-$7D37-$7EE0
+$7DEB-$7F94
Resident writable state below overlays
Resident heap
-$7EE2-$8DFD
+$7F96-$8DFD
cc65 heap below overlay load address
@@ -423,6 +605,11 @@ 8.2 State/scratch bank
registry reader. CAT is safe to place in the same scratch area because
command overlays execute serially; while CAT is active, no other command
owns that transient handoff area.
+The diagnostic ring has no C64-RAM mirror. The former
+$C7A0-$C7DF data and $C7F0 head is now
+resident shim-owned capacity; only small live cursor/availability
+variables remain in ReadyShell BSS, while ring contents and head are
+read and written in the loader-assigned state bank.
9. Responsibilities
Resident code owns the shell loop, overlay boot/load/restore logic,
@@ -438,8 +625,8 @@ 9. Responsibilities
10. Current Constraints
-Resident heap below the overlay load address is 3868
-bytes.
+Resident heap below the overlay load address is 3688
+bytes in the current release map.
OVERLAY6 is currently the tightest overlay, with only
11 bytes left in the $3800 live window.
The assigned cache layout leaves 8192 bytes free at the
@@ -449,3 +636,5 @@ 10. Current Constraints
External commands now pay a launcher/loader preload cost instead of
repeated disk loads during each command call.
+
+
diff --git a/docs/ReadyShellArchitecture.md b/docs/ReadyShellArchitecture.md
index 2c00ea5..6ec7198 100644
--- a/docs/ReadyShellArchitecture.md
+++ b/docs/ReadyShellArchitecture.md
@@ -64,11 +64,12 @@ Current release build layout:
| Region | Range | Purpose |
| --- | --- | --- |
-| Resident app window | `$1000-$C5FF` | ReadyShell-owned app RAM |
+| ReadyOS snapshot window | `$1000-$C5FF` | ReadyShell-owned app RAM captured by the shim |
| Overlay load bytes | `$8DFE-$8DFF` | PRG load-address bytes for overlay sidecars |
| Overlay execution window | `$8E00-$C5FF` | Shared live window for whichever overlay is active |
-| Resident BSS | `$7D37-$7EE0` | Resident writable state below overlays |
-| Resident heap | `$7EE2-$8DFD` | cc65 heap below overlay load address |
+| Resident shim expansion reserve | `$C600-$C7FF` | ReadyOS-owned capacity outside ReadyShell's proven overlay ABI |
+| Resident BSS | `$7DEB-$7F94` | Resident writable state below overlays |
+| Resident heap | `$7F96-$8DFD` | cc65 heap below overlay load address |
| High runtime area | `$CA00-$CFFF` | ReadyShell runtime state outside app snapshot |
Important constraints:
@@ -342,6 +343,11 @@ reader. CAT is safe to place in the same scratch area because command overlays
execute serially; while CAT is active, no other command owns that transient
handoff area.
+The diagnostic ring has no C64-RAM mirror. The former `$C7A0-$C7DF` data and
+`$C7F0` head is now resident shim-owned capacity; only small live
+cursor/availability variables remain in ReadyShell BSS, while ring contents
+and head are read and written in the loader-assigned state bank.
+
## 9. Responsibilities
- Resident code owns the shell loop, overlay boot/load/restore logic, generic
@@ -355,7 +361,8 @@ handoff area.
## 10. Current Constraints
-- Resident heap below the overlay load address is `3868` bytes.
+- Resident heap below the overlay load address is `3688` bytes in the current
+ release map.
- `OVERLAY6` is currently the tightest overlay, with only `11` bytes left in the
`$3800` live window.
- The assigned cache layout leaves `8192` bytes free at the tail of assigned
diff --git a/docs/ReadyShellHostTesting.html b/docs/ReadyShellHostTesting.html
index 971dcc8..9356784 100644
--- a/docs/ReadyShellHostTesting.html
+++ b/docs/ReadyShellHostTesting.html
@@ -1,201 +1,236 @@
-
-
+
+
-
- ReadyShell Host Version For Mocking, Unit, And Smoke Testing
+
+
+ ReadyShellHostTesting
-
- ReadyShell Host Version For Mocking, Unit, And Smoke Testing
-
- This document describes the current host-side ReadyShell test harness in
- ReadyOS. It is a native clang harness around the real parser,
- VM, value, serialization, and command-protocol code, not a separate
- productized host port of the shell.
-
-
-
-
- What It Is
-
- ReadyShell host testing exists to validate logic quickly without booting
- VICE or running on a real C64. The harness compiles selected ReadyShell
- sources as normal native code and substitutes only the hardware-facing
- edges with narrow mocks.
-
-
- Strongest value: parser, VM, value, serialization, and command-protocol
- regressions fail fast on the host. Weakest area: real overlay loading,
- memory banking, IEC behavior, and UI integration are still outside the
- host harness.
-
-
-
-
- Targets
-
-
- Target Purpose Included In make verify
-
-
- readyshell-host-testsAggregate parser + VM/overlay + REU suite Yes
- readyshell-parse-smoke-hostParser-only smoke checks Via aggregate
- readyshell-vm-smoke-hostGeneric VM smoke plus overlay-aware C64 dispatch and mocked file-command smoke Via aggregate
- readyshell-reu-tests-hostREU-backed value and serialization tests Via aggregate
-
-
-
-
-
- Shape
- native clang build
+
+CURRENT DOCUMENT Current ReadyShell host-testing counterpart generated from ReadyShellHostTesting.md.
+
+ReadyShell
+Host Version For Mocking, Unit, And Smoke Testing
+This document describes the current host-side ReadyShell test harness
+in ReadyOS.
+It is not a separate productized host port of ReadyShell. It is a
+native clang test harness around the real parser, VM,
+value, serialization, and external-command protocol code used by the C64
+build.
+For the user-facing shell guide, see ../src/apps/readyshell/README.md .
+For the full C64 architecture, overlay model, and runtime layout, see ./ReadyShellArchitecture.md .
+1. What The Host Harness Is
+ReadyShell host testing exists to validate logic quickly without
+booting VICE or running on a real C64.
+The host harness compiles selected ReadyShell sources as normal
+native code and runs small test executables on the host machine. It
+keeps the same parser, VM, value, and REU-serialization code paths
+wherever possible, but replaces the hardware-facing pieces with narrow
+mocks.
+That means the host harness is best thought of as:
+
+a fast parser smoke test
+a fast VM and pipeline behavior smoke test
+a fast REU-backed value and serialization unit test
+a protocol-level test for the external overlay command ABI
+
+It is not:
+
+a full host UI version of ReadyShell
+a cycle-accurate C64 emulator
+a replacement for disk boot testing in ReadyOS
+a substitute for overlay loading, REU DMA, or true-drive
+verification
+
+2. Make Targets
+The current host-side targets are:
+
+make readyshell-host-tests
+make readyshell-parse-smoke-host
+make readyshell-vm-smoke-host
+make readyshell-reu-tests-host
+
+make verify now runs:
+
+That aggregate target runs:
+
+readyshell-parse-smoke-host
+readyshell-vm-smoke-host
+readyshell-reu-tests-host
+
+3. End-To-End Shape
+native clang build
|
+--> parser smoke binary
| uses real parser sources
@@ -210,155 +245,393 @@ Shape
|
`--> REU/value test binary
uses real value, serialization, and LDV-side helpers
- with mocked REU backing
-
-
-
-
-
Parser Smoke
-
Compiles the real parser and checks the documented syntax surface plus malformed-input rejection.
-
- Expressions, statements, and command forms
- Command, expression, filter, and foreach pipeline stages
- Arrays, ranges, indexing, and property access
- Error code and position reporting
-
-
-
-
VM Smoke
-
Runs the real VM with mocked platform edges and a mocked overlay-command layer.
-
- Assignments, filters, foreach, `PRT`, `GEN`, `TOP`, `MORE`, `SEL`
- Pipeline capture shape rules and nested array/object access
- `LST`, `DRVI`, `LDV`, and `STV` with mocked platform/file I/O
- Overlay-side `CAT`, `PUT`, `ADD`, `DEL`, `REN`, and `COPY`
-
-
-
-
REU Tests
-
Validates REU-backed value persistence, nested graph round-trips, and malformed RSV1 rejection.
-
- String, array, object, and nested graph cloning
- Representative scalar, array, and object file-byte checks
- Serialization, deserialization, and loader rejection paths
- `LDV` heap reconstruction path
-
-
-
-
-
-
-
What Gets Mocked
-
- REU becomes a 16 MB in-process byte array.
- `LST` sees a synthetic fixed directory.
- `DRVI` sees synthetic drive metadata.
- `rs_overlay_command_call()` is stubbed in the overlay-aware host pass.
- Overlay debug marking becomes a no-op.
- Fixed C64 high-RAM flags become ordinary host globals.
-
-
- The host harness preserves the logical REU offsets, scratch layout, and
- heap metadata model. It does not preserve DMA behavior or true hardware
- probing.
-
-
-
-
What Runs Real Code
-
- The real lexer and parser
- The real generic VM
- The real C64-oriented VM dispatch path in the overlay-aware pass
- The real value model and formatting logic
- The real serialization logic
- The real REU-backed value reconstruction helpers
- The real external-command capability model
-
-
- The harness is valuable specifically because it executes the real core
- logic and only fakes the hardware boundary.
-
-
-
-
-
-
-
How It Handles C64 Differences
-
- REU access is abstracted behind rs_reu_available, rs_reu_read, and rs_reu_write.
- Platform services are abstracted behind RSVMPlatform callbacks.
- Fixed-address state is replaced with ordinary host globals when not compiling under __CC65__.
- The host path tests the overlay command ABI rather than emulating PRG loading and ROM banking.
-
-
-
-
What It Does Not Cover
-
- The text UI and prompt editor
- PETSCII and keyboard quirks in the live shell
- Real IEC or KERNAL file I/O
- Actual overlay PRG loading from disk
- REU cache restore and verification failures
- BASIC ROM banking and IRQ-state bugs
- cc65 memory pressure and stack behavior
- Timing-sensitive issues
-
-
-
-
-
- Coverage Notes
-
-
- Area Host Coverage
-
-
- Parser, expressions, pipeline semantics Strong
- `PRT`, `GEN`, `MORE`, `TOP`, `SEL` Strong
- `LST`, `DRVI` formatting and downstream behavior Strong, but mocked
- REU-backed value persistence and `LDV` reconstruction Strong
- `LDV` / `STV` real media behavior Partial
- `CAT`, `PUT`, `ADD`, `DEL`, `REN`, `COPY` media behavior Weak to none
- Overlay loading and REU cache restore Not covered
- UI loop and real C64 integration Not covered
-
-
-
-
-
-
-
How To Read Failures
-
- If parser smoke fails, suspect lexer/parser changes first.
- If generic VM smoke fails, suspect evaluation or pipeline logic.
- If only the overlay-aware VM pass fails, suspect external-command protocol handling.
- If REU tests fail, suspect serialization or REU-backed value layout.
- If host tests pass but C64 behavior fails, suspect overlays, banking, REU DMA, or disk integration.
-
-
-
-
Recommended Workflow
-
- Run the host checks while iterating on parser, VM, or value logic.
- Run make verify for the normal repo verification path.
- Run ReadyOS through the supported run.sh workflow for actual C64/VICE validation.
-
-
- Host success is useful evidence, not final proof. The harness stops at
- the hardware boundary by design.
-
-
-
-
-
- Bottom Line
-
- ReadyShell host testing is intentionally a logic harness, not a hardware
- emulator. Its strength is fast execution of the real parser, VM, value,
- and REU-data-path code. Its weakness is that it cannot validate the real
- C64 overlay loader, memory map, disk environment, or UI loop.
-
-
-
+ with mocked REU backing
+4. What Each Target Actually
+Tests
+4.1
+readyshell-parse-smoke-host
+This target compiles the real parser sources and calls
+rs_parse_source() directly.
+What it covers:
+
+parsing the documented expression, statement, and command forms
+parsing command, expression, filter, and foreach pipeline
+stages
+parsing multi-statement lines, array literals, ranges, indexing, and
+property access
+parser rejection paths
+error code, message, line, and column reporting
+
+What it does not cover:
+
+execution
+REU use
+overlays
+platform callbacks
+shell UI behavior
+
+4.2
+readyshell-vm-smoke-host
+This target has two passes.
+The first pass links the generic VM path and injects platform
+callbacks for directory listing, drive info, and mocked snapshot file
+I/O.
+What it covers:
+
+expression evaluation
+assignments
+pipeline capture shape rules (0 -> FALSE,
+1 -> scalar, 2+ -> array)
+filters
+foreach stages
+PRT
+GEN
+TOP
+MORE
+SEL
+nested arrays, indexing, and property access through variables
+SEL single-property scalar projection vs multi-property
+object projection
+array and object access
+LST through a mocked directory listing provider
+DRVI through a mocked drive-info provider
+LDV / STV through mocked binary file
+read/write callbacks
+pause-flag behavior stored in REU metadata
+
+The second pass links the C64-oriented VM dispatch path and exercises
+the resident-to-external-command protocol through a mocked
+rs_overlay_command_call().
+What that second pass adds:
+
+external command capability handling
+BEGIN / ITEM iteration flow
+RUN command flow
+C64-side external command dispatch shape
+DRVI and LST through the overlay command
+ABI instead of the generic RSVMPlatform callbacks
+mocked CAT, PUT, ADD,
+DEL, REN, and COPY flows through
+the overlay command ABI
+mocked overlay-side LDV / STV argument
+handling, including explicit drive forms
+
+What this target still does not cover:
+
+real PRG overlay loading from disk
+REU overlay cache restore and verification
+ROM banking under BASIC
+the actual shell UI loop
+IEC/KERNAL disk transport or true-drive timing
+
+4.3
+readyshell-reu-tests-host
+This target is closer to a unit test suite for REU-backed value
+handling.
+What it covers:
+
+drive-prefix parsing and canonicalization helpers
+REU heap reset behavior
+cloning strings into REU-backed storage
+cloning arrays into REU-backed storage
+cloning objects into REU-backed storage
+cloning nested array/object graphs into REU-backed storage
+reading arrays and objects back out
+file-payload serialization
+file-payload deserialization
+exact representative RSV1 byte-shape checks for scalar,
+array, and object files
+equality after round-trip
+the LDV-side loader that reconstructs values from the
+REU scratch area
+malformed RSV1 rejection paths
+
+What it does not cover:
+
+real file I/O
+real STV / LDV disk transport
+real overlay PRG loading
+shell UI or command-line interaction
+
+5. What Gets Mocked
+The host harness deliberately mocks only the edges where the real
+ReadyShell implementation meets C64-specific hardware or media.
+5.1 Mocked REU Backend
+The host REU implementation is a 16 MB byte array in process
+memory.
+Behavior:
+
+rs_reu_available() always returns true
+rs_reu_read() and rs_reu_write() become
+bounds-checked memcpy operations
+the same absolute REU offsets and shared metadata regions are still
+used
+
+What this preserves:
+
+REU address discipline
+scratch-region conventions
+REU heap layout and metadata validation
+shared pause-flag storage
+
+What this skips:
+
+DMA timing
+bank-switch edge cases
+transfer failures caused by hardware state
+probe logic for actual REU presence
+
+
+The generic VM harness injects synthetic implementations for:
+
+directory listing
+drive information
+
+LST always sees a small fixed directory with entries
+like:
+
+DRVI always sees predictable drive metadata such as:
+
+drive number
+disk name readyos
+ID ro
+free blocks 664
+
+This lets the host VM test selection, formatting, indexing, and
+downstream pipeline behavior without touching IEC or disk images.
+5.3 Mocked Overlay Command ABI
+The overlay-aware host pass does not load real overlay PRGs.
+Instead, it replaces rs_overlay_command_call() with a
+stub that simulates:
+
+LST as a BEGIN + repeated
+ITEM stream
+DRVI as a RUN command
+
+This is important because it validates the resident VM’s
+command-protocol handling:
+
+command capability bits
+BEGIN
+ITEM
+RUN
+iteration count handling
+result propagation into downstream pipeline stages
+
+It does not validate the real overlay loader or REU cache.
+5.4 Overlay Debug Marking
+The host build turns overlay debug marking into a no-op.
+That keeps the signatures satisfied for code that expects the hook,
+without pretending the host process is reproducing the real C64
+overlay-debug path.
+6. What Runs Real Code
+Large parts of ReadyShell are not mocked in host mode.
+The host harness still uses the real:
+
+parser
+lexer
+error model
+generic VM
+C64-oriented VM dispatcher for the overlay-aware pass
+value model
+array/object access logic
+formatting logic
+serialization logic
+LDV-side heap reconstruction helpers
+external command capability model
+
+That is the main value of the harness: logic changes in these areas
+fail fast without requiring a full ReadyOS boot.
+7. How It Deals
+With C64 Architectural Differences
+The host harness does not try to re-create the entire C64 memory map.
+Instead, it isolates the portable logic behind small interfaces and
+substitutes only the hardware boundary.
+7.1 REU Access Is Abstracted
+ReadyShell core code talks to:
+
+rs_reu_available()
+rs_reu_read()
+rs_reu_write()
+
+On the real C64 build, these go through REU DMA.
+On the host build, they go through the in-memory REU mock.
+This keeps the logical REU contract intact while removing hardware
+timing from the test path.
+
+The generic VM talks to an RSVMPlatform structure for
+operations like:
+
+file read
+file write
+directory list
+drive info
+
+The host harness only supplies the callbacks needed for the scenarios
+under test. Everything else stays unavailable by design.
+That is useful because it makes missing coverage obvious. If a
+command needs real file I/O and no callback is provided, the generic VM
+path reports that the command is unavailable on that platform.
+7.3 Fixed C64 RAM
+State Becomes Plain Host State
+The real app has fixed RAM assumptions, for example:
+
+runtime state at $CA00-$CFFF
+REU/session flags in fixed high-RAM bytes
+a much smaller tap-log budget under cc65 constraints
+
+In host mode:
+
+those fixed-address flags become normal globals
+the process uses the native heap
+some buffers are intentionally larger than the cc65 build
+
+This means host tests preserve logic and data-format contracts, but
+not the exact memory pressure or placement constraints of the C64
+build.
+7.4 The
+Overlay ABI Is Tested, Not The Overlay Loader
+The C64 build must:
+
+map RAM under BASIC
+preserve IRQ state
+load overlay PRGs through KERNAL/CBM paths
+cache overlays into REU
+restore them into the shared window
+
+The host harness does not emulate that mechanism.
+Instead, it tests one layer up:
+
+command protocol correctness
+output/result shaping
+resident/external command dispatch expectations
+
+That is a deliberate tradeoff. It is much faster, but it leaves real
+overlay loading and banking to C64/VICE verification.
+8. Important Limitations
+The host harness has real value, but it is intentionally
+incomplete.
+It does not validate:
+
+shell prompt editing
+keyboard normalization and PETSCII quirks
+screen rendering
+pause/resume key handling in the live UI
+true-drive behavior
+KERNAL disk I/O side effects
+actual disk-mounted file access
+overlay PRG loading from disk
+REU cache restore failures
+BASIC/ROM banking mistakes
+cc65 stack pressure
+C64 heap fragmentation behavior
+timing-sensitive bugs
+launch/shim/resume interactions across the full ReadyOS boot
+flow
+
+In practice, that means host success proves:
+
+parser/VM/value logic is probably correct
+REU data-format logic is probably correct
+external command protocol handling is probably correct
+
+It does not prove:
+
+the feature works inside the shipped ReadyOS app on a real C64
+memory map
+the feature survives overlay swaps
+the feature survives real disk and drive behavior
+
+9. Coverage Notes By Command
+Family
+Host coverage is strongest for:
+
+parser behavior
+expression and pipeline semantics
+PRT
+GEN
+MORE
+TOP
+SEL
+LST formatting and downstream selection behavior
+DRVI formatting and downstream selection behavior
+REU-backed value persistence and reconstruction
+
+Host coverage is partial or protocol-only for:
+
+LDV
+STV
+external command overlay dispatch
+
+Host coverage is effectively absent for real media behavior of:
+
+CAT
+PUT
+ADD
+DEL
+REN
+COPY
+
+Those still need C64/VICE validation through the normal ReadyOS
+workflow.
+10. How To Interpret Failures
+Use host failures to narrow the problem layer.
+If readyshell-parse-smoke-host fails:
+
+suspect lexer/parser changes first
+
+If the generic part of readyshell-vm-smoke-host
+fails:
+
+suspect parser-to-VM semantics
+suspect expression/pipeline execution logic
+suspect value formatting or pipeline stage behavior
+
+If only the overlay-aware part of
+readyshell-vm-smoke-host fails:
+
+suspect external-command protocol handling
+suspect C64 VM dispatch integration
+suspect command capability or frame-shaping logic
+
+If readyshell-reu-tests-host fails:
+
+suspect REU-backed value layout
+suspect serialization/deserialization
+suspect LDV-side heap reconstruction helpers
+
+If host tests pass but the app still fails in ReadyOS:
+
+suspect overlay loading
+suspect memory-map or banking behavior
+suspect KERNAL/IEC disk behavior
+suspect REU DMA or cache restore behavior
+suspect UI-only integration issues
+
+11. Recommended Use
+The current host harness is best used as a fast first gate:
+
+run host checks while iterating on parser/VM/value logic
+run full make verify for the normal repo path
+run ReadyOS through the supported run.sh workflow for
+C64/VICE validation
+
+That ordering keeps feedback fast without confusing host-level
+success for full platform-level correctness.
+12. Bottom Line
+ReadyShell host testing is intentionally a logic harness, not a
+hardware emulator.
+Its strength is that it executes the real parser, VM, value, and
+REU-data-path code very quickly on the host. Its weakness is that it
+stops at the hardware boundary and cannot prove correctness of the real
+C64 overlay, memory-map, or disk environment.
+That separation is deliberate and useful, as long as host-test
+success is treated as one layer of evidence rather than final proof.
diff --git a/docs/readybasic_memory_diagrams.html b/docs/readybasic_memory_diagrams.html
index e5bab47..f59a8e8 100644
--- a/docs/readybasic_memory_diagrams.html
+++ b/docs/readybasic_memory_diagrams.html
@@ -111,6 +111,9 @@
+
+CURRENT DOCUMENT Current generated ReadyBASIC memory visualization. Regenerate after linker or module-layout changes.
+
ReadyBASIC Memory Diagrams
@@ -119,7 +122,7 @@
ReadyBASIC Memory Diagrams
$2AC1 BASIC start; 30013 formula free bytes.
3 x 2K Command submodule slots at $A800, $B000, and $B800.
loader-assigned Runtime registry bank plus payload bank.
-
2.3K Current built-in command payload bytes in the assigned payload bank.
+
11.3K Current built-in command payload bytes in the assigned payload bank.
@@ -134,8 +137,8 @@ ReadyBASIC Memory Diagrams
Whole C64 RAM: ReadyOS Contract And ReadyBASIC Runtime
- ReadyOS snapshots app RAM from $1000-$C5FF. ReadyBASIC stays inside that contract, while using RAM behind BASIC ROM for command payloads and loader-assigned REU resource banks for durable runtime state.
- Zero page $0000-$00FF 256B
C64/BASIC/KERNAL zero page; cc65 ZP is not stomped. Stack $0100-$01FF 256B
Hardware stack. Vectors, buffers, screen $0200-$0FFF 3.5K
Includes page-3 hooks, input buffer, screen RAM, and low BASIC/system RAM. ReadyBASIC entry $1000-$10F1 242B
Cold/warm discriminator and early copies. ReadyBASIC resident $1200-$2AB0 6.2K
Parser, hooks, ROM calls, REU DMA, PROC/FUNC, flow control, command dispatch. BASIC sentinel $2AC0-$2AC0 1B
Must be zero before stored-program RUN. BASIC workspace $2AC1-$9FFF 29.3K
Program text, variables, arrays, strings, and reclaimed cold-load seed space. Under BASIC ROM $A000-$BFFF 8K
Common helper plus three 2K command submodule slots. Bridge and frames $C000-$C5FF 1.5K
Bridge through $C1F6, shared frames and buffers through $C5FF. ReadyOS REU metadata $C600-$C7FF 0.5K
Allocation table and system metadata; not ReadyBASIC scratch. ReadyOS shim ABI $C800-$C9FF 0.5K
Resident jump table/data. High RAM gap $CA00-$CFFF 1.5K
Outside app snapshot and below I/O. I/O / color $D000-$DFFF 4K
REU registers at $DF00-$DF0A when I/O visible. KERNAL ROM $E000-$FFFF 8K
Normally visible after banking is restored.
+ ReadyOS snapshots app RAM from $1000-$C5FF. The resident 1 KB shim owns $C600-$C9FF, while ReadyBASIC deliberately keeps its custom compact image and bridge shape through $C5FF; its custom assembler/linker contract must remain compatible with this exact shape. Loader-assigned REU resource banks hold durable module state.
+ Zero page $0000-$00FF 256B
C64/BASIC/KERNAL zero page; cc65 ZP is not stomped. Stack $0100-$01FF 256B
Hardware stack. Vectors, buffers, screen $0200-$0FFF 3.5K
Includes page-3 hooks, input buffer, screen RAM, and low BASIC/system RAM. ReadyBASIC entry $1000-$11FF 0.5K
Cold/warm discriminator and early copies. ReadyBASIC resident $1200-$2ABF 6.2K
Parser, hooks, ROM calls, REU DMA, PROC/FUNC, flow control, command dispatch. BASIC sentinel $2AC0-$2AC0 1B
Must be zero before stored-program RUN. BASIC workspace $2AC1-$9FFF 29.3K
Program text, variables, arrays, strings, and reclaimed cold-load seed space. Under BASIC ROM $A000-$BFFF 8K
Common helper plus three 2K command submodule slots. Bridge and frames $C000-$C5FF 1.5K
Bridge through $C1FE, shared frames and buffers through $C5FF. ReadyOS shim expansion reserve $C600-$C7FF 0.5K
Resident capacity reserved for future shim functionality; not app RAM. ReadyOS shim ABI $C800-$C9FF 0.5K
Resident jump table/data; public addresses remain stable. High RAM gap $CA00-$CFFF 1.5K
Outside app snapshot and below I/O. I/O / color $D000-$DFFF 4K
REU registers at $DF00-$DF0A when I/O visible. KERNAL ROM $E000-$FFFF 8K
Normally visible after banking is restored.
@@ -144,23 +147,26 @@ ReadyBASIC Before And After BASIC Initialization
Before BASIC Is Initialized: Seed Bytes Are Temporary
The PRG load image temporarily occupies ranges that will later be BASIC workspace. Cold entry copies those bytes into their runtime homes and REU.
-
Sentinel/pad $2AC0-$2AFF 64B
Cold padding before command seed bytes. CMDPACK seed window $2B00-$3FFF 5.2K
Built-in module payload seed; prestashed into the assigned code bank before BASIC owns this RAM. HIDLOAD helper seed $4000-$4431 1K
Copied to $A000 and $C280 shadow. HIDLOAD reserved tail $4432-$47FF 1K
Reserved load window tail. BRLOAD bridge seed $4800-$49FA 0.5K
Copied to $C000 bridge state. BRLOAD reserved tail $49FB-$4FFF 1.5K
Reserved load window tail. REGSEED registry $5000-$600F 4K
Header plus 128 command descriptors; prestashed into the assigned core bank. REGSEED reserved tail $6010-$61FF 496B
Reserved load window tail. Future BASIC bytes $6200-$9FFF 15.5K
Also reclaimed by BASIC after cold setup.
+
Sentinel/pad $2AC0-$2AFF 64B
Cold padding before command seed bytes. CMDPACK seed window $2B00-$3FFF 5.2K
Built-in module payload seed; prestashed into the assigned code bank before BASIC owns this RAM. HIDLOAD helper seed $4000-$478A 1.9K
Copied to $A000 and REU core-bank $3000 shadow. HIDLOAD reserved tail $478B-$47FF 117B
Reserved load window tail. BRLOAD bridge seed $4800-$49FE 0.5K
Copied to $C000 bridge state. BRLOAD reserved tail $49FF-$4FFF 1.5K
Reserved load window tail. REGSEED registry $5000-$600F 4K
Header plus 128 command descriptors; prestashed into the assigned core bank. REGSEED reserved tail $6010-$61FF 496B
Reserved load window tail. CMDPACK2 overlay seed window $6200-$7FFF 7.5K
Additional built-in overlay payload seed; prestashed into sparse assigned code-bank offsets. Future BASIC bytes $8000-$9FFF 8K
Also reclaimed by BASIC after cold setup.
After BASIC Is Initialized: Workspace Is Reclaimed
BASIC owns $2AC1-$9FFF. The command registry and payload bytes are authoritative in REU, not in the old load-image addresses.
-
Resident ReadyBASIC $1200-$2AB0 6.2K
Still live in visible RAM. BASIC workspace $2AC1-$9FFF 29.3K
Former seed bytes are user BASIC memory now. Under-ROM command slots $A000-$BFFF 8K
Fetched from the assigned code bank on demand. Bridge/frames $C000-$C5FF 1.5K
Bridge and shared command frames.
+
Resident ReadyBASIC $1200-$2ABF 6.2K
Still live in visible RAM. BASIC workspace $2AC1-$9FFF 29.3K
Former seed bytes are user BASIC memory now. Under-ROM command slots $A000-$BFFF 8K
Fetched from the assigned code bank on demand. Bridge/frames $C000-$C5FF 1.5K
Bridge and shared command frames.
Inside The Cold CMDPACK Seed Window
- This is the built-in command/module payload portion that is prestashed contiguously into the loader-assigned ReadyBASIC payload bank.
- Slot 0 payload seed $2B00-$31D0 1.7K
Module 1 system/default payload; runtime $A800-$AED0. ZECHO1 ZADD16 UPPER LOWER ZHIDDENRAM ZSUMNUMARRAY ZRANGENUMARRAY BUFNEW BUFFILL BUFFREE ZTEMPSCRATCH ZFAIL FREEMEM SCRCAP FADD ZPAUSE ERRCODE ERRLINE ZSLOT0 ZCPYRST ZCOPY SCRPUT
Slot 1 payload seed $31D1-$340B 0.6K
Module 2 proof and loader payload; runtime $B000-$B23A. ZSLOT1 ZMODLD
Slot 2 base seed $340C-$3420 21B
Module 2 slot-2 proof payload; runtime $B800-$B814. ZSLOT2
Span seed $3421-$3435 21B
Two-slot proof payload; runtime $B000-$B014. ZSPAN
Overlay 1 seed $3436-$344A 21B
Slot-2 overlay proof payload; runtime $B815-$B829. ZOVL1
Overlay 2 seed $344B-$345F 21B
Slot-2 overlay proof payload; runtime $B82A-$B83E. ZOVL2
CMDPACK free seed room $3460-$3FFF 2.9K
Unused cold-load seed capacity.
+ This is the original built-in command/module payload portion that is prestashed into the loader-assigned ReadyBASIC payload bank.
+ Slot 0 payload seed $2B00-$32DB 2K
Module 1 system/default payload; runtime $A800-$AFDB. ZECHO1 ZADD16 UPPER LOWER ZHIDDENRAM ZSUMNUMARRAY ZRANGENUMARRAY BUFMAKE BUFFILL BUFDROP ZTEMPSCRATCH ZFAIL MEMAVL SCRCAP FADD ZPAUSE ERRCODE ERRLINE ZSLOT0 ZCPYRST ZCOPY GFXSURF GFXTGT GFXBLIT SCRPUT
Slot 1 payload seed $32DC-$381C 1.3K
Module 2 proof, loader, and GFXCORE payload; runtime $B000-$B540. ZSLOT1 ZMODLD GFXMODE GFXTEXT GFXCLEAR GFXSYNC
Slot 2 base seed $381D-$3F54 1.8K
Module 2 slot-2 proof plus GFXPRIM payload; runtime $B800-$BF37. ZSLOT2 PLOT PNT LINE RECT FBOX CIRCLE FCIRCLE TILE CHARAT
Span seed $3F55-$3F69 21B
Two-slot proof payload; runtime $B000-$B014. ZSPAN
CMDPACK free seed room $3F6A-$3FFF 150B
Unused cold-load seed capacity.
+ Inside The Cold CMDPACK2 Overlay Seed Window
+ This second cold-only seed window carries built-in replacement overlays and is stashed into sparse, fixed REU code offsets before BASIC owns the memory.
+ Overlay 1 seed $6200-$6471 0.6K
Slot-2 replacement overlay; runtime $B800-$BA71; REU code offset $5000. ZOVL1
Overlay 2 seed $6472-$64DE 109B
Slot-2 replacement overlay; runtime $B800-$B86C; REU code offset $5800. ZOVL2
Overlay 3 seed $64DF-$6C57 1.9K
Slot-2 replacement overlay; runtime $B800-$BF78; REU code offset $6000. POLY FPOLY PBMAKE PBUFSET PBDROP POLYH FPOLYH
Overlay 4 seed $6C58-$73DA 1.9K
Slot-2 replacement overlay; runtime $B800-$BF82; REU code offset $6800. DLMAKE DLRST DLPLOT DLLINE DLRECT DLFBOX DLDRAW
Overlay 5 seed $73DB-$78B4 1.2K
Slot-2 replacement overlay; runtime $B800-$BCD9; REU code offset $7000. CHRMAKE CHRROW CHRUSE TSMAKE TSSET TMMAKE TMSET TMDRAW MCELL MCBG
Overlay 6 seed $78B5-$7AC2 0.5K
Slot-2 replacement overlay; runtime $B800-$BA0D; REU code offset $7800. SIDRST SIDOFF VOL FRQ PITCH PULSE ADSR WAVE GATE VOICE FILTER SOUND
CMDPACK2 free seed room $7AC3-$7FFF 1.3K
Unused cold-load seed capacity.
The 6K Under-ROM Command Window
At runtime, command payloads are fetched from REU into one or more fixed 2K slots behind BASIC ROM. Small proof payloads are visually thickened here so they remain visible; the table below preserves exact byte counts.
- Slot 0 current $A800-$AED0 1.7K
Module 1 system/default payload. ZECHO1 ZADD16 UPPER LOWER ZHIDDENRAM ZSUMNUMARRAY ZRANGENUMARRAY BUFNEW BUFFILL BUFFREE ZTEMPSCRATCH ZFAIL FREEMEM SCRCAP FADD ZPAUSE ERRCODE ERRLINE ZSLOT0 ZCPYRST ZCOPY SCRPUT
Slot 0 free $AED1-$AFFF 303B
303B free inside slot 0. Slot 1 current $B000-$B23A 0.6K
Module 2 proof plus ZMODLD. ZSLOT1 ZMODLD
Slot 1 free $B23B-$B7FF 1.4K
1.4K free inside slot 1. Slot 2 current front $B800-$B83E 63B
Base proof plus two overlay proof slices in the slot-2 address space. ZSLOT2 ZOVL1 ZOVL2
Slot 2 free $B83F-$BFFF 1.9K
1.9K free inside slot 2.
+ Slot 0 current $A800-$AFDB 2K
Module 1 system/default payload. ZECHO1 ZADD16 UPPER LOWER ZHIDDENRAM ZSUMNUMARRAY ZRANGENUMARRAY BUFMAKE BUFFILL BUFDROP ZTEMPSCRATCH ZFAIL MEMAVL SCRCAP FADD ZPAUSE ERRCODE ERRLINE ZSLOT0 ZCPYRST ZCOPY GFXSURF GFXTGT GFXBLIT SCRPUT
Slot 0 free $AFDC-$AFFF 36B
36B free inside slot 0. Slot 1 current $B000-$B540 1.3K
Module 2 proof, ZMODLD, and GFXCORE. ZSLOT1 ZMODLD GFXMODE GFXTEXT GFXCLEAR GFXSYNC
Slot 1 free $B541-$B7FF 0.7K
0.7K free inside slot 1. Slot 2 GFXPRIM current $B800-$BF37 1.8K
Base proof plus GFXPRIM; replacement overlays load over this when called. ZSLOT2 PLOT PNT LINE RECT FBOX CIRCLE FCIRCLE TILE CHARAT
Slot 2 GFXPRIM free $BF38-$BFFF 200B
200B free in the GFXPRIM slot image. Slot 2 GFXSPR overlay $B800-$BA71 0.6K
Replacement overlay for sprite commands. ZOVL1 SPRSET SPRMOVE SPRROW SPRSIZE SPRPRI SPRMUL SPRCOL SPRMCO SPRSCAN SPRCOLL
Slot 2 GFXSPR free $BA72-$BFFF 1.4K
1.4K free in the GFXSPR overlay image. Slot 2 INPUTEV overlay $B800-$B86C 109B
Replacement overlay for polling input commands. ZOVL2 JOY KEYP KEYSCAN KEYLAST
Slot 2 INPUTEV free $B86D-$BFFF 1.9K
1.9K free in the INPUTEV overlay image. Slot 2 GFXPOLY overlay $B800-$BF78 1.9K
Replacement overlay for polygon and point-buffer commands. POLY FPOLY PBMAKE PBUFSET PBDROP POLYH FPOLYH
Slot 2 GFXPOLY free $BF79-$BFFF 135B
135B free in the GFXPOLY overlay image. Slot 2 GFXDL overlay $B800-$BF82 1.9K
Replacement overlay for retained display-list commands. DLMAKE DLRST DLPLOT DLLINE DLRECT DLFBOX DLDRAW
Slot 2 GFXDL free $BF83-$BFFF 125B
125B free in the GFXDL overlay image. Slot 2 GFXTILE overlay $B800-$BCD9 1.2K
Replacement overlay for charset, tileset, tilemap, and multicolor-cell commands. CHRMAKE CHRROW CHRUSE TSMAKE TSSET TMMAKE TMSET TMDRAW MCELL MCBG
Slot 2 GFXTILE free $BCDA-$BFFF 0.8K
0.8K free in the GFXTILE overlay image. Slot 2 SIDCORE overlay $B800-$BA0D 0.5K
Replacement overlay for immediate SID sound commands. SIDRST SIDOFF VOL FRQ PITCH PULSE ADSR WAVE GATE VOICE FILTER SOUND
Slot 2 SIDCORE free $BA0E-$BFFF 1.5K
1.5K free in the SIDCORE overlay image.
@@ -168,7 +174,7 @@ REU Picture
16MB REU Ownership Overview
-
ReadyOS control/global 64K
Logical bank 0 control/global state; launcher snapshot is Start+1 and Start+2 begins dynamic allocation. App snapshots 1536K
Historical low-bank snapshot capacity; current snapshots are launcher-assigned and resolved through logical bank 0. Logical bank 1 can map to Start+2. Legacy high-bank gap 384K
No current ReadyOS fixed resource assignment here; ReadyBASIC banks and ReadyShell diagnostics/scratch are no longer fixed in this range. Dynamic resources / free 11712K
Remaining 16MB REU space from Start+2 upward as banks become available, including launcher-assigned ReadyBASIC core/code resource banks.
+
ReadyOS bank 64K
Physical Skip: launcher snapshot at $0000-$B5FF plus schema-v5 mappings, status, clipboard, hotkeys, app/resource registry, catalog, audit, and runtime records at $B600-$FFFF. Dynamic pool 16320K
Physical Skip+1 through the detected end, shared by mapped app snapshots, ReadyBASIC/ReadyShell resources, clipboard payloads, and app-owned allocations. Physical Skip is reserved for ReadyOS.
ReadyBASIC Core Resource Bank: Registry/Runtime
@@ -176,7 +182,7 @@ ReadyBASIC Core Resource Bank: Registry/Runtime
ReadyBASIC Code Resource Bank: Built-In And Disk-Loaded Payloads
- Built-in payloads $0000-$095F 2.3K
Current built-in module/submodule payload blob prestashed from CMDPACK. Built-in free gap $0960-$14FF 2.9K
Free before current disk-module descriptor samples. rbm.sample1 descriptor $1500-$151F 32B
ZDM1 descriptor streamed by ZMODLD. ZDM1
rbm.sample2 descriptors $1600-$165F 96B
Three descriptors; submodule 5 appears twice as overlays 1 and 2. ZDM2S ZDOV1 ZDOV2
Free gap $1660-$2FFF 6.4K
Available packed-code space before sample payloads. rbm.sample3 descriptors $1700-$1ABF 0.9K
Thirty descriptors for the large SEQ package proof. ZSAA-ZUEB
rbm.sample1 payload $3000-$3014 21B
Module 3, submodule 1, slot 1. ZDM1
rbm.sample2 span payload $3200-$3214 21B
Module 4, submodule 2, slots 1+2. ZDM2S
rbm.sample2 overlay 1 $3300-$3314 21B
Module 4, submodule 5, overlay 1, slot 2. ZDOV1
rbm.sample2 overlay 2 $3400-$3414 21B
Module 4, submodule 5, overlay 2, slot 2. ZDOV2
rbm.sample3 group A $3800-$3C3C 1.1K
ZSAA-ZSEB payload records, submodule 6 overlays 1-5 with A/B entrypoints sharing one state byte inside each loaded overlay image. ZSAA-ZSEB
rbm.sample3 group B $3D00-$413C 1.1K
ZTAA-ZTEB payload records, submodule 7 overlays 1-5 with A/B entrypoints sharing one state byte inside each loaded overlay image. ZTAA-ZTEB
rbm.sample3 group C $4200-$463C 1.1K
ZUAA-ZUEB payload records, submodule 8 overlays 1-5 with A/B entrypoints sharing one state byte inside each loaded overlay image and using the slot 1+2 span mask. ZUAA-ZUEB
Payload bank free tail $463D-$FFFF 46.4K
Remaining space in the current single ReadyBASIC code bank.
+ Built-in base payloads $0000-$1469 5.1K
LOWPACK, SLOTPACK1, SLOTPACK2, and SPANPACK prestashed from CMDPACK. Built-in base free gap $146A-$14FF 150B
Free before current disk-module descriptor samples. rbm.sample1 descriptor $1500-$151F 32B
ZDM1 descriptor streamed by ZMODLD. ZDM1
rbm.sample2 descriptors $1600-$165F 96B
Three descriptors; submodule 5 appears twice as overlays 1 and 2. ZDM2S ZDOV1 ZDOV2
Free gap $1660-$2FFF 6.4K
Available packed-code space before sample payloads. rbm.sample3 descriptors $1700-$1ABF 0.9K
Thirty descriptors for the large SEQ package proof. ZSAA-ZUEB
rbm.sample1 payload $3000-$3014 21B
Module 3, submodule 1, slot 1. ZDM1
rbm.sample2 span payload $3200-$3214 21B
Module 4, submodule 2, slots 1+2. ZDM2S
rbm.sample2 overlay 1 $3300-$3314 21B
Module 4, submodule 5, overlay 1, slot 2. ZDOV1
rbm.sample2 overlay 2 $3400-$3414 21B
Module 4, submodule 5, overlay 2, slot 2. ZDOV2
rbm.sample3 group A $3800-$3C3C 1.1K
ZSAA-ZSEB payload records, submodule 6 overlays 1-5 with A/B entrypoints sharing one state byte inside each loaded overlay image. ZSAA-ZSEB
rbm.sample3 group B $3D00-$413C 1.1K
ZTAA-ZTEB payload records, submodule 7 overlays 1-5 with A/B entrypoints sharing one state byte inside each loaded overlay image. ZTAA-ZTEB
rbm.sample3 group C $4200-$463C 1.1K
ZUAA-ZUEB payload records, submodule 8 overlays 1-5 with A/B entrypoints sharing one state byte inside each loaded overlay image and using the slot 1+2 span mask. ZUAA-ZUEB
Free gap before built-in overlays $463D-$4FFF 2.4K
Available packed-code space before fixed built-in overlay offsets. Built-in GFXSPR overlay $5000-$5271 0.6K
Prestashed from CMDPACK2 and fetched into slot 2 when sprite commands run. ZOVL1 SPRSET SPRMOVE SPRROW SPRSIZE SPRPRI SPRMUL SPRCOL SPRMCO SPRSCAN SPRCOLL
GFXSPR reserved headroom $5272-$57FF 1.4K
Reserved so the overlay can grow toward a full 2K slot without moving INPUTEV. Built-in INPUTEV overlay $5800-$586C 109B
Prestashed from CMDPACK2 and fetched into slot 2 when input commands run. JOY KEYP KEYSCAN KEYLAST
INPUTEV reserved headroom $586D-$5FFF 1.9K
Reserved so the overlay can grow toward a full 2K slot without moving GFXPOLY. Built-in GFXPOLY overlay $6000-$6778 1.9K
Prestashed from CMDPACK2 and fetched into slot 2 when polygon commands run. POLY FPOLY PBMAKE PBUFSET PBDROP POLYH FPOLYH
GFXPOLY reserved headroom $6779-$67FF 135B
Reserved so the overlay can grow toward a full 2K slot without moving GFXDL. Built-in GFXDL overlay $6800-$6F82 1.9K
Prestashed from CMDPACK2 and fetched into slot 2 when display-list commands run. DLMAKE DLRST DLPLOT DLLINE DLRECT DLFBOX DLDRAW
GFXDL reserved headroom $6F83-$6FFF 125B
Reserved so the overlay can grow toward a full 2K slot without moving GFXTILE. Built-in GFXTILE overlay $7000-$74D9 1.2K
Prestashed from CMDPACK2 and fetched into slot 2 when charset/tile commands run. CHRMAKE CHRROW CHRUSE TSMAKE TSSET TMMAKE TMSET TMDRAW MCELL MCBG
GFXTILE reserved headroom $74DA-$77FF 0.8K
Reserved for charset/tile overlay growth. Built-in SIDCORE overlay $7800-$7A0D 0.5K
Prestashed from CMDPACK2 and fetched into slot 2 when sound commands run. SIDRST SIDOFF VOL FRQ PITCH PULSE ADSR WAVE GATE VOICE FILTER SOUND
SIDCORE reserved headroom $7A0E-$7FFF 1.5K
Reserved for immediate sound command growth. Payload bank free tail $8000-$FFFF 32K
Remaining space in the current single ReadyBASIC code bank.
@@ -198,16 +204,20 @@ Example In REU: Compact Stored Payloads
Exact Tables
Measured ReadyBASIC Segments
Range Segment Display size Exact bytes Detail Commands
- $1000-$10F1ENTRY 242B 242B Cold/warm entry.
-$1200-$2AB0RESIDENT 6.2K 6321B Visible ReadyBASIC core.
-$A000-$A431HIDDEN 1K 1074B Common under-ROM helper.
-$A800-$AED0LOWPACK 1.7K 1745B Slot 0 built-in payload. ZECHO1, ZADD16, UPPER, LOWER, ZHIDDENRAM, ZSUMNUMARRAY, ZRANGENUMARRAY, BUFNEW, BUFFILL, BUFFREE, ZTEMPSCRATCH, ZFAIL, FREEMEM, SCRCAP, FADD, ZPAUSE, ERRCODE, ERRLINE, ZSLOT0, ZCPYRST, ZCOPY, SCRPUT
-$B000-$B23ASLOTPACK1 0.6K 571B Slot 1 proof/loader payload. ZSLOT1, ZMODLD
-$B800-$B814SLOTPACK2 21B 21B Slot 2 proof payload. ZSLOT2
+ $1000-$11FFENTRY 0.5K 512B Cold/warm entry.
+$1200-$2ABFRESIDENT 6.2K 6336B Visible ReadyBASIC core.
+$A000-$A78AHIDDEN 1.9K 1931B Common under-ROM helper.
+$A800-$AFDBLOWPACK 2K 2012B Slot 0 built-in payload. ZECHO1, ZADD16, UPPER, LOWER, ZHIDDENRAM, ZSUMNUMARRAY, ZRANGENUMARRAY, BUFMAKE, BUFFILL, BUFDROP, ZTEMPSCRATCH, ZFAIL, MEMAVL, SCRCAP, FADD, ZPAUSE, ERRCODE, ERRLINE, ZSLOT0, ZCPYRST, ZCOPY, GFXSURF, GFXTGT, GFXBLIT, SCRPUT
+$B000-$B540SLOTPACK1 1.3K 1345B Slot 1 proof/loader/GFXCORE payload. ZSLOT1, ZMODLD, GFXMODE, GFXTEXT, GFXCLEAR, GFXSYNC
+$B800-$BF37SLOTPACK2 1.8K 1848B Slot 2 proof/GFXPRIM payload. ZSLOT2, PLOT, PNT, LINE, RECT, FBOX, CIRCLE, FCIRCLE, TILE, CHARAT
$B000-$B014SPANPACK 21B 21B Two-slot proof payload. ZSPAN
-$B815-$B829OVL1PACK 21B 21B Slot 2 overlay proof. ZOVL1
-$B82A-$B83EOVL2PACK 21B 21B Slot 2 overlay proof. ZOVL2
-$C000-$C1FABRIDGE 0.5K 507B Persistent bridge state.
+$B800-$BA71OVL1PACK 0.6K 626B Slot 2 replacement overlay for GFXSPR. ZOVL1, SPRSET, SPRMOVE, SPRROW, SPRSIZE, SPRPRI, SPRMUL, SPRCOL, SPRMCO, SPRSCAN, SPRCOLL
+$B800-$B86COVL2PACK 109B 109B Slot 2 replacement overlay for INPUTEV. ZOVL2, JOY, KEYP, KEYSCAN, KEYLAST
+$B800-$BF78OVL3PACK 1.9K 1913B Slot 2 replacement overlay for GFXPOLY. POLY, FPOLY, PBMAKE, PBUFSET, PBDROP, POLYH, FPOLYH
+$B800-$BF82OVL4PACK 1.9K 1923B Slot 2 replacement overlay for GFXDL. DLMAKE, DLRST, DLPLOT, DLLINE, DLRECT, DLFBOX, DLDRAW
+$B800-$BCD9OVL5PACK 1.2K 1242B Slot 2 replacement overlay for GFXTILE. CHRMAKE, CHRROW, CHRUSE, TSMAKE, TSSET, TMMAKE, TMSET, TMDRAW, MCELL, MCBG
+$B800-$BA0DOVL6PACK 0.5K 526B Slot 2 replacement overlay for SIDCORE. SIDRST, SIDOFF, VOL, FRQ, PITCH, PULSE, ADSR, WAVE, GATE, VOICE, FILTER, SOUND
+$C000-$C1FEBRIDGE 0.5K 511B Persistent bridge state.
$5000-$600FREGSEED 4K 4112B Load-only registry seed.
Disk Module Proof Storage
diff --git a/docs/readyshell_overlay_inventory.html b/docs/readyshell_overlay_inventory.html
index e9d2d51..1094331 100644
--- a/docs/readyshell_overlay_inventory.html
+++ b/docs/readyshell_overlay_inventory.html
@@ -3,7 +3,7 @@
- ReadyShell Overlay Inventory Report (v0.2.4M)
+ ReadyShell Overlay Inventory Report (v0.2.5Y)
+
+CURRENT DOCUMENT Current artifact-backed ReadyShell overlay inventory for the version/profile named in the report.
+
- ReadyShell Overlay Inventory Report (v0.2.4M)
+ ReadyShell Overlay Inventory Report (v0.2.5Y)
Artifact-backed inventory for the current ReadyShell overlay system. This report is generated from the live build
- outputs, the ReadyShell linker map, and the active D71 disk image instead of hand-maintained notes.
+ outputs, the ReadyShell linker map, and the active D81 disk image instead of hand-maintained notes.
Executive Summary
-
-
Disk Source
Releases/0.2.4/precog-dual-d71/readyos-v0.2.4m-dual-d71_1.d71
+
+
Disk Source
Releases/0.2.5/precog-d81/readyos-v0.2.5y-d81.d81
Overlay Window
$8E00-$C5FF
-
+
Overlays 1-9 are boot-loaded once and cached in fixed full-window REU slots.
- Bank 0x38 holds overlays 1, 2, 3, and 5;
- bank 0x39 holds overlays 4, 6, 7, and 8;
- bank 0x3A holds overlay 9. Bank
+ Bank 0x36 holds overlays 1, 2, 3, and 5;
+ bank 0x37 holds overlays 4, 6, 7, and 8;
+ bank 0x38 holds overlay 9. Bank
0x48 is shared for the external-command registry, overlay metadata, pause state, command handoff scratch,
and the REU-backed ReadyShell value arena.
@@ -262,18 +265,18 @@ Executive Summary
Runtime Memory Map
- Resident app window: $1000-$C5FF (46592 bytes)
+ ReadyOS snapshot window: $1000-$C5FF (46592 bytes); the resident 1 KB shim begins at $C600.
Overlay load bytes: $8DFE-$8DFF
Overlay execution window: $8E00-$C5FF (14336 bytes)
- Resident BSS: $7D4D-$7EF6 (426 bytes)
- Resident heap: $7EF8-$8DFD (3846 bytes)
+ Resident BSS: $7DEB-$7F94 (426 bytes)
+ Resident heap: $7F96-$8DFD (3688 bytes)
High RAM runtime: $CA00-$CFFF (1536 bytes)
REU Layout
- Shared cache bank 1: $380000-$38FFFF (65536 bytes)Overlay 1 parse slot: $380000-$3837FF (14336 bytes)Overlay 2 exec slot: $383800-$386FFF (14336 bytes)Overlay 3 command slot: $387000-$38A7FF (14336 bytes)Overlay 5 command slot: $38A800-$38DFFF (14336 bytes)Cache bank 1 free tail: $38E000-$38FFFF (8192 bytes)Shared cache bank 2: $390000-$39FFFF (65536 bytes)Overlay 4 command slot: $390000-$3937FF (14336 bytes)Overlay 6 command slot: $393800-$396FFF (14336 bytes)Overlay 7 command slot: $397000-$39A7FF (14336 bytes)Overlay 8 command slot: $39A800-$39DFFF (14336 bytes)Cache bank 2 free tail: $39E000-$39FFFF (8192 bytes)Shared cache bank 3: $3A0000-$3AFFFF (65536 bytes)Overlay 9 editor slot: $3A0000-$3A37FF (14336 bytes)Cache bank 3 free tail: $3A3800-$3AFFFF (51200 bytes)Debug trace ring: $3B7DE0-$3B7FEF (528 bytes)Command scratch: $3B0000-$3B7DDF (32224 bytes)Command registry header: $3B8010-$3B8017 (8 bytes)Command descriptor table: $3B8020-$3B807F (96 bytes)Overlay state table: $3B8080-$3B80EB (108 bytes)Shared metadata: $3B80F0-$3B8113 (36 bytes)Pause flag: $3B8114 (1 byte)Heap metadata: $3B8000-$3B80FFHeap arena: $3B8120-$3BFEFF (32224 bytes)
+ Shared cache bank 1: $360000-$36FFFF (65536 bytes)Overlay 1 parse slot: $360000-$3637FF (14336 bytes)Overlay 2 exec slot: $363800-$366FFF (14336 bytes)Overlay 3 command slot: $367000-$36A7FF (14336 bytes)Overlay 5 command slot: $36A800-$36DFFF (14336 bytes)Cache bank 1 free tail: $36E000-$36FFFF (8192 bytes)Shared cache bank 2: $370000-$37FFFF (65536 bytes)Overlay 4 command slot: $370000-$3737FF (14336 bytes)Overlay 6 command slot: $373800-$376FFF (14336 bytes)Overlay 7 command slot: $377000-$37A7FF (14336 bytes)Overlay 8 command slot: $37A800-$37DFFF (14336 bytes)Cache bank 2 free tail: $37E000-$37FFFF (8192 bytes)Shared cache bank 3: $380000-$38FFFF (65536 bytes)Overlay 9 editor slot: $380000-$3837FF (14336 bytes)Cache bank 3 free tail: $383800-$38FFFF (51200 bytes)Debug trace ring: $397DE0-$397FEF (528 bytes)Command scratch: $390000-$397DDF (32224 bytes)Command registry header: $398010-$398017 (8 bytes)Command descriptor table: $398020-$39807F (96 bytes)Overlay state table: $398080-$3980EB (108 bytes)Shared metadata: $3980F0-$398113 (36 bytes)Pause flag: $398114 (1 byte)Heap metadata: $398000-$3980FFHeap arena: $398120-$39FEFF (32224 bytes)
@@ -282,38 +285,38 @@ REU Layout
Shared REU Bank Visual
-
Bank 0x38: Overlay Cache
+
Bank 0x36: Overlay Cache
-
Overlay 1 parse slot $380000-$3837FFFull 0x3800-byte window image for rsparser.prg. Live payload is 13005 bytes, but the cache stores the whole overlay window so writable overlay data survives phase switching.
-
Overlay 2 exec slot $383800-$386FFFFull 0x3800-byte window image for rsvm.prg. Live payload is 14028 bytes.
-
Overlay 3 command slot $387000-$38A7FFFull window snapshot for rsdrvilst.prg, serving both DRVI and LST.
-
Overlay 5 command slot $38A800-$38DFFFFull window snapshot for rsstv.prg.
-
Free tail $38E000-$38FFFF8192 bytes left free after the four cache slots in assigned bank 0x38.
+
Overlay 1 parse slot $360000-$3637FFFull 0x3800-byte window image for rsparser.prg. Live payload is 13005 bytes, but the cache stores the whole overlay window so writable overlay data survives phase switching.
+
Overlay 2 exec slot $363800-$366FFFFull 0x3800-byte window image for rsvm.prg. Live payload is 14028 bytes.
+
Overlay 3 command slot $367000-$36A7FFFull window snapshot for rsdrvilst.prg, serving both DRVI and LST.
+
Overlay 5 command slot $36A800-$36DFFFFull window snapshot for rsstv.prg.
+
Free tail $36E000-$36FFFF8192 bytes left free after the four cache slots in assigned bank 0x36.
-
Bank 0x39: Overlay Cache
+
Bank 0x37: Overlay Cache
-
Overlay 4 command slot $390000-$3937FFFull window snapshot for rsldv.prg.
-
Overlay 6 command slot $393800-$396FFFFull window snapshot for rsfops.prg.
-
Overlay 7 command slot $397000-$39A7FFFull window snapshot for rscat.prg.
-
Overlay 8 command slot $39A800-$39DFFFFull window snapshot for rscopy.prg.
-
Free tail $39E000-$39FFFF8192 bytes left free after the four cache slots in assigned bank 0x39.
+
Overlay 4 command slot $370000-$3737FFFull window snapshot for rsldv.prg.
+
Overlay 6 command slot $373800-$376FFFFull window snapshot for rsfops.prg.
+
Overlay 7 command slot $377000-$37A7FFFull window snapshot for rscat.prg.
+
Overlay 8 command slot $37A800-$37DFFFFull window snapshot for rscopy.prg.
+
Free tail $37E000-$37FFFF8192 bytes left free after the four cache slots in assigned bank 0x37.
-
Bank 0x3A: Editor Overlay Cache
+
Bank 0x38: Editor Overlay Cache
-
Overlay 9 prompt editor slot $3A0000-$3A37FFFull window snapshot for rsedit.prg. Live payload is 2002 bytes, leaving room inside this cache bank for future editor-side state.
-
Free tail $3A3800-$3AFFFF51200 bytes left free after the editor slot in assigned bank 0x3A.
+
Overlay 9 prompt editor slot $380000-$3837FFFull window snapshot for rsedit.prg. Live payload is 2002 bytes, leaving room inside this cache bank for future editor-side state.
+
Free tail $383800-$38FFFF51200 bytes left free after the editor slot in assigned bank 0x38.
Bank 0x48: Shared Shell State
-
Command registry $3B8010-$3B80EBRegistry header, external-command descriptors, and per-overlay load/cache state stored in REU metadata so new external commands do not consume resident BSS.
-
Shared metadata + pause $3B80F0-$3B8114Overlay cache metadata record plus the shared pause bit used by the resident line printer and MORE.
-
Command scratch + value arena $3B0000-$3BFEFFCommand handoff scratch, REU heap metadata, and the persistent value arena for REU-backed strings, arrays, and objects.
+
Command registry $398010-$3980EBRegistry header, external-command descriptors, and per-overlay load/cache state stored in REU metadata so new external commands do not consume resident BSS.
+
Shared metadata + pause $3980F0-$398114Overlay cache metadata record plus the shared pause bit used by the resident line printer and MORE.
+
Command scratch + value arena $390000-$39FEFFCommand handoff scratch, REU heap metadata, and the persistent value arena for REU-backed strings, arrays, and objects.
@@ -338,7 +341,7 @@ Command Scratch And Value Arena Usage
- PRT, MORE, TOP, SEL, GEN, TAP 2 / rsvmNo direct use Indirect only Run inside the shared execution core. They do not stage command-local data in `$3B0000-$3B7DDF`; any REU-backed values are handled through the normal overlay-2 value/runtime paths. DRVI 3 / rsdrvilstNo No Reads drive header/status data and builds its output object in transient overlay-local RAM. LST 3 / rsdrvilstYes No Spools 28-byte directory records through `$3B0000-$3B7DDF` so `BEGIN`/`ITEM` can walk the listing without keeping the directory channel open. LDV 4 / rsldvYes Yes, writes persistent values Reads the RSV1 file into `$3B0000-$3B7DDF`, validates its header, then materializes strings, arrays, and objects into the REU heap arena `$3B8120-$3BFEFF`. STV 5 / rsstvYes Yes, reads existing pointer values Uses `$3B0000-$3B00FF` for session metadata and `$3B0100-$3B7DDF` for the outgoing RSV1 payload. When serializing pointer-backed values, it dereferences them from the persistent REU heap arena before flattening them into scratch. DEL, REN 6 / rsfopsNo No Issue DOS scratch/rename commands directly through command-channel I/O with no REU staging. PUT, ADD 6 / rsfopsYes No Use `$3B0000-$3B001F` for session metadata and `$3B0020-$3B7DDF` as a text spool for new/appended SEQ content before writing it back to disk. CAT 7 / rscatYes No Uses `$3B0000-$3B07FF` as a line-record table and `$3B0800-$3B7DDF` as the line-data spool so `ITEM` can replay file lines after the initial read pass. COPY 8 / rscopyNo No Uses its overlay-local 128-byte transfer buffer plus direct DOS copy/streamed file I/O. It does not use the shared command scratch or the persistent value arena.
+ PRT, MORE, TOP, SEL, GEN, TAP 2 / rsvmNo direct use Indirect only Run inside the shared execution core. They do not stage command-local data in `$390000-$397DDF`; any REU-backed values are handled through the normal overlay-2 value/runtime paths. DRVI 3 / rsdrvilstNo No Reads drive header/status data and builds its output object in transient overlay-local RAM. LST 3 / rsdrvilstYes No Spools 28-byte directory records through `$390000-$397DDF` so `BEGIN`/`ITEM` can walk the listing without keeping the directory channel open. LDV 4 / rsldvYes Yes, writes persistent values Reads the RSV1 file into `$390000-$397DDF`, validates its header, then materializes strings, arrays, and objects into the REU heap arena `$398120-$39FEFF`. STV 5 / rsstvYes Yes, reads existing pointer values Uses `$390000-$3900FF` for session metadata and `$390100-$397DDF` for the outgoing RSV1 payload. When serializing pointer-backed values, it dereferences them from the persistent REU heap arena before flattening them into scratch. DEL, REN 6 / rsfopsNo No Issue DOS scratch/rename commands directly through command-channel I/O with no REU staging. PUT, ADD 6 / rsfopsYes No Use `$390000-$39001F` for session metadata and `$390020-$397DDF` as a text spool for new/appended SEQ content before writing it back to disk. CAT 7 / rscatYes No Uses `$390000-$3907FF` as a line-record table and `$390800-$397DDF` as the line-data spool so `ITEM` can replay file lines after the initial read pass. COPY 8 / rscopyNo No Uses its overlay-local 128-byte transfer buffer plus direct DOS copy/streamed file I/O. It does not use the shared command scratch or the persistent value arena.
@@ -351,7 +354,7 @@ Static Audit Checks
the ReadyShell REU metadata packing or overlay registry capacities drift out of sync.
- Registry capacity check: `rs_cmd_registry.c` seeds `10` external command descriptors into `16` reserved descriptor slots and `6` overlay-state rows into `6` reserved state slots. Metadata packing check: ReadyShell control metadata starts in `$3B8000-$3B80FF`. Header uses `$3B8010-$3B8017`, descriptor rows reserve `$3B8020-$3B807F` with live rows ending at `$3B805B`, state rows reserve `$3B8080-$3B80EB` with live rows ending at `$3B80EB`, shared metadata uses `$3B80F0-$3B8113`, and the pause flag sits at `$3B8114` before the value arena at `$3B8120`. Non-overlap check: command scratch ends at `$3B7DDF` and REU heap metadata begins at `$3B8000`; the state table ends at `$3B80EB` and shared metadata begins at `$3B80F0`; shared metadata ends at `$3B8113` and the pause flag is `$3B8114`; the value arena begins at `$3B8120`. Cache-slot audit: ReadyShell caches overlays 1-9. Bank `0x38` carries overlays `1`, `2`, `3`, and `5`; bank `0x39` carries overlays `4`, `6`, `7`, and `8`; bank `0x3A` carries overlay `9`. Every slot is a full `14336`-byte overlay-window snapshot. Command-source audit: `DRVI` builds output only in overlay-local RAM; `LST` writes 28-byte directory records into shared scratch; `LDV` streams RSV1 payloads into scratch and materializes persistent values into the REU heap arena; `STV` serializes into scratch and dereferences pointer-backed values from the arena; `DEL` and `REN` issue direct DOS commands without REU staging; `PUT` and `ADD` use scratch metadata plus a text spool; `CAT` uses a scratch record table plus line-data spool; `COPY` stays overlay-local with `g_copy_buf[128]`.
+ Registry capacity check: `rs_cmd_registry.c` seeds `10` external command descriptors into `16` reserved descriptor slots and `6` overlay-state rows into `6` reserved state slots. Metadata packing check: ReadyShell control metadata starts in `$398000-$3980FF`. Header uses `$398010-$398017`, descriptor rows reserve `$398020-$39807F` with live rows ending at `$39805B`, state rows reserve `$398080-$3980EB` with live rows ending at `$3980EB`, shared metadata uses `$3980F0-$398113`, and the pause flag sits at `$398114` before the value arena at `$398120`. Non-overlap check: command scratch ends at `$397DDF` and REU heap metadata begins at `$398000`; the state table ends at `$3980EB` and shared metadata begins at `$3980F0`; shared metadata ends at `$398113` and the pause flag is `$398114`; the value arena begins at `$398120`. Cache-slot audit: ReadyShell caches overlays 1-9. Bank `0x36` carries overlays `1`, `2`, `3`, and `5`; bank `0x37` carries overlays `4`, `6`, `7`, and `8`; bank `0x38` carries overlay `9`. Every slot is a full `14336`-byte overlay-window snapshot. Command-source audit: `DRVI` builds output only in overlay-local RAM; `LST` writes 28-byte directory records into shared scratch; `LDV` streams RSV1 payloads into scratch and materializes persistent values into the REU heap arena; `STV` serializes into scratch and dereferences pointer-backed values from the arena; `DEL` and `REN` issue direct DOS commands without REU staging; `PUT` and `ADD` use scratch metadata plus a text spool; `CAT` uses a scratch record table plus line-data spool; `COPY` stays overlay-local with `g_copy_buf[128]`.
@@ -374,7 +377,7 @@ Overlay Inventory
- 1 Parser / Lexer rsparser.prgrsparser13007 52 13005 90.7% None directly; parse phase support. bank 0x38 slot $380000-$3837FF 2 Execution Core rsvm.prgrsvm14030 56 14028 97.9% PRT, MORE, TOP, SEL, GEN, TAP and the shared execution paths that command overlays return to. bank 0x38 slot $383800-$386FFF 3 Drive Info + Directory Listing rsdrvilst.prgrsdrvilst11260 45 11258 78.5% DRVI, LST bank 0x38 slot $387000-$38A7FF 4 Load Value rsldv.prgrsldv11896 47 11894 83.0% LDV bank 0x39 slot $390000-$3937FF 5 Store Value rsstv.prgrsstv10251 41 10249 71.5% STV bank 0x38 slot $38A800-$38DFFF 6 File Delete / Rename / Write rsfops.prgrsfops14327 57 14325 99.9% DEL, REN, PUT, ADD bank 0x39 slot $393800-$396FFF 7 File Read rscat.prgrscat8083 32 8081 56.4% CAT bank 0x39 slot $397000-$39A7FF 8 File Copy rscopy.prgrscopy6601 26 6599 46.0% COPY bank 0x39 slot $39A800-$39DFFF 9 Prompt Editor rsedit.prgrsedit2004 8 2002 14.0% None directly; prompt/input phase support. bank 0x3A slot $3A0000-$3A37FF
+ 1 Parser / Lexer rsparser.prgrsparser13007 52 13005 90.7% None directly; parse phase support. bank 0x36 slot $360000-$3637FF 2 Execution Core rsvm.prgrsvm14030 56 14028 97.9% PRT, MORE, TOP, SEL, GEN, TAP and the shared execution paths that command overlays return to. bank 0x36 slot $363800-$366FFF 3 Drive Info + Directory Listing rsdrvilst.prgrsdrvilst11260 45 11258 78.5% DRVI, LST bank 0x36 slot $367000-$36A7FF 4 Load Value rsldv.prgrsldv11896 47 11894 83.0% LDV bank 0x37 slot $370000-$3737FF 5 Store Value rsstv.prgrsstv10251 41 10249 71.5% STV bank 0x36 slot $36A800-$36DFFF 6 File Delete / Rename / Write rsfops.prgrsfops14327 57 14325 99.9% DEL, REN, PUT, ADD bank 0x37 slot $373800-$376FFF 7 File Read rscat.prgrscat8083 32 8081 56.4% CAT bank 0x37 slot $377000-$37A7FF 8 File Copy rscopy.prgrscopy6601 26 6599 46.0% COPY bank 0x37 slot $37A800-$37DFFF 9 Prompt Editor rsedit.prgrsedit2004 8 2002 14.0% None directly; prompt/input phase support. bank 0x38 slot $380000-$3837FF
@@ -395,11 +398,11 @@ Resident Program
Build PRG: readyshell.prg
Disk name: readyshell
- Disk footprint: 27983 bytes, 111 D71 blocks
+ Disk footprint: 28141 bytes, 111 D71 blocks
Resident sources: readyshell.c, rs_token.c, rs_bc.c, rs_errors.c, rs_cmd_registry.c, rs_vm_c64.c, rs_overlay_c64.c, rs_platform_c64.c, tui_nav.c, reu_mgr_dma.c, resume_state_ctx.c, resume_state_core.c
- Resident asm/runtime: rs_runtime_c64.s
+ Resident asm/runtime: rs_runtime_c64.s, $(TUI_READYOS_SRC)
Role: Resident app shell loop plus vm/overlay runtime. Command tokens resolved here, then dispatched to overlay 2 or command overlays.
- Current resident segments: CODE $688D, RODATA $03F2, DATA $0047, INIT $001C, ONCE $0038, BSS $01AA
+ Current resident segments: CODE $692C, RODATA $03F2, DATA $0046, INIT $001C, ONCE $0038, BSS $01AA
@@ -415,8 +418,8 @@ Observations
Overlay 2 is effectively full at 14028 bytes of 14336 (97.9%).
Overlay 1 is also large at 13005 bytes (90.7%).
- The resident heap below the overlay load address is only 3846 bytes, so large working sets depend on overlays and REU-backed storage.
- ReadyShell now uses three loader-assigned REU resource banks (current generated EasyFlash assignment): 0x38 for overlays 1, 2, 3, and 5; 0x39 for overlays 4, 6, 7, and 8; and 0x3A for overlay 9 in this artifact.
+ The resident heap below the overlay load address is only 3688 bytes, so large working sets depend on overlays and REU-backed storage.
+ ReadyShell now uses three loader-assigned REU resource banks (current generated EasyFlash assignment): 0x36 for overlays 1, 2, 3, and 5; 0x37 for overlays 4, 6, 7, and 8; and 0x38 for overlay 9 in this artifact.
Assigned bank 1 leaves 8192 bytes free; assigned bank 2 leaves 8192 bytes free; assigned bank 3 leaves 51200 bytes free.
External commands now pay a launcher/loader preload cost instead of a repeated disk-load cost during each command call.
Overlay 2 owns the shared formatting buffers, which is why it consumes almost the entire overlay window.
diff --git a/docs/readyshell_overlay_inventory.md b/docs/readyshell_overlay_inventory.md
index 7cfafa8..0147e83 100644
--- a/docs/readyshell_overlay_inventory.md
+++ b/docs/readyshell_overlay_inventory.md
@@ -1,134 +1,134 @@
-# ReadyShell Overlay Inventory Report (v0.2.4M)
+# ReadyShell Overlay Inventory Report (v0.2.5Y)
-Artifact-backed report generated from the current local ReadyShell build, linker map, and D71 disk image.
+Artifact-backed report generated from the current local ReadyShell build, linker map, and D81 disk image.
## Executive Summary
-- Profile / disk source: `precog-dual-d71` using `Releases/0.2.4/precog-dual-d71/readyos-v0.2.4m-dual-d71_1.d71` (disk label `readyos`, `29` blocks free).
-- Resident ReadyShell PRG: `readyshell.prg` on disk as `readyshell`, `27983` bytes and `111` D71 blocks.
+- Profile / disk source: `precog-d81` using `Releases/0.2.5/precog-d81/readyos-v0.2.5y-d81.d81` (disk label `readyosd81`, `227` blocks free).
+- Resident ReadyShell PRG: `readyshell.prg` on disk as `readyshell`, `28141` bytes and `111` D71 blocks.
- Overlay execution window: `$8E00-$C5FF` for `14336` bytes, with PRG load-address bytes at `$8DFE-$8DFF`.
-- Resident BSS / heap below overlays: BSS `$7D4D-$7EF6` (`426` bytes), heap `$7EF8-$8DFD` (`3846` bytes).
+- Resident BSS / heap below overlays: BSS `$7DEB-$7F94` (`426` bytes), heap `$7F96-$8DFD` (`3688` bytes).
- High RAM runtime region outside the app window: `$CA00-$CFFF`.
- REU policy split:
- overlays 1-9 are boot-loaded during shell startup and cached into fixed full-window REU slots
- - bank `0x38` holds overlays `1`, `2`, `3`, and `5`; bank `0x39` holds overlays `4`, `6`, `7`, and `8`; bank `0x3A` holds overlay `9`
- - the ReadyShell state bank (current generated EasyFlash state bank 0x3B) holds the external-command registry, overlay metadata, pause state, command handoff scratch, and REU-backed value arena
+ - bank `0x36` holds overlays `1`, `2`, `3`, and `5`; bank `0x37` holds overlays `4`, `6`, `7`, and `8`; bank `0x38` holds overlay `9`
+ - the ReadyShell state bank (current generated EasyFlash state bank 0x39) holds the external-command registry, overlay metadata, pause state, command handoff scratch, and REU-backed value arena
## Runtime Memory Map
| Region | Range | Size | Notes |
| --- | --- | ---: | --- |
-| Resident app window | `$1000-$C5FF` | `46592` | ReadyOS app-owned RAM window for ReadyShell. |
+| ReadyOS snapshot window | `$1000-$C5FF` | `46592` | Full app-owned RAM captured by the shim; the resident 1 KB shim begins at `$C600`. |
| Overlay load address bytes | `$8DFE-$8DFF` | `2` | PRG load address emitted ahead of each overlay sidecar file. |
| Overlay execution window | `$8E00-$C5FF` | `14336` | Shared live area for whichever overlay is active. |
-| Resident BSS | `$7D4D-$7EF6` | `426` | Resident writable data below the overlay load address. |
-| Resident heap | `$7EF8-$8DFD` | `3846` | cc65 heap carved below the overlay load address. |
+| Resident BSS | `$7DEB-$7F94` | `426` | Resident writable data below the overlay load address. |
+| Resident heap | `$7F96-$8DFD` | `3688` | cc65 heap carved below the overlay load address. |
| High-RAM runtime | `$CA00-$CFFF` | `1536` | Fixed ReadyShell runtime state outside the app snapshot window. |
## REU Layout And Loading Model
| Use | REU range | Size | How it is used |
| --- | --- | ---: | --- |
-| Shared cache bank 1 | `$380000-$38FFFF` | `65536` | Loader-assigned ReadyShell resource bank holding overlays 1, 2, 3, and 5 (current generated EasyFlash assignment). |
-| Overlay 1 parse slot | `$380000-$3837FF` | `14336` | Full overlay-window snapshot for overlay 1. |
-| Overlay 2 exec slot | `$383800-$386FFF` | `14336` | Full overlay-window snapshot for overlay 2. |
-| Overlay 3 command slot | `$387000-$38A7FF` | `14336` | Full overlay-window snapshot for overlay 3. |
-| Overlay 5 command slot | `$38A800-$38DFFF` | `14336` | Full overlay-window snapshot for overlay 5. |
-| Cache bank 1 free tail | `$38E000-$38FFFF` | `8192` | Unused tail after the four cache slots in assigned bank 1. |
-| Shared cache bank 2 | `$390000-$39FFFF` | `65536` | Loader-assigned ReadyShell resource bank holding overlays 4, 6, 7, and 8 (current generated EasyFlash assignment). |
-| Overlay 4 command slot | `$390000-$3937FF` | `14336` | Full overlay-window snapshot for overlay 4. |
-| Overlay 6 command slot | `$393800-$396FFF` | `14336` | Full overlay-window snapshot for overlay 6. |
-| Overlay 7 command slot | `$397000-$39A7FF` | `14336` | Full overlay-window snapshot for overlay 7. |
-| Overlay 8 command slot | `$39A800-$39DFFF` | `14336` | Full overlay-window snapshot for overlay 8. |
-| Cache bank 2 free tail | `$39E000-$39FFFF` | `8192` | Unused tail after the four cache slots in assigned bank 2. |
-| Shared cache bank 3 | `$3A0000-$3AFFFF` | `65536` | Loader-assigned ReadyShell resource bank holding overlay 9, the prompt editor (current generated EasyFlash assignment). |
-| Overlay 9 editor slot | `$3A0000-$3A37FF` | `14336` | Full overlay-window snapshot for overlay 9. |
-| Cache bank 3 free tail | `$3A3800-$3AFFFF` | `51200` | Unused tail after the editor slot in assigned bank 3. |
-| ReadyShell state bank | `$3B0000-$3BFFFF` | `65536` | Loader-assigned ReadyShell resource bank for command scratch, registry metadata, pause state, and the value arena (current generated EasyFlash state bank 0x3B). |
-| Debug trace ring | `$3B7DE0-$3B7FEF` | `528` | Overlay debug markers and verification state. |
-| Command scratch | `$3B0000-$3B7DDF` | `32224` | Inter-overlay handoff area for command frames and streaming state. |
-| Command registry header | `$3B8010-$3B8017` | `8` | REU-backed external-command registry header. |
-| Command descriptor table | `$3B8020-$3B807F` | `96` | Fixed-capacity external-command descriptor table in REU metadata. |
-| Overlay state table | `$3B8080-$3B80EB` | `108` | Fixed-capacity overlay load/cache state table for external command overlays. |
-| Shared ReadyShell metadata | `$3B80F0-$3B8113` | `36` | Shared core-overlay cache metadata record. |
-| Pause flag | `$3B8114` | `1` | Shared output-pause bit used by resident output and `MORE`. |
-| REU heap metadata | `$3B8000-$3B80FF` | `256` | ReadyShell REU heap header region, including shared metadata bytes. |
-| Reserved metadata guard | `$3B8100-$3B811F` | `32` | Reserved gap keeping shared overlay metadata and pause state clear of the value arena. |
-| REU heap arena | `$3B8120-$3BFEFF` | `32224` | Persistent value payload arena for REU-backed strings/arrays/objects. |
+| Shared cache bank 1 | `$360000-$36FFFF` | `65536` | Loader-assigned ReadyShell resource bank holding overlays 1, 2, 3, and 5 (current generated EasyFlash assignment). |
+| Overlay 1 parse slot | `$360000-$3637FF` | `14336` | Full overlay-window snapshot for overlay 1. |
+| Overlay 2 exec slot | `$363800-$366FFF` | `14336` | Full overlay-window snapshot for overlay 2. |
+| Overlay 3 command slot | `$367000-$36A7FF` | `14336` | Full overlay-window snapshot for overlay 3. |
+| Overlay 5 command slot | `$36A800-$36DFFF` | `14336` | Full overlay-window snapshot for overlay 5. |
+| Cache bank 1 free tail | `$36E000-$36FFFF` | `8192` | Unused tail after the four cache slots in assigned bank 1. |
+| Shared cache bank 2 | `$370000-$37FFFF` | `65536` | Loader-assigned ReadyShell resource bank holding overlays 4, 6, 7, and 8 (current generated EasyFlash assignment). |
+| Overlay 4 command slot | `$370000-$3737FF` | `14336` | Full overlay-window snapshot for overlay 4. |
+| Overlay 6 command slot | `$373800-$376FFF` | `14336` | Full overlay-window snapshot for overlay 6. |
+| Overlay 7 command slot | `$377000-$37A7FF` | `14336` | Full overlay-window snapshot for overlay 7. |
+| Overlay 8 command slot | `$37A800-$37DFFF` | `14336` | Full overlay-window snapshot for overlay 8. |
+| Cache bank 2 free tail | `$37E000-$37FFFF` | `8192` | Unused tail after the four cache slots in assigned bank 2. |
+| Shared cache bank 3 | `$380000-$38FFFF` | `65536` | Loader-assigned ReadyShell resource bank holding overlay 9, the prompt editor (current generated EasyFlash assignment). |
+| Overlay 9 editor slot | `$380000-$3837FF` | `14336` | Full overlay-window snapshot for overlay 9. |
+| Cache bank 3 free tail | `$383800-$38FFFF` | `51200` | Unused tail after the editor slot in assigned bank 3. |
+| ReadyShell state bank | `$390000-$39FFFF` | `65536` | Loader-assigned ReadyShell resource bank for command scratch, registry metadata, pause state, and the value arena (current generated EasyFlash state bank 0x39). |
+| Debug trace ring | `$397DE0-$397FEF` | `528` | Overlay debug markers and verification state. |
+| Command scratch | `$390000-$397DDF` | `32224` | Inter-overlay handoff area for command frames and streaming state. |
+| Command registry header | `$398010-$398017` | `8` | REU-backed external-command registry header. |
+| Command descriptor table | `$398020-$39807F` | `96` | Fixed-capacity external-command descriptor table in REU metadata. |
+| Overlay state table | `$398080-$3980EB` | `108` | Fixed-capacity overlay load/cache state table for external command overlays. |
+| Shared ReadyShell metadata | `$3980F0-$398113` | `36` | Shared core-overlay cache metadata record. |
+| Pause flag | `$398114` | `1` | Shared output-pause bit used by resident output and `MORE`. |
+| REU heap metadata | `$398000-$3980FF` | `256` | ReadyShell REU heap header region, including shared metadata bytes. |
+| Reserved metadata guard | `$398100-$39811F` | `32` | Reserved gap keeping shared overlay metadata and pause state clear of the value arena. |
+| REU heap arena | `$398120-$39FEFF` | `32224` | Persistent value payload arena for REU-backed strings/arrays/objects. |
## Shared Overlay Cache Visual
```text
-REU bank 0x38
+REU bank 0x36
-+----------------------------------------+ $380000
++----------------------------------------+ $360000
| overlay 1 parse slot |
| full overlay-window image: 0x3800 |
| active file: rsparser.prg |
-+----------------------------------------+ $383800
++----------------------------------------+ $363800
| overlay 2 exec slot |
| full overlay-window image: 0x3800 |
| active file: rsvm.prg |
-+----------------------------------------+ $387000
++----------------------------------------+ $367000
| overlay 3 command slot |
| full overlay-window image: 0x3800 |
| active file: rsdrvilst.prg |
-+----------------------------------------+ $38A800
++----------------------------------------+ $36A800
| overlay 5 command slot |
| full overlay-window image: 0x3800 |
| active file: rsstv.prg |
-+----------------------------------------+ $38E000
++----------------------------------------+ $36E000
| free tail |
| 0x2000 bytes |
-+----------------------------------------+ $38FFFF
++----------------------------------------+ $36FFFF
-REU bank 0x39
+REU bank 0x37
-+----------------------------------------+ $390000
++----------------------------------------+ $370000
| overlay 4 command slot |
| full overlay-window image: 0x3800 |
| active file: rsldv.prg |
-+----------------------------------------+ $393800
++----------------------------------------+ $373800
| overlay 6 command slot |
| full overlay-window image: 0x3800 |
| active file: rsfops.prg |
-+----------------------------------------+ $397000
++----------------------------------------+ $377000
| overlay 7 command slot |
| full overlay-window image: 0x3800 |
| active file: rscat.prg |
-+----------------------------------------+ $39A800
++----------------------------------------+ $37A800
| overlay 8 command slot |
| full overlay-window image: 0x3800 |
| active file: rscopy.prg |
-+----------------------------------------+ $39E000
++----------------------------------------+ $37E000
| free tail |
| 0x2000 bytes |
-+----------------------------------------+ $39FFFF
++----------------------------------------+ $37FFFF
-REU bank 0x3A
+REU bank 0x38
-+----------------------------------------+ $3A0000
++----------------------------------------+ $380000
| overlay 9 prompt editor slot |
| full overlay-window image: 0x3800 |
| active file: rsedit.prg |
-+----------------------------------------+ $3A3800
++----------------------------------------+ $383800
| free tail |
| 0xc800 bytes |
-+----------------------------------------+ $3AFFFF
++----------------------------------------+ $38FFFF
```
## Command Scratch And Value Arena Usage
| Commands | Overlay | Command scratch | Value arena | How the REU region is used |
| --- | --- | --- | --- | --- |
-| PRT, MORE, TOP, SEL, GEN, TAP | `2 / rsvm` | No direct use | Indirect only | Run inside the shared execution core. They do not stage command-local data in `$3B0000-$3B7DDF`; any REU-backed values are handled through the normal overlay-2 value/runtime paths. |
+| PRT, MORE, TOP, SEL, GEN, TAP | `2 / rsvm` | No direct use | Indirect only | Run inside the shared execution core. They do not stage command-local data in `$390000-$397DDF`; any REU-backed values are handled through the normal overlay-2 value/runtime paths. |
| DRVI | `3 / rsdrvilst` | No | No | Reads drive header/status data and builds its output object in transient overlay-local RAM. |
-| LST | `3 / rsdrvilst` | Yes | No | Spools 28-byte directory records through `$3B0000-$3B7DDF` so `BEGIN`/`ITEM` can walk the listing without keeping the directory channel open. |
-| LDV | `4 / rsldv` | Yes | Yes, writes persistent values | Reads the RSV1 file into `$3B0000-$3B7DDF`, validates its header, then materializes strings, arrays, and objects into the REU heap arena `$3B8120-$3BFEFF`. |
-| STV | `5 / rsstv` | Yes | Yes, reads existing pointer values | Uses `$3B0000-$3B00FF` for session metadata and `$3B0100-$3B7DDF` for the outgoing RSV1 payload. When serializing pointer-backed values, it dereferences them from the persistent REU heap arena before flattening them into scratch. |
+| LST | `3 / rsdrvilst` | Yes | No | Spools 28-byte directory records through `$390000-$397DDF` so `BEGIN`/`ITEM` can walk the listing without keeping the directory channel open. |
+| LDV | `4 / rsldv` | Yes | Yes, writes persistent values | Reads the RSV1 file into `$390000-$397DDF`, validates its header, then materializes strings, arrays, and objects into the REU heap arena `$398120-$39FEFF`. |
+| STV | `5 / rsstv` | Yes | Yes, reads existing pointer values | Uses `$390000-$3900FF` for session metadata and `$390100-$397DDF` for the outgoing RSV1 payload. When serializing pointer-backed values, it dereferences them from the persistent REU heap arena before flattening them into scratch. |
| DEL, REN | `6 / rsfops` | No | No | Issue DOS scratch/rename commands directly through command-channel I/O with no REU staging. |
-| PUT, ADD | `6 / rsfops` | Yes | No | Use `$3B0000-$3B001F` for session metadata and `$3B0020-$3B7DDF` as a text spool for new/appended SEQ content before writing it back to disk. |
-| CAT | `7 / rscat` | Yes | No | Uses `$3B0000-$3B07FF` as a line-record table and `$3B0800-$3B7DDF` as the line-data spool so `ITEM` can replay file lines after the initial read pass. |
+| PUT, ADD | `6 / rsfops` | Yes | No | Use `$390000-$39001F` for session metadata and `$390020-$397DDF` as a text spool for new/appended SEQ content before writing it back to disk. |
+| CAT | `7 / rscat` | Yes | No | Uses `$390000-$3907FF` as a line-record table and `$390800-$397DDF` as the line-data spool so `ITEM` can replay file lines after the initial read pass. |
| COPY | `8 / rscopy` | No | No | Uses its overlay-local 128-byte transfer buffer plus direct DOS copy/streamed file I/O. It does not use the shared command scratch or the persistent value arena. |
- The command scratch window is shared, not partitioned per overlay. Only one command overlay owns it at a time even though all external overlays are preloaded into REU, because they still run serially through the shared overlay window.
@@ -137,24 +137,24 @@ REU bank 0x3A
## Static Audit Checks
- Registry capacity check: `rs_cmd_registry.c` seeds `10` external command descriptors into `16` reserved descriptor slots and `6` overlay-state rows into `6` reserved state slots.
-- Metadata packing check: ReadyShell control metadata starts in `$3B8000-$3B80FF`. Header uses `$3B8010-$3B8017`, descriptor rows reserve `$3B8020-$3B807F` with live rows ending at `$3B805B`, state rows reserve `$3B8080-$3B80EB` with live rows ending at `$3B80EB`, shared metadata uses `$3B80F0-$3B8113`, and the pause flag sits at `$3B8114` before the value arena at `$3B8120`.
-- Non-overlap check: command scratch ends at `$3B7DDF` and REU heap metadata begins at `$3B8000`; the state table ends at `$3B80EB` and shared metadata begins at `$3B80F0`; shared metadata ends at `$3B8113` and the pause flag is `$3B8114`; the value arena begins at `$3B8120`.
-- Cache-slot audit: ReadyShell caches overlays 1-9. Bank `0x38` carries overlays `1`, `2`, `3`, and `5`; bank `0x39` carries overlays `4`, `6`, `7`, and `8`; bank `0x3A` carries overlay `9`. Every slot is a full `14336`-byte overlay-window snapshot.
+- Metadata packing check: ReadyShell control metadata starts in `$398000-$3980FF`. Header uses `$398010-$398017`, descriptor rows reserve `$398020-$39807F` with live rows ending at `$39805B`, state rows reserve `$398080-$3980EB` with live rows ending at `$3980EB`, shared metadata uses `$3980F0-$398113`, and the pause flag sits at `$398114` before the value arena at `$398120`.
+- Non-overlap check: command scratch ends at `$397DDF` and REU heap metadata begins at `$398000`; the state table ends at `$3980EB` and shared metadata begins at `$3980F0`; shared metadata ends at `$398113` and the pause flag is `$398114`; the value arena begins at `$398120`.
+- Cache-slot audit: ReadyShell caches overlays 1-9. Bank `0x36` carries overlays `1`, `2`, `3`, and `5`; bank `0x37` carries overlays `4`, `6`, `7`, and `8`; bank `0x38` carries overlay `9`. Every slot is a full `14336`-byte overlay-window snapshot.
- Command-source audit: `DRVI` builds output only in overlay-local RAM; `LST` writes 28-byte directory records into shared scratch; `LDV` streams RSV1 payloads into scratch and materializes persistent values into the REU heap arena; `STV` serializes into scratch and dereferences pointer-backed values from the arena; `DEL` and `REN` issue direct DOS commands without REU staging; `PUT` and `ADD` use scratch metadata plus a text spool; `CAT` uses a scratch record table plus line-data spool; `COPY` stays overlay-local with `g_copy_buf[128]`.
## Overlay Inventory
| Ovl | Role | Build PRG | Disk name | PRG bytes | Disk blocks | Live bytes | Window use | REU cache | Commands |
| ---: | --- | --- | --- | ---: | ---: | ---: | ---: | --- | --- |
-| 1 | Parser / Lexer | `rsparser.prg` | `rsparser` | `13007` | `52` | `13005` | `90.7%` | bank `0x38` slot `$380000-$3837FF` | None directly; parse phase support. |
-| 2 | Execution Core | `rsvm.prg` | `rsvm` | `14030` | `56` | `14028` | `97.9%` | bank `0x38` slot `$383800-$386FFF` | PRT, MORE, TOP, SEL, GEN, TAP and the shared execution paths that command overlays return to. |
-| 3 | Drive Info + Directory Listing | `rsdrvilst.prg` | `rsdrvilst` | `11260` | `45` | `11258` | `78.5%` | bank `0x38` slot `$387000-$38A7FF` | DRVI, LST |
-| 4 | Load Value | `rsldv.prg` | `rsldv` | `11896` | `47` | `11894` | `83.0%` | bank `0x39` slot `$390000-$3937FF` | LDV |
-| 5 | Store Value | `rsstv.prg` | `rsstv` | `10251` | `41` | `10249` | `71.5%` | bank `0x38` slot `$38A800-$38DFFF` | STV |
-| 6 | File Delete / Rename / Write | `rsfops.prg` | `rsfops` | `14327` | `57` | `14325` | `99.9%` | bank `0x39` slot `$393800-$396FFF` | DEL, REN, PUT, ADD |
-| 7 | File Read | `rscat.prg` | `rscat` | `8083` | `32` | `8081` | `56.4%` | bank `0x39` slot `$397000-$39A7FF` | CAT |
-| 8 | File Copy | `rscopy.prg` | `rscopy` | `6601` | `26` | `6599` | `46.0%` | bank `0x39` slot `$39A800-$39DFFF` | COPY |
-| 9 | Prompt Editor | `rsedit.prg` | `rsedit` | `2004` | `8` | `2002` | `14.0%` | bank `0x3A` slot `$3A0000-$3A37FF` | None directly; prompt/input phase support. |
+| 1 | Parser / Lexer | `rsparser.prg` | `rsparser` | `13007` | `52` | `13005` | `90.7%` | bank `0x36` slot `$360000-$3637FF` | None directly; parse phase support. |
+| 2 | Execution Core | `rsvm.prg` | `rsvm` | `14030` | `56` | `14028` | `97.9%` | bank `0x36` slot `$363800-$366FFF` | PRT, MORE, TOP, SEL, GEN, TAP and the shared execution paths that command overlays return to. |
+| 3 | Drive Info + Directory Listing | `rsdrvilst.prg` | `rsdrvilst` | `11260` | `45` | `11258` | `78.5%` | bank `0x36` slot `$367000-$36A7FF` | DRVI, LST |
+| 4 | Load Value | `rsldv.prg` | `rsldv` | `11896` | `47` | `11894` | `83.0%` | bank `0x37` slot `$370000-$3737FF` | LDV |
+| 5 | Store Value | `rsstv.prg` | `rsstv` | `10251` | `41` | `10249` | `71.5%` | bank `0x36` slot `$36A800-$36DFFF` | STV |
+| 6 | File Delete / Rename / Write | `rsfops.prg` | `rsfops` | `14327` | `57` | `14325` | `99.9%` | bank `0x37` slot `$373800-$376FFF` | DEL, REN, PUT, ADD |
+| 7 | File Read | `rscat.prg` | `rscat` | `8083` | `32` | `8081` | `56.4%` | bank `0x37` slot `$377000-$37A7FF` | CAT |
+| 8 | File Copy | `rscopy.prg` | `rscopy` | `6601` | `26` | `6599` | `46.0%` | bank `0x37` slot `$37A800-$37DFFF` | COPY |
+| 9 | Prompt Editor | `rsedit.prg` | `rsedit` | `2004` | `8` | `2002` | `14.0%` | bank `0x38` slot `$380000-$3837FF` | None directly; prompt/input phase support. |
## Command Topology
@@ -195,12 +195,12 @@ Resident ReadyShell dispatcher
- Disk filename: `readyshell`
- Disk staging comes from the main ReadyShell build artifact, not an overlay copy.
- Resident sources: `readyshell.c, rs_token.c, rs_bc.c, rs_errors.c, rs_cmd_registry.c, rs_vm_c64.c, rs_overlay_c64.c, rs_platform_c64.c, tui_nav.c, reu_mgr_dma.c, resume_state_ctx.c, resume_state_core.c`
-- Resident asm/runtime support: `rs_runtime_c64.s`
+- Resident asm/runtime support: `rs_runtime_c64.s, $(TUI_READYOS_SRC)`
- Command role: Resident app shell loop plus vm/overlay runtime. Command tokens resolved here, then dispatched to overlay 2 or command overlays.
- Current linker-visible resident footprint:
- - `CODE` `0x688D`
+ - `CODE` `0x692C`
- `RODATA` `0x03F2`
- - `DATA` `0x0047`
+ - `DATA` `0x0046`
- `INIT` `0x001C`
- `ONCE` `0x0038`
- `BSS` `0x01AA`
@@ -218,7 +218,7 @@ Resident ReadyShell dispatcher
- Runtime bytes in overlay window: `13005` at `$8E00-$C0CC`
- Window share: `90.7%` used, `1331` bytes free
- Disk footprint: `13007` bytes, `52` D71 blocks
-- REU policy: Boot-loaded from disk during shell startup, then restored from bank `0x38` slot `$380000-$3837FF` as a full `0x3800`-byte overlay-window snapshot.
+- REU policy: Boot-loaded from disk during shell startup, then restored from bank `0x36` slot `$360000-$3637FF` as a full `0x3800`-byte overlay-window snapshot.
- RAM notes: Lives entirely inside the shared overlay window while active.
### Overlay 2: Execution Core
@@ -232,7 +232,7 @@ Resident ReadyShell dispatcher
- Runtime bytes in overlay window: `14028` at `$8E00-$C4CB`
- Window share: `97.9%` used, `308` bytes free
- Disk footprint: `14030` bytes, `56` D71 blocks
-- REU policy: Boot-loaded from disk during shell startup, then restored from bank `0x38` slot `$383800-$386FFF` as a full `0x3800`-byte overlay-window snapshot.
+- REU policy: Boot-loaded from disk during shell startup, then restored from bank `0x36` slot `$363800-$366FFF` as a full `0x3800`-byte overlay-window snapshot.
- RAM notes: Includes rs_vm_fmt_buf[128] and rs_vm_line_buf[384] inside the overlay image.
### Overlay 3: Drive Info + Directory Listing
@@ -246,7 +246,7 @@ Resident ReadyShell dispatcher
- Runtime bytes in overlay window: `11258` at `$8E00-$B9F9`
- Window share: `78.5%` used, `3078` bytes free
- Disk footprint: `11260` bytes, `45` D71 blocks
-- REU policy: Boot-loaded from disk during shell startup, then restored from bank `0x38` slot `$387000-$38A7FF` as a full `0x3800`-byte overlay-window snapshot.
+- REU policy: Boot-loaded from disk during shell startup, then restored from bank `0x36` slot `$367000-$36A7FF` as a full `0x3800`-byte overlay-window snapshot.
- RAM notes: Shares the inter-command REU handoff area at offset $0000-$7FFF in the loader-assigned ReadyShell state bank.
### Overlay 4: Load Value
@@ -260,7 +260,7 @@ Resident ReadyShell dispatcher
- Runtime bytes in overlay window: `11894` at `$8E00-$BC75`
- Window share: `83.0%` used, `2442` bytes free
- Disk footprint: `11896` bytes, `47` D71 blocks
-- REU policy: Boot-loaded from disk during shell startup, then restored from bank `0x39` slot `$390000-$3937FF` as a full `0x3800`-byte overlay-window snapshot.
+- REU policy: Boot-loaded from disk during shell startup, then restored from bank `0x37` slot `$370000-$3737FF` as a full `0x3800`-byte overlay-window snapshot.
- RAM notes: Uses the shared handoff region plus the REU-backed value arena in the loader-assigned ReadyShell state bank when hydrating pointer-backed values.
### Overlay 5: Store Value
@@ -274,7 +274,7 @@ Resident ReadyShell dispatcher
- Runtime bytes in overlay window: `10249` at `$8E00-$B608`
- Window share: `71.5%` used, `4087` bytes free
- Disk footprint: `10251` bytes, `41` D71 blocks
-- REU policy: Boot-loaded from disk during shell startup, then restored from bank `0x38` slot `$38A800-$38DFFF` as a full `0x3800`-byte overlay-window snapshot.
+- REU policy: Boot-loaded from disk during shell startup, then restored from bank `0x36` slot `$36A800-$36DFFF` as a full `0x3800`-byte overlay-window snapshot.
- RAM notes: Uses the shared handoff region plus the REU-backed value arena in the loader-assigned ReadyShell state bank when serializing pointer-backed values.
### Overlay 6: File Delete / Rename / Write
@@ -288,7 +288,7 @@ Resident ReadyShell dispatcher
- Runtime bytes in overlay window: `14325` at `$8E00-$C5F4`
- Window share: `99.9%` used, `11` bytes free
- Disk footprint: `14327` bytes, `57` D71 blocks
-- REU policy: Boot-loaded from disk during shell startup, then restored from bank `0x39` slot `$393800-$396FFF` as a full `0x3800`-byte overlay-window snapshot.
+- REU policy: Boot-loaded from disk during shell startup, then restored from bank `0x37` slot `$373800-$376FFF` as a full `0x3800`-byte overlay-window snapshot.
- RAM notes: Keeps file-operation staging and transient command state in overlay-local code plus the shared REU scratch region.
### Overlay 7: File Read
@@ -302,7 +302,7 @@ Resident ReadyShell dispatcher
- Runtime bytes in overlay window: `8081` at `$8E00-$AD90`
- Window share: `56.4%` used, `6255` bytes free
- Disk footprint: `8083` bytes, `32` D71 blocks
-- REU policy: Boot-loaded from disk during shell startup, then restored from bank `0x39` slot `$397000-$39A7FF` as a full `0x3800`-byte overlay-window snapshot.
+- REU policy: Boot-loaded from disk during shell startup, then restored from bank `0x37` slot `$377000-$37A7FF` as a full `0x3800`-byte overlay-window snapshot.
- RAM notes: Uses overlay-local file I/O logic plus shared REU scratch when line staging is needed.
### Overlay 8: File Copy
@@ -316,7 +316,7 @@ Resident ReadyShell dispatcher
- Runtime bytes in overlay window: `6599` at `$8E00-$A7C6`
- Window share: `46.0%` used, `7737` bytes free
- Disk footprint: `6601` bytes, `26` D71 blocks
-- REU policy: Boot-loaded from disk during shell startup, then restored from bank `0x39` slot `$39A800-$39DFFF` as a full `0x3800`-byte overlay-window snapshot.
+- REU policy: Boot-loaded from disk during shell startup, then restored from bank `0x37` slot `$37A800-$37DFFF` as a full `0x3800`-byte overlay-window snapshot.
- RAM notes: Uses an overlay-local 128-byte transfer buffer plus direct DOS copy or streamed file I/O. It does not use the shared REU scratch or value arena.
### Overlay 9: Prompt Editor
@@ -330,15 +330,15 @@ Resident ReadyShell dispatcher
- Runtime bytes in overlay window: `2002` at `$8E00-$95D1`
- Window share: `14.0%` used, `12334` bytes free
- Disk footprint: `2004` bytes, `8` D71 blocks
-- REU policy: Boot-loaded from disk during shell startup, then restored from bank `0x3A` slot `$3A0000-$3A37FF` as a full `0x3800`-byte overlay-window snapshot.
+- REU policy: Boot-loaded from disk during shell startup, then restored from bank `0x38` slot `$380000-$3837FF` as a full `0x3800`-byte overlay-window snapshot.
- RAM notes: Keeps the editable physical-line buffer overlay-local; the final logical command line remains resident in g_line.
## Observations
- Overlay 2 is effectively full: `14028` of `14336` bytes (`97.9%`).
- Overlay 1 is also large at `13005` bytes (`90.7%`).
-- The resident heap below the overlay load address is only `3846` bytes, so large transient work must lean on overlays and REU-backed storage.
-- ReadyShell now uses three loader-assigned REU resource banks (current generated EasyFlash assignment): `0x38` for overlays `1`, `2`, `3`, and `5`; `0x39` for overlays `4`, `6`, `7`, and `8`; and `0x3A` for overlay `9` in this artifact.
+- The resident heap below the overlay load address is only `3688` bytes, so large transient work must lean on overlays and REU-backed storage.
+- ReadyShell now uses three loader-assigned REU resource banks (current generated EasyFlash assignment): `0x36` for overlays `1`, `2`, `3`, and `5`; `0x37` for overlays `4`, `6`, `7`, and `8`; and `0x38` for overlay `9` in this artifact.
- Assigned bank 1 leaves `8192` bytes free; assigned bank 2 leaves `8192` bytes free; assigned bank 3 leaves `51200` bytes free.
- External commands now pay a launcher/loader preload cost instead of a repeated disk-load cost during each command call.
- Overlay 2 carries the shared formatting buffers, so its footprint reflects both command support code and the text-rendering scratch it owns.
diff --git a/docs/release_root_readme_template.md b/docs/release_root_readme_template.md
index 4b7987c..c792348 100644
--- a/docs/release_root_readme_template.md
+++ b/docs/release_root_readme_template.md
@@ -23,6 +23,11 @@ rather than being explicitly tailored to the new C64 Ultimate. The next release
is expected to push further in that Ultimate-first direction while still trying
to stay usable on other REU-capable C64 setups.
+The source tree may also contain an experimental C64 Ultimate DOS DMA launcher
+build. It is not implied by choosing a D81 SKU: normal public artifacts use the
+portable disk path unless explicitly built with `LAUNCHER_DMA_LOAD=1`, and the
+experimental path retains disk fallback.
+
## What ReadyOS Is
ReadyOS is not trying to be a generic desktop shell squeezed into a C64. It is
@@ -40,6 +45,20 @@ The current public release line is `{{PUBLIC_VERSION}}`. Full-content ReadyOS
profiles currently expose `{{CURRENT_APP_COUNT}}` launcher-visible apps, with
the exact app mix depending on the variant you choose.
+## Runtime And REU Contract
+
+- The active app snapshot is `$1000-$C5FF` (`$B600` bytes). The resident 1 KB
+ shim owns `$C600-$C9FF`; its public ABI remains at `$C800-$C9FF`.
+- Physical REU bank `Skip` is the **ReadyOS bank** and is never allocated to an
+ app/resource. Physical `Skip+1` is the first dynamic bank.
+- The ReadyOS bank contains the launcher snapshot at `$0000-$B5FF` and
+ schema-v5 mappings, status, clipboard, hotkeys, registry/catalog, audit, and
+ launcher runtime state at `$B600-$FFFF`.
+- Logical app tokens resolve through the explicit `$B740` table; they are not
+ physical bank numbers and must not be converted with arithmetic.
+- ReadyShell and ReadyBASIC resource banks are loader-assigned and recorded in
+ the ReadyOS bank. ReadyBASIC retains its custom ca65/ld65 compact-image shape.
+
## Why There Are Multiple Variants
The short answer is that C64 storage and loader realities are not uniform.
diff --git a/docs/reports/ReadyOSREUPhase1Completed.html b/docs/reports/ReadyOSREUPhase1Completed.html
index a4cb868..605d2f3 100644
--- a/docs/reports/ReadyOSREUPhase1Completed.html
+++ b/docs/reports/ReadyOSREUPhase1Completed.html
@@ -1,3 +1,16 @@
+
+
+ Current ReadyOS contract (2026-08-02):
+ Physical Skip is the ReadyOS bank and Skip+1 is the first dynamic bank.
+ The launcher snapshot is ReadyOS $0000-$B5FF; schema v5 is $B600-$FFFF,
+ with token map $B740 and status $B840. C64 app RAM is
+ $1000-$C5FF ($B600), and the resident 1 KB shim owns
+ $C600-$C9FF with its public ABI at $C800.
+ Dated layouts and measurements below are retained as historical evidence.
+
+
+PRESERVED SNAPSHOT / DESIGN Preserved completed-phase record. Its full commented shim appendix is byte-verified current; other values describe the phase at the time and are not a live 0.2.5 memory contract.
+
ReadyOS
REU Enhancement Refactor - Phase 1 Completed
Phase 1 Completion Note
@@ -1084,304 +1097,295 @@ Shim Change Status
The canonical resident shim image is still
-src/boot/readyos_shim.inc. The copy below is included
-because this branch changed the resident shim mapping contract while
-keeping the final image at 512 bytes.
+src/boot/readyos_shim.inc. The complete commented copy below
+is byte-verified during the documentation audit and includes the current
+control-bank lookup while keeping the final image at
+512 bytes.
;-----------------------------------------------------------------------------
-; Shared ReadyOS shim image ($C800-$C9FF, 512 bytes)
-; This file is the canonical shim byte layout used by both the disk boot path
-; and the EasyFlash cartridge flavor. Keep it identical across all variants.
-;-----------------------------------------------------------------------------
-
-;-----------------------------------------------------------------------------
-; Page 1: $C800-$C8FF - Jump table, data, and helper routines
-;-----------------------------------------------------------------------------
-
-; $C800-$C817: Jump Table (24 bytes, 8 entries)
- jt_load_disk = $ C800 ; Load from disk, run
- jt_load_reu = $ C803 ; Fetch from REU, run
- jt_run_app = $ C806 ; Just run app
- jt_preload = $ C809 ; Preload to REU, return
- jt_return = $ C80C ; Return to launcher
- jt_switch = $ C80F ; Switch to another app
- jt_stash_cur = $ C812 ; Helper: stash current app
- jt_fetch_bank = $ C815 ; Helper: fetch from bank in A
-
- .byte $ 4C , $ 40 , $ C8 ; $C800: JMP load_disk ($C840)
- .byte $ 4C , $ 60 , $ C8 ; $C803: JMP load_reu ($C860)
- .byte $ 4C , $ 00 , $ 10 ; $C806: JMP $1000 (run app)
- .byte $ 4C , $ 80 , $ C8 ; $C809: JMP preload ($C880)
- .byte $ 4C , $ 00 , $ C9 ; $C80C: JMP return_to_launcher ($C900)
- .byte $ 4C , $ 40 , $ C9 ; $C80F: JMP switch_app ($C940)
- .byte $ 4C , $ C0, $ C8 ; $C812: JMP stash_current ($C8C0) - placeholder
- .byte $ 4C , $ F0, $ C8 ; $C815: JMP fetch_bank ($C8F0)
-
-; $C818: JMP log_byte ($C9E0)
- .byte $ 4C , $ E0, $ C9 ; $C818: JMP log_byte
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ; $C81B-$C81F: Padding
-
-; $C820-$C83F: Data Area (32 bytes)
-; $C820: target_bank - bank to load/switch to
-; $C821: filename_len
-; $C822-$C823: unused
-; $C824-$C82F: filename (12 bytes)
-; $C830: load_end_lo (KERNAL LOAD end addr low byte, saved by preload)
-; $C831: load_end_hi (KERNAL LOAD end addr high byte, saved by preload)
-; $C832-$C833: unused
-; $C834: current_bank - currently running app
-; $C835: last_saved
-; $C836: reu_bitmap_lo (banks 0-7)
-; $C837: reu_bitmap_hi (banks 8-15)
-; $C838: reu_bitmap_xhi (banks 16-23)
-; $C839: storage_drive - shim-global default storage drive for D8/D9 app dialogs
-; This persists across app switches and is shared by apps that use the
-; common file-dialog default-drive contract.
-; $C83A: log_index - debug byte ring head
-; $C83B: reu_bank_skip - physical 64K banks reserved before ReadyOS bank start
-; $C83C: launcher_flags - launcher-owned one-shot state flags
-; $C83D: reu_lookup_scratch - one-byte physical bank fetched from REU bank 0
-; $C83E-$C83F: reserved
-
- .byte $ 00 ; $C820: target_bank
- .byte $ 08 ; $C821: filename_len
- .byte $ 00 , $ 00 ; $C822-$C823: unused
- .byte "LAUNCHER " ; $C824-$C82F: filename (12 bytes)
- .byte $ 00 ,$ 00 ; $C830-$C831: load_end_lo, load_end_hi
- .byte $ 00 ,$ 00 ; $C832-$C833: unused
- .byte $ 00 ; $C834: current_bank
- .byte $ FF ; $C835: last_saved
- .byte $ 00 ; $C836: reu_bitmap_lo
- .byte $ 00 ; $C837: reu_bitmap_hi
- .byte $ 00 ; $C838: reu_bitmap_xhi
- .byte $ 08 ; $C839: storage_drive (default drive 8)
- .byte $ 00 ; $C83A: log_index (for debug buffer)
- .byte READYOS_REU_BANK_SKIP ; $C83B: reu_bank_skip (compiled into boot image)
- .byte $ 00 ; $C83C: launcher_flags
- .byte $ 00 ; $C83D: reu_lookup_scratch
- .byte $ 00 ,$ 00 ; $C83E-$C83F: reserved
-
-;-----------------------------------------------------------------------------
-; $C840: load_disk - Load app from disk and run (32 bytes)
-;-----------------------------------------------------------------------------
- .byte $ AD, $ 21 , $ C8 ; LDA $C821 (filename len)
- .byte $ A2, $ 24 ; LDX #$24
- .byte $ A0, $ C8 ; LDY #$C8 (filename at $C824)
- .byte $ 20 , $ BD, $ FF ; JSR $FFBD (SETNAM)
- .byte $ A9, $ 00 ; LDA #0
- .byte $ A2, $ 08 ; LDX #8
- .byte $ A0, $ 01 ; LDY #1
- .byte $ 20 , $ BA, $ FF ; JSR $FFBA (SETLFS)
- .byte $ A9, $ 00 ; LDA #0
- .byte $ 20 , $ D5, $ FF ; JSR $FFD5 (LOAD)
- .byte $ 4C , $ 00 , $ 10 ; JMP $1000
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ; Padding to $C860
-
-;-----------------------------------------------------------------------------
-; $C860: load_reu - Fetch app from REU and run (32 bytes)
-;-----------------------------------------------------------------------------
- .byte $ AD, $ 20 , $ C8 ; LDA $C820 (target bank)
- .byte $ 20 , $ F0, $ C8 ; JSR fetch_bank ($C8F0)
- .byte $ 4C , $ 00 , $ 10 ; JMP $1000
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00
-
-;-----------------------------------------------------------------------------
-; $C880: preload - Load to REU, return to launcher
-; Called via JSR $C809
-; DEBUG: writes markers to $C007-$C00C
-;-----------------------------------------------------------------------------
- .byte $ A9, $ AA ; LDA #$AA (170 = "preload entered")
- .byte $ 8D , $ 07 , $ C0 ; STA $C007
-
- .byte $ A9, $ 00 ; LDA #0 (bank 0)
- .byte $ 20 , $ E0, $ C8 ; JSR stash_to_bank ($C8E0)
-
- .byte $ A9, $ BB ; LDA #$BB (187 = "launcher stashed")
- .byte $ 8D , $ 08 , $ C0 ; STA $C008
-
- .byte $ AD, $ 21 , $ C8 ; LDA $C821 (len)
- .byte $ A2, $ 24 ; LDX #$24
- .byte $ A0, $ C8 ; LDY #$C8 (filename at $C824)
- .byte $ 20 , $ BD, $ FF ; JSR SETNAM
-
- .byte $ A9, $ 00 ; LDA #0
- .byte $ A2, $ 08 ; LDX #8
- .byte $ A0, $ 01 ; LDY #1
- .byte $ 20 , $ BA, $ FF ; JSR SETLFS
-
- .byte $ A9, $ CC ; LDA #$CC (204 = "about to LOAD")
- .byte $ 8D , $ 09 , $ C0 ; STA $C009
-
- .byte $ A9, $ 00 ; LDA #0
- .byte $ 20 , $ D5, $ FF ; JSR LOAD
-
- .byte $ 8E , $ 30 , $ C8 ; STX $C830 (end addr lo)
- .byte $ 8C , $ 31 , $ C8 ; STY $C831 (end addr hi)
-
- .byte $ AD, $ 20 , $ C8 ; LDA $C820 (target bank)
- .byte $ 20 , $ E0, $ C8 ; JSR stash_to_bank ($C8E0)
-
- .byte $ A9, $ EE ; LDA #$EE (238 = "app stashed")
- .byte $ 8D , $ 0B , $ C0 ; STA $C00B
-
- .byte $ AD, $ 20 , $ C8 ; LDA $C820 (target bank)
- .byte $ 20 , $ C0, $ C9 ; JSR set_bitmap ($C9C0)
-
- .byte $ A9, $ 00 ; LDA #0
- .byte $ 20 , $ F0, $ C8 ; JSR fetch_bank ($C8F0)
-
- .byte $ A9, $ FF ; LDA #$FF (255 = "launcher restored")
- .byte $ 8D , $ 0C , $ C0 ; STA $C00C
-
- .byte $ 60 ; RTS
-
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00
-
-;-----------------------------------------------------------------------------
-; $C8E0: stash_to_bank - Stash $1000-$C5FF to REU bank in A (16 bytes)
-;-----------------------------------------------------------------------------
- .byte $ 20 , $ 60 , $ C9 ; JSR reu_setup_logical ($C960)
- .byte $ A9, $ 90 ; LDA #$90 (STASH command)
- .byte $ 8D , $ 01 , $ DF ; STA $DF01 - execute transfer
- .byte $ 60 ; RTS
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00
-
-;-----------------------------------------------------------------------------
-; $C8F0: fetch_bank - Fetch from REU bank in A to $1000-$C5FF (16 bytes)
-;-----------------------------------------------------------------------------
- .byte $ 20 , $ 60 , $ C9 ; JSR reu_setup_logical ($C960)
- .byte $ A9, $ 91 ; LDA #$91 (FETCH command)
- .byte $ 8D , $ 01 , $ DF ; STA $DF01 - execute transfer
- .byte $ 60 ; RTS
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00
-
-;-----------------------------------------------------------------------------
-; Page 2: $C900-$C9FF - Main routines
-;-----------------------------------------------------------------------------
-
-;-----------------------------------------------------------------------------
-; $C900: return_to_launcher (64 bytes)
-;-----------------------------------------------------------------------------
- .byte $ AD, $ 34 , $ C8 ; LDA $C834 (current bank)
- .byte $ 20 , $ E0, $ C8 ; JSR stash_to_bank ($C8E0)
- .byte $ AD, $ 34 , $ C8 ; LDA $C834 (current bank)
- .byte $ 20 , $ C0, $ C9 ; JSR set_bitmap ($C9C0)
- .byte $ AD, $ 34 , $ C8 ; LDA $C834
- .byte $ 8D , $ 35 , $ C8 ; STA $C835
- .byte $ A9, $ 00 ; LDA #0
- .byte $ 20 , $ F0, $ C8 ; JSR fetch_bank ($C8F0)
- .byte $ A9, $ 00 ; LDA #0
- .byte $ 8D , $ 34 , $ C8 ; STA $C834
- .byte $ 4C , $ 00 , $ 10 ; JMP $1000
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00
- .byte $ 00
-
-;-----------------------------------------------------------------------------
-; $C940: switch_app (64 bytes)
-;-----------------------------------------------------------------------------
- .byte $ AD, $ 34 , $ C8 ; LDA $C834 (current bank)
- .byte $ 20 , $ E0, $ C8 ; JSR stash_to_bank ($C8E0)
- .byte $ AD, $ 34 , $ C8 ; LDA $C834 (current bank)
- .byte $ 20 , $ C0, $ C9 ; JSR set_bitmap ($C9C0)
- .byte $ AD, $ 20 , $ C8 ; LDA $C820 (target bank)
- .byte $ 20 , $ F0, $ C8 ; JSR fetch_bank ($C8F0)
- .byte $ AD, $ 20 , $ C8 ; LDA $C820
- .byte $ 8D , $ 34 , $ C8 ; STA $C834
- .byte $ 4C , $ 00 , $ 10 ; JMP $1000
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00
-
-;-----------------------------------------------------------------------------
-; $C960: reu_setup_logical - Resolve logical token via REU bank 0, then setup regs
-;-----------------------------------------------------------------------------
- .byte $ C9, $ 00 ; CMP #0 (logical launcher bank?)
- .byte $ D0, $ 09 ; BNE lookup_app_bank
- .byte $ AD, $ 3B , $ C8 ; LDA $C83B (reu_bank_skip)
- .byte $ 18 ; CLC
- .byte $ 69 , $ 01 ; ADC #$01 (launcher is Start+1)
- .byte $ 4C , $ A0, $ C9 ; JMP reu_setup ($C9A0)
- .byte $ AA ; lookup_app_bank: TAX (preserve logical token)
- .byte $ A9, $ 3D ; LDA #<$C83D
- .byte $ 8D , $ 02 , $ DF ; STA $DF02 (C64 addr lo)
- .byte $ A9, $ C8 ; LDA #>$C83D
- .byte $ 8D , $ 03 , $ DF ; STA $DF03 (C64 addr hi)
- .byte $ 8A ; TXA
- .byte $ 8D , $ 04 , $ DF ; STA $DF04 (REU offset lo = logical token)
- .byte $ A9, $ 2F ; LDA #$2F
- .byte $ 8D , $ 05 , $ DF ; STA $DF05 (REU offset hi = lookup page)
- .byte $ AD, $ 3B , $ C8 ; LDA $C83B (ReadyOS global physical bank)
- .byte $ 8D , $ 06 , $ DF ; STA $DF06
- .byte $ A9, $ 01 ; LDA #1
- .byte $ 8D , $ 07 , $ DF ; STA $DF07 (length lo)
- .byte $ A9, $ 00 ; LDA #0
- .byte $ 8D , $ 08 , $ DF ; STA $DF08 (length hi)
- .byte $ A9, $ 91 ; LDA #$91 (FETCH command)
- .byte $ 8D , $ 01 , $ DF ; STA $DF01 - fetch physical bank byte
- .byte $ AD, $ 3D , $ C8 ; LDA $C83D (resolved physical bank)
- .byte $ 4C , $ A0, $ C9 ; JMP reu_setup ($C9A0)
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ; Padding to $C9A0
-
-;-----------------------------------------------------------------------------
-; $C9A0: reu_setup - Set up REU registers for $B600 transfer at $1000
-;-----------------------------------------------------------------------------
- .byte $ 8D , $ 06 , $ DF ; STA $DF06 (bank)
- .byte $ A9, $ 00 ; LDA #$00
- .byte $ 8D , $ 02 , $ DF ; STA $DF02 (C64 addr lo = $00)
- .byte $ A9, $ 10 ; LDA #$10
- .byte $ 8D , $ 03 , $ DF ; STA $DF03 (C64 addr hi = $10, so $1000)
- .byte $ A9, $ 00 ; LDA #$00
- .byte $ 8D , $ 04 , $ DF ; STA $DF04 (REU addr lo)
- .byte $ 8D , $ 05 , $ DF ; STA $DF05 (REU addr hi)
- .byte $ 8D , $ 07 , $ DF ; STA $DF07 (len lo = $00)
- .byte $ A9, $ B6 ; LDA #$B6
- .byte $ 8D , $ 08 , $ DF ; STA $DF08 (len hi = $B6, so $B600 bytes)
- .byte $ 60 ; RTS
- .byte $ 00 ,$ 00
-
-;-----------------------------------------------------------------------------
-; $C9C0: set_bitmap - Set bit for bank in A in reu_bitmap ($C836-$C838)
-;-----------------------------------------------------------------------------
- .byte $ C9, $ 18 ; CMP #$18 (only banks 0-23 are tracked)
- .byte $ B0, $ 17 ; BCS done
- .byte $ AA ; TAX - preserve full bank
- .byte $ 29 , $ 07 ; AND #$07 - bit index within byte
- .byte $ A8 ; TAY - Y = bit index
- .byte $ 8A ; TXA - restore full bank
- .byte $ 4A ; LSR A
- .byte $ 4A ; LSR A
- .byte $ 4A ; LSR A
- .byte $ AA ; TAX - X = byte offset 0..2
- .byte $ A9, $ 01 ; LDA #$01
- .byte $ 88 ; DEY
- .byte $ 30 , $ 03 ; BMI store_bit
- .byte $ 0A ; ASL A
- .byte $ 10 , $ FA ; BPL shift_loop
- .byte $ 1D , $ 36 , $ C8 ; ORA $C836,X
- .byte $ 9D , $ 36 , $ C8 ; STA $C836,X
- .byte $ 60 ; RTS
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00
-
-;-----------------------------------------------------------------------------
-; $C9E0: log_byte - Write debug marker to buffer at $C980
-;-----------------------------------------------------------------------------
- .byte $ 48 ; PHA - save the byte to log
- .byte $ 8E , $ FC, $ 00 ; STX $00FC - save X to ZP temp
- .byte $ AE, $ 3A , $ C8 ; LDX $C83A - get log_index
- .byte $ 68 ; PLA - get byte back
- .byte $ 9D , $ 80 , $ C9 ; STA $C980,X - write to buffer
- .byte $ E8 ; INX - increment index
- .byte $ E0, $ 20 ; CPX #$20 - wrap at 32
- .byte $ D0, $ 02 ; BNE +2 (skip reset)
- .byte $ A2, $ 00 ; LDX #$00 - reset to 0
- .byte $ 8E , $ 3A , $ C8 ; STX $C83A - store new index
- .byte $ AE, $ FC, $ 00 ; LDX $00FC - restore X
- .byte $ 60 ; RTS
- .byte $ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00 ,$ 00
+class="sourceCode asm">;-----------------------------------------------------------------------------
+; Shared ReadyOS shim image ($C600-$C9FF, 1024 bytes)
+; This file is the canonical shim byte layout used by both the disk boot path
+; and the EasyFlash cartridge flavor. Keep it identical across all variants.
+;-----------------------------------------------------------------------------
+
+;-----------------------------------------------------------------------------
+; Pages 1-2: $C600-$C7FF - reserved resident expansion space
+;-----------------------------------------------------------------------------
+; This space used to contain the C64-RAM REU allocation/metadata mirror. The
+; authoritative state now lives in the ReadyOS REU bank, but the RAM remains
+; resident shim-owned capacity rather than becoming app snapshot memory.
+.ifndef READYOS_SHIM_ABI_ONLY
+.res $0200, $00
+.endif
+
+;-----------------------------------------------------------------------------
+; Page 3: $C800-$C8FF - Jump table, data, and helper routines
+;-----------------------------------------------------------------------------
+
+; $C800-$C817: Jump Table (24 bytes, 8 entries)
+jt_load_disk = $C800 ; Load from disk, run
+jt_load_reu = $C803 ; Fetch from REU, run
+jt_run_app = $C806 ; Just run app
+jt_preload = $C809 ; Preload to REU, return
+jt_return = $C80C ; Return to launcher
+jt_switch = $C80F ; Switch to another app
+jt_reserved = $C812 ; Reserved compatibility slot (safe no-op)
+jt_fetch_bank = $C815 ; Helper: fetch from bank in A
+
+.byte $4C, $40, $C8 ; $C800: JMP load_disk ($C840)
+.byte $4C, $60, $C8 ; $C803: JMP load_reu ($C860)
+.byte $4C, $00, $10 ; $C806: JMP $1000 (run app)
+.byte $4C, $80, $C8 ; $C809: JMP preload ($C880)
+.byte $4C, $00, $C9 ; $C80C: JMP return_to_launcher ($C900)
+.byte $4C, $40, $C9 ; $C80F: JMP switch_app ($C940)
+.byte $4C, $FF, $C9 ; $C812: reserved helper -> safe RTS
+.byte $4C, $F0, $C8 ; $C815: JMP fetch_bank ($C8F0)
+
+; $C818: deprecated logger compatibility slot
+.byte $4C, $FF, $C9 ; $C818: deprecated logger -> safe RTS
+.byte $4C, $C0, $C9 ; $C81B: JMP mark_loaded (token in A)
+.byte $00,$00 ; $C81E-$C81F: reserved
+
+; $C820-$C83F: Data Area (32 bytes)
+; $C820: target_bank - bank to load/switch to
+; $C821: filename_len
+; $C822-$C823: launcher-side app-size scratch (not consumed by the shim)
+; $C824-$C82F: filename (12 bytes)
+; $C830: load_end_lo (KERNAL LOAD end addr low byte, saved by preload)
+; $C831: load_end_hi (KERNAL LOAD end addr high byte, saved by preload)
+; $C832-$C833: unused
+; $C834: current_bank - currently running app
+; $C835: last_saved
+; $C836-$C838: retired bitmap bytes (reserved; authoritative state is in REU)
+; $C839: storage_drive - shim-global default storage drive for D8/D9 app dialogs
+; This persists across app switches and is shared by apps that use the
+; common file-dialog default-drive contract.
+; $C83A: reserved (formerly log_index)
+; $C83B: readyos_bank - direct physical ReadyOS bank number (Skip)
+; $C83C: launcher_flags - launcher-owned one-shot state flags
+; $C83D: reu_lookup_scratch - one-byte ReadyOS-bank DMA scratch
+; $C83E: token_scratch; $C83F: reserved
+
+.byte $00 ; $C820: target_bank
+.byte $08 ; $C821: filename_len
+.byte $00, $00 ; $C822-$C823: launcher app-size scratch
+.byte "LAUNCHER " ; $C824-$C82F: filename (12 bytes)
+.byte $00,$00 ; $C830-$C831: load_end_lo, load_end_hi
+.byte $00,$00 ; $C832-$C833: unused
+.byte $00 ; $C834: current_bank
+.byte $FF ; $C835: last_saved
+.byte $00 ; $C836: reserved (retired bitmap byte)
+.byte $00 ; $C837: reserved (retired bitmap byte)
+.byte $00 ; $C838: reserved (retired bitmap byte)
+.byte $08 ; $C839: storage_drive (default drive 8)
+.byte $00 ; $C83A: reserved (retired debug-ring head)
+.byte READYOS_REU_BANK_SKIP ; $C83B: readyos_bank (physical Skip)
+.byte $00 ; $C83C: launcher_flags
+.byte $00 ; $C83D: reu_lookup_scratch
+.byte $00,$00 ; $C83E-$C83F: reserved
+
+;-----------------------------------------------------------------------------
+; $C840: load_disk - Load app from disk and run (32 bytes)
+;-----------------------------------------------------------------------------
+.byte $AD, $21, $C8 ; LDA $C821 (filename len)
+.byte $A2, $24 ; LDX #$24
+.byte $A0, $C8 ; LDY #$C8 (filename at $C824)
+.byte $20, $BD, $FF ; JSR $FFBD (SETNAM)
+.byte $A9, $00 ; LDA #0
+.byte $AE, $39, $C8 ; LDX $C839 (storage drive)
+.byte $A0, $01 ; LDY #1
+.byte $20, $BA, $FF ; JSR $FFBA (SETLFS)
+.byte $A9, $00 ; LDA #0
+.byte $20, $D5, $FF ; JSR $FFD5 (LOAD)
+.byte $4C, $00, $10 ; JMP $1000
+.byte $00,$00,$00,$00 ; Padding to $C860
+
+;-----------------------------------------------------------------------------
+; $C860: load_reu - Fetch app from REU and run (32 bytes)
+;-----------------------------------------------------------------------------
+.byte $AD, $20, $C8 ; LDA $C820 (target bank)
+.byte $20, $F0, $C8 ; JSR fetch_bank ($C8F0)
+.byte $4C, $00, $10 ; JMP $1000
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00
+
+;-----------------------------------------------------------------------------
+; $C880: preload - Load to REU, return to launcher
+; Called via JSR $C809
+;-----------------------------------------------------------------------------
+.byte $A9, $00 ; LDA #0 (launcher token -> ReadyOS bank)
+.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
+
+.byte $AD, $21, $C8 ; LDA $C821 (len)
+.byte $A2, $24 ; LDX #$24
+.byte $A0, $C8 ; LDY #$C8 (filename at $C824)
+.byte $20, $BD, $FF ; JSR SETNAM
+
+.byte $A9, $00 ; LDA #0
+.byte $AE, $39, $C8 ; LDX $C839 (storage drive)
+.byte $A0, $01 ; LDY #1
+.byte $20, $BA, $FF ; JSR SETLFS
+
+.byte $A9, $00 ; LDA #0
+.byte $20, $D5, $FF ; JSR LOAD
+
+.byte $8E, $30, $C8 ; STX $C830 (end addr lo)
+.byte $8C, $31, $C8 ; STY $C831 (end addr hi)
+
+.byte $AD, $20, $C8 ; LDA $C820 (target bank)
+.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
+
+.byte $AD, $20, $C8 ; LDA $C820 (target bank)
+.byte $20, $C0, $C9 ; JSR mark_loaded ($C9C0)
+
+.byte $A9, $00 ; LDA #0
+.byte $20, $F0, $C8 ; JSR fetch_bank ($C8F0)
+
+.byte $60 ; RTS
+
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00
+
+;-----------------------------------------------------------------------------
+; $C8E0: stash_to_bank - Stash $1000-$C5FF to REU bank in A (16 bytes)
+;-----------------------------------------------------------------------------
+.byte $20, $60, $C9 ; JSR reu_setup_logical ($C960)
+.byte $A9, $90 ; LDA #$90 (STASH command)
+.byte $8D, $01, $DF ; STA $DF01 - execute transfer
+.byte $60 ; RTS
+.byte $00,$00,$00,$00,$00,$00,$00
+
+;-----------------------------------------------------------------------------
+; $C8F0: fetch_bank - Fetch from REU bank in A to $1000-$C5FF (16 bytes)
+;-----------------------------------------------------------------------------
+.byte $20, $60, $C9 ; JSR reu_setup_logical ($C960)
+.byte $A9, $91 ; LDA #$91 (FETCH command)
+.byte $8D, $01, $DF ; STA $DF01 - execute transfer
+.byte $60 ; RTS
+.byte $00,$00,$00,$00,$00,$00,$00
+
+;-----------------------------------------------------------------------------
+; Page 4: $C900-$C9FF - Main routines
+;-----------------------------------------------------------------------------
+
+;-----------------------------------------------------------------------------
+; $C900: return_to_launcher (64 bytes)
+;-----------------------------------------------------------------------------
+.byte $AD, $34, $C8 ; LDA $C834 (current bank)
+.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
+.byte $AD, $34, $C8 ; LDA $C834 (current bank)
+.byte $20, $C0, $C9 ; JSR mark_loaded ($C9C0)
+.byte $AD, $34, $C8 ; LDA $C834
+.byte $8D, $35, $C8 ; STA $C835
+.byte $A9, $00 ; LDA #0
+.byte $20, $F0, $C8 ; JSR fetch_bank ($C8F0)
+.byte $A9, $00 ; LDA #0
+.byte $8D, $34, $C8 ; STA $C834
+.byte $4C, $00, $10 ; JMP $1000
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00
+
+;-----------------------------------------------------------------------------
+; $C940: switch_app (64 bytes)
+;-----------------------------------------------------------------------------
+.byte $AD, $34, $C8 ; LDA $C834 (current bank)
+.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
+.byte $AD, $34, $C8 ; LDA $C834 (current bank)
+.byte $20, $C0, $C9 ; JSR mark_loaded ($C9C0)
+.byte $AD, $20, $C8 ; LDA $C820 (target bank)
+.byte $20, $F0, $C8 ; JSR fetch_bank ($C8F0)
+.byte $AD, $20, $C8 ; LDA $C820
+.byte $8D, $34, $C8 ; STA $C834
+.byte $4C, $00, $10 ; JMP $1000
+.byte $00,$00,$00,$00,$00
+
+;-----------------------------------------------------------------------------
+; $C960: reu_setup_logical - Resolve token via the ReadyOS bank, then setup regs
+;-----------------------------------------------------------------------------
+.byte $C9, $00 ; CMP #0 (logical launcher bank?)
+.byte $D0, $06 ; BNE lookup_app_bank
+.byte $AD, $3B, $C8 ; LDA $C83B (ReadyOS bank contains launcher)
+.byte $4C, $A0, $C9 ; JMP reu_setup ($C9A0)
+.byte $AA ; lookup_app_bank: TAX (preserve logical token)
+.byte $A9, $3D ; LDA #<$C83D
+.byte $8D, $02, $DF ; STA $DF02 (C64 addr lo)
+.byte $A9, $C8 ; LDA #>$C83D
+.byte $8D, $03, $DF ; STA $DF03 (C64 addr hi)
+.byte $8A ; TXA
+.byte $18 ; CLC
+.byte $69, $40 ; ADC #<$B740 (mapping offset + token)
+.byte $8D, $04, $DF ; STA $DF04 (REU offset lo)
+.byte $A9, $B7 ; LDA #>$B740
+.byte $69, $00 ; ADC #0 (include low-byte carry)
+.byte $8D, $05, $DF ; STA $DF05 (REU offset hi)
+.byte $AD, $3B, $C8 ; LDA $C83B (ReadyOS global physical bank)
+.byte $8D, $06, $DF ; STA $DF06
+.byte $A9, $01 ; LDA #1
+.byte $8D, $07, $DF ; STA $DF07 (length lo)
+.byte $A9, $00 ; LDA #0
+.byte $8D, $08, $DF ; STA $DF08 (length hi)
+.byte $A9, $91 ; LDA #$91 (FETCH command)
+.byte $8D, $01, $DF ; STA $DF01 - fetch physical bank byte
+.byte $AD, $3D, $C8 ; LDA $C83D (resolved physical bank)
+.byte $4C, $A0, $C9 ; JMP reu_setup ($C9A0)
+.byte $00,$00 ; Padding to $C9A0
+
+;-----------------------------------------------------------------------------
+; $C9A0: reu_setup - Set up REU registers for $B600 transfer at $1000
+;-----------------------------------------------------------------------------
+.byte $8D, $06, $DF ; STA $DF06 (bank)
+.byte $A9, $00 ; LDA #$00
+.byte $8D, $02, $DF ; STA $DF02 (C64 addr lo = $00)
+.byte $A9, $10 ; LDA #$10
+.byte $8D, $03, $DF ; STA $DF03 (C64 addr hi = $10, so $1000)
+.byte $A9, $00 ; LDA #$00
+.byte $8D, $04, $DF ; STA $DF04 (REU addr lo)
+.byte $8D, $05, $DF ; STA $DF05 (REU addr hi)
+.byte $8D, $07, $DF ; STA $DF07 (len lo = $00)
+.byte $A9, $B6 ; LDA #$B6
+.byte $8D, $08, $DF ; STA $DF08 (len hi = $B6, so $B600 bytes)
+.byte $60 ; RTS
+.byte $00,$00
+
+;-----------------------------------------------------------------------------
+; $C9C0: mark_loaded - Commit token status after a successful snapshot stash
+; A = logical token. Status $07 means valid, loaded, and resumable.
+;-----------------------------------------------------------------------------
+.byte $8D, $3E, $C8 ; STA $C83E (preserve token)
+.byte $A9, $07 ; LDA #VALID|LOADED|RESUMABLE
+.byte $8D, $3D, $C8 ; STA $C83D
+.byte $A9, $3D ; C64 source = $C83D
+.byte $8D, $02, $DF
+.byte $A9, $C8
+.byte $8D, $03, $DF
+.byte $AD, $3E, $C8 ; token
+.byte $18 ; CLC
+.byte $69, $40 ; + <$B840 (token status table)
+.byte $8D, $04, $DF
+.byte $A9, $B8 ; >$B840
+.byte $69, $00 ; include low-byte carry
+.byte $8D, $05, $DF
+.byte $AD, $3B, $C8 ; ReadyOS physical bank
+.byte $8D, $06, $DF
+.byte $A9, $01 ; one byte
+.byte $8D, $07, $DF
+.byte $A9, $00
+.byte $8D, $08, $DF
+.byte $A9, $90 ; STASH C64 byte to ReadyOS bank
+.byte $8D, $01, $DF
+.byte $AD, $3E, $C8 ; preserve caller-visible token in A
+.byte $60 ; RTS
+.byte $00,$00,$00,$00 ; reserved through $C9FE
+.byte $60 ; $C9FF: compatibility no-op RTS
+
Implemented Logical Bank 0
Layout
The implemented v4 layout deliberately separates "hot, cheap to copy"
diff --git a/docs/reports/easyflash_boot_flow.html b/docs/reports/easyflash_boot_flow.html
index b218641..475ad94 100644
--- a/docs/reports/easyflash_boot_flow.html
+++ b/docs/reports/easyflash_boot_flow.html
@@ -1,3 +1,180 @@
+
+
+
+
+
+
+ easyflash_boot_flow
+
+
+
+
+CURRENT DOCUMENT Current EasyFlash boot-flow counterpart generated from easyflash_boot_flow.md.
+
ReadyOS EasyFlash Boot Flow
This document describes how the current ReadyOS EasyFlash cartridge
flavor boots, what executes where, when cartridge banking happens, when
@@ -30,7 +207,7 @@
Scope
src/generated/easyflash_layout.inc
High-Level Model
-The EasyFlash flavor is not a "run directly from cartridge forever"
+
The EasyFlash flavor is not a “run directly from cartridge forever”
design.
It is a two-stage system:
@@ -48,18 +225,24 @@ Current Cartridge Layout
bank 0: boot bank
banks 1-2: launcher payload
-banks 3-34: application payloads
-later banks: ReadyShell overlay/state/resource payloads and unused
-capacity, according to the generated EasyFlash layout
+banks 3-43: 21 application payloads in the current
+generated layout
+banks 44-52: nine ReadyShell overlay payloads
+banks 53-63: unused cartridge capacity in the current
+one-megabyte image
Current generated constants:
EASYFLASH_LAUNCHER_BANK = 1
EASYFLASH_LAUNCHER_BANK_SPAN = 2
-EASYFLASH_APP_COUNT = 16
+EASYFLASH_APP_COUNT = 21 in the current generated
+layout
overlay/resource counts are generated from the profile resource
metadata
+This count is a generated-layout measurement, not an ABI constant.
+Regenerate the report after catalog changes rather than copying the
+number forward.
Each EasyFlash bank is treated as one 16 KiB payload slot, split
across:
@@ -77,23 +260,24 @@ Cartridge-visible areas
$DE00: cart bank register
$DE01, $DE02: cart control registers
-RAM execution / staging areas
+RAM execution / staging areas
$0800-$27FF: EasyFlash loader copied from cartridge and
executed from RAM
-$1000-$C5FF: app working window and launcher restore
-window
+$1000-$C5FF: $B600 app working/launcher
+restore window
$1000-$47FF: upper part of loader tail refresh
$1000-$47FF / full window: temporary staging during
preload
-$C600-$C7FF: REU bookkeeping and loader state
-$C7F0-$C7FB: overlay metadata staging block
-$C800-$C9FF: historical shim copied into RAM
+$C600-$C7FF: resident shim expansion reserve (no REU
+bookkeeping mirror)
+$C600-$C9FF: canonical 1 KB shim copied into RAM;
+public ABI remains at $C800
$CA00+: diagnostic/debug scratch
$CC00-$CC8F: copied app layout table
$CC90-...: copied overlay layout table
-Screen / VIC visible areas
+Screen / VIC visible areas
$0400: expected text screen RAM
$D020: border color
@@ -108,6 +292,12 @@ Boot Color Guide
stage-specific border colors so the machine is visibly doing work during
the long cold-boot preload.
+
+
+
+
+
+
Visible color
@@ -294,8 +484,8 @@ Stage 3A: Early REU
Stage 4: Historical Shim
Install
- The loader copies the historical shim byte image into
-$C800-$C9FF.
+The loader copies the canonical 1 KB shim byte image into
+$C600-$C9FF.
Source:
shim_data in
@@ -306,7 +496,7 @@ Stage 4: Historical Shim
Destination:
-RAM $C800-$C9FF
+RAM $C600-$C9FF
What the shim is:
@@ -329,15 +519,14 @@ Stage 4: Historical Shim
It is always copied into resident RAM first.
The border switches to the shim color for this phase.
-Stage 5: REU State Init
-The loader initializes REU-side bookkeeping in RAM, including:
-
-zeroing tables around $C600-$C7FF
-writing magic at $C700
-setting shim default storage drive at $C839
-setting last_saved at $C835
-
-This is RAM bookkeeping, not yet the app preload pass itself.
+Stage 5: Shim State Init
+The loader initializes only the small resident shim fields needed
+during preload: the default storage drive at $C839 and
+last_saved at $C835. It does not create a
+$C600-$C7FF mirror. The launcher snapshot is placed in
+physical Skip during Stage 7; after handoff, the launcher
+initializes the schema-v5 portion at $B600-$FFFF without
+disturbing that snapshot.
Stage 6: Copy
Generated Layout Tables To RAM
The generated tables from
@@ -357,10 +546,10 @@
Stage 6: Copy
Stage 7: Preload Launcher
Snapshot
The launcher payload is copied from EasyFlash into the app window and
-then stashed into its assigned launcher snapshot bank. The current
-runtime also publishes logical REU bank 0 as the ReadyOS
-control/global bank rather than treating it as only the launcher
-image.
+then stashed into the launcher portion of the ReadyOS bank. Physical
+Skip is the single source of truth for both the launcher
+snapshot and schema-v5 runtime metadata; it is not logical app token
+0 and is never a dynamic app bank.
Current launcher layout:
cart start bank: 1
@@ -374,13 +563,12 @@ Stage 7: Preload Launcher
Set current cart bank to launcher start bank.
Copy launcher payload from cart to RAM at $1000.
Stash the full app window $1000-$C5FF
-($B600 bytes) into the assigned launcher snapshot
-bank.
+($B600 bytes) into the ReadyOS bank.
Important nuance:
The payload itself is about 30.2 KiB.
-The stash is the full 46 KiB app window.
+The stash is the full 46,592 byte app window.
That means the REU snapshot stores the complete runtime RAM image
shape expected by the launcher, not just the compressed-on-cart payload
bytes.
@@ -395,20 +583,20 @@ Stage 8: Preload
Clear the full app window $1000-$C5FF.
Read app metadata from the copied RAM table at
$CC00.
-Select the app's EasyFlash start bank by writing
+ Select the app’s EasyFlash start bank by writing
$DE00.
Copy the app payload from cart to RAM at the specified load address,
normally $1000.
-Stash the full $B600 app window to the app's assigned
+ Stash the full $B600 app window to the app’s assigned
REU bank.
-Publish the app token to physical-bank lookup into logical REU bank
-0 so the shim can resolve the app token without a fixed
-app-slot gap.
+Leave the explicit app token and physical bank pair in the generated
+catalog for the launcher to publish at ReadyOS
+$B740/$B840 after handoff.
Current app REU banks are loader-assigned. The cartridge SKU preloads
-the profile's app payloads up front, but the steady-state metadata shape
-matches the disk launcher: app token -> assigned snapshot bank in
-bank 0.
+the profile’s app payloads up front, but the steady-state metadata shape
+matches the disk launcher: app token -> explicitly assigned snapshot
+bank in ReadyOS.
Important nuances:
This is where most of the long cold-boot time goes.
@@ -420,7 +608,7 @@ Stage 8: Preload
stashes a large full-window snapshot to REU
-So the long "blue screen pause" is mostly a batch build of all app
+
So the long “blue screen pause” is mostly a batch build of all app
snapshots.
During this loop, the border repeatedly alternates:
@@ -436,7 +624,7 @@ Stage 9: Preload
Clear the overlay staging region beginning at
$1000.
-Select the resource payload's EasyFlash bank.
+Select the resource payload’s EasyFlash bank.
Copy resource payload from cart to RAM.
Stash the staged bytes to the assigned REU bank and bank-relative
offset.
@@ -463,20 +651,21 @@ Stage 9: Preload
use.
The loader uses $1000 as a temporary staging region for
this work.
-Logical REU bank 0 records the owner/resource
-relationships so REU Viewer and launcher unload logic can see which
-banks belong to ReadyShell.
+After handoff, the launcher records the owner/resource relationships
+in the ReadyOS-bank schema so REU Viewer and unload logic see the same
+source of truth.
The same yellow-then-orange border pattern is used here too.
-The loader writes compact runtime metadata for assigned ReadyShell
-resources and mirrors the richer relationship records into logical REU
-bank 0.
+The loader writes compact runtime metadata into ReadyShell’s assigned
+state bank. After handoff, the launcher writes the richer relationship
+records directly into the ReadyOS bank from the same generated EasyFlash
+catalog.
The small runtime block is still deliberately tiny so ReadyShell does
-not need to parse the full control bank. ReadyShell consumes the
+not need to parse the full ReadyOS bank. ReadyShell consumes the
assigned overlay/state bank ids and bank-relative offsets; launcher and
-REU Viewer consume the richer bank 0 records.
+REU Viewer consume the richer schema-v5 records.
Metadata includes:
"OV" signature
@@ -488,7 +677,7 @@
This lets the runtime know how the overlay cache has been organized
without reintroducing fixed physical bank constants.
-Stage 11: "Verify" Stage
+Stage 11: “Verify” Stage
The boot banner includes a "VERIFYING PRELOADS" stage
label.
Important nuance:
@@ -532,20 +721,20 @@ Stage 12: KERNAL and VIC
Current REU Physical
Placement
-Start means physical REU bank
-READYOS_REU_BANK_SKIP. Start+0 is logical REU
-bank 0, the ReadyOS control/global bank.
-Start+1 is the launcher snapshot/resume bank for launcher
-token 0. Start+2 is the first dynamic
-allocation bank. Shim-facing app tokens are resolved through logical REU
-bank 0's lookup page; the current default writer maps token
-1 to Start+2.
+Skip means physical READYOS_REU_BANK_SKIP.
+Physical Skip is the combined ReadyOS bank: launcher
+snapshot at $0000-$B5FF, schema v5 at
+$B600-$FFFF. The allocator skips it and continues at
+Skip+1. Shim-facing app tokens resolve through ReadyOS
+$B740; the cartridge emits explicit token/physical pairs
+and does not use arithmetic.
Stage 13:
Restore Launcher Snapshot and Handoff
At the end of boot:
-The loader fetches logical launcher bank 0 (physical
-Start+1) back into $1000-$C5FF.
+The loader fetches the launcher snapshot selected by shim token
+0 (physical Skip) back into
+$1000-$C5FF.
It disables unwanted interrupt sources.
It jumps to $1000.
@@ -555,8 +744,7 @@ Stage 13:
The launcher is not starting directly from cartridge data.
It is starting from a RAM image restored from the launcher snapshot
-bank (Start+1, launcher token 0), not from
-logical REU bank 0.
+bank (the ReadyOS bank, launcher token 0).
The border switches to orange for the final restore, then light
green for the last handoff into launcher code.
@@ -575,10 +763,10 @@ Pure asm, RAM-resident boot
Pure asm, resident shim
-shim image at $C800-$C9FF:
+ shim image at $C600-$C9FF:
src/boot/readyos_shim.inc
-C / cc65 launcher stage
+C / cc65 launcher stage
launcher program in $1000-$C5FF
source entry:
@@ -590,8 +778,8 @@ C / cc65 launcher stage
Later app launches
After boot, app launches are usually:
-launcher saves itself back to the launcher snapshot bank
-(Start+1)
+launcher saves itself back to the ReadyOS bank
+(Skip)
shim fetches target app snapshot from REU
control jumps to $1000
@@ -618,7 +806,7 @@ Where Cartridge Banking
increments cart bank
repeats until payload length is satisfied
-This is the core "read from cartridge" loop used by
+
This is the core “read from cartridge” loop used by
launcher/app/overlay preload.
Where Cartridge
Banking Does Not Matter Anymore
@@ -637,21 +825,22 @@ Why the Blue Screen Pause
What boot is doing during that pause:
preloading launcher snapshot
-preloading 16 application snapshots
-preloading 8 overlay snapshots
+preloading 21 application snapshots
+preloading 9 ReadyShell overlay/resource payloads
clearing large RAM windows before each preload
copying payloads from cartridge into RAM in software loops
stashing large windows into REU
Roughly:
-about 531 KiB of actual payload content gets copied
-from cartridge
-about 885 KiB of snapshot/stage data gets stashed into
-REU
+about 635 KiB of current launcher/app/overlay payload
+content gets copied from cartridge
+app snapshots alone account for about 956 KiB of REU
+stash traffic, before launcher and ReadyShell resource/state
+transfers
plus a large amount of repeated RAM clearing
-The visible effect is "nothing happening", but the machine is
+
The visible effect is “nothing happening”, but the machine is
actually building all of the runtime REU state up front.
With the new stage colors, the more accurate user-facing
interpretation is:
@@ -683,8 +872,11 @@ Summary
RAM loader preloads launcher/apps/overlays from EasyFlash
RAM loader stashes them into REU snapshots
machine state is normalized
-launcher snapshot is restored from Start+1
+launcher snapshot is restored from the ReadyOS bank
+(Skip)
launcher starts in C at $1000
The large cold-boot delay is mostly the price of making later
launches effectively instant.
+
+
diff --git a/docs/reports/easyflash_boot_flow.md b/docs/reports/easyflash_boot_flow.md
index abba4dd..d1334db 100644
--- a/docs/reports/easyflash_boot_flow.md
+++ b/docs/reports/easyflash_boot_flow.md
@@ -46,17 +46,20 @@ The generated layout currently defines:
- bank `0`: boot bank
- banks `1-2`: launcher payload
-- banks `3-34`: application payloads
-- later banks: ReadyShell overlay/state/resource payloads and unused capacity,
- according to the generated EasyFlash layout
+- banks `3-43`: 21 application payloads in the current generated layout
+- banks `44-52`: nine ReadyShell overlay payloads
+- banks `53-63`: unused cartridge capacity in the current one-megabyte image
Current generated constants:
- `EASYFLASH_LAUNCHER_BANK = 1`
- `EASYFLASH_LAUNCHER_BANK_SPAN = 2`
-- `EASYFLASH_APP_COUNT = 16`
+- `EASYFLASH_APP_COUNT = 21` in the current generated layout
- overlay/resource counts are generated from the profile resource metadata
+This count is a generated-layout measurement, not an ABI constant. Regenerate
+the report after catalog changes rather than copying the number forward.
+
Each EasyFlash bank is treated as one 16 KiB payload slot, split across:
- `$8000-$9FFF` (ROML half, 8 KiB)
@@ -74,12 +77,11 @@ Each EasyFlash bank is treated as one 16 KiB payload slot, split across:
### RAM execution / staging areas
- `$0800-$27FF`: EasyFlash loader copied from cartridge and executed from RAM
-- `$1000-$C5FF`: app working window and launcher restore window
+- `$1000-$C5FF`: `$B600` app working/launcher restore window
- `$1000-$47FF`: upper part of loader tail refresh
- `$1000-$47FF` / full window: temporary staging during preload
-- `$C600-$C7FF`: REU bookkeeping and loader state
-- `$C7F0-$C7FB`: overlay metadata staging block
-- `$C800-$C9FF`: historical shim copied into RAM
+- `$C600-$C7FF`: resident shim expansion reserve (no REU bookkeeping mirror)
+- `$C600-$C9FF`: canonical 1 KB shim copied into RAM; public ABI remains at `$C800`
- `$CA00+`: diagnostic/debug scratch
- `$CC00-$CC8F`: copied app layout table
- `$CC90-...`: copied overlay layout table
@@ -235,7 +237,7 @@ Important nuance:
## Stage 4: Historical Shim Install
-The loader copies the historical shim byte image into `$C800-$C9FF`.
+The loader copies the canonical 1 KB shim byte image into `$C600-$C9FF`.
Source:
@@ -245,7 +247,7 @@ Source:
Destination:
-- RAM `$C800-$C9FF`
+- RAM `$C600-$C9FF`
What the shim is:
@@ -267,16 +269,13 @@ Important nuance:
- It is always copied into resident RAM first.
- The border switches to the shim color for this phase.
-## Stage 5: REU State Init
-
-The loader initializes REU-side bookkeeping in RAM, including:
-
-- zeroing tables around `$C600-$C7FF`
-- writing magic at `$C700`
-- setting shim default storage drive at `$C839`
-- setting `last_saved` at `$C835`
+## Stage 5: Shim State Init
-This is RAM bookkeeping, not yet the app preload pass itself.
+The loader initializes only the small resident shim fields needed during
+preload: the default storage drive at `$C839` and `last_saved` at `$C835`.
+It does not create a `$C600-$C7FF` mirror. The launcher snapshot is placed in
+physical `Skip` during Stage 7; after handoff, the launcher initializes the
+schema-v5 portion at `$B600-$FFFF` without disturbing that snapshot.
## Stage 6: Copy Generated Layout Tables To RAM
@@ -293,9 +292,9 @@ Why:
## Stage 7: Preload Launcher Snapshot
The launcher payload is copied from EasyFlash into the app window and then
-stashed into its assigned launcher snapshot bank. The current runtime also
-publishes logical REU bank `0` as the ReadyOS control/global bank rather than
-treating it as only the launcher image.
+stashed into the launcher portion of the ReadyOS bank. Physical `Skip` is the
+single source of truth for both the launcher snapshot and schema-v5 runtime
+metadata; it is not logical app token `0` and is never a dynamic app bank.
Current launcher layout:
@@ -309,13 +308,12 @@ Detailed flow:
1. Clear `$1000-$C5FF`.
2. Set current cart bank to launcher start bank.
3. Copy launcher payload from cart to RAM at `$1000`.
-4. Stash the full app window `$1000-$C5FF` (`$B600` bytes) into the assigned
- launcher snapshot bank.
+4. Stash the full app window `$1000-$C5FF` (`$B600` bytes) into the ReadyOS bank.
Important nuance:
- The payload itself is about `30.2 KiB`.
-- The stash is the full `46 KiB` app window.
+- The stash is the full `46,592` byte app window.
- That means the REU snapshot stores the complete runtime RAM image shape expected by the launcher, not just the compressed-on-cart payload bytes.
- The border switches to yellow for cart-to-RAM copy, then orange for the REU stash.
@@ -330,12 +328,12 @@ Per app, it does:
3. Select the app's EasyFlash start bank by writing `$DE00`.
4. Copy the app payload from cart to RAM at the specified load address, normally `$1000`.
5. Stash the full `$B600` app window to the app's assigned REU bank.
-6. Publish the app token to physical-bank lookup into logical REU bank `0` so
- the shim can resolve the app token without a fixed app-slot gap.
+6. Leave the explicit app token and physical bank pair in the generated catalog
+ for the launcher to publish at ReadyOS `$B740`/`$B840` after handoff.
Current app REU banks are loader-assigned. The cartridge SKU preloads the
profile's app payloads up front, but the steady-state metadata shape matches
-the disk launcher: app token -> assigned snapshot bank in bank `0`.
+the disk launcher: app token -> explicitly assigned snapshot bank in ReadyOS.
Important nuances:
@@ -380,19 +378,20 @@ Important nuance:
- Overlays and resource banks are not executed during boot.
- They are staged and cached into REU for later ReadyShell runtime use.
- The loader uses `$1000` as a temporary staging region for this work.
-- Logical REU bank `0` records the owner/resource relationships so REU Viewer
- and launcher unload logic can see which banks belong to ReadyShell.
+- After handoff, the launcher records the owner/resource relationships in the
+ ReadyOS-bank schema so REU Viewer and unload logic see the same source of truth.
- The same yellow-then-orange border pattern is used here too.
## Stage 10: Resource Metadata Write
-The loader writes compact runtime metadata for assigned ReadyShell resources and
-mirrors the richer relationship records into logical REU bank `0`.
+The loader writes compact runtime metadata into ReadyShell's assigned state bank.
+After handoff, the launcher writes the richer relationship records directly into
+the ReadyOS bank from the same generated EasyFlash catalog.
The small runtime block is still deliberately tiny so ReadyShell does not need
-to parse the full control bank. ReadyShell consumes the assigned overlay/state
+to parse the full ReadyOS bank. ReadyShell consumes the assigned overlay/state
bank ids and bank-relative offsets; launcher and REU Viewer consume the richer
-bank `0` records.
+schema-v5 records.
Metadata includes:
@@ -444,17 +443,17 @@ This is also the reason you may briefly see text/color flashes late in boot:
## Current REU Physical Placement
-`Start` means physical REU bank `READYOS_REU_BANK_SKIP`. `Start+0` is logical
-REU bank `0`, the ReadyOS control/global bank. `Start+1` is the launcher
-snapshot/resume bank for launcher token `0`. `Start+2` is the first dynamic
-allocation bank. Shim-facing app tokens are resolved through logical REU bank
-`0`'s lookup page; the current default writer maps token `1` to `Start+2`.
+`Skip` means physical `READYOS_REU_BANK_SKIP`. Physical `Skip` is the combined ReadyOS bank: launcher snapshot
+at `$0000-$B5FF`, schema v5 at `$B600-$FFFF`. The allocator skips it and
+continues at `Skip+1`. Shim-facing app tokens resolve through ReadyOS `$B740`;
+the cartridge emits explicit token/physical pairs and does not use arithmetic.
## Stage 13: Restore Launcher Snapshot and Handoff
At the end of boot:
-1. The loader fetches logical launcher bank `0` (physical `Start+1`) back into `$1000-$C5FF`.
+1. The loader fetches the launcher snapshot selected by shim token `0`
+ (physical `Skip`) back into `$1000-$C5FF`.
2. It disables unwanted interrupt sources.
3. It jumps to `$1000`.
@@ -464,7 +463,7 @@ Important nuance:
- The launcher is not starting directly from cartridge data.
- It is starting from a RAM image restored from the launcher snapshot bank
- (`Start+1`, launcher token `0`), not from logical REU bank `0`.
+ (the ReadyOS bank, launcher token `0`).
- The border switches to orange for the final restore, then light green for the last handoff into launcher code.
## What Runs Where
@@ -479,7 +478,7 @@ Important nuance:
### Pure asm, resident shim
-- shim image at `$C800-$C9FF`: `src/boot/readyos_shim.inc`
+- shim image at `$C600-$C9FF`: `src/boot/readyos_shim.inc`
### C / cc65 launcher stage
@@ -492,7 +491,7 @@ Important nuance:
After boot, app launches are usually:
-1. launcher saves itself back to the launcher snapshot bank (`Start+1`)
+1. launcher saves itself back to the ReadyOS bank (`Skip`)
2. shim fetches target app snapshot from REU
3. control jumps to `$1000`
@@ -538,16 +537,18 @@ The long pause at 100 percent speed is expected from the current design.
What boot is doing during that pause:
- preloading launcher snapshot
-- preloading 16 application snapshots
-- preloading 8 overlay snapshots
+- preloading 21 application snapshots
+- preloading 9 ReadyShell overlay/resource payloads
- clearing large RAM windows before each preload
- copying payloads from cartridge into RAM in software loops
- stashing large windows into REU
Roughly:
-- about `531 KiB` of actual payload content gets copied from cartridge
-- about `885 KiB` of snapshot/stage data gets stashed into REU
+- about `635 KiB` of current launcher/app/overlay payload content gets copied
+ from cartridge
+- app snapshots alone account for about `956 KiB` of REU stash traffic, before
+ launcher and ReadyShell resource/state transfers
- plus a large amount of repeated RAM clearing
The visible effect is "nothing happening", but the machine is actually building all of the runtime REU state up front.
@@ -577,7 +578,7 @@ The EasyFlash boot process is a preload-and-snapshot pipeline:
3. RAM loader preloads launcher/apps/overlays from EasyFlash
4. RAM loader stashes them into REU snapshots
5. machine state is normalized
-6. launcher snapshot is restored from `Start+1`
+6. launcher snapshot is restored from the ReadyOS bank (`Skip`)
7. launcher starts in C at `$1000`
The large cold-boot delay is mostly the price of making later launches effectively instant.
diff --git a/docs/reports/function_key_audit.html b/docs/reports/function_key_audit.html
index 083c00a..cbae17a 100644
--- a/docs/reports/function_key_audit.html
+++ b/docs/reports/function_key_audit.html
@@ -287,6 +287,9 @@
+
+PRESERVED SNAPSHOT / DESIGN Preserved function-key audit snapshot. Revalidate profile/app coverage before treating counts as current.
+
ReadyOS Function Key Audit
diff --git a/docs/reports/readyos_memory_size_comparison_0_1_5_vs_now.html b/docs/reports/readyos_memory_size_comparison_0_1_5_vs_now.html
index d30dc70..b7b6857 100644
--- a/docs/reports/readyos_memory_size_comparison_0_1_5_vs_now.html
+++ b/docs/reports/readyos_memory_size_comparison_0_1_5_vs_now.html
@@ -81,6 +81,20 @@
+
+
+ Current ReadyOS contract (2026-08-02):
+ Physical Skip is the ReadyOS bank and Skip+1 is the first dynamic bank.
+ The launcher snapshot is ReadyOS $0000-$B5FF; schema v5 is $B600-$FFFF,
+ with token map $B740 and status $B840. C64 app RAM is
+ $1000-$C5FF ($B600), and the resident 1 KB shim owns
+ $C600-$C9FF with its public ABI at $C800.
+ Dated layouts and measurements below are retained as historical evidence.
+
+
+
+PRESERVED SNAPSHOT / DESIGN Preserved 0.1.5-to-0.2.4 comparison. Sections saying “current” mean the 0.2.4 audit point, not the present 0.2.5 tree.
+
ReadyOS Memory/Size Comparison: 0.1.5 vs 0.2.4
diff --git a/docs/reports/readyos_shim_architecture_report_v3.html b/docs/reports/readyos_shim_architecture_report_v3.html
index 4bd6461..92314bd 100644
--- a/docs/reports/readyos_shim_architecture_report_v3.html
+++ b/docs/reports/readyos_shim_architecture_report_v3.html
@@ -205,6 +205,9 @@
+
+PRESERVED SNAPSHOT / DESIGN Preserved 0.2.4 v3 report with its full commented source appendix refreshed and byte-verified current. Use ReadyOS_SHIM_ARCHITECTURE_0.2.5.html for current architecture.
+
ReadyOS SHIM Architecture: 0.2.4 Runtime Reality
@@ -221,12 +224,13 @@
ReadyOS SHIM Architecture: 0.2.4 Runtime Reality
+ Current 0.2.5 contract: The full resident shim owns $C600-$C9FF (1024 bytes), with 512 bytes of expansion reserve below the stable ABI at $C800 . Physical Skip is the ReadyOS bank; Skip+1 is the first dynamic bank. The app snapshot is $1000-$C5FF ($B600 ), and schema v5 begins at ReadyOS offset $B600 . Historical 0.2.4 discussion below is retained as version history.
Executive Snapshot
@@ -266,7 +270,7 @@ Canonical C64 RAM Map
@@ -365,7 +369,8 @@
Shim data ABI
$C83A log_index legacy ring head; $C980-$C99F is no longer safe ring storage
$C83B reu_bank_skip compiled physical REU bank offset for the ReadyOS region
$C83C launcher_flags launcher-owned one-shot state flags
-
$C83D-$C83F reserved unused padding
+
$C83D reu_lookup_scratch one-byte physical bank fetched from control bank 0
+
$C83E-$C83F reserved unused padding
$C84D device immediate load_disk launcher-patched drive byte
$C89C device immediate preload launcher-patched drive byte
@@ -383,20 +388,31 @@
Shim data ABI
Annotated Resident Shim Walkthrough
- This is a complete report-local annotation of the resident shim byte image.
- The comments here use the clearer 0.2.4 Start-relative terminology; the
- emitted byte sequence is checked against src/boot/readyos_shim.inc
- and still covers the jump table, every data ABI byte, all live routines,
- and all padding bytes in the 512-byte $C800-$C9FF image.
+ This is a complete commented copy of the current resident shim byte image.
+ The source appendix was refreshed against src/boot/readyos_shim.inc
+ for the 0.2.5 documentation audit. It covers the jump table, every data
+ ABI byte, all live routines, and all padding bytes in the 1024-byte
+ $C600-$C9FF image. The surrounding report remains
+ a preserved 0.2.4 architecture snapshot.
;-----------------------------------------------------------------------------
-; Shared ReadyOS shim image ($C800-$C9FF, 512 bytes)
+; Shared ReadyOS shim image ($C600-$C9FF, 1024 bytes)
; This file is the canonical shim byte layout used by both the disk boot path
; and the EasyFlash cartridge flavor. Keep it identical across all variants.
;-----------------------------------------------------------------------------
;-----------------------------------------------------------------------------
-; Page 1: $C800-$C8FF - Jump table, data, and helper routines
+; Pages 1-2: $C600-$C7FF - reserved resident expansion space
+;-----------------------------------------------------------------------------
+; This space used to contain the C64-RAM REU allocation/metadata mirror. The
+; authoritative state now lives in the ReadyOS REU bank, but the RAM remains
+; resident shim-owned capacity rather than becoming app snapshot memory.
+.ifndef READYOS_SHIM_ABI_ONLY
+.res $0200, $00
+.endif
+
+;-----------------------------------------------------------------------------
+; Page 3: $C800-$C8FF - Jump table, data, and helper routines
;-----------------------------------------------------------------------------
; $C800-$C817: Jump Table (24 bytes, 8 entries)
@@ -406,7 +422,7 @@ Annotated Resident Shim Walkthrough
jt_preload = $C809 ; Preload to REU, return
jt_return = $C80C ; Return to launcher
jt_switch = $C80F ; Switch to another app
-jt_stash_cur = $C812 ; Helper: stash current app
+jt_reserved = $C812 ; Reserved compatibility slot (safe no-op)
jt_fetch_bank = $C815 ; Helper: fetch from bank in A
.byte $4C, $40, $C8 ; $C800: JMP load_disk ($C840)
@@ -415,52 +431,51 @@ Annotated Resident Shim Walkthrough
.byte $4C, $80, $C8 ; $C809: JMP preload ($C880)
.byte $4C, $00, $C9 ; $C80C: JMP return_to_launcher ($C900)
.byte $4C, $40, $C9 ; $C80F: JMP switch_app ($C940)
-.byte $4C, $C0, $C8 ; $C812: JMP stash_current ($C8C0) - placeholder
+.byte $4C, $FF, $C9 ; $C812: reserved helper -> safe RTS
.byte $4C, $F0, $C8 ; $C815: JMP fetch_bank ($C8F0)
-; $C818: JMP log_byte ($C9E0)
-; Legacy diagnostic entry. The old $C980-$C99F ring now overlaps active
-; reu_setup_logical bytes, so callers must not use this unless the ring moves.
-.byte $4C, $E0, $C9 ; $C818: JMP log_byte
-.byte $00,$00,$00,$00,$00 ; $C81B-$C81F: Padding
+; $C818: deprecated logger compatibility slot
+.byte $4C, $FF, $C9 ; $C818: deprecated logger -> safe RTS
+.byte $4C, $C0, $C9 ; $C81B: JMP mark_loaded (token in A)
+.byte $00,$00 ; $C81E-$C81F: reserved
; $C820-$C83F: Data Area (32 bytes)
-; $C820: target_bank - logical bank to load/switch to
+; $C820: target_bank - bank to load/switch to
; $C821: filename_len
-; $C822-$C823: unused
+; $C822-$C823: launcher-side app-size scratch (not consumed by the shim)
; $C824-$C82F: filename (12 bytes)
; $C830: load_end_lo (KERNAL LOAD end addr low byte, saved by preload)
; $C831: load_end_hi (KERNAL LOAD end addr high byte, saved by preload)
; $C832-$C833: unused
-; $C834: current_bank - currently running logical bank
+; $C834: current_bank - currently running app
; $C835: last_saved
-; $C836: reu_bitmap_lo (logical banks 0-7)
-; $C837: reu_bitmap_hi (logical banks 8-15)
-; $C838: reu_bitmap_xhi (logical banks 16-23)
+; $C836-$C838: retired bitmap bytes (reserved; authoritative state is in REU)
; $C839: storage_drive - shim-global default storage drive for D8/D9 app dialogs
; This persists across app switches and is shared by apps that use the
; common file-dialog default-drive contract.
-; $C83A: log_index - legacy debug byte ring head
-; $C83B: reu_bank_skip - physical 64K banks reserved before ReadyOS bank start
- ; $C83C: launcher_flags - launcher-owned one-shot state flags
- ; $C83D-$C83F: reserved
+; $C83A: reserved (formerly log_index)
+; $C83B: readyos_bank - direct physical ReadyOS bank number (Skip)
+; $C83C: launcher_flags - launcher-owned one-shot state flags
+; $C83D: reu_lookup_scratch - one-byte ReadyOS-bank DMA scratch
+; $C83E: token_scratch; $C83F: reserved
.byte $00 ; $C820: target_bank
.byte $08 ; $C821: filename_len
-.byte $00, $00 ; $C822-$C823: unused
-.byte "LAUNCHER " ; $C824-$C82F: filename (12 bytes)
+.byte $00, $00 ; $C822-$C823: launcher app-size scratch
+.byte "LAUNCHER " ; $C824-$C82F: filename (12 bytes)
.byte $00,$00 ; $C830-$C831: load_end_lo, load_end_hi
.byte $00,$00 ; $C832-$C833: unused
.byte $00 ; $C834: current_bank
.byte $FF ; $C835: last_saved
-.byte $00 ; $C836: reu_bitmap_lo
-.byte $00 ; $C837: reu_bitmap_hi
-.byte $00 ; $C838: reu_bitmap_xhi
+.byte $00 ; $C836: reserved (retired bitmap byte)
+.byte $00 ; $C837: reserved (retired bitmap byte)
+.byte $00 ; $C838: reserved (retired bitmap byte)
.byte $08 ; $C839: storage_drive (default drive 8)
-.byte $00 ; $C83A: log_index (legacy debug buffer)
-.byte READYOS_REU_BANK_SKIP ; $C83B: reu_bank_skip (compiled into boot image)
- .byte $00 ; $C83C: launcher_flags
- .byte $00,$00,$00 ; $C83D-$C83F: reserved
+.byte $00 ; $C83A: reserved (retired debug-ring head)
+.byte READYOS_REU_BANK_SKIP ; $C83B: readyos_bank (physical Skip)
+.byte $00 ; $C83C: launcher_flags
+.byte $00 ; $C83D: reu_lookup_scratch
+.byte $00,$00 ; $C83E-$C83F: reserved
;-----------------------------------------------------------------------------
; $C840: load_disk - Load app from disk and run (32 bytes)
@@ -470,13 +485,13 @@ Annotated Resident Shim Walkthrough
.byte $A0, $C8 ; LDY #$C8 (filename at $C824)
.byte $20, $BD, $FF ; JSR $FFBD (SETNAM)
.byte $A9, $00 ; LDA #0
-.byte $A2, $08 ; LDX #8
+.byte $AE, $39, $C8 ; LDX $C839 (storage drive)
.byte $A0, $01 ; LDY #1
.byte $20, $BA, $FF ; JSR $FFBA (SETLFS)
.byte $A9, $00 ; LDA #0
.byte $20, $D5, $FF ; JSR $FFD5 (LOAD)
.byte $4C, $00, $10 ; JMP $1000
-.byte $00,$00,$00,$00,$00 ; Padding to $C860
+.byte $00,$00,$00,$00 ; Padding to $C860
;-----------------------------------------------------------------------------
; $C860: load_reu - Fetch app from REU and run (32 bytes)
@@ -491,30 +506,20 @@ Annotated Resident Shim Walkthrough
;-----------------------------------------------------------------------------
; $C880: preload - Load to REU, return to launcher
; Called via JSR $C809
-; DEBUG: writes markers to $C007-$C00C
;-----------------------------------------------------------------------------
-.byte $A9, $AA ; LDA #$AA (170 = "preload entered")
-.byte $8D, $07, $C0 ; STA $C007
-
-.byte $A9, $00 ; LDA #0 (select launcher bank at Start+1)
+.byte $A9, $00 ; LDA #0 (launcher token -> ReadyOS bank)
.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
-.byte $A9, $BB ; LDA #$BB (187 = "launcher stashed")
-.byte $8D, $08, $C0 ; STA $C008
-
.byte $AD, $21, $C8 ; LDA $C821 (len)
.byte $A2, $24 ; LDX #$24
.byte $A0, $C8 ; LDY #$C8 (filename at $C824)
.byte $20, $BD, $FF ; JSR SETNAM
.byte $A9, $00 ; LDA #0
-.byte $A2, $08 ; LDX #8
+.byte $AE, $39, $C8 ; LDX $C839 (storage drive)
.byte $A0, $01 ; LDY #1
.byte $20, $BA, $FF ; JSR SETLFS
-.byte $A9, $CC ; LDA #$CC (204 = "about to LOAD")
-.byte $8D, $09, $C0 ; STA $C009
-
.byte $A9, $00 ; LDA #0
.byte $20, $D5, $FF ; JSR LOAD
@@ -524,25 +529,23 @@ Annotated Resident Shim Walkthrough
.byte $AD, $20, $C8 ; LDA $C820 (target bank)
.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
-.byte $A9, $EE ; LDA #$EE (238 = "app stashed")
-.byte $8D, $0B, $C0 ; STA $C00B
-
.byte $AD, $20, $C8 ; LDA $C820 (target bank)
-.byte $20, $C0, $C9 ; JSR set_bitmap ($C9C0)
+.byte $20, $C0, $C9 ; JSR mark_loaded ($C9C0)
-.byte $A9, $00 ; LDA #0 (select launcher bank at Start+1)
+.byte $A9, $00 ; LDA #0
.byte $20, $F0, $C8 ; JSR fetch_bank ($C8F0)
-.byte $A9, $FF ; LDA #$FF (255 = "launcher restored")
-.byte $8D, $0C, $C0 ; STA $C00C
-
.byte $60 ; RTS
-.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00
;-----------------------------------------------------------------------------
-; $C8E0: stash_to_bank - Stash $1000-$C5FF to logical REU bank in A (16 bytes)
+; $C8E0: stash_to_bank - Stash $1000-$C5FF to REU bank in A (16 bytes)
;-----------------------------------------------------------------------------
.byte $20, $60, $C9 ; JSR reu_setup_logical ($C960)
.byte $A9, $90 ; LDA #$90 (STASH command)
@@ -551,7 +554,7 @@ Annotated Resident Shim Walkthrough
.byte $00,$00,$00,$00,$00,$00,$00
;-----------------------------------------------------------------------------
-; $C8F0: fetch_bank - Fetch logical REU bank in A to $1000-$C5FF (16 bytes)
+; $C8F0: fetch_bank - Fetch from REU bank in A to $1000-$C5FF (16 bytes)
;-----------------------------------------------------------------------------
.byte $20, $60, $C9 ; JSR reu_setup_logical ($C960)
.byte $A9, $91 ; LDA #$91 (FETCH command)
@@ -560,21 +563,21 @@ Annotated Resident Shim Walkthrough
.byte $00,$00,$00,$00,$00,$00,$00
;-----------------------------------------------------------------------------
-; Page 2: $C900-$C9FF - Main routines
+; Page 4: $C900-$C9FF - Main routines
;-----------------------------------------------------------------------------
;-----------------------------------------------------------------------------
; $C900: return_to_launcher (64 bytes)
;-----------------------------------------------------------------------------
-.byte $AD, $34, $C8 ; LDA $C834 (current logical bank)
+.byte $AD, $34, $C8 ; LDA $C834 (current bank)
.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
-.byte $AD, $34, $C8 ; LDA $C834 (current logical bank)
-.byte $20, $C0, $C9 ; JSR set_bitmap ($C9C0)
+.byte $AD, $34, $C8 ; LDA $C834 (current bank)
+.byte $20, $C0, $C9 ; JSR mark_loaded ($C9C0)
.byte $AD, $34, $C8 ; LDA $C834
.byte $8D, $35, $C8 ; STA $C835
-.byte $A9, $00 ; LDA #0 (select launcher bank at Start+1)
+.byte $A9, $00 ; LDA #0
.byte $20, $F0, $C8 ; JSR fetch_bank ($C8F0)
-.byte $A9, $00 ; LDA #0 (select launcher bank at Start+1)
+.byte $A9, $00 ; LDA #0
.byte $8D, $34, $C8 ; STA $C834
.byte $4C, $00, $10 ; JMP $1000
.byte $00,$00,$00,$00,$00,$00,$00,$00
@@ -586,11 +589,11 @@ Annotated Resident Shim Walkthrough
;-----------------------------------------------------------------------------
; $C940: switch_app (64 bytes)
;-----------------------------------------------------------------------------
-.byte $AD, $34, $C8 ; LDA $C834 (current logical bank)
+.byte $AD, $34, $C8 ; LDA $C834 (current bank)
.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
-.byte $AD, $34, $C8 ; LDA $C834 (current logical bank)
-.byte $20, $C0, $C9 ; JSR set_bitmap ($C9C0)
-.byte $AD, $20, $C8 ; LDA $C820 (target logical bank)
+.byte $AD, $34, $C8 ; LDA $C834 (current bank)
+.byte $20, $C0, $C9 ; JSR mark_loaded ($C9C0)
+.byte $AD, $20, $C8 ; LDA $C820 (target bank)
.byte $20, $F0, $C8 ; JSR fetch_bank ($C8F0)
.byte $AD, $20, $C8 ; LDA $C820
.byte $8D, $34, $C8 ; STA $C834
@@ -598,40 +601,38 @@ Annotated Resident Shim Walkthrough
.byte $00,$00,$00,$00,$00
;-----------------------------------------------------------------------------
-; $C960: reu_setup_logical - Map logical bank to physical, then setup REU regs
-;
-; Current note:
-; this older listing's retired fixed app-slot description has
-; been superseded by logical REU bank 0 token -> physical-bank lookup.
-; See ReadyOSREUPhase1Completed.html for the completed Phase 1 shim contract.
+; $C960: reu_setup_logical - Resolve token via the ReadyOS bank, then setup regs
;-----------------------------------------------------------------------------
-.byte $C9, $00 ; CMP #0 (select launcher bank at Start+1?)
-.byte $D0, $09 ; BNE app_bank
-.byte $AD, $3B, $C8 ; LDA $C83B (reu_bank_skip)
+.byte $C9, $00 ; CMP #0 (logical launcher bank?)
+.byte $D0, $06 ; BNE lookup_app_bank
+.byte $AD, $3B, $C8 ; LDA $C83B (ReadyOS bank contains launcher)
+.byte $4C, $A0, $C9 ; JMP reu_setup ($C9A0)
+.byte $AA ; lookup_app_bank: TAX (preserve logical token)
+.byte $A9, $3D ; LDA #<$C83D
+.byte $8D, $02, $DF ; STA $DF02 (C64 addr lo)
+.byte $A9, $C8 ; LDA #>$C83D
+.byte $8D, $03, $DF ; STA $DF03 (C64 addr hi)
+.byte $8A ; TXA
.byte $18 ; CLC
-.byte $69, $01 ; ADC #$01 (launcher is Start+1)
-.byte $4C, $74, $C9 ; JMP store_physical_bank
-.byte $18 ; app_bank: CLC
-.byte $6D, $3B, $C8 ; ADC $C83B (logical app bank + skip)
-.byte $18 ; CLC
-.byte $69, $01 ; ADC #$01 (global + launcher snapshot only)
-.byte $8D, $06, $DF ; STA $DF06 (physical bank)
-.byte $A9, $00 ; LDA #$00
-.byte $8D, $02, $DF ; STA $DF02 (C64 addr lo = $00)
-.byte $A9, $10 ; LDA #$10
-.byte $8D, $03, $DF ; STA $DF03 (C64 addr hi = $10, so $1000)
-.byte $A9, $00 ; LDA #$00
-.byte $8D, $04, $DF ; STA $DF04 (REU addr lo)
-.byte $8D, $05, $DF ; STA $DF05 (REU addr hi)
-.byte $8D, $07, $DF ; STA $DF07 (len lo = $00)
-.byte $A9, $B6 ; LDA #$B6
-.byte $8D, $08, $DF ; STA $DF08 (len hi = $B6, so $B600 bytes)
-.byte $60 ; RTS
-
-.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+.byte $69, $40 ; ADC #<$B740 (mapping offset + token)
+.byte $8D, $04, $DF ; STA $DF04 (REU offset lo)
+.byte $A9, $B7 ; LDA #>$B740
+.byte $69, $00 ; ADC #0 (include low-byte carry)
+.byte $8D, $05, $DF ; STA $DF05 (REU offset hi)
+.byte $AD, $3B, $C8 ; LDA $C83B (ReadyOS global physical bank)
+.byte $8D, $06, $DF ; STA $DF06
+.byte $A9, $01 ; LDA #1
+.byte $8D, $07, $DF ; STA $DF07 (length lo)
+.byte $A9, $00 ; LDA #0
+.byte $8D, $08, $DF ; STA $DF08 (length hi)
+.byte $A9, $91 ; LDA #$91 (FETCH command)
+.byte $8D, $01, $DF ; STA $DF01 - fetch physical bank byte
+.byte $AD, $3D, $C8 ; LDA $C83D (resolved physical bank)
+.byte $4C, $A0, $C9 ; JMP reu_setup ($C9A0)
+.byte $00,$00 ; Padding to $C9A0
;-----------------------------------------------------------------------------
-; $C9A0: reu_setup - Set up REU registers for a physical bank in A
+; $C9A0: reu_setup - Set up REU registers for $B600 transfer at $1000
;-----------------------------------------------------------------------------
.byte $8D, $06, $DF ; STA $DF06 (bank)
.byte $A9, $00 ; LDA #$00
@@ -648,46 +649,35 @@ Annotated Resident Shim Walkthrough
.byte $00,$00
;-----------------------------------------------------------------------------
-; $C9C0: set_bitmap - Set bit for bank in A in reu_bitmap ($C836-$C838)
+; $C9C0: mark_loaded - Commit token status after a successful snapshot stash
+; A = logical token. Status $07 means valid, loaded, and resumable.
;-----------------------------------------------------------------------------
-.byte $C9, $18 ; CMP #$18 (only logical banks 0-23 are tracked)
-.byte $B0, $17 ; BCS done
-.byte $AA ; TAX - preserve full bank
-.byte $29, $07 ; AND #$07 - bit index within byte
-.byte $A8 ; TAY - Y = bit index
-.byte $8A ; TXA - restore full bank
-.byte $4A ; LSR A
-.byte $4A ; LSR A
-.byte $4A ; LSR A
-.byte $AA ; TAX - X = byte offset 0..2
-.byte $A9, $01 ; LDA #$01
-.byte $88 ; DEY
-.byte $30, $03 ; BMI store_bit
-.byte $0A ; ASL A
-.byte $10, $FA ; BPL shift_loop
-.byte $1D, $36, $C8 ; ORA $C836,X
-.byte $9D, $36, $C8 ; STA $C836,X
-.byte $60 ; RTS
-.byte $00,$00,$00,$00
-
-;-----------------------------------------------------------------------------
-; $C9E0: log_byte - Legacy debug marker writer
-; WARNING: $C980-$C99F now overlaps active reu_setup_logical code bytes.
-; This entry is kept for ABI shape only; do not call it unless the ring moves.
-;-----------------------------------------------------------------------------
-.byte $48 ; PHA - save the byte to log
-.byte $8E, $FC, $00 ; STX $00FC - save X to ZP temp
-.byte $AE, $3A, $C8 ; LDX $C83A - get log_index
-.byte $68 ; PLA - get byte back
-.byte $9D, $80, $C9 ; STA $C980,X - write to buffer
-.byte $E8 ; INX - increment index
-.byte $E0, $20 ; CPX #$20 - wrap at 32
-.byte $D0, $02 ; BNE +2 (skip reset)
-.byte $A2, $00 ; LDX #$00 - reset to 0
-.byte $8E, $3A, $C8 ; STX $C83A - store new index
-.byte $AE, $FC, $00 ; LDX $00FC - restore X
+.byte $8D, $3E, $C8 ; STA $C83E (preserve token)
+.byte $A9, $07 ; LDA #VALID|LOADED|RESUMABLE
+.byte $8D, $3D, $C8 ; STA $C83D
+.byte $A9, $3D ; C64 source = $C83D
+.byte $8D, $02, $DF
+.byte $A9, $C8
+.byte $8D, $03, $DF
+.byte $AD, $3E, $C8 ; token
+.byte $18 ; CLC
+.byte $69, $40 ; + <$B840 (token status table)
+.byte $8D, $04, $DF
+.byte $A9, $B8 ; >$B840
+.byte $69, $00 ; include low-byte carry
+.byte $8D, $05, $DF
+.byte $AD, $3B, $C8 ; ReadyOS physical bank
+.byte $8D, $06, $DF
+.byte $A9, $01 ; one byte
+.byte $8D, $07, $DF
+.byte $A9, $00
+.byte $8D, $08, $DF
+.byte $A9, $90 ; STASH C64 byte to ReadyOS bank
+.byte $8D, $01, $DF
+.byte $AD, $3E, $C8 ; preserve caller-visible token in A
.byte $60 ; RTS
-.byte $00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00 ; reserved through $C9FE
+.byte $60 ; $C9FF: compatibility no-op RTS
diff --git a/docs/reports/simplefiles_once_bss_resume_headroom_0_1_8w.html b/docs/reports/simplefiles_once_bss_resume_headroom_0_1_8w.html
index 8d4b9b6..bcfacf1 100644
--- a/docs/reports/simplefiles_once_bss_resume_headroom_0_1_8w.html
+++ b/docs/reports/simplefiles_once_bss_resume_headroom_0_1_8w.html
@@ -190,6 +190,20 @@
+
+
+ Current ReadyOS contract (2026-08-02):
+ Physical Skip is the ReadyOS bank and Skip+1 is the first dynamic bank.
+ The launcher snapshot is ReadyOS $0000-$B5FF; schema v5 is $B600-$FFFF,
+ with token map $B740 and status $B840. C64 app RAM is
+ $1000-$C5FF ($B600), and the resident 1 KB shim owns
+ $C600-$C9FF with its public ABI at $C800.
+ Dated layouts and measurements below are retained as historical evidence.
+
+
+
+
PRESERVED SNAPSHOT / DESIGN Preserved 0.1.8W measurement report; it is evidence from that build, not current headroom.
+
Simple Files ONCE/BSS Resume Headroom Report: 0.1.8W
diff --git a/docs/ultimate_dos_dma_loading.html b/docs/ultimate_dos_dma_loading.html
new file mode 100644
index 0000000..72365d1
--- /dev/null
+++ b/docs/ultimate_dos_dma_loading.html
@@ -0,0 +1,321 @@
+
+
+
+
+
+
+ ultimate_dos_dma_loading
+
+
+
+
+CURRENT DOCUMENT Current C64 Ultimate DOS DMA behavior. The launcher path is opt-in and disk fallback remains part of the contract.
+
+C64 Ultimate DOS DMA Loading
+ReadyOS has an opt-in launcher path that reads PRG payloads from a
+configured C64 Ultimate disk image directly into their allocated REU
+locations through the Ultimate Command Interface (UCI). This accelerates
+preload and cold app or resource loading without changing the resident
+shim or the $1000-$C5FF snapshot contract.
+Availability
+
+Build gate: LAUNCHER_DMA_LOAD=1.
+Default: disabled (LAUNCHER_DMA_LOAD=0). Normal release
+artifacts therefore use KERNAL/disk loading unless explicitly built with
+the gate enabled.
+Launcher variant: regular disk launcher only; EasyFlash does not
+link this path because cartridge preload already supplies its REU
+payloads.
+Hardware target: C64 Ultimate/Ultimate-family UCI with Ultimate DOS
+support.
+Catalog key: c64u_image_path, currently configured by
+cfg/profiles/precog-d81.ini as
+/usb1/readyos.d81.
+
+Build and run ReadyOS itself through the normal workflow:
+LAUNCHER_DMA_LOAD = 1 /bin/bash ./run.sh --profile precog-d81 --vice-fast
+VICE does not provide the hardware UCI service. An enabled build
+detects that condition and continues through the normal disk path.
+Runtime Flow
+
+The launcher parses c64u_image_path from
+apps.cfg.
+After drawing the launcher, it probes UCI and validates the image
+path.
+For an app or resource load, Ultimate DOS mounts or reuses the
+configured image, obtains the exact PRG file size, skips the two-byte
+PRG load header, and issues an exact-size LOAD_REU into the
+loader-assigned bank and offset.
+On success the launcher marks the allocation/resource loaded and the
+normal shim later restores app snapshots from REU.
+If UCI is absent, the path is invalid, the image cannot be mounted,
+the file cannot be opened, or transfer verification fails, the launcher
+quiesces UCI state and falls back to its established KERNAL/disk
+loader.
+
+DMA only changes how a cold PRG reaches REU. App switching still uses
+the same resident shim, logical-token lookup in the ReadyOS bank at
+$B740, and $B600 REU stash/fetch
+operations.
+Launcher Indicator
+
+DMA:YES: UCI and the configured path are available, but
+no successful DMA load has yet been recorded.
+DMA:ON: at least one current or cached load used the
+DMA path.
+DMA:NO: DMA is unavailable; disk fallback remains
+active.
+
+Transient DMA LOADING n/n progress text is used by
+hardware smoke tests.
+Exact-Size Rule
+Ultimate DOS LOAD_REU must receive the payload’s exact
+byte length (file size minus the two-byte PRG header), not the capacity
+of the destination slot. This is especially important for ReadyShell
+overlays sharing a resource bank: a slot-sized transfer can consume
+bytes belonging to the following packed payload. The loader also
+validates the expected PRG load address before accepting the
+transfer.
+Verification
+python3 build_support/verify_launcher_dma_gate.py
+Focused protocol work is documented in ../probes/uci_dma/README.md .
+Launcher acceptance fixtures are in ../build_support/c64u_dma_acceptance/README.md .
+The chronological hardware investigation remains in ../ULTIMATEDOS_DMA_LOADING_LESSONS_LEARNT.md .
+C64 Ultimate REST/FTP automation must be launched from a separate,
+long-running Terminal-owned/background shell as described in
+AGENTS.md; foreground one-shot probes can report false
+connectivity failures.
+
+
diff --git a/docs/ultimate_dos_dma_loading.md b/docs/ultimate_dos_dma_loading.md
new file mode 100644
index 0000000..6d6ebda
--- /dev/null
+++ b/docs/ultimate_dos_dma_loading.md
@@ -0,0 +1,79 @@
+# C64 Ultimate DOS DMA Loading
+
+ReadyOS has an opt-in launcher path that reads PRG payloads from a configured
+C64 Ultimate disk image directly into their allocated REU locations through
+the Ultimate Command Interface (UCI). This accelerates preload and cold app or
+resource loading without changing the resident shim or the `$1000-$C5FF`
+snapshot contract.
+
+## Availability
+
+- Build gate: `LAUNCHER_DMA_LOAD=1`.
+- Default: disabled (`LAUNCHER_DMA_LOAD=0`). Normal release artifacts therefore
+ use KERNAL/disk loading unless explicitly built with the gate enabled.
+- Launcher variant: regular disk launcher only; EasyFlash does not link this
+ path because cartridge preload already supplies its REU payloads.
+- Hardware target: C64 Ultimate/Ultimate-family UCI with Ultimate DOS support.
+- Catalog key: `c64u_image_path`, currently configured by
+ `cfg/profiles/precog-d81.ini` as `/usb1/readyos.d81`.
+
+Build and run ReadyOS itself through the normal workflow:
+
+```sh
+LAUNCHER_DMA_LOAD=1 /bin/bash ./run.sh --profile precog-d81 --vice-fast
+```
+
+VICE does not provide the hardware UCI service. An enabled build detects that
+condition and continues through the normal disk path.
+
+## Runtime Flow
+
+1. The launcher parses `c64u_image_path` from `apps.cfg`.
+2. After drawing the launcher, it probes UCI and validates the image path.
+3. For an app or resource load, Ultimate DOS mounts or reuses the configured
+ image, obtains the exact PRG file size, skips the two-byte PRG load header,
+ and issues an exact-size `LOAD_REU` into the loader-assigned bank and offset.
+4. On success the launcher marks the allocation/resource loaded and the normal
+ shim later restores app snapshots from REU.
+5. If UCI is absent, the path is invalid, the image cannot be mounted, the file
+ cannot be opened, or transfer verification fails, the launcher quiesces UCI
+ state and falls back to its established KERNAL/disk loader.
+
+DMA only changes how a cold PRG reaches REU. App switching still uses the same
+resident shim, logical-token lookup in the ReadyOS bank at `$B740`, and `$B600` REU
+stash/fetch operations.
+
+## Launcher Indicator
+
+- `DMA:YES`: UCI and the configured path are available, but no successful DMA
+ load has yet been recorded.
+- `DMA:ON`: at least one current or cached load used the DMA path.
+- `DMA:NO`: DMA is unavailable; disk fallback remains active.
+
+Transient `DMA LOADING n/n` progress text is used by hardware smoke tests.
+
+## Exact-Size Rule
+
+Ultimate DOS `LOAD_REU` must receive the payload's exact byte length (file size
+minus the two-byte PRG header), not the capacity of the destination slot. This
+is especially important for ReadyShell overlays sharing a resource bank: a
+slot-sized transfer can consume bytes belonging to the following packed
+payload. The loader also validates the expected PRG load address before
+accepting the transfer.
+
+## Verification
+
+```sh
+python3 build_support/verify_launcher_dma_gate.py
+```
+
+Focused protocol work is documented in
+[`../probes/uci_dma/README.md`](../probes/uci_dma/README.md). Launcher acceptance
+fixtures are in
+[`../build_support/c64u_dma_acceptance/README.md`](../build_support/c64u_dma_acceptance/README.md).
+The chronological hardware investigation remains in
+[`../ULTIMATEDOS_DMA_LOADING_LESSONS_LEARNT.md`](../ULTIMATEDOS_DMA_LOADING_LESSONS_LEARNT.md).
+
+C64 Ultimate REST/FTP automation must be launched from a separate,
+long-running Terminal-owned/background shell as described in `AGENTS.md`;
+foreground one-shot probes can report false connectivity failures.
diff --git a/futureREUrefactor.md b/futureREUrefactor.md
index b9cca7a..1ce5515 100644
--- a/futureREUrefactor.md
+++ b/futureREUrefactor.md
@@ -1,8 +1,22 @@
# Future REU Refactor Plan
+
+> **Current ReadyOS contract (2026-08-02):** Physical `Skip` is the ReadyOS
+> bank and `Skip+1` is the first dynamic bank. The launcher snapshot occupies
+> ReadyOS `$0000-$B5FF`; schema v5 occupies `$B600-$FFFF`, including the token
+> map at `$B740` and status at `$B840`. C64 app RAM is `$1000-$C5FF` (`$B600`),
+> and the resident 1 KB shim owns `$C600-$C9FF` with its public ABI at `$C800`.
+> Dated layouts and measurements below are retained as historical evidence.
+
+> **Historical schema-v5 checkpoint (2026-08-01).** This plan is preserved
+> rather than deleted. Its physical `Skip+1` ReadyOS bank, `$B800` snapshot,
+> and `$B940/$BA40` mapping/status offsets were superseded by the current
+> contract summarized immediately above. See
+> `privatedocs/top_level_md/MEMORY_MAP.md` for current authority.
+
## Purpose
-This is the active future plan after Phase 1 of the ReadyOS REU refactor.
+This was the active future plan after Phase 1 of the ReadyOS REU refactor.
The completed Phase 1 record lives in `ReadyOSREUPhase1Completed.md`.
The future work here builds on a working v4 REU control-bank model. The goal is
diff --git a/privatedocs/reports/OLD_READYBASIC_MEMORY_REARRANGEMENT_IMPLEMENTED.md b/privatedocs/reports/OLD_READYBASIC_MEMORY_REARRANGEMENT_IMPLEMENTED.md
index e94a12f..fb4659b 100644
--- a/privatedocs/reports/OLD_READYBASIC_MEMORY_REARRANGEMENT_IMPLEMENTED.md
+++ b/privatedocs/reports/OLD_READYBASIC_MEMORY_REARRANGEMENT_IMPLEMENTED.md
@@ -1,5 +1,13 @@
# OLD ReadyBASIC Memory Rearrangement Implementation
+
+> **Current ReadyOS contract (2026-08-02):** Physical `Skip` is the ReadyOS
+> bank and `Skip+1` is the first dynamic bank. The launcher snapshot occupies
+> ReadyOS `$0000-$B5FF`; schema v5 occupies `$B600-$FFFF`, including the token
+> map at `$B740` and status at `$B840`. C64 app RAM is `$1000-$C5FF` (`$B600`),
+> and the resident 1 KB shim owns `$C600-$C9FF` with its public ABI at `$C800`.
+> Dated layouts and measurements below are retained as historical evidence.
+
This is an old planning/proposal document kept in `privatedocs/reports` for
history. The memory rearrangement described here has already been implemented.
Do not use this as the main current reference; use
diff --git a/privatedocs/reports/easyflash_boot_flow.html b/privatedocs/reports/easyflash_boot_flow.html
index 583cee3..a7e6963 100644
--- a/privatedocs/reports/easyflash_boot_flow.html
+++ b/privatedocs/reports/easyflash_boot_flow.html
@@ -187,6 +187,20 @@
+
+
+ Current ReadyOS contract (2026-08-02):
+ Physical Skip is the ReadyOS bank and Skip+1 is the first dynamic bank.
+ The launcher snapshot is ReadyOS $0000-$B5FF; schema v5 is $B600-$FFFF,
+ with token map $B740 and status $B840. C64 app RAM is
+ $1000-$C5FF ($B600), and the resident 1 KB shim owns
+ $C600-$C9FF with its public ABI at $C800.
+ Dated layouts and measurements below are retained as historical evidence.
+
+
+
+PRESERVED SNAPSHOT / DESIGN Preserved older styled EasyFlash report. The current public Markdown/HTML boot-flow pair supersedes its fixed-slot and app-count measurements.
+
ReadyOS EasyFlash Boot Flow
diff --git a/privatedocs/reports/easyflash_boot_flow.md b/privatedocs/reports/easyflash_boot_flow.md
index 035ca5a..bda99a2 100644
--- a/privatedocs/reports/easyflash_boot_flow.md
+++ b/privatedocs/reports/easyflash_boot_flow.md
@@ -1,5 +1,18 @@
# ReadyOS EasyFlash Boot Flow
+
+> **Current ReadyOS contract (2026-08-02):** Physical `Skip` is the ReadyOS
+> bank and `Skip+1` is the first dynamic bank. The launcher snapshot occupies
+> ReadyOS `$0000-$B5FF`; schema v5 occupies `$B600-$FFFF`, including the token
+> map at `$B740` and status at `$B840`. C64 app RAM is `$1000-$C5FF` (`$B600`),
+> and the resident 1 KB shim owns `$C600-$C9FF` with its public ABI at `$C800`.
+> Dated layouts and measurements below are retained as historical evidence.
+
+> Preserved older styled-report source. Its 16-app/eight-overlay and fixed-slot
+> measurements describe an earlier cartridge layout. The current public
+> `docs/reports/easyflash_boot_flow.md` and generated HTML counterpart supersede
+> those values; this file remains intact as design history.
+
This document describes how the current ReadyOS EasyFlash cartridge flavor boots, what executes where, when cartridge banking happens, when it does not, how REU preload works, how the early REU-required guard behaves, and why the machine appears to sit on a blue screen for a long time before the launcher appears.
The description is based on the current source and generated layout in this repository, not on a hypothetical design.
diff --git a/privatedocs/reports/old_readybasic_memory_rearrangement_implemented.html b/privatedocs/reports/old_readybasic_memory_rearrangement_implemented.html
index 3149694..326cb2d 100644
--- a/privatedocs/reports/old_readybasic_memory_rearrangement_implemented.html
+++ b/privatedocs/reports/old_readybasic_memory_rearrangement_implemented.html
@@ -390,6 +390,20 @@
+
+
+ Current ReadyOS contract (2026-08-02):
+ Physical Skip is the ReadyOS bank and Skip+1 is the first dynamic bank.
+ The launcher snapshot is ReadyOS $0000-$B5FF; schema v5 is $B600-$FFFF,
+ with token map $B740 and status $B840. C64 app RAM is
+ $1000-$C5FF ($B600), and the resident 1 KB shim owns
+ $C600-$C9FF with its public ABI at $C800.
+ Dated layouts and measurements below are retained as historical evidence.
+
+
+
+PRESERVED SNAPSHOT / DESIGN Historical ReadyBASIC implementation record. READYBASIC_CURRENT_DESIGN.md and the generated memory diagrams are authoritative now.
+
Old ReadyBASIC memory implementation note
diff --git a/privatedocs/reports/readyos_memory_layout_print.html b/privatedocs/reports/readyos_memory_layout_print.html
index f64c0f4..c5b3c5f 100644
--- a/privatedocs/reports/readyos_memory_layout_print.html
+++ b/privatedocs/reports/readyos_memory_layout_print.html
@@ -655,6 +655,20 @@
+
+
+ Current ReadyOS contract (2026-08-02):
+ Physical Skip is the ReadyOS bank and Skip+1 is the first dynamic bank.
+ The launcher snapshot is ReadyOS $0000-$B5FF; schema v5 is $B600-$FFFF,
+ with token map $B740 and status $B840. C64 app RAM is
+ $1000-$C5FF ($B600), and the resident 1 KB shim owns
+ $C600-$C9FF with its public ABI at $C800.
+ Dated layouts and measurements below are retained as historical evidence.
+
+
+
+
PRESERVED SNAPSHOT / DESIGN Historical memory-layout options report. Use the canonical private MEMORY_MAP.md for current spatial layout and sizes.
+
diff --git a/probes/uci_dma/README.md b/probes/uci_dma/README.md
new file mode 100644
index 0000000..7911765
--- /dev/null
+++ b/probes/uci_dma/README.md
@@ -0,0 +1,127 @@
+# UCI DMA Probe
+
+Standalone C64 Ultimate probe for Ultimate DOS DMA loading from a mounted disk
+image. This is the reference project for the technique; launcher integration is
+intentionally out of scope until the D81 probe has been manually verified.
+
+## Build
+
+Build the D81 image:
+
+```sh
+PROBE_IMAGE_TYPE=d81 /bin/bash probes/uci_dma/build.sh
+```
+
+Output:
+
+```text
+build/uci_dma_probe/uci_dma_probe.d81
+```
+
+The image contains:
+
+```text
+probe
+udma1
+udma2
+udma3
+```
+
+## Manual C64U Test
+
+1. Copy `build/uci_dma_probe/uci_dma_probe.d81` to the C64U USB drive.
+2. On the C64U, set drive A / device 8 to a 1581-compatible D81 drive.
+3. Mount the D81 as drive 8.
+4. At BASIC:
+
+```basic
+LOAD"PROBE",8
+RUN
+```
+
+## Expected Success Screen
+
+The probe should reach:
+
+```text
+PROBE DONE
+P:42 C:51 F1:55 F2:55 F3:55
+```
+
+The screen should also show UCI found and a real SoftIEC bus byte.
+
+`P` is the launcher-style plain-name check before the probe changes the
+Ultimate DOS current directory. `42` means Ultimate DOS did not resolve
+`udma1` as a valid file stat from the plain mounted-drive context. This is the
+important negative proof for launcher integration: IEC drive 8 can have the D81
+mounted while Ultimate DOS still cannot open plain filenames from that image
+until its own directory context is changed.
+
+`C` is the same pre-CD check after `COPY_UI_PATH`. `51` means the
+`COPY_UI_PATH` command itself did not return a usable success status in the
+REST-mounted case. So, for automation-mounted D81s, `COPY_UI_PATH` is not a
+safe pathless bridge either.
+
+`F1`, `F2`, and `F3` correspond to the three payload files:
+
+```text
+udma1 -> $11 pattern
+udma2 -> $42 pattern
+udma3 -> $83 pattern
+```
+
+Each `55` means the file was opened, read/seeked, DMA-loaded to REU, fetched
+back, and verified after the probe has changed Ultimate DOS into the D81 image
+filesystem.
+
+## Automated C64U REST Test
+
+The REST harness rebuilds, uploads, configures/mounts, resets cleanly, runs the
+probe, captures screen/result memory, and validates the REU snapshots.
+
+```sh
+PROBE_IMAGE_TYPE=d81 C64U_HOST=10.0.0.79 C64U_REMOTE_DIR=USB1 \
+ /bin/bash build_support/run_uci_dma_probe_c64u_rest.sh
+```
+
+The automation intentionally types one byte at a time and waits for the C64
+keyboard buffer to drain. Bulk keyboard-buffer injection was not reliable
+enough for this test.
+
+Do not poll screen/RAM aggressively while KERNAL disk I/O is active. The
+ReadyOS boot automation reproduced a stuck `LOADING LAUNCHER...` screen when it
+captured memory during the booter's `LOAD "launcher",8`; adding a quiet wait
+before the first REST memory read allowed the same normal D81 to boot and launch
+Editor. Treat mid-load REST captures as intrusive.
+
+## Automated VICE/dotnet Sanity Test
+
+VICE does not provide the C64U UCI device, so this is a no-UCI regression check
+rather than proof of Ultimate DOS DMA. It verifies that the D81 builds, mounts,
+loads `probe`, reaches `PROBE DONE`, and leaves the DMA file-result blocks
+untouched when UCI is absent.
+
+```sh
+/bin/bash build_support/run_uci_dma_probe_vice.sh
+```
+
+The runner uses the existing dotnet VICE task framework and validates the
+result artifacts with:
+
+```sh
+python3 build_support/analyze_uci_dma_probe_run.py
\
+ --expect no-uci --version 41
+```
+
+## Important Boundaries
+
+- This probe uses Ultimate DOS UCI commands for the DMA load path.
+- SoftIEC is detected and reported, but it is not the DMA transport.
+- The payloads are loaded only after Ultimate DOS has changed into the D81/D64
+ filesystem context.
+- The probe currently proves that "plain file from IEC drive 8's mounted image"
+ is not the same context as "plain file from Ultimate DOS current directory."
+- The probe also proves that REST-mounted D81 plus `COPY_UI_PATH` did not
+ produce a usable Ultimate DOS image context.
+- Do not use this probe as a launcher implementation directly; first manually
+ verify the D81, then port the exact proven sequence.
diff --git a/probes/uci_dma/build.sh b/probes/uci_dma/build.sh
new file mode 100755
index 0000000..e1f1d1b
--- /dev/null
+++ b/probes/uci_dma/build.sh
@@ -0,0 +1,94 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+root_dir="$(cd "$(dirname "$0")/../.." && pwd)"
+build_dir="$root_dir/build/uci_dma_probe"
+
+mkdir -p "$build_dir"
+
+ca65_flags=()
+if [[ "${PROBE_DO_CD:-0}" == "1" ]]; then
+ ca65_flags+=("-D" "DO_CD")
+fi
+image_type="${PROBE_IMAGE_TYPE:-d81}"
+case "$image_type" in
+ d64)
+ ca65_flags+=("-D" "PROBE_D64")
+ ;;
+ d81)
+ ;;
+ *)
+ echo "PROBE_IMAGE_TYPE must be d81 or d64" >&2
+ exit 64
+ ;;
+esac
+
+if (( ${#ca65_flags[@]} )); then
+ ca65 "${ca65_flags[@]}" -o "$build_dir/uci_dma_probe.o" "$root_dir/probes/uci_dma/uci_dma_probe.s"
+else
+ ca65 -o "$build_dir/uci_dma_probe.o" "$root_dir/probes/uci_dma/uci_dma_probe.s"
+fi
+ld65 -C "$root_dir/probes/uci_dma/probe.cfg" \
+ -o "$build_dir/uci_dma_probe.prg" \
+ "$build_dir/uci_dma_probe.o"
+
+python3 - "$build_dir" <<'PY'
+import pathlib
+import sys
+
+build = pathlib.Path(sys.argv[1])
+payloads = [
+ ("udma1.prg", 0x11),
+ ("udma2.prg", 0x42),
+ ("udma3.prg", 0x83),
+]
+for name, value in payloads:
+ (build / name).write_bytes(bytes([0x00, 0x40]) + bytes([value]) * 0x100)
+PY
+
+disk="$build_dir/uci_dma_probe.$image_type"
+rm -f "$disk"
+c1541 -format "uci dma probe,up" "$image_type" "$disk" \
+ -write "$build_dir/uci_dma_probe.prg" "probe" \
+ -write "$build_dir/udma1.prg" "udma1" \
+ -write "$build_dir/udma2.prg" "udma2" \
+ -write "$build_dir/udma3.prg" "udma3"
+
+verify_dir="$build_dir/readback"
+rm -rf "$verify_dir"
+mkdir -p "$verify_dir"
+
+c1541 "$disk" -read "probe" "$verify_dir/probe.prg" >/dev/null
+c1541 "$disk" -read "udma1" "$verify_dir/udma1.prg" >/dev/null
+c1541 "$disk" -read "udma2" "$verify_dir/udma2.prg" >/dev/null
+c1541 "$disk" -read "udma3" "$verify_dir/udma3.prg" >/dev/null
+
+cmp -s "$build_dir/uci_dma_probe.prg" "$verify_dir/probe.prg"
+cmp -s "$build_dir/udma1.prg" "$verify_dir/udma1.prg"
+cmp -s "$build_dir/udma2.prg" "$verify_dir/udma2.prg"
+cmp -s "$build_dir/udma3.prg" "$verify_dir/udma3.prg"
+
+python3 - "$disk" <<'PY'
+import pathlib
+import sys
+
+disk = pathlib.Path(sys.argv[1])
+data = disk.read_bytes()
+expected = [
+ b"PROBE" + b"\xa0" * 11,
+ b"UDMA1" + b"\xa0" * 11,
+ b"UDMA2" + b"\xa0" * 11,
+ b"UDMA3" + b"\xa0" * 11,
+]
+missing = [name for name in expected if data.find(name) < 0]
+if missing:
+ names = " ".join(name[:5].decode("ascii") for name in missing)
+ raise SystemExit(f"missing lowercase PETSCII directory names: {names}")
+print("verified raw lowercase PETSCII directory names")
+PY
+
+image_type_upper="$(printf "%s" "$image_type" | tr '[:lower:]' '[:upper:]')"
+echo "verified ${image_type_upper} readback: probe udma1 udma2 udma3"
+shasum -a 256 "$disk"
+
+echo "$disk"
diff --git a/probes/uci_dma/probe.cfg b/probes/uci_dma/probe.cfg
new file mode 100644
index 0000000..c39dc76
--- /dev/null
+++ b/probes/uci_dma/probe.cfg
@@ -0,0 +1,14 @@
+MEMORY {
+ ZP: file = "", start = $0002, size = $001A, type = rw, define = yes;
+ LOADADDR: file = %O, start = $07FF, size = $0002;
+ RAM: file = %O, start = $0801, size = $17FF;
+}
+
+SEGMENTS {
+ ZEROPAGE: load = ZP, type = zp;
+ LOADADDR: load = LOADADDR, type = ro;
+ STARTUP: load = RAM, type = ro;
+ CODE: load = RAM, type = ro;
+ RODATA: load = RAM, type = ro;
+ DATA: load = RAM, type = rw;
+}
diff --git a/probes/uci_dma/uci_dma_probe.s b/probes/uci_dma/uci_dma_probe.s
new file mode 100644
index 0000000..e148ff2
--- /dev/null
+++ b/probes/uci_dma/uci_dma_probe.s
@@ -0,0 +1,2192 @@
+;
+; Standalone Ultimate UCI + Ultimate DOS REU load probe.
+;
+
+ .segment "LOADADDR"
+ .word $0801
+
+ .segment "STARTUP"
+ .word basic_next
+ .word 10
+ .byte $9e, "2061", 0
+basic_next:
+ .word 0
+
+CHROUT = $FFD2
+GETIN = $FFE4
+SETLFS = $FFBA
+SETNAM = $FFBD
+OPEN = $FFC0
+CLOSE = $FFC3
+READST = $FFB7
+CPU_PORT = $0001
+RESULTS = $3000
+LOAD_BUF = $4000
+VERIFY_BUF = $5000
+SNAP1_BUF = $6000
+SNAP2_BUF = $6100
+SNAP3_BUF = $6200
+.ifdef PROBE_D64
+PROBE_VERSION = $40
+.else
+PROBE_VERSION = $41
+.endif
+
+REU_COMMAND = $DF01
+REU_C64_LO = $DF02
+REU_C64_HI = $DF03
+REU_REU_LO = $DF04
+REU_REU_HI = $DF05
+REU_REU_BANK = $DF06
+REU_LEN_LO = $DF07
+REU_LEN_HI = $DF08
+
+REU_CMD_STASH = $90
+REU_CMD_FETCH = $91
+
+name_ptr = $04
+
+UCI_STAT_DATA = $80
+UCI_STAT_STAT = $40
+UCI_STATE_MASK = $30
+UCI_STATE_IDLE = $00
+UCI_STATE_LAST = $20
+UCI_STATE_MORE = $30
+UCI_STAT_ABORT = $04
+UCI_STAT_ERROR = $08
+
+ .macro PRINT label
+ lda #label
+ jsr print_z
+ .endmacro
+
+ .segment "CODE"
+
+start:
+ lda #$93
+ jsr CHROUT
+ lda #$01
+ sta $0286
+ PRINT title_msg
+ jsr cr
+ jsr init_results
+ jsr probe_uci
+ bcs have_uci
+ PRINT no_uci_msg
+ jsr cr
+ jmp done
+
+have_uci:
+ PRINT using_msg
+ lda uci_base_hi
+ jsr print_hex_a
+ lda uci_base_lo
+ jsr print_hex_a
+ PRINT bus_msg
+ lda softiec_bus
+ jsr print_hex_a
+ jsr cr
+ jsr print_softiec_summary
+ jsr dos_identify
+ jsr print_response_summary
+ jsr print_data_text
+ jsr ctrl_get_drvinfo
+ jsr print_response_summary
+ jsr print_drvinfo
+ jsr reset_udos_root
+ jsr plain_stat_probe
+ jsr copy_ui_stat_probe
+ jsr cd_usb_root
+ bcs cd_usb_ok
+ PRINT usb_fail_msg
+ PRINT fail_msg
+ jsr cr
+ jmp done
+cd_usb_ok:
+ lda selected_usb
+ sta RESULTS+$0B
+ jsr dos_get_path
+ jsr print_response_summary
+ jsr print_data_text
+ PRINT mount_d81_msg
+ jsr dos_mount_d81
+ jsr print_response_summary
+ PRINT cd_d81_msg
+ jsr cr
+ lda #d81_name
+ sta name_ptr+1
+ jsr dos_cd
+ jsr print_response_summary
+ jsr status_ok
+ bcs cd_d81_ok
+ jsr select_d81_abs_path
+ PRINT cd_d81_abs_msg
+ jsr cr
+ jsr dos_cd
+ jsr print_response_summary
+cd_d81_ok:
+ jsr status_ok
+ bcs cd_d81_ready
+ PRINT d81_fail_msg
+ PRINT fail_msg
+ jsr cr
+ jmp done
+cd_d81_ready:
+ jsr dos_get_path
+ jsr print_response_summary
+ jsr print_data_text
+ jsr dir_peek
+ PRINT close_msg
+ jsr dos_close
+ jsr print_response_summary
+ lda #file1_name
+ sta name_ptr+1
+ lda #$11
+ sta expected_byte
+ lda #$00
+ sta reu_off_hi
+ sta reu_off_lo
+ lda #>SNAP1_BUF
+ sta snapshot_hi
+ lda #$10
+ sta result_base_offset
+ PRINT file1_msg
+ jsr do_file_dos_probe
+
+ lda #file2_name
+ sta name_ptr+1
+ lda #$42
+ sta expected_byte
+ lda #$01
+ sta reu_off_hi
+ lda #$00
+ sta reu_off_lo
+ lda #>SNAP2_BUF
+ sta snapshot_hi
+ lda #$20
+ sta result_base_offset
+ PRINT file2_msg
+ jsr do_file_dos_probe
+
+ lda #file3_name
+ sta name_ptr+1
+ lda #$83
+ sta expected_byte
+ lda #$02
+ sta reu_off_hi
+ lda #$00
+ sta reu_off_lo
+ lda #>SNAP3_BUF
+ sta snapshot_hi
+ lda #$30
+ sta result_base_offset
+ PRINT file3_msg
+ jsr do_file_dos_probe
+
+done:
+ jsr print_final_summary
+ PRINT done_msg
+ jsr cr
+forever:
+ jsr GETIN
+ jmp forever
+
+init_results:
+ ldx #$00
+ lda #$00
+clear_results:
+ sta RESULTS,x
+ inx
+ cpx #$80
+ bne clear_results
+ lda #'U'
+ sta RESULTS
+ lda #'D'
+ sta RESULTS+1
+ lda #'M'
+ sta RESULTS+2
+ lda #'A'
+ sta RESULTS+3
+ lda #PROBE_VERSION
+ sta RESULTS+10
+ rts
+
+store_result_y:
+ sta result_value
+ tya
+ clc
+ adc result_base_offset
+ tax
+ lda result_value
+ sta RESULTS,x
+ rts
+
+probe_uci:
+ PRINT probe_msg
+ jsr cr
+ lda #<$DF1C
+ ldx #>$DF1C
+ jsr try_base
+ bcs probe_ok
+ lda #<$DE1C
+ ldx #>$DE1C
+ jsr try_base
+ bcs probe_ok
+ lda #<$DFFC
+ ldx #>$DFFC
+ jsr try_base
+ bcs probe_ok
+ clc
+ rts
+probe_ok:
+ lda #$01
+ sta RESULTS+4
+ lda uci_base_lo
+ sta RESULTS+5
+ lda uci_base_hi
+ sta RESULTS+6
+ lda uci_id_byte
+ sta RESULTS+7
+ lda uci_status_byte
+ sta RESULTS+8
+ lda softiec_bus
+ sta RESULTS+9
+ sec
+ rts
+
+try_base:
+ jsr set_uci_base
+ PRINT base_msg
+ lda uci_base_hi
+ jsr print_hex_a
+ lda uci_base_lo
+ jsr print_hex_a
+ PRINT id_msg
+ jsr uci_id
+ sta uci_id_byte
+ jsr print_hex_a
+ PRINT stat_msg
+ jsr uci_status
+ sta uci_status_byte
+ jsr print_hex_a
+ PRINT bus_msg
+ jsr uci_softiec
+ sta softiec_bus
+ jsr print_hex_a
+ jsr cr
+
+ lda uci_id_byte
+ and #$7F
+ cmp #$49
+ bne try_base_no
+ beq try_base_yes
+try_base_no:
+ clc
+ rts
+try_base_yes:
+ sec
+ rts
+
+softiec_ok:
+ lda softiec_bus
+ beq softiec_bad
+ cmp #$FF
+ beq softiec_bad
+ sec
+ rts
+softiec_bad:
+ clc
+ rts
+
+reset_udos_root:
+ PRINT cd_root_msg
+ jsr cr
+ lda #root_name
+ sta name_ptr+1
+ jsr dos_cd
+ jsr print_response_summary
+ rts
+
+plain_stat_probe:
+ PRINT plain_stat_msg
+ jsr cr
+ PRINT close_msg
+ jsr dos_close
+ jsr print_response_summary
+ lda #file1_name
+ sta name_ptr+1
+ PRINT stat_file_msg
+ jsr dos_file_stat
+ jsr print_response_summary
+ jsr print_data_text
+ lda data_len
+ sta RESULTS+$41
+ lda stat_len
+ sta RESULTS+$42
+ lda stat_buf
+ sta RESULTS+$43
+ lda stat_buf+1
+ sta RESULTS+$44
+ lda data_buf
+ sta RESULTS+$45
+ lda data_buf+1
+ sta RESULTS+$46
+ lda data_buf+8
+ sta RESULTS+$47
+ bcs plain_stat_transport_ok
+ lda #$41
+ sta RESULTS+$40
+ PRINT fail_msg
+ jsr cr
+ rts
+plain_stat_transport_ok:
+ jsr file_stat_ok
+ bcs plain_stat_ok
+ lda #$42
+ sta RESULTS+$40
+ PRINT fail_msg
+ jsr cr
+ rts
+plain_stat_ok:
+ lda #$55
+ sta RESULTS+$40
+ PRINT ok_msg
+ jsr cr
+ rts
+
+copy_ui_stat_probe:
+ PRINT copy_ui_stat_msg
+ jsr cr
+ jsr dos_copy_ui_path
+ jsr print_response_summary
+ jsr print_data_text
+ jsr status_ok
+ bcs copy_ui_ready
+ lda #$51
+ sta RESULTS+$48
+ PRINT fail_msg
+ jsr cr
+ rts
+copy_ui_ready:
+ PRINT close_msg
+ jsr dos_close
+ jsr print_response_summary
+ lda #file1_name
+ sta name_ptr+1
+ PRINT stat_file_msg
+ jsr dos_file_stat
+ jsr print_response_summary
+ jsr print_data_text
+ lda data_len
+ sta RESULTS+$49
+ lda stat_len
+ sta RESULTS+$4A
+ lda stat_buf
+ sta RESULTS+$4B
+ lda stat_buf+1
+ sta RESULTS+$4C
+ lda data_buf
+ sta RESULTS+$4D
+ lda data_buf+1
+ sta RESULTS+$4E
+ lda data_buf+8
+ sta RESULTS+$4F
+ bcs copy_ui_stat_transport_ok
+ lda #$52
+ sta RESULTS+$48
+ PRINT fail_msg
+ jsr cr
+ rts
+copy_ui_stat_transport_ok:
+ jsr file_stat_ok
+ bcs copy_ui_stat_ok
+ lda #$53
+ sta RESULTS+$48
+ PRINT fail_msg
+ jsr cr
+ rts
+copy_ui_stat_ok:
+ lda #$55
+ sta RESULTS+$48
+ PRINT ok_msg
+ jsr cr
+ rts
+
+cd_usb_root:
+ PRINT cd_root_msg
+ jsr cr
+ lda #root_name
+ sta name_ptr+1
+ jsr dos_cd
+ jsr print_response_summary
+ lda #$01
+ sta selected_usb
+ PRINT cd_usb1_msg
+ jsr cr
+ lda #usb1_name
+ sta name_ptr+1
+ jsr dos_cd
+ jsr print_response_summary
+ jsr status_ok
+ bcs cd_usb_root_ok
+ PRINT cd_usb1_abs_msg
+ jsr cr
+ lda #usb1_abs_name
+ sta name_ptr+1
+ jsr dos_cd
+ jsr print_response_summary
+ jsr status_ok
+ bcs cd_usb_root_ok
+ lda #$00
+ sta selected_usb
+ PRINT cd_usb0_msg
+ jsr cr
+ lda #usb0_name
+ sta name_ptr+1
+ jsr dos_cd
+ jsr print_response_summary
+ jsr status_ok
+ bcs cd_usb_root_ok
+ PRINT cd_usb0_abs_msg
+ jsr cr
+ lda #usb0_abs_name
+ sta name_ptr+1
+ jsr dos_cd
+ jsr print_response_summary
+ jmp status_ok
+cd_usb_root_ok:
+ sec
+ rts
+
+select_d81_abs_path:
+ lda selected_usb
+ beq select_d81_usb0
+ lda #d81_usb1_abs_name
+ sta name_ptr+1
+ rts
+select_d81_usb0:
+ lda #d81_usb0_abs_name
+ sta name_ptr+1
+ rts
+
+do_file:
+ jsr clear_buffers
+ PRINT stat_file_msg
+ jsr dos_file_stat
+ jsr print_response_summary
+ bcs file_stat_transport_ok
+ PRINT fail_msg
+ jsr cr
+ lda #$12
+ ldy #$00
+ jsr store_result_y
+ rts
+file_stat_transport_ok:
+ jsr file_stat_ok
+ bcs file_stat_ready
+ PRINT fail_msg
+ jsr cr
+ lda #$13
+ ldy #$00
+ jsr store_result_y
+ rts
+file_stat_ready:
+ jsr print_file_stat
+ lda stat_size_lo
+ ldy #$07
+ jsr store_result_y
+ lda stat_size_hi
+ iny
+ jsr store_result_y
+
+ PRINT close_msg
+do_file_open_start:
+ jsr dos_close
+ jsr print_response_summary
+do_file_open_no_close:
+ PRINT open_msg
+ jsr dos_open_read
+ jsr print_response_summary
+ bcs open_transport_ok
+ PRINT fail_msg
+ jsr cr
+ lda #$01
+ ldy #$00
+ jsr store_result_y
+ rts
+
+do_file_dos_nostat:
+ jsr clear_buffers
+ lda #$02
+ ldy #$07
+ jsr store_result_y
+ lda #$01
+ iny
+ jsr store_result_y
+ PRINT nostat_file_msg
+ jmp do_file_open_start
+
+do_file_dos_probe:
+ jsr clear_buffers
+ PRINT close_msg
+ jsr dos_close
+ jsr print_response_summary
+ PRINT stat_file_msg
+ jsr dos_file_stat
+ jsr print_response_summary
+ jsr print_data_text
+ jmp do_file_open_start
+open_transport_ok:
+ jsr status_ok
+ bcs open_rc_ok
+ PRINT fail_msg
+ jsr cr
+ lda #$05
+ ldy #$00
+ jsr store_result_y
+ rts
+open_rc_ok:
+ lda #$11
+ ldy #$00
+ jsr store_result_y
+
+ PRINT hdr_read_msg
+ jsr dos_read_header
+ jsr print_response_summary
+ bcs hdr_read_transport_ok
+ PRINT fail_msg
+ jsr cr
+ lda #$02
+ ldy #$00
+ jsr store_result_y
+ rts
+hdr_read_transport_ok:
+ jsr data_or_status_ok
+ bcs hdr_read_rc_ok
+ PRINT fail_msg
+ jsr cr
+ lda #$06
+ ldy #$00
+ jsr store_result_y
+ rts
+hdr_read_rc_ok:
+ jsr verify_header_buffer
+ bcs header_ok
+ PRINT fail_msg
+ jsr cr
+ lda #$03
+ ldy #$00
+ jsr store_result_y
+ rts
+header_ok:
+ PRINT ok_msg
+ jsr cr
+
+ jsr read_ram_chunks
+ bcs ram_read_ok
+ PRINT fail_msg
+ jsr cr
+ lda ram_error
+ ldy #$00
+ jsr store_result_y
+ rts
+ram_read_ok:
+ jsr verify_load_buffer
+ bcs ram_ok
+ PRINT fail_msg
+ jsr cr
+ lda #$0D
+ ldy #$00
+ jsr store_result_y
+ rts
+ram_ok:
+ PRINT ok_msg
+ jsr cr
+ lda #$01
+ ldy #$04
+ jsr store_result_y
+ lda ram_chunk_count
+ ldy #$06
+ jsr store_result_y
+
+ PRINT seek_msg
+ jsr dos_seek_payload
+ jsr print_response_summary
+ bcs seek_transport_ok
+ PRINT fail_msg
+ jsr cr
+ lda #$0E
+ ldy #$00
+ jsr store_result_y
+ rts
+seek_transport_ok:
+ jsr status_ok
+ bcs seek_rc_ok
+ PRINT fail_msg
+ jsr cr
+ lda #$0F
+ ldy #$00
+ jsr store_result_y
+ rts
+seek_rc_ok:
+ PRINT reu_load1_msg
+ lda #$00
+ sta reu_off_lo
+ lda #$80
+ sta reu_len_lo
+ jsr dos_load_reu_chunk
+ jsr print_response_summary
+ bcs reu_load1_transport_ok
+ PRINT fail_msg
+ jsr cr
+ lda #$07
+ ldy #$00
+ jsr store_result_y
+ rts
+reu_load1_transport_ok:
+ jsr status_ok
+ bcs reu_load1_rc_ok
+ PRINT fail_msg
+ jsr cr
+ lda #$08
+ ldy #$00
+ jsr store_result_y
+ rts
+reu_load1_rc_ok:
+ PRINT reu_load2_msg
+ lda #$80
+ sta reu_off_lo
+ lda #$80
+ sta reu_len_lo
+ jsr dos_load_reu_chunk
+ jsr print_response_summary
+ bcs reu_load2_transport_ok
+ PRINT fail_msg
+ jsr cr
+ lda #$09
+ ldy #$00
+ jsr store_result_y
+ rts
+reu_load2_transport_ok:
+ jsr status_ok
+ bcs reu_load2_rc_ok
+ PRINT fail_msg
+ jsr cr
+ lda #$0A
+ ldy #$00
+ jsr store_result_y
+ rts
+reu_load2_rc_ok:
+ lda #$22
+ ldy #$00
+ jsr store_result_y
+ lda stat_buf
+ ldy #$01
+ jsr store_result_y
+ lda stat_buf+1
+ iny
+ jsr store_result_y
+ lda stat_buf+2
+ iny
+ jsr store_result_y
+ PRINT reu_msg
+ jsr clear_verify
+ jsr fetch_from_reu
+ jsr verify_fetch_buffer
+ bcs reu_ok
+ PRINT fail_msg
+ jsr cr
+ lda #$04
+ ldy #$00
+ jsr store_result_y
+ rts
+reu_ok:
+ PRINT ok_msg
+ jsr cr
+ jsr snapshot_verify
+ PRINT close_msg
+ jsr dos_close
+ jsr print_response_summary
+ lda #$01
+ ldy #$05
+ jsr store_result_y
+ lda snapshot_hi
+ ldy #$09
+ jsr store_result_y
+ lda #$55
+ ldy #$00
+ jsr store_result_y
+ rts
+
+dir_peek:
+ PRINT dir_open_msg
+ jsr dos_open_dir
+ jsr print_response_summary
+ jsr status_ok
+ bcc dir_peek_done
+ lda #$02
+ sta dir_count
+dir_peek_loop:
+ PRINT dir_read_msg
+ jsr dos_read_dir
+ jsr print_response_summary
+ jsr print_data_text
+ dec dir_count
+ bne dir_peek_loop
+dir_peek_done:
+ rts
+
+do_file_softiec:
+ jsr clear_buffers
+ PRINT softiec_load_su_msg
+ jsr softiec_load_su
+ jsr print_response_summary
+ bcs softiec_su_transport_ok
+ PRINT fail_msg
+ jsr cr
+ lda #$31
+ ldy #$00
+ jsr store_result_y
+ rts
+softiec_su_transport_ok:
+ jsr status_ok
+ bcs softiec_su_status_ok
+ PRINT fail_msg
+ jsr cr
+ lda #$33
+ ldy #$00
+ jsr store_result_y
+ rts
+softiec_su_status_ok:
+ jsr verify_header_buffer
+ bcs softiec_su_ok
+ PRINT fail_msg
+ jsr cr
+ lda #$32
+ ldy #$00
+ jsr store_result_y
+ rts
+softiec_su_ok:
+ PRINT ok_msg
+ jsr cr
+
+ PRINT softiec_load_ex_msg
+ jsr softiec_load_ex
+ jsr print_response_summary
+ bcs softiec_ex_transport_ok
+ PRINT fail_msg
+ jsr cr
+ lda #$34
+ ldy #$00
+ jsr store_result_y
+ rts
+softiec_ex_transport_ok:
+ jsr status_ok
+ bcs softiec_ex_status_ok
+ PRINT fail_msg
+ jsr cr
+ lda #$35
+ ldy #$00
+ jsr store_result_y
+ rts
+softiec_ex_status_ok:
+ jsr verify_load_buffer_softiec
+ bcs softiec_ram_ok
+ PRINT fail_msg
+ jsr cr
+ lda #$0D
+ ldy #$00
+ jsr store_result_y
+ rts
+softiec_ram_ok:
+ PRINT ok_msg
+ jsr cr
+ lda #$01
+ ldy #$04
+ jsr store_result_y
+ ldy #$06
+ jsr store_result_y
+ lda #$02
+ ldy #$07
+ jsr store_result_y
+ lda #$01
+ iny
+ jsr store_result_y
+
+ PRINT reu_msg
+ jsr stash_to_reu
+ jsr clear_verify
+ jsr fetch_from_reu
+ jsr verify_fetch_buffer
+ bcs softiec_reu_ok
+ PRINT fail_msg
+ jsr cr
+ lda #$04
+ ldy #$00
+ jsr store_result_y
+ rts
+softiec_reu_ok:
+ PRINT ok_msg
+ jsr cr
+ jsr snapshot_verify
+ lda #$01
+ ldy #$05
+ jsr store_result_y
+ lda snapshot_hi
+ ldy #$09
+ jsr store_result_y
+ lda #$55
+ ldy #$00
+ jsr store_result_y
+ rts
+
+read_ram_chunks:
+ lda #$00
+ sta load_off
+ sta ram_chunk_count
+read_ram_chunk_loop:
+ PRINT ram_read_msg
+ lda load_off
+ jsr print_hex_a
+ jsr dos_read_ram_64
+ jsr print_response_summary
+ bcs read_ram_transport_ok
+ lda #$0B
+ sta ram_error
+ clc
+ rts
+read_ram_transport_ok:
+ lda data_full
+ bne read_ram_count_fail
+ lda data_len
+ cmp #$40
+ bne read_ram_count_fail
+ lda stat_len
+ beq read_ram_one_ok
+ jsr status_ok
+ bcs read_ram_one_ok
+ lda #$0C
+ sta ram_error
+ clc
+ rts
+read_ram_count_fail:
+ lda #$10
+ sta ram_error
+ clc
+ rts
+read_ram_one_ok:
+ inc ram_chunk_count
+ lda load_off
+ clc
+ adc #$40
+ sta load_off
+ lda ram_chunk_count
+ cmp #$04
+ bne read_ram_chunk_loop
+ sec
+ rts
+
+dos_identify:
+ jsr sync_interface
+ bcs dos_identify_sync_ok
+ jmp command_fail
+dos_identify_sync_ok:
+ lda #$01
+ jsr uci_write_cmd
+ lda #$01
+ jsr uci_write_cmd
+ jsr uci_push_cmd
+ jmp drain_response
+
+ctrl_get_drvinfo:
+ jsr sync_interface
+ bcs ctrl_drvinfo_sync_ok
+ jmp command_fail
+ctrl_drvinfo_sync_ok:
+ lda #$04
+ jsr uci_write_cmd
+ lda #$29
+ jsr uci_write_cmd
+ lda #$00
+ jsr uci_write_cmd
+ jsr uci_push_cmd
+ jmp drain_response
+
+dos_close:
+ jsr sync_interface
+ bcs dos_close_sync_ok
+ jmp command_fail
+dos_close_sync_ok:
+ lda #$01
+ jsr uci_write_cmd
+ lda #$03
+ jsr uci_write_cmd
+ jsr uci_push_cmd
+ jmp drain_response
+
+dos_cd:
+ jsr sync_interface
+ bcs dos_cd_sync_ok
+ jmp command_fail
+dos_cd_sync_ok:
+ lda #$01
+ jsr uci_write_cmd
+ lda #$11
+ jsr uci_write_cmd
+ ldy #$00
+dos_cd_name:
+ lda (name_ptr),y
+ beq dos_cd_push
+ jsr uci_write_cmd
+ iny
+ bne dos_cd_name
+dos_cd_push:
+ jsr uci_push_cmd
+ jmp drain_response
+
+dos_get_path:
+ jsr sync_interface
+ bcs dos_get_path_sync_ok
+ jmp command_fail
+dos_get_path_sync_ok:
+ lda #$01
+ jsr uci_write_cmd
+ lda #$12
+ jsr uci_write_cmd
+ jsr uci_push_cmd
+ jmp drain_response
+
+dos_copy_ui_path:
+ jsr sync_interface
+ bcs dos_copy_ui_sync_ok
+ jmp command_fail
+dos_copy_ui_sync_ok:
+ lda #$01
+ jsr uci_write_cmd
+ lda #$15
+ jsr uci_write_cmd
+ jsr uci_push_cmd
+ jmp drain_response
+
+dos_mount_d81:
+ jsr sync_interface
+ bcs dos_mount_sync_ok
+ jmp command_fail
+dos_mount_sync_ok:
+ lda #$01
+ jsr uci_write_cmd
+ lda #$23
+ jsr uci_write_cmd
+ lda #$08
+ jsr uci_write_cmd
+ ldy #$00
+dos_mount_name:
+ lda d81_name,y
+ beq dos_mount_push
+ jsr uci_write_cmd
+ iny
+ bne dos_mount_name
+dos_mount_push:
+ jsr uci_push_cmd
+ jmp drain_response
+
+dos_open_dir:
+ jsr sync_interface
+ bcs dos_open_dir_sync_ok
+ jmp command_fail
+dos_open_dir_sync_ok:
+ lda #$01
+ jsr uci_write_cmd
+ lda #$13
+ jsr uci_write_cmd
+ jsr uci_push_cmd
+ jmp drain_response
+
+dos_read_dir:
+ jsr sync_interface
+ bcs dos_read_dir_sync_ok
+ jmp command_fail
+dos_read_dir_sync_ok:
+ lda #$01
+ jsr uci_write_cmd
+ lda #$14
+ jsr uci_write_cmd
+ jsr uci_push_cmd
+ jmp drain_response
+
+dos_file_stat:
+ jsr sync_interface
+ bcs dos_file_stat_sync_ok
+ jmp command_fail
+dos_file_stat_sync_ok:
+ lda #$01
+ jsr uci_write_cmd
+ lda #$08
+ jsr uci_write_cmd
+ ldy #$00
+dos_file_stat_name:
+ lda (name_ptr),y
+ beq dos_file_stat_push
+ jsr uci_write_cmd
+ iny
+ bne dos_file_stat_name
+dos_file_stat_push:
+ jsr uci_push_cmd
+ jmp drain_response
+
+dos_open_read:
+ jsr sync_interface
+ bcs dos_open_sync_ok
+ jmp command_fail
+dos_open_sync_ok:
+ lda #$01
+ jsr uci_write_cmd
+ lda #$02
+ jsr uci_write_cmd
+ lda #$01
+ jsr uci_write_cmd
+ ldy #$00
+dos_open_name:
+ lda (name_ptr),y
+ beq dos_open_push
+ jsr uci_write_cmd
+ iny
+ bne dos_open_name
+dos_open_push:
+ jsr uci_push_cmd
+ jmp drain_response
+
+dos_read_header:
+ jsr sync_interface
+ bcs dos_read_header_sync_ok
+ jmp command_fail
+dos_read_header_sync_ok:
+ lda #$01
+ jsr uci_write_cmd
+ lda #$04
+ jsr uci_write_cmd
+ lda #$02
+ jsr uci_write_cmd
+ lda #$00
+ jsr uci_write_cmd
+ jsr uci_push_cmd
+ jmp drain_response
+
+dos_read_ram_64:
+ jsr sync_interface
+ bcs dos_read_ram_sync_ok
+ jmp command_fail
+dos_read_ram_sync_ok:
+ lda #$01
+ jsr uci_write_cmd
+ lda #$04
+ jsr uci_write_cmd
+ lda #$40
+ jsr uci_write_cmd
+ lda #$00
+ jsr uci_write_cmd
+ jsr uci_push_cmd
+ jmp drain_response_to_load
+
+dos_seek_payload:
+ jsr sync_interface
+ bcs dos_seek_sync_ok
+ jmp command_fail
+dos_seek_sync_ok:
+ lda #$01
+ jsr uci_write_cmd
+ lda #$06
+ jsr uci_write_cmd
+ lda #$02
+ jsr uci_write_cmd
+ lda #$00
+ jsr uci_write_cmd
+ jsr uci_write_cmd
+ jsr uci_write_cmd
+ jsr uci_push_cmd
+ jmp drain_response
+
+dos_load_reu_chunk:
+ jsr sync_interface
+ bcs dos_load_reu_sync_ok
+ jmp command_fail
+dos_load_reu_sync_ok:
+ lda #$01
+ jsr uci_write_cmd
+ lda #$21
+ jsr uci_write_cmd
+ lda reu_off_lo
+ jsr uci_write_cmd
+ lda reu_off_hi
+ jsr uci_write_cmd
+ lda #$02
+ jsr uci_write_cmd
+ lda #$00
+ jsr uci_write_cmd
+ lda reu_len_lo
+ jsr uci_write_cmd
+ lda #$00
+ jsr uci_write_cmd
+ lda #$00
+ jsr uci_write_cmd
+ jsr uci_write_cmd
+ jsr uci_push_cmd
+ jmp drain_response
+
+softiec_load_su:
+ jsr sync_interface
+ bcc command_fail
+ lda #$05
+ jsr uci_write_cmd
+ lda #$10
+ jsr uci_write_cmd
+ lda #$00
+ jsr uci_write_cmd
+ jsr uci_write_cmd
+ lda #LOAD_BUF
+ jsr uci_write_cmd
+ ldy #$00
+softiec_load_su_name:
+ lda (name_ptr),y
+ beq softiec_load_su_push
+ jsr uci_write_cmd
+ iny
+ bne softiec_load_su_name
+softiec_load_su_push:
+ jsr uci_push_cmd
+ jmp drain_response
+
+softiec_load_ex:
+ jsr sync_interface
+ bcc command_fail
+ lda #$05
+ jsr uci_write_cmd
+ lda #$11
+ jsr uci_write_cmd
+ lda #$00
+ jsr uci_write_cmd
+ jsr uci_write_cmd
+ jsr uci_push_cmd
+ jmp drain_response
+
+command_fail:
+ clc
+ rts
+
+sync_interface:
+ lda #$40
+ sta timeout_hi
+sync_loop:
+ jsr uci_status
+ sta last_status
+ and #UCI_STAT_ERROR
+ beq sync_no_error
+ jsr uci_clear_error
+ lda #$40
+ sta timeout_hi
+ jmp sync_loop
+sync_no_error:
+ lda last_status
+ and #UCI_STAT_ABORT
+ beq sync_no_abort
+ jsr uci_abort
+ lda #$40
+ sta timeout_hi
+ jmp sync_loop
+sync_no_abort:
+ lda last_status
+ and #UCI_STAT_DATA
+ beq sync_no_data
+ jsr uci_read_data
+ lda #$40
+ sta timeout_hi
+ jmp sync_loop
+sync_no_data:
+ lda last_status
+ and #UCI_STAT_STAT
+ beq sync_no_stat
+ jsr uci_read_stat
+ lda #$40
+ sta timeout_hi
+ jmp sync_loop
+sync_no_stat:
+ lda last_status
+ and #UCI_STATE_MASK
+ cmp #UCI_STATE_LAST
+ beq sync_accept
+ cmp #UCI_STATE_MORE
+ beq sync_accept
+ lda last_status
+ and #$31
+ beq sync_ok
+ dec timeout_hi
+ bne sync_loop
+ jsr uci_abort
+ clc
+ rts
+sync_accept:
+ jsr uci_accept_data
+ lda #$40
+ sta timeout_hi
+ jmp sync_loop
+sync_ok:
+ sec
+ rts
+
+wait_data_state:
+ lda #$80
+ sta timeout_hi
+ ldy #$00
+wait_state_loop:
+ jsr uci_status
+ sta last_status
+ and #UCI_STAT_ERROR
+ bne wait_state_fail
+ lda last_status
+ and #UCI_STATE_MASK
+ cmp #UCI_STATE_LAST
+ beq wait_state_ok
+ cmp #UCI_STATE_MORE
+ beq wait_state_ok
+ cmp #UCI_STATE_IDLE
+ beq wait_state_ok
+ dey
+ bne wait_state_loop
+ dec timeout_hi
+ bne wait_state_loop
+wait_state_fail:
+ clc
+ rts
+wait_state_ok:
+ sec
+ rts
+
+wait_idle:
+ lda #$40
+ sta timeout_hi
+ ldy #$00
+wait_idle_loop:
+ jsr uci_status
+ sta last_status
+ lda last_status
+ and #$31
+ beq wait_idle_ok
+ dey
+ bne wait_idle_loop
+ dec timeout_hi
+ bne wait_idle_loop
+ clc
+ rts
+wait_idle_ok:
+ sec
+ rts
+
+drain_response:
+ lda #$00
+ sta data_len
+ sta stat_len
+ jsr wait_data_state
+ bcs drain_loop
+ clc
+ rts
+drain_loop:
+ jsr uci_status
+ sta last_status
+ and #UCI_STAT_ERROR
+ beq drain_no_error
+ clc
+ rts
+drain_no_error:
+ lda last_status
+ and #UCI_STATE_MASK
+ sta current_state
+ beq drain_done
+ cmp #UCI_STATE_LAST
+ beq drain_state_ok
+ cmp #UCI_STATE_MORE
+ beq drain_state_ok
+ jsr wait_data_state
+ bcs drain_loop
+ clc
+ rts
+drain_state_ok:
+ lda #$10
+ sta timeout_hi
+ ldy #$00
+drain_bytes:
+ jsr uci_status
+ sta last_status
+ and #UCI_STAT_DATA
+ beq drain_check_stat
+ jsr uci_read_data
+ ldx data_len
+ cpx #$20
+ bcs drain_reset_guard
+ sta data_buf,x
+ inc data_len
+ jmp drain_reset_guard
+drain_check_stat:
+ lda last_status
+ and #UCI_STAT_STAT
+ beq drain_wait_byte
+ jsr uci_read_stat
+ ldx stat_len
+ cpx #$08
+ bcs drain_reset_guard
+ sta stat_buf,x
+ inc stat_len
+drain_reset_guard:
+ lda #$10
+ sta timeout_hi
+ ldy #$00
+ jmp drain_bytes
+drain_wait_byte:
+ dey
+ bne drain_bytes
+ dec timeout_hi
+ bne drain_bytes
+ jsr uci_accept_data
+ lda current_state
+ cmp #UCI_STATE_LAST
+ bne drain_more
+ jsr wait_idle
+ sec
+ rts
+drain_more:
+ jsr wait_data_state
+ bcc drain_more_fail
+ jmp drain_loop
+drain_more_fail:
+ clc
+ rts
+drain_done:
+ sec
+ rts
+
+drain_response_to_load:
+ lda #$00
+ sta data_len
+ sta data_full
+ sta stat_len
+ jsr wait_data_state
+ bcs drain_load_loop
+ clc
+ rts
+drain_load_loop:
+ jsr uci_status
+ sta last_status
+ and #UCI_STAT_ERROR
+ beq drain_load_no_error
+ clc
+ rts
+drain_load_no_error:
+ lda last_status
+ and #UCI_STATE_MASK
+ sta current_state
+ beq drain_load_done
+ cmp #UCI_STATE_LAST
+ beq drain_load_state_ok
+ cmp #UCI_STATE_MORE
+ beq drain_load_state_ok
+ jsr wait_data_state
+ bcs drain_load_loop
+ clc
+ rts
+drain_load_state_ok:
+ lda #$10
+ sta timeout_hi
+ ldy #$00
+drain_load_bytes:
+ jsr uci_status
+ sta last_status
+ and #UCI_STAT_DATA
+ beq drain_load_check_stat
+ jsr uci_read_data
+ pha
+ ldx data_len
+ txa
+ clc
+ adc load_off
+ tax
+ pla
+ sta LOAD_BUF,x
+ inc data_len
+ bne drain_load_reset_guard
+ inc data_full
+ jmp drain_load_reset_guard
+drain_load_check_stat:
+ lda last_status
+ and #UCI_STAT_STAT
+ beq drain_load_wait_byte
+ jsr uci_read_stat
+ ldx stat_len
+ cpx #$08
+ bcs drain_load_reset_guard
+ sta stat_buf,x
+ inc stat_len
+drain_load_reset_guard:
+ lda #$10
+ sta timeout_hi
+ ldy #$00
+ jmp drain_load_bytes
+drain_load_wait_byte:
+ dey
+ bne drain_load_bytes
+ dec timeout_hi
+ bne drain_load_bytes
+ jsr uci_accept_data
+ lda current_state
+ cmp #UCI_STATE_LAST
+ bne drain_load_more
+ jsr wait_idle
+ sec
+ rts
+drain_load_more:
+ jsr wait_data_state
+ bcc drain_load_more_fail
+ jmp drain_load_loop
+drain_load_more_fail:
+ clc
+ rts
+drain_load_done:
+ sec
+ rts
+
+clear_buffers:
+ jsr clear_load
+clear_verify:
+ ldx #$00
+ lda #$00
+clear_verify_loop:
+ sta VERIFY_BUF,x
+ inx
+ bne clear_verify_loop
+ rts
+
+clear_load:
+ ldx #$00
+ lda #$00
+clear_load_loop:
+ sta LOAD_BUF,x
+ inx
+ bne clear_load_loop
+ rts
+
+verify_header_buffer:
+ lda data_len
+ cmp #$02
+ bcc verify_fail
+ lda data_buf
+ bne verify_fail
+ lda data_buf+1
+ cmp #$40
+ bne verify_fail
+ sec
+ rts
+
+verify_load_buffer:
+ lda ram_chunk_count
+ cmp #$04
+ bne verify_fail
+ ldx #$00
+verify_load_loop:
+ lda LOAD_BUF,x
+ cmp expected_byte
+ bne verify_fail
+ inx
+ bne verify_load_loop
+ sec
+ rts
+
+verify_load_buffer_softiec:
+ ldx #$00
+verify_load_softiec_loop:
+ lda LOAD_BUF,x
+ cmp expected_byte
+ bne verify_fail
+ inx
+ bne verify_load_softiec_loop
+ sec
+ rts
+
+verify_fetch_buffer:
+ ldx #$00
+verify_fetch_loop:
+ lda VERIFY_BUF,x
+ cmp expected_byte
+ bne verify_fail
+ inx
+ bne verify_fetch_loop
+ sec
+ rts
+verify_fail:
+ stx fail_offset
+ clc
+ rts
+
+fetch_from_reu:
+ lda #VERIFY_BUF
+ sta REU_C64_HI
+ lda #$00
+ sta REU_REU_LO
+ lda reu_off_hi
+ sta REU_REU_HI
+ lda #$02
+ sta REU_REU_BANK
+ lda #$00
+ sta REU_LEN_LO
+ lda #$01
+ sta REU_LEN_HI
+ lda #REU_CMD_FETCH
+ sta REU_COMMAND
+ rts
+
+stash_to_reu:
+ lda #LOAD_BUF
+ sta REU_C64_HI
+ lda #$00
+ sta REU_REU_LO
+ lda reu_off_hi
+ sta REU_REU_HI
+ lda #$02
+ sta REU_REU_BANK
+ lda #$00
+ sta REU_LEN_LO
+ lda #$01
+ sta REU_LEN_HI
+ lda #REU_CMD_STASH
+ sta REU_COMMAND
+ rts
+
+snapshot_verify:
+ lda snapshot_hi
+ sta snapshot_store+2
+ ldx #$00
+snapshot_loop:
+ lda VERIFY_BUF,x
+snapshot_store:
+ sta SNAP1_BUF,x
+ inx
+ bne snapshot_loop
+ rts
+
+status_ok:
+ lda stat_len
+ beq status_not_ok
+ lda stat_buf
+ cmp #'0'
+ bne status_not_ok
+ lda stat_buf+1
+ cmp #'0'
+ bne status_not_ok
+status_is_ok:
+ sec
+ rts
+status_not_ok:
+ clc
+ rts
+
+data_or_status_ok:
+ lda stat_len
+ beq data_or_status_from_data
+ jmp status_ok
+data_or_status_from_data:
+ lda data_len
+ ora data_full
+ beq status_not_ok
+ sec
+ rts
+
+file_stat_ok:
+ jsr data_or_status_ok
+ bcc file_stat_not_ok
+ lda data_len
+ cmp #$0B
+ bcc file_stat_not_ok
+ lda data_buf
+ cmp #$02
+ bne file_stat_not_ok
+ lda data_buf+1
+ cmp #$01
+ bne file_stat_not_ok
+ lda data_buf+2
+ ora data_buf+3
+ bne file_stat_not_ok
+ lda data_buf+8
+ cmp #'P'
+ bne file_stat_not_ok
+ lda data_buf+9
+ cmp #'R'
+ bne file_stat_not_ok
+ lda data_buf+10
+ cmp #'G'
+ bne file_stat_not_ok
+ lda data_buf
+ sta stat_size_lo
+ lda data_buf+1
+ sta stat_size_hi
+ sec
+ rts
+file_stat_not_ok:
+ clc
+ rts
+
+print_response_summary:
+ php
+ PRINT data_msg
+ lda data_full
+ jsr print_hex_a
+ lda data_len
+ jsr print_hex_a
+ PRINT stat_count_msg
+ lda stat_len
+ jsr print_hex_a
+ PRINT rc_msg
+ lda stat_buf
+ jsr print_hex_a
+ PRINT end_msg
+ lda stat_buf+2
+ jsr print_hex_a
+ lda stat_buf+1
+ jsr print_hex_a
+ jsr cr
+ plp
+ rts
+
+print_data_text:
+ php
+ lda data_len
+ ora data_full
+ beq print_data_text_done
+ PRINT text_msg
+ ldx #$00
+print_data_text_loop:
+ cpx data_len
+ beq print_data_text_cr
+ lda data_buf,x
+ beq print_data_text_cr
+ jsr print_safe_char
+ inx
+ cpx #$20
+ bne print_data_text_loop
+print_data_text_cr:
+ jsr cr
+print_data_text_done:
+ plp
+ rts
+
+print_drvinfo:
+ php
+ lda data_len
+ cmp #$04
+ bcc print_drvinfo_done
+ PRINT drv_msg
+ lda data_buf
+ jsr print_hex_a
+ PRINT drv_a_msg
+ lda data_buf+1
+ jsr print_hex_a
+ lda data_buf+2
+ jsr print_hex_a
+ lda data_buf+3
+ jsr print_hex_a
+ lda data_buf
+ cmp #$02
+ bcc print_drvinfo_cr
+ lda data_len
+ cmp #$07
+ bcc print_drvinfo_cr
+ PRINT drv_b_msg
+ lda data_buf+4
+ jsr print_hex_a
+ lda data_buf+5
+ jsr print_hex_a
+ lda data_buf+6
+ jsr print_hex_a
+print_drvinfo_cr:
+ jsr cr
+ lda data_buf
+ sta RESULTS+$0C
+ lda data_buf+1
+ sta RESULTS+$0D
+ lda data_buf+2
+ sta RESULTS+$0E
+ lda data_buf+3
+ sta RESULTS+$0F
+print_drvinfo_done:
+ plp
+ rts
+
+print_file_stat:
+ php
+ PRINT file_stat_msg
+ lda stat_size_hi
+ jsr print_hex_a
+ lda stat_size_lo
+ jsr print_hex_a
+ PRINT file_stat_ext_msg
+ lda data_buf+8
+ jsr print_safe_char
+ lda data_buf+9
+ jsr print_safe_char
+ lda data_buf+10
+ jsr print_safe_char
+ jsr cr
+ plp
+ rts
+
+print_final_summary:
+ PRINT summary_msg
+ lda RESULTS+$0B
+ jsr print_hex_a
+ PRINT summary_plain_msg
+ lda RESULTS+$40
+ jsr print_hex_a
+ PRINT summary_copy_ui_msg
+ lda RESULTS+$48
+ jsr print_hex_a
+ PRINT summary_f1_msg
+ lda RESULTS+$10
+ jsr print_hex_a
+ PRINT summary_f2_msg
+ lda RESULTS+$20
+ jsr print_hex_a
+ PRINT summary_f3_msg
+ lda RESULTS+$30
+ jsr print_hex_a
+ jsr cr
+ rts
+
+print_softiec_summary:
+ PRINT softiec_msg
+ jsr softiec_ok
+ bcs print_softiec_yes
+ PRINT no_msg
+ jmp print_softiec_bus
+print_softiec_yes:
+ PRINT yes_msg
+print_softiec_bus:
+ PRINT bus_msg
+ lda softiec_bus
+ jsr print_hex_a
+ jsr cr
+ rts
+
+print_safe_char:
+ cmp #$20
+ bcc print_dot
+ cmp #$7F
+ bcs print_dot
+ jmp CHROUT
+print_dot:
+ lda #'.'
+ jmp CHROUT
+
+print_z:
+ sta print_z_load+1
+ sty print_z_load+2
+print_z_loop:
+print_z_load:
+ lda $FFFF
+ beq print_z_done
+ jsr CHROUT
+ inc print_z_load+1
+ bne print_z_loop
+ inc print_z_load+2
+ jmp print_z_loop
+print_z_done:
+ rts
+
+cr:
+ lda #$0D
+ jmp CHROUT
+
+print_hex_a:
+ pha
+ lsr
+ lsr
+ lsr
+ lsr
+ jsr print_nibble
+ pla
+ and #$0F
+print_nibble:
+ cmp #$0A
+ bcc print_digit
+ clc
+ adc #('A' - $0A)
+ jmp CHROUT
+print_digit:
+ clc
+ adc #'0'
+ jmp CHROUT
+
+set_uci_base:
+ sta uci_base_lo
+ stx uci_base_hi
+ sta uci_status_abs+1
+ sta uci_push_abs+1
+ sta uci_accept_abs+1
+ sta uci_abort_abs+1
+ sta uci_clear_abs+1
+ stx uci_status_abs+2
+ stx uci_push_abs+2
+ stx uci_accept_abs+2
+ stx uci_abort_abs+2
+ stx uci_clear_abs+2
+
+ lda uci_base_lo
+ sec
+ sbc #$01
+ sta uci_softiec_abs+1
+ lda uci_base_hi
+ sbc #$00
+ sta uci_softiec_abs+2
+
+ lda uci_base_lo
+ clc
+ adc #$01
+ sta uci_write_abs+1
+ sta uci_id_abs+1
+ lda uci_base_hi
+ adc #$00
+ sta uci_write_abs+2
+ sta uci_id_abs+2
+
+ lda uci_base_lo
+ clc
+ adc #$02
+ sta uci_data_abs+1
+ lda uci_base_hi
+ adc #$00
+ sta uci_data_abs+2
+
+ lda uci_base_lo
+ clc
+ adc #$03
+ sta uci_stat_abs+1
+ lda uci_base_hi
+ adc #$00
+ sta uci_stat_abs+2
+ rts
+
+uci_write_cmd:
+ sta uci_value
+ php
+ sei
+ lda CPU_PORT
+ pha
+ and #$F8
+ ora #$07
+ sta CPU_PORT
+ lda uci_value
+uci_write_abs:
+ sta $DF1D
+ pla
+ sta CPU_PORT
+ plp
+ lda uci_value
+ rts
+
+uci_id:
+ php
+ sei
+ lda CPU_PORT
+ pha
+ and #$F8
+ ora #$07
+ sta CPU_PORT
+uci_id_abs:
+ lda $DF1D
+ tax
+ pla
+ sta CPU_PORT
+ plp
+ txa
+ rts
+
+uci_status:
+ php
+ sei
+ lda CPU_PORT
+ pha
+ and #$F8
+ ora #$07
+ sta CPU_PORT
+uci_status_abs:
+ lda $DF1C
+ tax
+ pla
+ sta CPU_PORT
+ plp
+ txa
+ rts
+
+uci_read_data:
+ php
+ sei
+ lda CPU_PORT
+ pha
+ and #$F8
+ ora #$07
+ sta CPU_PORT
+uci_data_abs:
+ lda $DF1E
+ tax
+ pla
+ sta CPU_PORT
+ plp
+ txa
+ rts
+
+uci_read_stat:
+ php
+ sei
+ lda CPU_PORT
+ pha
+ and #$F8
+ ora #$07
+ sta CPU_PORT
+uci_stat_abs:
+ lda $DF1F
+ tax
+ pla
+ sta CPU_PORT
+ plp
+ txa
+ rts
+
+uci_push_cmd:
+ php
+ sei
+ lda CPU_PORT
+ pha
+ and #$F8
+ ora #$07
+ sta CPU_PORT
+ lda #$01
+uci_push_abs:
+ sta $DF1C
+ pla
+ sta CPU_PORT
+ plp
+ rts
+
+uci_accept_data:
+ php
+ sei
+ lda CPU_PORT
+ pha
+ and #$F8
+ ora #$07
+ sta CPU_PORT
+ lda #$02
+uci_accept_abs:
+ sta $DF1C
+ pla
+ sta CPU_PORT
+ plp
+ rts
+
+uci_abort:
+ php
+ sei
+ lda CPU_PORT
+ pha
+ and #$F8
+ ora #$07
+ sta CPU_PORT
+ lda #$04
+uci_abort_abs:
+ sta $DF1C
+ pla
+ sta CPU_PORT
+ plp
+ rts
+
+uci_clear_error:
+ php
+ sei
+ lda CPU_PORT
+ pha
+ and #$F8
+ ora #$07
+ sta CPU_PORT
+ lda #$08
+uci_clear_abs:
+ sta $DF1C
+ pla
+ sta CPU_PORT
+ plp
+ rts
+
+uci_softiec:
+ php
+ sei
+ lda CPU_PORT
+ pha
+ and #$F8
+ ora #$07
+ sta CPU_PORT
+uci_softiec_abs:
+ lda $DF1B
+ tax
+ pla
+ sta CPU_PORT
+ plp
+ txa
+ rts
+
+ .segment "RODATA"
+.ifdef PROBE_D64
+title_msg: .byte "UCI DOS REU PROBE V40", 0
+.else
+title_msg: .byte "UCI DOS REU PROBE V41", 0
+.endif
+probe_msg: .byte "PROBING UCI", 0
+base_msg: .byte "BASE $", 0
+id_msg: .byte " ID:", 0
+stat_msg: .byte " ST:", 0
+bus_msg: .byte " BUS:", 0
+softiec_msg: .byte "SOFTIEC:", 0
+yes_msg: .byte "YES", 0
+no_msg: .byte "NO", 0
+using_msg: .byte "UCI OK $", 0
+no_uci_msg: .byte "UCI NOT FOUND", 0
+drv_msg: .byte "DRV:", 0
+drv_a_msg: .byte " A:", 0
+drv_b_msg: .byte " B:", 0
+file1_msg: .byte "FILE UDMA1", 13, 0
+file2_msg: .byte "FILE UDMA2", 13, 0
+file3_msg: .byte "FILE UDMA3", 13, 0
+close_msg: .byte " CLOSE", 0
+open_msg: .byte " OPEN", 0
+hdr_read_msg: .byte " READ HDR", 0
+ram_read_msg: .byte " READ RAM", 0
+seek_msg: .byte " SEEK +2", 0
+reu_load1_msg: .byte " LOAD_REU 1", 0
+reu_load2_msg: .byte " LOAD_REU 2", 0
+reu_msg: .byte " REU VERIFY ", 0
+softiec_load_su_msg: .byte " LOAD_SU", 0
+softiec_load_ex_msg: .byte " LOAD_EX", 0
+cd_root_msg: .byte "CD /", 0
+cd_usb1_msg: .byte "CD USB1", 0
+cd_usb1_abs_msg: .byte "CD /USB1", 0
+cd_usb0_msg: .byte "CD USB0", 0
+cd_usb0_abs_msg: .byte "CD /USB0", 0
+.ifdef PROBE_D64
+cd_d81_msg: .byte "CD UCI40.D64", 0
+mount_d81_msg: .byte "MOUNT8 UCI40.D64", 13, 0
+.else
+cd_d81_msg: .byte "CD UCI41.D81", 0
+mount_d81_msg: .byte "MOUNT8 UCI41.D81", 13, 0
+.endif
+cd_d81_abs_msg: .byte "CD /USBX/UCI.D81", 0
+usb_fail_msg: .byte "USB ROOT ", 0
+d81_fail_msg: .byte "D81 PATH ", 0
+dir_open_msg: .byte " OPEN DIR", 0
+dir_read_msg: .byte " READ DIR", 0
+stat_file_msg: .byte " STAT", 0
+nostat_file_msg: .byte " OPEN DIRECT", 0
+data_msg: .byte " D:", 0
+stat_count_msg: .byte " S:", 0
+text_msg: .byte " TXT:", 0
+rc_msg: .byte " RC:", 0
+end_msg: .byte " END:", 0
+summary_msg: .byte "SUM USB:", 0
+summary_plain_msg: .byte " P:", 0
+summary_copy_ui_msg: .byte " C:", 0
+summary_f1_msg: .byte " F1:", 0
+summary_f2_msg: .byte " F2:", 0
+summary_f3_msg: .byte " F3:", 0
+file_stat_msg: .byte " SIZE:", 0
+file_stat_ext_msg: .byte " EXT:", 0
+plain_stat_msg: .byte "PLAIN STAT UDMA1", 0
+copy_ui_stat_msg: .byte "COPYUI STAT UDMA1", 0
+ok_msg: .byte "OK", 0
+fail_msg: .byte "FAIL", 0
+done_msg: .byte "PROBE DONE", 0
+; Ultimate DOS command spelling that matched the known-good D64 probe run.
+file1_name: .byte "udma1", 0
+file2_name: .byte "udma2", 0
+file3_name: .byte "udma3", 0
+root_name: .byte "/", 0
+usb1_name: .byte "USB1", 0
+usb1_abs_name: .byte "/USB1", 0
+usb0_name: .byte "USB0", 0
+usb0_abs_name: .byte "/USB0", 0
+.ifdef PROBE_D64
+d81_name: .byte "UCI40.D64", 0
+d81_usb1_abs_name: .byte "/USB1/UCI40.D64", 0
+d81_usb0_abs_name: .byte "/USB0/UCI40.D64", 0
+.else
+d81_name: .byte "UCI41.D81", 0
+d81_usb1_abs_name: .byte "/USB1/UCI41.D81", 0
+d81_usb0_abs_name: .byte "/USB0/UCI41.D81", 0
+.endif
+
+ .segment "DATA"
+uci_base_lo: .byte <$DF1C
+uci_base_hi: .byte >$DF1C
+uci_value: .byte 0
+uci_id_byte: .byte 0
+uci_status_byte: .byte 0
+softiec_bus: .byte 0
+selected_usb: .byte 1
+last_status: .byte 0
+current_state: .byte 0
+timeout_hi: .byte 0
+data_len: .byte 0
+data_full: .byte 0
+stat_len: .byte 0
+expected_byte: .byte 0
+reu_off_hi: .byte 0
+reu_off_lo: .byte 0
+reu_len_lo: .byte 0
+load_off: .byte 0
+ram_chunk_count: .byte 0
+ram_error: .byte 0
+stat_size_lo: .byte 0
+stat_size_hi: .byte 0
+result_base_offset: .byte 0
+result_value: .byte 0
+fail_offset: .byte 0
+snapshot_hi: .byte >SNAP1_BUF
+dir_count: .byte 0
+data_buf: .res 32, 0
+stat_buf: .res 8, 0
diff --git a/probes/uci_timing/build.sh b/probes/uci_timing/build.sh
new file mode 100644
index 0000000..fe954f6
--- /dev/null
+++ b/probes/uci_timing/build.sh
@@ -0,0 +1,108 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+root_dir="$(cd "$(dirname "$0")/../.." && pwd)"
+build_dir="$root_dir/build/uci_timing"
+profile="$root_dir/cfg/profiles/precog-d81.ini"
+base_d81="${BASE_D81:-}"
+
+mkdir -p "$build_dir"
+
+if [[ -z "$base_d81" ]]; then
+ base_d81="$(ls -t "$root_dir"/Releases/0.2.5/precog-d81/*.d81 2>/dev/null | head -1 || true)"
+fi
+if [[ -z "$base_d81" || ! -f "$base_d81" ]]; then
+ echo "no base D81 found; set BASE_D81 or build the precog-d81 release first" >&2
+ exit 1
+fi
+
+python3 "$root_dir/probes/uci_timing/build_asm_probe.py" \
+ "$root_dir" \
+ "$root_dir/probes/uci_dma/uci_dma_probe.s" \
+ "$profile" \
+ "$build_dir/uci_timing_probe.s"
+python3 "$root_dir/build_support/instrument_launcher_uci_dma_for_timing.py" \
+ "$root_dir/src/apps/launcher/launcher_uci_dma.s" \
+ "$build_dir/launcher_uci_dma_timed.s"
+
+ca65 -o "$build_dir/uci_timing_probe.o" "$build_dir/uci_timing_probe.s"
+ca65 -o "$build_dir/launcher_uci_dma.o" "$build_dir/launcher_uci_dma_timed.s"
+ld65 -C "$root_dir/probes/uci_timing/probe.cfg" \
+ -o "$build_dir/uci_timing_probe.prg" \
+ -m "$build_dir/uci_timing_probe.map" \
+ "$build_dir/uci_timing_probe.o" \
+ "$build_dir/launcher_uci_dma.o"
+
+python3 "$root_dir/build_support/build_apps_catalog_petscii.py" \
+ --input "$profile" \
+ --output "$build_dir/apps_cfg_petscii.seq" \
+ --variant-asm-output "$build_dir/msg_variant.inc" \
+ --reu-config-asm-output "$build_dir/readyos_reu_config.inc"
+
+disk="$build_dir/readyos.d81"
+rm -f "$disk"
+if [[ "${UCI_TIMING_FRESH_D81:-0}" == "1" ]]; then
+ c1541 -format "uci timing,ut" d81 "$disk" \
+ -write "$build_dir/apps_cfg_petscii.seq" "apps.cfg,s" \
+ -write "$build_dir/uci_timing_probe.prg" "utime"
+ python3 - "$root_dir" "$profile" "$build_dir/files_to_write.txt" <<'PY'
+import pathlib
+import sys
+
+root = pathlib.Path(sys.argv[1])
+profile = pathlib.Path(sys.argv[2])
+out = pathlib.Path(sys.argv[3])
+sys.path.insert(0, str(root / "probes" / "uci_timing"))
+from build_asm_probe import parse_profile
+
+_, items = parse_profile(profile)
+seen = set()
+lines = []
+for item in items:
+ name = str(item["name"]).lower()
+ if name in seen:
+ continue
+ seen.add(name)
+ src = root / "bin" / f"{name}.prg"
+ if not src.exists():
+ raise SystemExit(f"missing {src}")
+ lines.append(f"{src}\t{name}")
+out.write_text("\n".join(lines) + "\n", encoding="utf-8")
+PY
+ while IFS=$'\t' read -r src name; do
+ [[ -n "$src" ]] || continue
+ c1541 "$disk" -write "$src" "$name"
+ done < "$build_dir/files_to_write.txt"
+else
+ cp "$base_d81" "$disk"
+ c1541 "$disk" \
+ -delete "apps.cfg" \
+ -delete "utime" \
+ -write "$build_dir/apps_cfg_petscii.seq" "apps.cfg,s" \
+ -write "$build_dir/uci_timing_probe.prg" "utime"
+fi
+
+verify_dir="$build_dir/readback"
+rm -rf "$verify_dir"
+mkdir -p "$verify_dir"
+(
+ cd "$verify_dir"
+ c1541 "$disk" -read "utime" >/dev/null
+ c1541 "$disk" -read "apps.cfg,s" >/dev/null
+)
+cmp -s "$build_dir/uci_timing_probe.prg" "$verify_dir/utime"
+cmp -s "$build_dir/apps_cfg_petscii.seq" "$verify_dir/apps.cfg"
+
+python3 - "$disk" <<'PY'
+import pathlib
+import sys
+
+data = pathlib.Path(sys.argv[1]).read_bytes()
+for raw in (b"UTIME" + b"\xa0" * 11, b"APPS.CFG" + b"\xa0" * 8):
+ if data.find(raw) < 0:
+ raise SystemExit(f"missing directory entry {raw!r}")
+print("verified probe image directory entries")
+PY
+
+shasum -a 256 "$disk"
+echo "$disk"
diff --git a/probes/uci_timing/build_asm_probe.py b/probes/uci_timing/build_asm_probe.py
new file mode 100644
index 0000000..80c34da
--- /dev/null
+++ b/probes/uci_timing/build_asm_probe.py
@@ -0,0 +1,788 @@
+#!/usr/bin/env python3
+from __future__ import annotations
+
+import os
+import pathlib
+import re
+import sys
+
+
+APP_LOAD = 0x1000
+RS_LOAD = 0x8E00
+APP_MAX = 0xB600
+RS_MAX = 0x3800
+
+
+def parse_profile(path: pathlib.Path) -> tuple[str, list[dict[str, object]]]:
+ section = ""
+ pending: dict[str, object] | None = None
+ pending_desc = False
+ image_name = os.environ.get("UCI_TIMING_IMAGE_NAME", "readyos.d81")
+ c64u_path = f"/usb1/{image_name}"
+ apps: list[dict[str, object]] = []
+
+ for raw in path.read_text(encoding="utf-8").splitlines():
+ line = raw.strip()
+ if not line or line.startswith("#") or line.startswith(";"):
+ continue
+ if line.startswith("[") and line.endswith("]"):
+ section = line[1:-1].strip().lower()
+ continue
+ if section == "launcher" and line.startswith("c64u_image_path="):
+ c64u_path = line.split("=", 1)[1].strip() or c64u_path
+ continue
+ if section != "apps":
+ continue
+ if pending and pending_desc:
+ for item in line.split(","):
+ item = item.strip()
+ if not item or "@" not in item or ":" not in item:
+ continue
+ name, rest = item.split("@", 1)
+ bank_raw, off_raw = rest.split(":", 1)
+ apps.append({
+ "name": name.strip(),
+ "kind": "rs",
+ "bank": 0x80 + int(bank_raw, 10),
+ "off": int(off_raw, 16),
+ "max_len": RS_MAX,
+ "expected": RS_LOAD,
+ })
+ pending = None
+ pending_desc = False
+ continue
+ if pending:
+ resource = str(pending.get("resource") or "")
+ if resource.endswith("+") and resource[:-1] == "rsovl":
+ pending_desc = True
+ else:
+ pending = None
+ continue
+ if re.match(r"^[0-9]+:", line):
+ parts = [p.strip() for p in line.split(":")]
+ if len(parts) < 3:
+ continue
+ name = parts[1]
+ resource = parts[4] if len(parts) >= 5 else (
+ parts[3] if len(parts) >= 4 and not parts[3].isdigit() else ""
+ )
+ app = {
+ "name": name,
+ "kind": "app",
+ "bank": 0x40 + sum(1 for a in apps if a.get("kind") == "app"),
+ "off": 0,
+ "max_len": APP_MAX,
+ "expected": APP_LOAD,
+ "resource": resource,
+ }
+ apps.append(app)
+ pending = app
+
+ return c64u_path, apps
+
+
+def asm_string(text: str) -> str:
+ return ", ".join(f"${b:02X}" for b in text.encode("ascii")) + ", 0"
+
+
+def payload_len(root: pathlib.Path, name: str) -> int:
+ path = root / "bin" / f"{name}.prg"
+ data = path.read_bytes()
+ if len(data) < 3:
+ raise ValueError(f"{path}: too small")
+ return len(data) - 2
+
+
+def image_path_parts(profile_path: pathlib.Path) -> tuple[str, str]:
+ c64u_path, _ = parse_profile(profile_path)
+ image_name = os.environ.get("UCI_TIMING_IMAGE_NAME")
+ if image_name:
+ c64u_path = f"/usb1/{image_name}"
+ slash = c64u_path.rfind("/")
+ if slash <= 0 or slash == len(c64u_path) - 1:
+ return "/", c64u_path.strip("/")
+ return c64u_path[:slash], c64u_path[slash + 1:]
+
+
+def build_workload(root: pathlib.Path, profile: pathlib.Path) -> tuple[str, int]:
+ _, items = parse_profile(profile)
+ only = [item.strip().lower() for item in os.environ.get("UCI_TIMING_ITEMS", "").split(",") if item.strip()]
+ if only:
+ wanted = set(only)
+ items = [item for item in items if str(item["name"]).lower() in wanted]
+ order = {name: i for i, name in enumerate(only)}
+ items.sort(key=lambda item: order.get(str(item["name"]).lower(), 999))
+ generated: list[str] = []
+ labels: list[tuple[str, str]] = []
+ used: set[str] = set()
+
+ generated.append("workload_run:")
+ for idx, item in enumerate(items):
+ name = str(item["name"]).lower()
+ label = "name_" + re.sub(r"[^a-z0-9_]", "_", name)
+ if label in used:
+ label = f"{label}_{idx}"
+ used.add(label)
+ labels.append((label, name))
+ length = payload_len(root, name)
+ raw_length = length + 2
+ max_len = int(item["max_len"])
+ if length > max_len and item["kind"] == "rs" and length <= 0x3A00:
+ length = max_len
+ if length > max_len:
+ raise ValueError(f"{name}: payload ${length:04X} exceeds max ${max_len:04X}")
+ probe_len = raw_length if os.environ.get("UCI_TIMING_FAST_RAW", "0") == "1" else max_len
+ generated.append(f"""
+ lda #<{label}
+ sta current_name
+ lda #>{label}
+ sta current_name+1
+ lda #${int(item['bank']) & 0xff:02X}
+ sta current_bank
+ lda #<${int(item['off']) & 0xffff:04X}
+ sta current_off
+ lda #>${int(item['off']) & 0xffff:04X}
+ sta current_off+1
+ lda #<${probe_len & 0xffff:04X}
+ sta current_max
+ lda #>${probe_len & 0xffff:04X}
+ sta current_max+1
+ lda #<${int(item['expected']) & 0xffff:04X}
+ sta current_expected
+ lda #>${int(item['expected']) & 0xffff:04X}
+ sta current_expected+1
+ jsr load_one_launcher_timed
+ bcs @item_{idx}_ok
+ inc failures
+@item_{idx}_ok:
+ inc item_index
+ jsr update_runtime_results
+""")
+
+ generated.append(" rts\n")
+ generated.append(f"WORKLOAD_COUNT = {len(items)}")
+ for label, name in labels:
+ generated.append(f"{label}: .byte " + asm_string(name))
+ return "\n".join(generated), len(items)
+
+
+ASM_TEMPLATE = r'''
+ .segment "LOADADDR"
+ .word $0801
+
+ .segment "STARTUP"
+ .word basic_next
+ .word 10
+ .byte $9e, "2061", 0
+basic_next:
+ .word 0
+
+ .import _launcher_uci_dma_detect
+ .import _launcher_uci_dma_load_prg
+ .import _launcher_uci_dma_quiesce
+ .import _launcher_uci_dma_clear_stage
+ .import _launcher_uci_dma_name
+ .import _launcher_uci_dma_reu_bank
+ .import _launcher_uci_dma_reu_offset
+ .import _launcher_uci_dma_max_len
+ .import _launcher_uci_dma_expected_load_addr
+ .import _launcher_uci_dma_loaded_size
+ .import _launcher_uci_dma_last_error
+ .import _launcher_uci_dma_dbg_stat0
+ .import _launcher_uci_dma_dbg_stat1
+ .import _launcher_uci_dma_image_dir
+ .import _launcher_uci_dma_image_name
+ .import _launcher_uci_dma_mount_name
+ .import _launcher_uci_dma_assume_mounted
+
+ .export _utime_stage_begin
+ .export _utime_stage_end
+
+CHROUT = $FFD2
+GETIN = $FFE4
+RESULTS = $3000
+STAGE_COUNT = $0D
+current_name = $04
+
+ .macro PRINT label
+ lda #label
+ jsr print_z
+ .endmacro
+
+ .segment "CODE"
+
+start:
+ lda #$93
+ jsr CHROUT
+ lda #$01
+ sta $0286
+ jsr init_results
+ PRINT title_msg
+ jsr cr
+ PRINT path_msg
+ PRINT image_dir
+ lda #'/'
+ jsr CHROUT
+ PRINT image_name
+ jsr cr
+ jsr _launcher_uci_dma_detect
+ cmp #$00
+ bne have_uci
+ lda #$02
+ sta done_code
+ lda #WORKLOAD_COUNT
+ sta failures
+ jsr update_runtime_results
+ PRINT no_uci_msg
+ jsr cr
+ jmp done
+have_uci:
+ PRINT uci_msg
+ jsr cr
+ jsr workload_run
+ lda failures
+ beq all_ok
+ lda #$04
+ bne set_done
+all_ok:
+ lda #$01
+set_done:
+ sta done_code
+ jsr update_runtime_results
+done:
+ jsr print_summary
+ jmp *
+
+load_one_launcher_timed:
+ jsr print_progress
+ lda #$31
+ sta $052d
+
+ lda #image_dir
+ sta _launcher_uci_dma_image_dir+1
+ lda #image_name
+ sta _launcher_uci_dma_image_name+1
+ sta _launcher_uci_dma_mount_name+1
+ lda current_name
+ sta _launcher_uci_dma_name
+ lda current_name+1
+ sta _launcher_uci_dma_name+1
+ lda current_bank
+ sta _launcher_uci_dma_reu_bank
+ lda current_off
+ sta _launcher_uci_dma_reu_offset
+ lda current_off+1
+ sta _launcher_uci_dma_reu_offset+1
+ lda current_max
+ sta _launcher_uci_dma_max_len
+ lda current_max+1
+ sta _launcher_uci_dma_max_len+1
+ lda current_expected
+ sta _launcher_uci_dma_expected_load_addr
+ lda current_expected+1
+ sta _launcher_uci_dma_expected_load_addr+1
+ lda image_ready
+ sta _launcher_uci_dma_assume_mounted
+
+ jsr read_jiffy16
+ sta tick_start
+ stx tick_start+1
+ jsr _launcher_uci_dma_load_prg
+ sta last_ok
+ tax
+ beq load_failed_quiesce
+ lda #$01
+ sta image_ready
+ sta _launcher_uci_dma_assume_mounted
+ jsr _launcher_uci_dma_quiesce
+ jsr _launcher_uci_dma_clear_stage
+ jmp after_loader_call
+load_failed_quiesce:
+ jsr apply_launcher_failure_state
+ jsr _launcher_uci_dma_quiesce
+after_loader_call:
+ jsr read_jiffy16
+ sec
+ sbc tick_start
+ sta last_ticks
+ txa
+ sbc tick_start+1
+ sta last_ticks+1
+ jsr add_total_ticks
+ jsr add_phase_ticks
+ jsr update_max_load
+ lda last_ok
+ bne load_succeeded
+ jsr store_first_failure
+ clc
+ rts
+load_succeeded:
+ inc successes
+ jsr add_loaded_kb
+ sec
+ rts
+
+apply_launcher_failure_state:
+ lda _launcher_uci_dma_last_error
+ cmp #$01
+ beq fail_disable_path
+ cmp #$08
+ bcc fail_keep_path
+ cmp #$11
+ bcs fail_keep_path
+fail_disable_path:
+ lda #$00
+ sta image_ready
+ sta _launcher_uci_dma_assume_mounted
+ rts
+fail_keep_path:
+ lda #$01
+ sta image_ready
+ sta _launcher_uci_dma_assume_mounted
+ rts
+
+add_total_ticks:
+ lda total_ticks
+ clc
+ adc last_ticks
+ sta total_ticks
+ lda total_ticks+1
+ adc last_ticks+1
+ sta total_ticks+1
+ rts
+
+add_phase_ticks:
+ lda item_index
+ beq add_first_ticks
+ lda subsequent_ticks
+ clc
+ adc last_ticks
+ sta subsequent_ticks
+ lda subsequent_ticks+1
+ adc last_ticks+1
+ sta subsequent_ticks+1
+ rts
+add_first_ticks:
+ lda first_ticks
+ clc
+ adc last_ticks
+ sta first_ticks
+ lda first_ticks+1
+ adc last_ticks+1
+ sta first_ticks+1
+ rts
+
+update_max_load:
+ lda max_load_ticks+1
+ cmp last_ticks+1
+ bcc set_max_load
+ bne max_load_done
+ lda max_load_ticks
+ cmp last_ticks
+ bcs max_load_done
+set_max_load:
+ lda last_ticks
+ sta max_load_ticks
+ lda last_ticks+1
+ sta max_load_ticks+1
+ ldy #$00
+copy_max_name:
+ cpy #$0f
+ beq term_max_name
+ lda (current_name),y
+ sta max_load_name,y
+ beq max_load_done
+ iny
+ bne copy_max_name
+term_max_name:
+ lda #$00
+ sta max_load_name,y
+max_load_done:
+ rts
+
+add_loaded_kb:
+ lda _launcher_uci_dma_loaded_size
+ clc
+ adc #$ff
+ lda _launcher_uci_dma_loaded_size+1
+ adc #$03
+ lsr
+ lsr
+ clc
+ adc total_kb
+ sta total_kb
+ lda total_kb+1
+ adc #$00
+ sta total_kb+1
+ rts
+
+store_first_failure:
+ lda first_fail_error
+ bne first_failure_done
+ lda item_index
+ sta first_fail_item
+ lda _launcher_uci_dma_last_error
+ sta first_fail_error
+ lda _launcher_uci_dma_dbg_stat0
+ sta first_fail_dbg0
+ lda _launcher_uci_dma_dbg_stat1
+ sta first_fail_dbg1
+ ldy #$00
+copy_fail_name:
+ cpy #$0f
+ beq term_fail_name
+ lda (current_name),y
+ sta first_fail_name,y
+ beq first_failure_done
+ iny
+ bne copy_fail_name
+term_fail_name:
+ lda #$00
+ sta first_fail_name,y
+first_failure_done:
+ rts
+
+read_jiffy16:
+ lda $A2
+ ldx $A1
+ rts
+
+_utime_stage_begin:
+ sta stage_id
+ jsr read_jiffy16
+ sta stage_start
+ stx stage_start+1
+ rts
+
+_utime_stage_end:
+ jsr read_jiffy16
+ sta stage_now
+ stx stage_now+1
+ lda stage_now
+ sec
+ sbc stage_start
+ sta stage_delta
+ lda stage_now+1
+ sbc stage_start+1
+ sta stage_delta+1
+ lda stage_id
+ asl
+ tax
+ lda stage_ticks,x
+ clc
+ adc stage_delta
+ sta stage_ticks,x
+ lda stage_ticks+1,x
+ adc stage_delta+1
+ sta stage_ticks+1,x
+ lda item_index
+ beq stage_end_done
+ lda stage_id
+ asl
+ tax
+ lda stage_subseq_ticks,x
+ clc
+ adc stage_delta
+ sta stage_subseq_ticks,x
+ lda stage_subseq_ticks+1,x
+ adc stage_delta+1
+ sta stage_subseq_ticks+1,x
+stage_end_done:
+ rts
+
+init_results:
+ ldx #$00
+ lda #$00
+clear_results:
+ sta RESULTS,x
+ inx
+ cpx #$80
+ bne clear_results
+ lda #'U'
+ sta RESULTS
+ lda #'T'
+ sta RESULTS+1
+ lda #'I'
+ sta RESULTS+2
+ lda #'M'
+ sta RESULTS+3
+ lda #__RESULT_VERSION__
+ sta RESULTS+4
+ lda #WORKLOAD_COUNT
+ sta RESULTS+6
+ jsr update_runtime_results
+ rts
+
+update_runtime_results:
+ lda #__RESULT_VERSION__
+ sta RESULTS+4
+ lda done_code
+ sta RESULTS+5
+ lda item_index
+ sta RESULTS+6
+ lda failures
+ sta RESULTS+7
+ lda total_ticks
+ sta RESULTS+8
+ lda total_ticks+1
+ sta RESULTS+9
+ lda total_kb
+ sta RESULTS+10
+ lda total_kb+1
+ sta RESULTS+11
+ lda max_load_ticks
+ sta RESULTS+12
+ lda max_load_ticks+1
+ sta RESULTS+13
+ lda successes
+ sta RESULTS+14
+ lda #STAGE_COUNT
+ sta RESULTS+15
+ lda first_ticks
+ sta RESULTS+16
+ lda first_ticks+1
+ sta RESULTS+17
+ lda subsequent_ticks
+ sta RESULTS+18
+ lda subsequent_ticks+1
+ sta RESULTS+19
+ ldx #$00
+copy_stages_result:
+ lda stage_ticks,x
+ sta RESULTS+20,x
+ inx
+ cpx #(STAGE_COUNT * 2)
+ bne copy_stages_result
+ ldx #$00
+copy_subseq_stages_result:
+ lda stage_subseq_ticks,x
+ sta RESULTS+80,x
+ inx
+ cpx #(STAGE_COUNT * 2)
+ bne copy_subseq_stages_result
+ ldx #$00
+copy_max_result:
+ lda max_load_name,x
+ sta RESULTS+48,x
+ inx
+ cpx #$10
+ bne copy_max_result
+ lda first_fail_item
+ sta RESULTS+64
+ lda first_fail_error
+ sta RESULTS+65
+ lda first_fail_dbg0
+ sta RESULTS+66
+ lda first_fail_dbg1
+ sta RESULTS+67
+ ldx #$00
+copy_fail_result:
+ lda first_fail_name,x
+ sta RESULTS+72,x
+ inx
+ cpx #$08
+ bne copy_fail_result
+ rts
+
+print_progress:
+ lda #$13
+ jsr CHROUT
+ PRINT loading_msg
+ lda item_index
+ jsr print_hex_a
+ lda #'/'
+ jsr CHROUT
+ lda #WORKLOAD_COUNT
+ jsr print_hex_a
+ lda #' '
+ jsr CHROUT
+ ldy #$00
+progress_name:
+ lda (current_name),y
+ beq progress_done
+ jsr CHROUT
+ iny
+ cpy #$0f
+ bne progress_name
+progress_done:
+ jsr cr
+ rts
+
+print_summary:
+ lda #$13
+ jsr CHROUT
+ PRINT done_msg
+ lda done_code
+ jsr print_hex_a
+ PRINT item_msg
+ lda item_index
+ jsr print_hex_a
+ PRINT fail_msg
+ lda failures
+ jsr print_hex_a
+ jsr cr
+ PRINT succ_msg
+ lda successes
+ jsr print_hex_a
+ PRINT kb_msg
+ lda total_kb+1
+ jsr print_hex_a
+ lda total_kb
+ jsr print_hex_a
+ PRINT ticks_msg
+ lda total_ticks+1
+ jsr print_hex_a
+ lda total_ticks
+ jsr print_hex_a
+ jsr cr
+ PRINT max_msg
+ lda max_load_ticks+1
+ jsr print_hex_a
+ lda max_load_ticks
+ jsr print_hex_a
+ lda #' '
+ jsr CHROUT
+ lda #max_load_name
+ jsr print_z
+ jsr cr
+ lda failures
+ beq no_fail_print
+ PRINT first_fail_msg
+ lda first_fail_item
+ jsr print_hex_a
+ lda #'/'
+ jsr CHROUT
+ lda first_fail_error
+ jsr print_hex_a
+ lda #' '
+ jsr CHROUT
+ lda #first_fail_name
+ jsr print_z
+ jsr cr
+no_fail_print:
+ PRINT probe_done_msg
+ jsr cr
+ rts
+
+print_z:
+ sta pz+1
+ sty pz+2
+ ldy #$00
+pz:
+ lda $FFFF,y
+ beq print_z_done
+ jsr CHROUT
+ iny
+ bne pz
+print_z_done:
+ rts
+
+print_hex_a:
+ pha
+ lsr
+ lsr
+ lsr
+ lsr
+ jsr print_hex_nibble
+ pla
+ and #$0f
+print_hex_nibble:
+ cmp #$0a
+ bcc print_hex_digit
+ adc #$06
+print_hex_digit:
+ adc #'0'
+ jsr CHROUT
+ rts
+
+cr:
+ lda #$0d
+ jsr CHROUT
+ rts
+
+ .segment "RODATA"
+__WORKLOAD__
+image_dir: .byte __IMAGE_DIR__
+image_name: .byte __IMAGE_NAME__
+title_msg: .byte __TITLE_MSG__
+path_msg: .byte "PATH ", 0
+uci_msg: .byte "UCI OK", 0
+no_uci_msg: .byte "NO UCI", 0
+loading_msg: .byte "LOADING ", 0
+done_msg: .byte "DONE:", 0
+item_msg: .byte " ITEMS:", 0
+fail_msg: .byte " FAIL:", 0
+succ_msg: .byte "SUCCESS:", 0
+kb_msg: .byte " KB:", 0
+ticks_msg: .byte " TICKS:", 0
+max_msg: .byte "MAX:", 0
+first_fail_msg: .byte "FIRST FAIL:", 0
+probe_done_msg: .byte "PROBE DONE", 0
+
+ .segment "DATA"
+done_code: .byte 0
+item_index: .byte 0
+successes: .byte 0
+failures: .byte 0
+image_ready: .byte 0
+last_ok: .byte 0
+tick_start: .word 0
+last_ticks: .word 0
+total_ticks: .word 0
+first_ticks: .word 0
+subsequent_ticks:.word 0
+total_kb: .word 0
+max_load_ticks: .word 0
+current_bank: .byte 0
+current_off: .word 0
+current_max: .word 0
+current_expected:.word 0
+first_fail_item: .byte 0
+first_fail_error:.byte 0
+first_fail_dbg0: .byte 0
+first_fail_dbg1: .byte 0
+max_load_name: .res 16
+first_fail_name: .res 16
+stage_id: .byte 0
+stage_start: .word 0
+stage_now: .word 0
+stage_delta: .word 0
+stage_ticks: .res STAGE_COUNT * 2
+stage_subseq_ticks: .res STAGE_COUNT * 2
+'''
+
+
+def main() -> int:
+ if len(sys.argv) != 5:
+ raise SystemExit("usage: build_asm_probe.py ROOT TEMPLATE PROFILE OUTPUT")
+ root = pathlib.Path(sys.argv[1]).resolve()
+ profile = pathlib.Path(sys.argv[3]).resolve()
+ output = pathlib.Path(sys.argv[4]).resolve()
+
+ workload, _ = build_workload(root, profile)
+ image_dir, image_name = image_path_parts(profile)
+ source = ASM_TEMPLATE.replace("__WORKLOAD__", workload)
+ source = source.replace("__IMAGE_DIR__", asm_string(image_dir.lower()))
+ source = source.replace("__IMAGE_NAME__", asm_string(image_name.lower()))
+ if os.environ.get("UCI_TIMING_FAST_RAW", "0") == "1":
+ source = source.replace("__RESULT_VERSION__", "$06")
+ source = source.replace("__TITLE_MSG__", asm_string("UCI TIMING FAST RAW"))
+ else:
+ source = source.replace("__RESULT_VERSION__", "$04")
+ source = source.replace("__TITLE_MSG__", asm_string("UCI TIMING LAUNCHER"))
+ output.parent.mkdir(parents=True, exist_ok=True)
+ output.write_text(source, encoding="utf-8")
+ print(f"wrote {output}")
+ return 0
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/probes/uci_timing/probe.cfg b/probes/uci_timing/probe.cfg
new file mode 100644
index 0000000..4fce8e9
--- /dev/null
+++ b/probes/uci_timing/probe.cfg
@@ -0,0 +1,15 @@
+MEMORY {
+ ZP: file = "", start = $0002, size = $001A, type = rw, define = yes;
+ LOADADDR: file = %O, start = $07FF, size = $0002;
+ RAM: file = %O, start = $0801, size = $37FF;
+}
+
+SEGMENTS {
+ ZEROPAGE: load = ZP, type = zp;
+ LOADADDR: load = LOADADDR, type = ro;
+ STARTUP: load = RAM, type = ro;
+ CODE: load = RAM, type = ro;
+ RODATA: load = RAM, type = ro;
+ DATA: load = RAM, type = rw;
+ BSS: load = RAM, type = bss, define = yes;
+}
diff --git a/probes/uci_timing/uci_timing_probe.c b/probes/uci_timing/uci_timing_probe.c
new file mode 100644
index 0000000..ac8d02d
--- /dev/null
+++ b/probes/uci_timing/uci_timing_probe.c
@@ -0,0 +1,754 @@
+#include
+#include
+#include
+#include
+#include
+
+#include "sysinfo_uci.h"
+
+#define MAX_ITEMS 48
+#define MAX_NAME 13
+#define CFG_CAP 1600
+#define LINE_CAP 176
+#define PATH_CAP 80
+
+#define APP_LOAD_ADDR 0x1000u
+#define APP_MAX_LEN 0xB600u
+#define RS_LOAD_ADDR 0x8E00u
+#define RS_SLOT_LEN 0x3800u
+
+#define KIND_APP 1u
+#define KIND_RS 2u
+
+#define PH_OPEN 0
+#define PH_INFO 1
+#define PH_READ2 2
+#define PH_SEEK 3
+#define PH_LOAD 4
+#define PH_CLOSE 5
+#define PH_COUNT 6
+
+#define UCI_DOS_TARGET 1u
+#define UCI_CTRL_TARGET 4u
+
+#define CMD_IDENTIFY 0x01u
+#define CMD_OPEN 0x02u
+#define CMD_CLOSE 0x03u
+#define CMD_READ 0x04u
+#define CMD_SEEK 0x06u
+#define CMD_FILE_INFO 0x07u
+#define CMD_CD 0x11u
+#define CMD_LOAD_REU 0x21u
+#define CMD_MOUNT 0x23u
+#define CMD_DRVINFO 0x29u
+
+#define RESULT_ADDR ((unsigned char*)0x3000)
+
+typedef struct WorkItem {
+ char name[MAX_NAME];
+ unsigned char kind;
+ unsigned char bank;
+ unsigned int off;
+ unsigned int max_len;
+ unsigned int expected;
+} WorkItem;
+
+typedef struct Stamp {
+ unsigned char j0;
+ unsigned char j1;
+ unsigned char j2;
+ unsigned int ta;
+} Stamp;
+
+static unsigned char cfg_buf[CFG_CAP];
+static unsigned int cfg_len;
+static char line_buf[LINE_CAP];
+static char image_path[PATH_CAP];
+static char image_dir[PATH_CAP];
+static char image_name[24];
+static WorkItem items[MAX_ITEMS];
+static unsigned char item_count;
+static unsigned char app_count;
+static unsigned char rs_count;
+static unsigned char rb_meta_count;
+static unsigned char failures;
+static unsigned int phase_ms[PH_COUNT];
+static unsigned int total_loaded_kb;
+static unsigned int total_ms;
+static unsigned int max_load_ms;
+static unsigned int last_cmd_ms;
+static char max_load_name[MAX_NAME];
+static unsigned char data_buf[48];
+static unsigned char stat_buf[32];
+static unsigned char data_len;
+static unsigned char stat_len;
+static unsigned char cmd_buf[112];
+
+static void put_u16(unsigned char *p, unsigned int v) {
+ p[0] = (unsigned char)(v & 0xffu);
+ p[1] = (unsigned char)(v >> 8);
+}
+
+static void write_results(unsigned char done) {
+ unsigned char *p = RESULT_ADDR;
+ unsigned char i;
+ p[0] = 'U';
+ p[1] = 'T';
+ p[2] = 'I';
+ p[3] = 'M';
+ p[4] = 1u;
+ p[5] = done;
+ p[6] = item_count;
+ p[7] = failures;
+ put_u16(p + 8, total_ms);
+ put_u16(p + 10, total_loaded_kb);
+ put_u16(p + 12, max_load_ms);
+ for (i = 0; i < PH_COUNT; ++i) {
+ put_u16(p + 16u + (unsigned int)i * 2u, phase_ms[i]);
+ }
+ memset(p + 32, 0, 16);
+ for (i = 0; i < MAX_NAME - 1 && max_load_name[i] != 0; ++i) {
+ p[32u + i] = (unsigned char)max_load_name[i];
+ }
+ memset(p + 48, 0, 48);
+ for (i = 0; i < 47u && image_path[i] != 0; ++i) {
+ p[48u + i] = (unsigned char)image_path[i];
+ }
+}
+
+static unsigned char lower_byte(unsigned char ch) {
+ if (ch >= 0x41u && ch <= 0x5Au) {
+ return (unsigned char)(ch + 0x20u);
+ }
+ return ch;
+}
+
+static unsigned char cieq(const char *a, const char *b) {
+ while (*a != 0 && *b != 0) {
+ if (lower_byte((unsigned char)*a) != lower_byte((unsigned char)*b)) {
+ return 0u;
+ }
+ ++a;
+ ++b;
+ }
+ return (unsigned char)(*a == 0 && *b == 0);
+}
+
+static unsigned char ciprefix(const char *s, const char *prefix) {
+ while (*prefix != 0) {
+ if (*s == 0 ||
+ lower_byte((unsigned char)*s) != lower_byte((unsigned char)*prefix)) {
+ return 0u;
+ }
+ ++s;
+ ++prefix;
+ }
+ return 1u;
+}
+
+static unsigned char c64u_path_key_match(const char *s) {
+ static const unsigned char key[] = {
+ 0x43, 0x36, 0x34, 0x55, 0x5f, 0x49, 0x4d, 0x41,
+ 0x47, 0x45, 0x5f, 0x50, 0x41, 0x54, 0x48, 0x3d
+ };
+ unsigned char i;
+
+ for (i = 0u; i < sizeof(key); ++i) {
+ if (lower_byte((unsigned char)s[i]) != lower_byte(key[i])) {
+ return 0u;
+ }
+ }
+ return 1u;
+}
+
+static unsigned char starts_section(const char *s, const char *name) {
+ unsigned char i;
+ if (s[0] != '[') {
+ return 0u;
+ }
+ for (i = 1u; s[i] != 0 && s[i] != ']'; ++i) {
+ if (!ciprefix(s + i, name)) {
+ continue;
+ }
+ return 1u;
+ }
+ return 0u;
+}
+
+static void trim(char *s) {
+ char *p = s;
+ unsigned char len;
+ while (*p == ' ') {
+ ++p;
+ }
+ if (p != s) {
+ memmove(s, p, strlen(p) + 1);
+ }
+ len = (unsigned char)strlen(s);
+ while (len != 0u && (s[(unsigned char)(len - 1u)] == ' ' ||
+ s[(unsigned char)(len - 1u)] == 13)) {
+ s[(unsigned char)(len - 1u)] = 0;
+ --len;
+ }
+}
+
+static void copy_token(char *dst, unsigned char cap, const char *src) {
+ unsigned char i = 0;
+ if (cap == 0u) {
+ return;
+ }
+ while (i < (unsigned char)(cap - 1u) && src[i] != 0) {
+ dst[i] = src[i];
+ ++i;
+ }
+ dst[i] = 0;
+}
+
+static unsigned char parse_hex_word(const char *s, unsigned int *out) {
+ unsigned int v = 0;
+ unsigned char i;
+ unsigned char ch;
+ for (i = 0; s[i] != 0; ++i) {
+ ch = (unsigned char)s[i];
+ v = (unsigned int)(v << 4);
+ if (ch >= '0' && ch <= '9') {
+ v = (unsigned int)(v + (unsigned int)(ch - '0'));
+ } else if (lower_byte(ch) >= 'a' && lower_byte(ch) <= 'f') {
+ ch = lower_byte(ch);
+ v = (unsigned int)(v + (unsigned int)(10u + ch - 'a'));
+ } else {
+ return 0u;
+ }
+ }
+ *out = v;
+ return (unsigned char)(i != 0u);
+}
+
+static unsigned char add_item(const char *name,
+ unsigned char kind,
+ unsigned char bank,
+ unsigned int off,
+ unsigned int max_len,
+ unsigned int expected) {
+ WorkItem *it;
+ if (item_count >= MAX_ITEMS || name[0] == 0) {
+ return 0u;
+ }
+ it = &items[item_count++];
+ memset(it, 0, sizeof(*it));
+ copy_token(it->name, sizeof(it->name), name);
+ it->kind = kind;
+ it->bank = bank;
+ it->off = off;
+ it->max_len = max_len;
+ it->expected = expected;
+ return 1u;
+}
+
+static unsigned char load_cfg(void) {
+ int n;
+ cfg_len = 0;
+ if (cbm_open(2, 8, 2, "apps.cfg,s,r") != 0) {
+ return 0u;
+ }
+ for (;;) {
+ n = cbm_read(2, cfg_buf + cfg_len, (unsigned int)(CFG_CAP - cfg_len));
+ if (n <= 0) {
+ break;
+ }
+ cfg_len = (unsigned int)(cfg_len + (unsigned int)n);
+ if (cfg_len >= CFG_CAP) {
+ break;
+ }
+ }
+ cbm_close(2);
+ return (unsigned char)(cfg_len != 0u && cfg_len < CFG_CAP);
+}
+
+static unsigned char next_line(unsigned int *pos) {
+ unsigned char len = 0;
+ while (*pos < cfg_len && cfg_buf[*pos] != 13) {
+ if (len < LINE_CAP - 1) {
+ line_buf[len++] = (char)cfg_buf[*pos];
+ }
+ *pos = (unsigned int)(*pos + 1u);
+ }
+ if (*pos < cfg_len && cfg_buf[*pos] == 13) {
+ *pos = (unsigned int)(*pos + 1u);
+ }
+ line_buf[len] = 0;
+ trim(line_buf);
+ return (unsigned char)(len != 0u || *pos < cfg_len);
+}
+
+static void parse_rs_deps(char *line) {
+ char *cursor = line;
+ char *comma;
+ char *at;
+ char *colon;
+ char *name;
+ unsigned int off;
+ unsigned char ordinal;
+
+ while (cursor != 0 && cursor[0] != 0) {
+ comma = strchr(cursor, ',');
+ if (comma != 0) {
+ *comma = 0;
+ }
+ trim(cursor);
+ at = strchr(cursor, '@');
+ colon = at ? strchr(at, ':') : 0;
+ if (at != 0 && colon != 0) {
+ *at = 0;
+ *colon = 0;
+ name = cursor;
+ trim(name);
+ ordinal = (unsigned char)((at[1] >= '0' && at[1] <= '2') ? at[1] - '0' : 0);
+ if (parse_hex_word(colon + 1, &off)) {
+ add_item(name, KIND_RS, (unsigned char)(0x80u + ordinal),
+ off, RS_SLOT_LEN, RS_LOAD_ADDR);
+ ++rs_count;
+ }
+ }
+ if (comma == 0) {
+ break;
+ }
+ cursor = comma + 1;
+ }
+}
+
+static void parse_app_entry(char *line,
+ char *out_resource,
+ unsigned char *dep_required) {
+ char *p0;
+ char *p1;
+ char *p2;
+ char *p3;
+ char *p4;
+ unsigned char bank;
+
+ *dep_required = 0u;
+ out_resource[0] = 0;
+ p0 = line;
+ p1 = strchr(p0, ':');
+ if (p1 == 0) return;
+ *p1++ = 0;
+ p2 = strchr(p1, ':');
+ if (p2 == 0) return;
+ *p2++ = 0;
+ p3 = strchr(p2, ':');
+ if (p3 != 0) {
+ *p3++ = 0;
+ p4 = strchr(p3, ':');
+ if (p4 != 0) {
+ *p4++ = 0;
+ copy_token(out_resource, 16, p4);
+ } else if (p3[0] < '0' || p3[0] > '9') {
+ copy_token(out_resource, 16, p3);
+ }
+ }
+ if (out_resource[0] != 0) {
+ unsigned char len = (unsigned char)strlen(out_resource);
+ if (len != 0u && out_resource[(unsigned char)(len - 1u)] == '+') {
+ out_resource[(unsigned char)(len - 1u)] = 0;
+ *dep_required = 1u;
+ }
+ }
+ bank = (unsigned char)(0x40u + app_count);
+ add_item(p1, KIND_APP, bank, 0u, APP_MAX_LEN, APP_LOAD_ADDR);
+ ++app_count;
+}
+
+static unsigned char parse_cfg(void) {
+ unsigned int pos = 0;
+ unsigned char in_launcher = 0;
+ unsigned char in_apps = 0;
+ unsigned char pending_dep = 0;
+ unsigned char pending_desc = 0;
+ char pending_resource[16];
+ char resource[16];
+ unsigned char dep_required;
+
+ image_path[0] = 0;
+ while (pos < cfg_len) {
+ if (!next_line(&pos) || line_buf[0] == 0) {
+ continue;
+ }
+ if (starts_section(line_buf, "launcher")) {
+ in_launcher = 1u;
+ in_apps = 0u;
+ continue;
+ }
+ if (starts_section(line_buf, "apps")) {
+ in_launcher = 0u;
+ in_apps = 1u;
+ continue;
+ }
+ if (line_buf[0] == '[') {
+ in_launcher = 0u;
+ in_apps = 0u;
+ continue;
+ }
+ if (c64u_path_key_match(line_buf)) {
+ copy_token(image_path, sizeof(image_path), line_buf + 16);
+ continue;
+ }
+ if (!in_apps) {
+ continue;
+ }
+ if (pending_dep && pending_desc) {
+ parse_rs_deps(line_buf);
+ if (cieq(pending_resource, "rbcore")) {
+ rb_meta_count = (unsigned char)(rb_meta_count + 2u);
+ }
+ pending_dep = 0u;
+ pending_desc = 0u;
+ pending_resource[0] = 0;
+ continue;
+ }
+ if (pending_dep) {
+ pending_desc = 1u;
+ continue;
+ }
+ if (line_buf[0] >= '0' && line_buf[0] <= '9' && line_buf[1] == ':') {
+ parse_app_entry(line_buf, resource, &dep_required);
+ if (dep_required) {
+ copy_token(pending_resource, sizeof(pending_resource), resource);
+ pending_dep = 1u;
+ pending_desc = 0u;
+ }
+ }
+ }
+ return (unsigned char)(item_count != 0u && image_path[0] != 0);
+}
+
+static unsigned char split_image_path(void) {
+ char *slash = 0;
+ char *p = image_path;
+ while (*p != 0) {
+ if (*p == '/') {
+ slash = p;
+ }
+ ++p;
+ }
+ if (slash == 0 || slash[1] == 0) {
+ return 0u;
+ }
+ copy_token(image_name, sizeof(image_name), slash + 1);
+ if (slash == image_path) {
+ copy_token(image_dir, sizeof(image_dir), "/");
+ } else {
+ *slash = 0;
+ copy_token(image_dir, sizeof(image_dir), image_path);
+ *slash = '/';
+ }
+ return 1u;
+}
+
+static unsigned char path_byte(unsigned char ch) {
+ if (ch >= 'a' && ch <= 'z') {
+ ch &= 0xdfu;
+ }
+ return ch;
+}
+
+static unsigned char cmd_add_path(unsigned char pos, const char *s) {
+ while (*s != 0 && pos < sizeof(cmd_buf)) {
+ cmd_buf[pos++] = path_byte((unsigned char)*s++);
+ }
+ return pos;
+}
+
+static unsigned char cmd_add_raw(unsigned char pos, const char *s) {
+ while (*s != 0 && pos < sizeof(cmd_buf)) {
+ cmd_buf[pos++] = (unsigned char)*s++;
+ }
+ return pos;
+}
+
+static unsigned char uci_cmd(unsigned char len) {
+ return sysinfo_uci_command(cmd_buf, len, data_buf, sizeof(data_buf),
+ &data_len, stat_buf, sizeof(stat_buf), &stat_len);
+}
+
+static unsigned char status_ok(void) {
+ return (unsigned char)(stat_len >= 2u && stat_buf[0] == '0' && stat_buf[1] == '0');
+}
+
+static unsigned char data_or_status_ok(void) {
+ if (stat_len != 0u) {
+ return status_ok();
+ }
+ return (unsigned char)(data_len != 0u);
+}
+
+static unsigned char dos_simple(unsigned char op) {
+ cmd_buf[0] = UCI_DOS_TARGET;
+ cmd_buf[1] = op;
+ return uci_cmd(2);
+}
+
+static unsigned char dos_cd(const char *name) {
+ unsigned char pos = 0;
+ cmd_buf[pos++] = UCI_DOS_TARGET;
+ cmd_buf[pos++] = CMD_CD;
+ pos = cmd_add_path(pos, name);
+ return uci_cmd(pos);
+}
+
+static unsigned char dos_mount(void) {
+ unsigned char pos = 0;
+ cmd_buf[pos++] = UCI_DOS_TARGET;
+ cmd_buf[pos++] = CMD_MOUNT;
+ cmd_buf[pos++] = 8u;
+ pos = cmd_add_path(pos, image_name);
+ return uci_cmd(pos);
+}
+
+static unsigned char dos_open(const char *name) {
+ unsigned char pos = 0;
+ cmd_buf[pos++] = UCI_DOS_TARGET;
+ cmd_buf[pos++] = CMD_OPEN;
+ cmd_buf[pos++] = 1u;
+ pos = cmd_add_raw(pos, name);
+ return uci_cmd(pos);
+}
+
+static unsigned char dos_read2(void) {
+ cmd_buf[0] = UCI_DOS_TARGET;
+ cmd_buf[1] = CMD_READ;
+ cmd_buf[2] = 2u;
+ cmd_buf[3] = 0u;
+ return uci_cmd(4);
+}
+
+static unsigned char dos_seek2(void) {
+ cmd_buf[0] = UCI_DOS_TARGET;
+ cmd_buf[1] = CMD_SEEK;
+ cmd_buf[2] = 2u;
+ cmd_buf[3] = 0u;
+ cmd_buf[4] = 0u;
+ cmd_buf[5] = 0u;
+ return uci_cmd(6);
+}
+
+static unsigned char dos_load_reu(const WorkItem *it, unsigned int len) {
+ cmd_buf[0] = UCI_DOS_TARGET;
+ cmd_buf[1] = CMD_LOAD_REU;
+ cmd_buf[2] = (unsigned char)(it->off & 0xffu);
+ cmd_buf[3] = (unsigned char)(it->off >> 8);
+ cmd_buf[4] = it->bank;
+ cmd_buf[5] = 0u;
+ cmd_buf[6] = (unsigned char)(len & 0xffu);
+ cmd_buf[7] = (unsigned char)(len >> 8);
+ cmd_buf[8] = 0u;
+ cmd_buf[9] = 0u;
+ return uci_cmd(10);
+}
+
+static void read_stamp(Stamp *s) {
+ unsigned char a;
+ unsigned char b;
+ do {
+ a = *(volatile unsigned char*)0xA2;
+ s->j1 = *(volatile unsigned char*)0xA1;
+ s->j0 = *(volatile unsigned char*)0xA0;
+ b = *(volatile unsigned char*)0xA2;
+ } while (a != b);
+ s->j2 = b;
+ s->ta = (unsigned int)(*(volatile unsigned char*)0xDC04) |
+ ((unsigned int)(*(volatile unsigned char*)0xDC05) << 8);
+}
+
+static unsigned int elapsed_ms(const Stamp *start, const Stamp *end) {
+ unsigned long sj = (unsigned long)start->j0 |
+ ((unsigned long)start->j1 << 8) |
+ ((unsigned long)start->j2 << 16);
+ unsigned long ej = (unsigned long)end->j0 |
+ ((unsigned long)end->j1 << 8) |
+ ((unsigned long)end->j2 << 16);
+ unsigned long dj = (ej - sj) & 0x00ffffffUL;
+ long sub = (long)start->ta - (long)end->ta;
+ long cycles = (long)(dj * 17095UL) + sub;
+ if (cycles < 0) {
+ cycles = (long)(dj * 17095UL);
+ }
+ if (cycles > 65535000L) {
+ return 65535u;
+ }
+ return (unsigned int)((cycles + 500L) / 1000L);
+}
+
+static unsigned char timed_cmd(unsigned char phase,
+ unsigned char (*fn)(void),
+ unsigned char need_status) {
+ Stamp a;
+ Stamp b;
+ unsigned int ms;
+ unsigned char ok;
+ read_stamp(&a);
+ ok = fn();
+ read_stamp(&b);
+ ms = elapsed_ms(&a, &b);
+ last_cmd_ms = ms;
+ phase_ms[phase] = (unsigned int)(phase_ms[phase] + ms);
+ total_ms = (unsigned int)(total_ms + ms);
+ if (!ok) {
+ return 0u;
+ }
+ if (need_status && !status_ok()) {
+ return 0u;
+ }
+ return 1u;
+}
+
+static const WorkItem *current_item;
+static unsigned int current_len;
+
+static unsigned char wrap_open(void) { return dos_open(current_item->name); }
+static unsigned char wrap_info(void) { return dos_simple(CMD_FILE_INFO); }
+static unsigned char wrap_read2(void) { return dos_read2(); }
+static unsigned char wrap_seek2(void) { return dos_seek2(); }
+static unsigned char wrap_load(void) { return dos_load_reu(current_item, current_len); }
+static unsigned char wrap_close(void) { return dos_simple(CMD_CLOSE); }
+
+static unsigned char setup_ultimate_path(void) {
+ cmd_buf[0] = UCI_DOS_TARGET;
+ cmd_buf[1] = CMD_IDENTIFY;
+ if (!uci_cmd(2)) return 0u;
+ cmd_buf[0] = UCI_CTRL_TARGET;
+ cmd_buf[1] = CMD_DRVINFO;
+ cmd_buf[2] = 0u;
+ if (!uci_cmd(3)) return 0u;
+ if (!dos_cd("/") || !status_ok()) return 0u;
+ if (!dos_cd(image_dir) || !status_ok()) {
+ if (image_dir[0] != '/' || image_dir[1] == 0 ||
+ !dos_cd(image_dir + 1) || !status_ok()) {
+ return 0u;
+ }
+ }
+ if (!dos_mount() || !status_ok()) return 0u;
+ if (!dos_cd(image_name) || !status_ok()) {
+ if (!dos_cd(image_name) || !status_ok()) {
+ return 0u;
+ }
+ }
+ return 1u;
+}
+
+static unsigned char load_one(const WorkItem *it) {
+ unsigned int file_size;
+ unsigned int payload_len;
+ unsigned int hdr;
+ gotoxy(0, 8);
+ cprintf("file %-12s %02u/%02u ", it->name,
+ (unsigned char)((it - items) + 1), item_count);
+ current_item = it;
+ if (!timed_cmd(PH_OPEN, wrap_open, 1u)) goto fail;
+ if (!timed_cmd(PH_INFO, wrap_info, 0u) || !data_or_status_ok()) goto fail;
+ if (data_len < 4u || data_buf[2] != 0u || data_buf[3] != 0u) goto fail;
+ file_size = (unsigned int)data_buf[0] | ((unsigned int)data_buf[1] << 8);
+ if (file_size <= 2u) goto fail;
+ payload_len = (unsigned int)(file_size - 2u);
+ if (payload_len > it->max_len) {
+ if (it->kind == KIND_RS && payload_len <= 0x3A00u) {
+ payload_len = it->max_len;
+ } else {
+ goto fail;
+ }
+ }
+ if (!timed_cmd(PH_READ2, wrap_read2, 0u) || !data_or_status_ok()) goto fail;
+ if (data_len < 2u) goto fail;
+ hdr = (unsigned int)data_buf[0] | ((unsigned int)data_buf[1] << 8);
+ if (hdr != it->expected) goto fail;
+ if (!timed_cmd(PH_SEEK, wrap_seek2, 1u)) goto fail;
+ current_len = payload_len;
+ if (!timed_cmd(PH_LOAD, wrap_load, 1u)) goto fail;
+ {
+ unsigned int load_ms = last_cmd_ms;
+ if (load_ms > max_load_ms) {
+ max_load_ms = load_ms;
+ copy_token(max_load_name, sizeof(max_load_name), it->name);
+ }
+ }
+ if (!timed_cmd(PH_CLOSE, wrap_close, 0u)) goto fail_close_counted;
+ total_loaded_kb = (unsigned int)(total_loaded_kb + ((payload_len + 1023u) >> 10));
+ return 1u;
+fail:
+ ++failures;
+ (void)timed_cmd(PH_CLOSE, wrap_close, 0u);
+fail_close_counted:
+ gotoxy(0, 10);
+ cprintf("failed %-12s st:%02x%02x dl:%02u",
+ it->name, stat_buf[0], stat_buf[1], data_len);
+ return 0u;
+}
+
+static void show_summary(void) {
+ unsigned int header_ms = (unsigned int)(phase_ms[PH_READ2] + phase_ms[PH_SEEK]);
+ clrscr();
+ cprintf("uci timing load-all probe\r\n");
+ cprintf("items:%u apps:%u rs:%u rbmeta:%u fail:%u\r\n",
+ item_count, app_count, rs_count, rb_meta_count, failures);
+ cprintf("total:%u ms loaded:%u kb\r\n", total_ms, total_loaded_kb);
+ cprintf("open:%u info:%u read2:%u\r\n",
+ phase_ms[PH_OPEN], phase_ms[PH_INFO], phase_ms[PH_READ2]);
+ cprintf("seek:%u load:%u close:%u\r\n",
+ phase_ms[PH_SEEK], phase_ms[PH_LOAD], phase_ms[PH_CLOSE]);
+ cprintf("header tax:%u ms (%u files)\r\n", header_ms, item_count);
+ cprintf("avg tax/file:%u ms\r\n",
+ item_count ? (unsigned int)(header_ms / item_count) : 0u);
+ cprintf("max load phase:%u ms\r\n", max_load_ms);
+ cprintf("config path:%s\r\n", image_path);
+ cprintf("PROBE DONE\r\n");
+}
+
+void main(void) {
+ unsigned char i;
+
+ clrscr();
+ textcolor(COLOR_LIGHTGREEN);
+ cprintf("uci timing probe\r\n");
+ textcolor(COLOR_WHITE);
+ write_results(0u);
+ cprintf("reading apps.cfg...\r\n");
+ if (!load_cfg()) {
+ failures = 1u;
+ write_results(2u);
+ cprintf("config load failed len:%u\r\n", cfg_len);
+ return;
+ }
+ if (!parse_cfg()) {
+ failures = 1u;
+ write_results(3u);
+ cprintf("config parse failed len:%u path:%s\r\n", cfg_len, image_path);
+ return;
+ }
+ if (!split_image_path()) {
+ failures = 1u;
+ write_results(4u);
+ cprintf("config path failed len:%u path:%s\r\n", cfg_len, image_path);
+ return;
+ }
+ cprintf("cfg ok apps:%u items:%u\r\n", app_count, item_count);
+ if (!sysinfo_uci_detect()) {
+ cprintf("no uci detected\r\n");
+ failures = 1u;
+ write_results(3u);
+ return;
+ }
+ cprintf("uci base:%04x path:%s\r\n", sysinfo_uci_base(), image_path);
+ cprintf("mounting via ultimate dos...\r\n");
+ if (!setup_ultimate_path()) {
+ cprintf("ultimate path setup failed st:%02x%02x\r\n", stat_buf[0], stat_buf[1]);
+ failures = 1u;
+ write_results(4u);
+ return;
+ }
+ for (i = 0; i < item_count; ++i) {
+ (void)load_one(&items[i]);
+ write_results(0u);
+ }
+ write_results(1u);
+ show_summary();
+}
diff --git a/reurefactorlessonslearnt.md b/reurefactorlessonslearnt.md
index d15a178..841e462 100644
--- a/reurefactorlessonslearnt.md
+++ b/reurefactorlessonslearnt.md
@@ -1,5 +1,45 @@
# REU Refactor Lessons Learnt
+
+> **Current ReadyOS contract (2026-08-02):** Physical `Skip` is the ReadyOS
+> bank and `Skip+1` is the first dynamic bank. The launcher snapshot occupies
+> ReadyOS `$0000-$B5FF`; schema v5 occupies `$B600-$FFFF`, including the token
+> map at `$B740` and status at `$B840`. C64 app RAM is `$1000-$C5FF` (`$B600`),
+> and the resident 1 KB shim owns `$C600-$C9FF` with its public ABI at `$C800`.
+> Dated layouts and measurements below are retained as historical evidence.
+
+> **Checkpoint clarification:** the “final authority cleanup” and
+> “schema-v5 completion” entries immediately below describe the preceding
+> 512-byte-shim / physical-`Skip+1` checkpoint. Their implementation lessons
+> remain useful, but the bank placement and C64 RAM sizes are superseded by the
+> current 1 KB-shim / physical-`Skip` contract above.
+
+## 2026-08-02 final authority cleanup
+
+- ReadyShell's `$C7A0-$C7DF` / `$C7F0` diagnostic mirror was the last live
+ duplicate found in the reclaimed tail. Diagnostics now have one durable
+ source in the loader-assigned ReadyShell state bank; only a live cursor and
+ availability flag remain in BSS.
+- Five unconsumed shim preload trace stores into `$C007-$C00C` were retired,
+ and reserved entry `$C812` became a safe no-op. The exact 512-byte shim now
+ has 129 verifier-checked padding bytes, with a 42-byte largest run.
+- Full REU clients share `reu_mgr_dma.c` through zero-frame assembly aliases;
+ lightweight apps retain a standalone no-BSS byte helper. A unique assembler
+ basename is required so Make cannot regenerate it from the retained C
+ reference adapter as an intermediate.
+
+## 2026-08-01 Schema-v5 completion
+
+- Physical `Skip+1` is now the combined ReadyOS bank and single metadata
+ authority; it contains the launcher snapshot plus schema-v5 state.
+- The earlier `$C600-$C7FF` RAM mirror and separate control bank were useful
+ migration steps, but are superseded. Physical `Skip` is reclaimed as the
+ first dynamic bank and tokens use explicit mapping/status tables.
+- Focused micromodules prevented broad app BSS growth; the complete 24-map
+ comparison is in `agentworking/readyos-bank-refactor/headroom_comparison.md`.
+- The shim stayed exactly 512 bytes, but changing one instruction length proved
+ why byte-anchor verification is mandatory for every disk and cartridge build.
+
## 2026-06-02
- The refactor must be treated as a whole-system contract change. Old app,
diff --git a/run.sh b/run.sh
index 062e3a9..69f359b 100644
--- a/run.sh
+++ b/run.sh
@@ -93,6 +93,7 @@ CONFIG_OVERRIDE_RUN_FIRST=""
RUN_VERSION_TEXT=""
SKIP_BUILD=0
BUILD_ALL=0
+BUILD_ONLY=0
FOR_RELEASE=0
MODE=""
PARSE_TRACE_DEBUG=""
@@ -259,6 +260,7 @@ show_help() {
echo " --profile ID Select release profile (default: $DEFAULT_PROFILE)"
echo " --list-profiles List available profiles and exit"
echo " --build-all Build every release profile and exit"
+ echo " --build-only Build the selected profile and exit without launching VICE"
echo " --for-release Build without the rolling A..Z suffix in versioned artifacts"
echo " --skipbuild Skip automatic build before run"
echo " --force-artifacts-from-d71 Promote latest built dual-D71 SEQ/REL support files"
@@ -329,6 +331,10 @@ while [ $# -gt 0 ]; do
BUILD_ALL=1
shift
;;
+ --build-only)
+ BUILD_ONLY=1
+ shift
+ ;;
--for-release)
FOR_RELEASE=1
shift
@@ -452,6 +458,16 @@ if [ "$BUILD_ALL" -eq 1 ] && [ "$SKIP_BUILD" -eq 1 ]; then
exit 1
fi
+if [ "$BUILD_ONLY" -eq 1 ] && [ "$SKIP_BUILD" -eq 1 ]; then
+ echo "Error: --build-only cannot be combined with --skipbuild."
+ exit 1
+fi
+
+if [ "$BUILD_ALL" -eq 1 ] && [ "$BUILD_ONLY" -eq 1 ]; then
+ echo "Error: --build-all cannot be combined with --build-only."
+ exit 1
+fi
+
if [ "$FOR_RELEASE" -eq 1 ] && [ "$SKIP_BUILD" -eq 1 ]; then
echo "Error: --for-release cannot be combined with --skipbuild."
exit 1
@@ -739,6 +755,10 @@ case "${MODE:-}" in
;;
esac
+if [ "$BUILD_ONLY" -eq 1 ]; then
+ exit 0
+fi
+
case "${MODE:-}" in
help|-h|--help)
show_help
diff --git a/skills/readyos-stability-analyst/references/debug_surfaces.md b/skills/readyos-stability-analyst/references/debug_surfaces.md
index ce87209..4538307 100644
--- a/skills/readyos-stability-analyst/references/debug_surfaces.md
+++ b/skills/readyos-stability-analyst/references/debug_surfaces.md
@@ -7,12 +7,16 @@ Primary runtime capture source:
## RAM debug surfaces
- Screen buffer: `$0400-$07E7`
-- Boot preload markers: `$C007-$C00C`
+- The former boot preload markers at `$C007-$C00C` are retired; preload no
+ longer writes diagnostics into app snapshot RAM. Use launcher state, the
+ ReadyOS-bank audit page, and harness stage traces instead.
- Shim data: `$C820-$C83F`
- Historical shim debug ring storage: `$C980-$C99F`; overlaps current
`$C960-$C99F` logical REU setup code and must not be treated as active
persistent debug storage.
-- ReadyShell RAM ring: `$C7A0-$C7DF` with head at `$C7F0`
+- The former ReadyShell RAM ring at `$C7A0-$C7DF` / `$C7F0` is retired.
+ ReadyShell diagnostics are authoritative only in its loader-assigned REU
+ state bank.
- REU registers: `$DF00-$DF08`
- ReadyShell overlay window base:
- release/default (`READYSHELL_PARSE_TRACE_DEBUG=0`): `$8E00`
diff --git a/skills/readyos-stability-analyst/references/memory_contracts.md b/skills/readyos-stability-analyst/references/memory_contracts.md
index fee4ba5..7af8b92 100644
--- a/skills/readyos-stability-analyst/references/memory_contracts.md
+++ b/skills/readyos-stability-analyst/references/memory_contracts.md
@@ -6,29 +6,31 @@ Canonical sources:
## Critical RAM windows
- App runtime snapshot: `$1000-$C5FF` (`$B600` bytes)
-- REU metadata/system table: `$C600-$C7FF`
-- Shim resident region: `$C800-$C9FF`
+- Shim resident region: `$C600-$C9FF` (1 KB)
+- Shim expansion reserve: `$C600-$C7FF`; scalable state is authoritative in REU
+- Public shim ABI: `$C800-$C9FF`
- Hardware I/O: `$D000-$DFFF`
## Shim jump/data anchors
- Jump table starts at `$C800`
- Shim data window: `$C820-$C83F`
-- Core logical-bank state bytes: `$C834-$C838`
-- Physical REU region skip byte: `$C83B`
+- Current/target token and reserved legacy bytes: `$C834-$C83A`
+- Direct physical ReadyOS-bank byte: `$C83B`
## REU physical/logical bank contract
- `Start` means physical REU bank `READYOS_REU_BANK_SKIP`.
-- `Start+0` is the system/global bank.
-- `Start+1` is the launcher snapshot/resume bank for launcher token `0`.
-- `Start+2` is the first dynamic allocation bank; no launcher overlay owns that bank.
-- Logical app/resource bank `N > 0` maps through logical REU bank `0`'s
- `$2F00-$2FFF` lookup page. The default writer currently maps token `1` to
- `Start+2`, but the lookup page is authoritative for shim-facing app tokens.
-- The dynamic allocation pool begins at `Start+2`; allocation tables skip any bank already marked in use.
-- The shim bitmap width remains 24 logical bits; app ABI-visible bank numbers are unchanged.
+- `Start+0` (`Skip`) is the combined ReadyOS bank: launcher snapshot
+ `$0000-$B5FF` plus schema-v5 state `$B600-$FFFF`.
+- `Start+1` (`Skip+1`) is the first dynamic allocation candidate; no launcher
+ overlay or fixed app slot owns it.
+- Shim token `0` resolves directly to the ReadyOS bank. Tokens `N > 0` resolve
+ through the ReadyOS bank's `$B740-$B83F` lookup table.
+- Loaded/resumable status is authoritative at ReadyOS `$B840-$B93F`; the
+ retired `$C836-$C838` bitmap is reserved and must not drive navigation.
+- The dynamic allocator begins at `Start+1` and skips banks already marked in
+ use in the ReadyOS `$B640-$B73F` bank-type table.
- Physical REU size is launcher-owned. Banks beyond the detected physical end
- are marked `REU_UNAVAIL` in `$C600-$C6FF`, mirrored to logical REU bank `0`,
- and consumed by REU Viewer.
+ are marked `REU_UNAVAIL` in ReadyOS `$B640-$B73F` and reported by REU Viewer.
## ReadyShell overlay/resource contract
- `__HIMEM__ = $C600`
@@ -55,7 +57,7 @@ Canonical sources:
- The primitive allocator remains `src/lib/reu_mgr_alloc.c`; apps that do not
need ownership records do not pay for the owner-record writer.
- Owner-recorded runtime banks create `REUCB_DEP_KIND_APP_ALLOC` records in
- logical REU bank `0` at `$0A00`, carrying owner app id, slot id, physical
+ the ReadyOS rich-resource table at `$C240`, carrying owner app id, slot id, physical
bank, and a four-character tag.
- Launcher unload frees owner-recorded `REU_APP_ALLOC` banks for the selected
app; the shim does not participate.
diff --git a/src/apps/calcplus/calcplus.c b/src/apps/calcplus/calcplus.c
index 7c9b95a..2561989 100644
--- a/src/apps/calcplus/calcplus.c
+++ b/src/apps/calcplus/calcplus.c
@@ -185,7 +185,7 @@ static ResumeReadSegment calcplus_resume_read_segments[] = {
#define CALCPLUS_RESUME_SEG_COUNT \
((unsigned char)(sizeof(calcplus_resume_read_segments) / sizeof(calcplus_resume_read_segments[0])))
-/* ROM float bridge buffers in always-visible RAM (must stay below $C600). */
+/* ROM float bridge buffers live inside the app snapshot (below the $C800 shim). */
static unsigned char* const romfp_in = (unsigned char*)ROMFP_IN_ADDR;
static unsigned char* const romfp_a = (unsigned char*)ROMFP_A_ADDR;
static unsigned char* const romfp_b = (unsigned char*)ROMFP_B_ADDR;
diff --git a/src/apps/clipmgr/clipmgr.c b/src/apps/clipmgr/clipmgr.c
index 5b6732b..1abfb32 100644
--- a/src/apps/clipmgr/clipmgr.c
+++ b/src/apps/clipmgr/clipmgr.c
@@ -346,9 +346,7 @@ static void draw_status(void) {
}
static unsigned char clip_item_bank(unsigned char index) {
- unsigned char *entry;
- entry = CLIP_TABLE + ((unsigned int)index * 8);
- return entry[0];
+ return clip_get_bank(index);
}
static void show_message(const char *msg, unsigned char color) {
@@ -565,33 +563,6 @@ static unsigned char show_open_dialog(DirPageEntry *out_entry) {
}
}
-static unsigned char clip_insert_bank_item(unsigned char bank, unsigned int size) {
- unsigned char count;
- unsigned char *entry;
-
- count = *CLIP_COUNT;
- if (count >= CLIP_MAX_ITEMS) {
- return 1;
- }
-
- if (count > 0) {
- memmove(CLIP_TABLE + 8, CLIP_TABLE, (unsigned int)count * 8);
- }
-
- entry = CLIP_TABLE;
- entry[0] = bank;
- entry[1] = CLIP_TYPE_TEXT;
- entry[2] = (unsigned char)(size & 0xFF);
- entry[3] = (unsigned char)(size >> 8);
- entry[4] = 0;
- entry[5] = 0;
- entry[6] = 0;
- entry[7] = 0;
-
- *CLIP_COUNT = count + 1;
- return 0;
-}
-
static void free_staged_entries(unsigned char staged_count) {
while (staged_count > 0u) {
--staged_count;
@@ -625,7 +596,7 @@ static unsigned char file_load_raw_to_clipboard(const char *name, unsigned char
*truncated_out = 0;
truncated = 0;
- if (*CLIP_COUNT >= CLIP_MAX_ITEMS) {
+ if (clip_item_count() >= CLIP_MAX_ITEMS) {
return 2;
}
@@ -671,7 +642,7 @@ static unsigned char file_load_raw_to_clipboard(const char *name, unsigned char
cbm_close(LFN_FILE);
- if (clip_insert_bank_item(bank, total) != 0) {
+ if (clip_insert_bank_item(bank, CLIP_TYPE_TEXT, total) != 0) {
reu_free_bank(bank);
return 2;
}
@@ -694,7 +665,7 @@ static unsigned char file_load_bundle_open(unsigned char *loaded_count_out) {
*loaded_count_out = 0u;
entry_count = bundle_hdr[6];
- avail_slots = (unsigned char)(CLIP_MAX_ITEMS - *CLIP_COUNT);
+ avail_slots = (unsigned char)(CLIP_MAX_ITEMS - clip_item_count());
staged_count = 0u;
rc = LOAD_RC_OK;
@@ -760,7 +731,7 @@ static unsigned char file_load_bundle_open(unsigned char *loaded_count_out) {
while (staged_count > 0u) {
--staged_count;
- if (clip_insert_bank_item(staged_banks[staged_count],
+ if (clip_insert_bank_item(staged_banks[staged_count], CLIP_TYPE_TEXT,
staged_sizes[staged_count]) != 0u) {
reu_free_bank(staged_banks[staged_count]);
return LOAD_RC_IO;
diff --git a/src/apps/launcher/launcher.c b/src/apps/launcher/launcher.c
index 7af0166..882ce69 100644
--- a/src/apps/launcher/launcher.c
+++ b/src/apps/launcher/launcher.c
@@ -10,6 +10,9 @@
#include "../../lib/reu_control_bank.h"
#include "../../lib/reu_phys.h"
#include "../../generated/build_version.h"
+#ifndef LAUNCHER_DMA_LOAD
+#define LAUNCHER_DMA_LOAD 0
+#endif
#ifndef READYOS_LAUNCHER_VARIANT_EASYFLASH
#define READYOS_LAUNCHER_VARIANT_EASYFLASH 0
#endif
@@ -27,7 +30,7 @@
#include
/*---------------------------------------------------------------------------
- * Shim Interface (shim is at $C800-$C9FF, 512 bytes)
+ * Shim Interface (resident area is $C600-$C9FF; ABI is at $C800-$C9FF)
*---------------------------------------------------------------------------*/
/* Shim jump table addresses (at $C800) */
@@ -45,13 +48,12 @@
#define SHIM_APP_NAME ((char*)0xC824)
#define SHIM_CURRENT_BANK ((unsigned char*)0xC834) /* Currently running app's bank */
#define SHIM_LAST_SAVED ((unsigned char*)0xC835) /* Last app saved by return_to_launcher */
-#define SHIM_REU_BITMAP_LO ((unsigned char*)0xC836) /* Bitmap bits 0-7 */
-#define SHIM_REU_BITMAP_HI ((unsigned char*)0xC837) /* Bitmap bits 8-15 */
-#define SHIM_REU_BITMAP_XHI ((unsigned char*)0xC838) /* Bitmap bits 16-23 */
-#define SHIM_REU_BANK_SKIP ((unsigned char*)0xC83B) /* Physical REU banks skipped before ReadyOS */
+#define SHIM_READYOS_BANK ((unsigned char*)0xC83B) /* Direct physical ReadyOS bank */
#define SHIM_LAUNCHER_FLAGS ((unsigned char*)0xC83C) /* Launcher one-shot flags */
-#define SHIM_LOAD_DISK_DEV_IMM ((unsigned char*)0xC84D) /* A2 xx at $C84C */
-#define SHIM_PRELOAD_DEV_IMM ((unsigned char*)0xC89C) /* A2 xx at $C89B */
+#define SHIM_STORAGE_DRIVE ((unsigned char*)0xC839)
+#define SHIM_LOAD_END_LO ((unsigned char*)0xC830)
+#define SHIM_LOAD_END_HI ((unsigned char*)0xC831)
+#define KERNAL_BLNSW ((unsigned char*)0x00CC) /* nonzero disables cursor blink */
/* REU registers for direct access */
#define REU_COMMAND (*(unsigned char*)0xDF01)
@@ -79,7 +81,8 @@ void reu_control_bank_write_launcher_registry(
const unsigned char *app_rs_bank2,
const unsigned char *app_rs_bank3,
const unsigned char *app_rs_bank4,
- const unsigned char *apps_loaded);
+ const unsigned char *apps_loaded,
+ const unsigned int *app_sizes);
void reu_dma_stash(unsigned int c64_addr, unsigned char bank,
unsigned int reu_offset, unsigned int length);
#define REUCB_WRITER_LAUNCHER 1u
@@ -107,8 +110,12 @@ void reu_dma_stash(unsigned int c64_addr, unsigned char bank,
#define REU_INDICATOR 0x2A /* '*' in PETSCII screen code */
/* App catalog limits */
+#if LAUNCHER_DMA_LOAD
+#define APP_SLOT_CAPACITY 32
+#else
#define APP_SLOT_CAPACITY 64
-#define MAX_APPS (APP_SLOT_CAPACITY + 1) /* optional slot 0 + 64 app slots */
+#endif
+#define MAX_APPS (APP_SLOT_CAPACITY + 1) /* optional slot 0 + app slots */
#define MAX_FILE_LEN 12 /* shim filename buffer is 12 bytes */
#define MAX_NAME_LEN 31
#define MAX_DESC_LEN 38
@@ -118,17 +125,8 @@ void reu_dma_stash(unsigned int c64_addr, unsigned char bank,
#define APP_MANIFEST_LFN 13
#define APP_MANIFEST_PREFIX "app."
-#define REU_ALLOC_TABLE ((unsigned char*)0xC600)
-#define REU_FREE 0
-#define REU_APP_STATE 1
-#define REU_RS_CACHE 5
-#define REU_RESERVED 4
-#define REU_RS_SCRATCH 13
-#define REU_RB_CORE 14
-#define REU_RB_CODE 15
-#define REU_TOTAL_BANKS 256
#define REU_SNAPSHOT_LOGICAL_MIN 1
-#define REU_SNAPSHOT_LOGICAL_SCAN_MAX 223
+#define REU_SNAPSHOT_LOGICAL_SCAN_MAX 254
#define APP_RESOURCE_NONE 0
#define APP_RESOURCE_READYSHELL_OVL 1
@@ -148,8 +146,17 @@ void reu_dma_stash(unsigned int c64_addr, unsigned char bank,
#define READYSHELL_META_VALID_LO 0xFFu
#define READYSHELL_META_VALID_HI 0x01u
#define READYSHELL_STATE_BANK_CACHE ((unsigned char*)0xCFF2)
-#define RESOURCE_IO_CHUNK 128
-
+#ifndef LAUNCHER_DMA_LOAD_READYSHELL
+#define LAUNCHER_DMA_LOAD_READYSHELL 1
+#endif
+#ifndef LAUNCHER_DMA_LOAD_RESOURCES
+#define LAUNCHER_DMA_LOAD_RESOURCES 1
+#endif
+#define RESOURCE_IO_CHUNK 96
+#define LAUNCHER_C64U_IMAGE_PATH_LEN 95
+#define LAUNCHER_C64U_IMAGE_DIR_LEN 63
+#define LAUNCHER_C64U_IMAGE_NAME_LEN 47
+#define LAUNCHER_C64U_IMAGE_PATH_DEFAULT "/usb1/readyos.d81"
#ifndef LAUNCHER_CFG_VERBOSE
#define LAUNCHER_CFG_VERBOSE 0
#endif
@@ -225,15 +232,16 @@ void reu_dma_stash(unsigned int c64_addr, unsigned char bank,
#endif
/* REU bank assignments */
-#define REU_BANK_LAUNCHER 0 /* Logical launcher bank; physical bank is skip + 1 */
-#define REU_LAUNCHER_PHYSICAL() ((unsigned char)(*SHIM_REU_BANK_SKIP + 1u))
-#define REU_LOGICAL_TO_PHYSICAL(bank) \
- ((unsigned char)(*SHIM_REU_BANK_SKIP + \
- (((unsigned char)(bank) == 0u) ? 1u : (1u + (unsigned char)(bank)))))
-#define LAUNCHER_RESUME_SCHEMA 8
+#define REU_BANK_LAUNCHER 0 /* Token 0 is the launcher in the ReadyOS bank */
+#define LAUNCHER_RESUME_SCHEMA 11
+#if !READYOS_LAUNCHER_VARIANT_EASYFLASH && LAUNCHER_DMA_LOAD
+#define LAUNCHER_RESUME_SEG_COUNT 2
+#else
+#define LAUNCHER_RESUME_SEG_COUNT 1
+#endif
/* App save size - must include code + data + BSS */
-#define APP_SAVE_SIZE 0xB600 /* $1000-$C5FF (46KB) */
+#define APP_SAVE_SIZE 0xB600 /* $1000-$C5FF (45.5KB) */
/* Valid app load range from cfg/ready_app.cfg: $1000-$C5FF */
#define APP_LOAD_START 0x1000
#define APP_LOAD_END_EXCL 0xC600
@@ -279,11 +287,42 @@ static unsigned char launcher_rs_meta_buf[READYSHELL_META_LEN];
static unsigned char launcher_rsrc_rec_buf[REUCB_RSRC_REC_SIZE];
static unsigned char launcher_dep_line_buf[REUCB_DEP_LINE_SIZE];
#if !READYOS_LAUNCHER_VARIANT_EASYFLASH
-static unsigned char launcher_resource_buf[RESOURCE_IO_CHUNK];
+unsigned char launcher_resource_buf[RESOURCE_IO_CHUNK];
static FileDialogState launcher_file_dialog;
static DirPageEntry launcher_manifest_entry;
static char launcher_manifest_open_spec[24];
static char launcher_resource_open_spec[18];
+#if LAUNCHER_DMA_LOAD
+#define LAUNCHER_DMA_ERR_NO_UCI 0x01u
+#define LAUNCHER_DMA_ERR_PATH_MIN 0x08u
+#define LAUNCHER_DMA_ERR_PATH_MAX 0x10u
+extern unsigned char launcher_uci_dma_detect(void);
+extern unsigned char launcher_uci_dma_load_prg(void);
+extern void launcher_uci_dma_quiesce(void);
+extern void launcher_uci_dma_clear_stage(void);
+extern unsigned char launcher_uci_dma_available;
+extern const char *launcher_uci_dma_name;
+extern unsigned char launcher_uci_dma_reu_bank;
+extern unsigned int launcher_uci_dma_reu_offset;
+extern unsigned int launcher_uci_dma_max_len;
+extern unsigned int launcher_uci_dma_expected_load_addr;
+extern unsigned int launcher_uci_dma_loaded_size;
+extern unsigned char launcher_uci_dma_last_error;
+extern unsigned char launcher_uci_dma_dbg_stat0;
+extern unsigned char launcher_uci_dma_dbg_stat1;
+extern const char *launcher_uci_dma_image_dir;
+extern const char *launcher_uci_dma_image_name;
+extern const char *launcher_uci_dma_mount_name;
+extern unsigned char launcher_uci_dma_assume_mounted;
+static char launcher_c64u_image_path[LAUNCHER_C64U_IMAGE_PATH_LEN + 1];
+static const char launcher_dma_root_dir[] = "/";
+static char launcher_dma_name_buf[MAX_FILE_LEN + 1];
+static unsigned char launcher_dma_available;
+static unsigned char launcher_dma_probe_ok;
+static unsigned char launcher_dma_used;
+static unsigned char launcher_dma_image_ready;
+static volatile unsigned char launcher_dma_breadcrumb;
+#endif
#endif
/* Menu state */
@@ -391,22 +430,72 @@ static void launcher_set_startup_suppressed(void) {
}
static unsigned char launcher_logical_to_physical(unsigned char logical_bank) {
- unsigned int physical;
+ unsigned char status;
- physical = (unsigned int)(*SHIM_REU_BANK_SKIP) + 1u + logical_bank;
- if (physical > 255u) {
- return 0xFFu;
+ if (logical_bank == 0u) {
+ return *SHIM_READYOS_BANK;
}
- if (REU_ALLOC_TABLE[physical] == REU_UNAVAIL) {
+ status = readyos_bank_read_byte((unsigned int)(REUCB_TOKEN_STATUS_OFF +
+ logical_bank));
+ if (!(status & REUCB_TOKEN_VALID)) {
return 0xFFu;
}
- return (unsigned char)physical;
+ return readyos_bank_read_byte((unsigned int)(REUCB_SHIM_LOOKUP_OFF +
+ logical_bank));
+}
+
+static void launcher_bind_snapshot_token(unsigned char token,
+ unsigned char physical,
+ unsigned char loaded) {
+ unsigned char status;
+
+ readyos_bank_write_byte((unsigned int)(REUCB_SHIM_LOOKUP_OFF + token),
+ physical);
+ status = REUCB_TOKEN_VALID;
+ if (loaded) {
+ status |= (REUCB_TOKEN_LOADED | REUCB_TOKEN_RESUMABLE);
+ }
+ readyos_bank_write_byte((unsigned int)(REUCB_TOKEN_STATUS_OFF + token),
+ status);
+}
+
+static void launcher_set_snapshot_loaded(unsigned char token,
+ unsigned char loaded) {
+ unsigned char status;
+
+ if (token == 0u) {
+ return;
+ }
+ status = readyos_bank_read_byte((unsigned int)(REUCB_TOKEN_STATUS_OFF + token));
+ if (!(status & REUCB_TOKEN_VALID)) {
+ return;
+ }
+ if (loaded) {
+ status |= (REUCB_TOKEN_LOADED | REUCB_TOKEN_RESUMABLE);
+ } else {
+ status &= (unsigned char)~(REUCB_TOKEN_LOADED | REUCB_TOKEN_RESUMABLE);
+ }
+ readyos_bank_write_byte((unsigned int)(REUCB_TOKEN_STATUS_OFF + token), status);
+}
+
+static void launcher_set_bank_type(unsigned char bank, unsigned char type) {
+ readyos_bank_write_byte((unsigned int)(REUCB_BANK_TYPE_OFF + bank), type);
+}
+
+static unsigned char launcher_bank_type(unsigned char bank) {
+ return readyos_bank_read_byte((unsigned int)(REUCB_BANK_TYPE_OFF + bank));
+}
+
+static void launcher_free_physical_bank(unsigned char bank) {
+ if (bank >= REU_FIRST_DYNAMIC_PHYSICAL() && bank != *SHIM_READYOS_BANK) {
+ launcher_set_bank_type(bank, REU_FREE);
+ }
}
#if READYOS_LAUNCHER_VARIANT_EASYFLASH
static void launcher_mark_bank_if_available(unsigned char bank, unsigned char type) {
- if (REU_ALLOC_TABLE[bank] != REU_UNAVAIL) {
- REU_ALLOC_TABLE[bank] = type;
+ if (launcher_bank_type(bank) != REU_UNAVAIL) {
+ readyos_bank_write_byte((unsigned int)(REUCB_BANK_TYPE_OFF + bank), type);
}
}
#endif
@@ -426,6 +515,7 @@ static unsigned char launcher_catalog_uses_bank(unsigned char bank,
static unsigned char launcher_alloc_snapshot_bank(unsigned char index) {
unsigned char bank;
unsigned char physical;
+ unsigned int physical_scan;
if (!launcher_is_app_slot(index)) {
return 0;
@@ -437,19 +527,30 @@ static unsigned char launcher_alloc_snapshot_bank(unsigned char index) {
for (bank = REU_SNAPSHOT_LOGICAL_MIN;
bank <= REU_SNAPSHOT_LOGICAL_SCAN_MAX;
++bank) {
- physical = launcher_logical_to_physical(bank);
- if (physical == 0xFFu) {
- break;
- }
if (launcher_catalog_uses_bank(bank, index)) {
continue;
}
- if (REU_ALLOC_TABLE[physical] == REU_FREE) {
- app_banks[index] = bank;
- REU_ALLOC_TABLE[physical] = REU_APP_STATE;
- launcher_mirror_reu_control();
- return bank;
+ if (readyos_bank_read_byte((unsigned int)(REUCB_TOKEN_STATUS_OFF + bank)) &
+ REUCB_TOKEN_VALID) {
+ continue;
}
+ for (physical_scan = REU_FIRST_DYNAMIC_PHYSICAL();
+ physical_scan < 255u;
+ ++physical_scan) {
+ physical = (unsigned char)physical_scan;
+ if (physical == *SHIM_READYOS_BANK) {
+ continue;
+ }
+ if (launcher_bank_type(physical) == REU_FREE) {
+ app_banks[index] = bank;
+ readyos_bank_write_byte((unsigned int)(REUCB_BANK_TYPE_OFF + physical),
+ REU_APP_STATE);
+ launcher_bind_snapshot_token(bank, physical, 0u);
+ launcher_mirror_reu_control();
+ return bank;
+ }
+ }
+ break;
}
return 0;
@@ -495,29 +596,22 @@ static unsigned char launcher_app_to_menu_index(unsigned char app_index) {
return (unsigned char)(app_index + launcher_menu_extra_count());
}
-/*---------------------------------------------------------------------------
- * Shim bitmap helpers ($C836-$C838)
- *---------------------------------------------------------------------------*/
-static unsigned char shim_bitmap_has_bank(unsigned char bank) {
- if (bank < 8) {
- return (unsigned char)(*SHIM_REU_BITMAP_LO & (unsigned char)(1U << bank));
- }
- if (bank < 16) {
- return (unsigned char)(*SHIM_REU_BITMAP_HI & (unsigned char)(1U << (bank - 8)));
- }
- if (bank < 24) {
- return (unsigned char)(*SHIM_REU_BITMAP_XHI & (unsigned char)(1U << (bank - 16)));
- }
- return 0;
-}
+static void launcher_mark_loaded_snapshot_banks(void) {
+ unsigned char i;
+ unsigned char bank;
+ unsigned char physical;
-static void shim_bitmap_clear_bank(unsigned char bank) {
- if (bank < 8) {
- *SHIM_REU_BITMAP_LO &= (unsigned char)~(unsigned char)(1U << bank);
- } else if (bank < 16) {
- *SHIM_REU_BITMAP_HI &= (unsigned char)~(unsigned char)(1U << (bank - 8));
- } else if (bank < 24) {
- *SHIM_REU_BITMAP_XHI &= (unsigned char)~(unsigned char)(1U << (bank - 16));
+ for (i = launcher_first_app_index(); i < app_count; ++i) {
+ bank = app_banks[i];
+ if (bank == 0u || !apps_loaded[i]) {
+ continue;
+ }
+ physical = launcher_logical_to_physical(bank);
+ if (physical != 0xFFu) {
+ readyos_bank_write_byte((unsigned int)(REUCB_BANK_TYPE_OFF + physical),
+ REU_APP_STATE);
+ launcher_set_snapshot_loaded(bank, 1u);
+ }
}
}
@@ -533,14 +627,15 @@ static void launcher_free_snapshot_bank(unsigned char index) {
if (bank == 0u) {
return;
}
- shim_bitmap_clear_bank(bank);
+ launcher_set_snapshot_loaded(bank, 0u);
if (*SHIM_LAST_SAVED == bank) {
*SHIM_LAST_SAVED = 0xFFu;
}
physical = launcher_logical_to_physical(bank);
if (physical != 0xFFu) {
- REU_ALLOC_TABLE[physical] = REU_FREE;
+ launcher_free_physical_bank(physical);
}
+ readyos_bank_write_byte((unsigned int)(REUCB_TOKEN_STATUS_OFF + bank), 0u);
launcher_free_app_resources(index);
app_banks[index] = 0u;
apps_loaded[index] = 0u;
@@ -550,43 +645,34 @@ static void launcher_free_snapshot_bank(unsigned char index) {
#endif
/*---------------------------------------------------------------------------
- * Sync apps_loaded[] from shim's reu_bitmap ($C836-$C838)
- * The shim updates reu_bitmap whenever an app is stashed to REU,
- * so this reflects the actual REU contents.
+ * Sync apps_loaded[] from the authoritative ReadyOS-bank token-status table.
+ * The shim commits LOADED|RESUMABLE after every successful snapshot stash.
*---------------------------------------------------------------------------*/
-static void sync_from_reu_bitmap(void) {
+static void sync_from_readyos_state(void) {
unsigned char i;
unsigned char bank;
unsigned char last_saved;
- /* Resilience: if return_to_launcher recorded a saved bank but bitmap
- * wasn't updated (e.g., interrupted path), heal bitmap from last_saved. */
+ /* Compatibility resilience for shims which only recorded last_saved. */
last_saved = *SHIM_LAST_SAVED;
- if (last_saved < 24 && launcher_catalog_uses_bank(last_saved, 0xFFu)) {
- if (last_saved < 8) {
- *SHIM_REU_BITMAP_LO |= (unsigned char)(1U << last_saved);
- } else if (last_saved < 16) {
- *SHIM_REU_BITMAP_HI |= (unsigned char)(1U << (last_saved - 8));
- } else {
- *SHIM_REU_BITMAP_XHI |= (unsigned char)(1U << (last_saved - 16));
- }
+ if (last_saved != 0xFFu && launcher_catalog_uses_bank(last_saved, 0xFFu)) {
+ launcher_set_snapshot_loaded(last_saved, 1u);
}
for (i = launcher_first_app_index(); i < app_count; ++i) {
bank = app_banks[i];
if (bank != 0) {
- if (bank < 24u && shim_bitmap_has_bank(bank)) {
- apps_loaded[i] = 1;
- app_sizes[i] = APP_SAVE_SIZE;
- } else if (bank >= 24u && last_saved == bank) {
+ if (readyos_bank_read_byte((unsigned int)(REUCB_TOKEN_STATUS_OFF + bank)) &
+ REUCB_TOKEN_LOADED) {
apps_loaded[i] = 1;
app_sizes[i] = APP_SAVE_SIZE;
- } else if (bank < 24u) {
+ } else {
apps_loaded[i] = 0;
app_sizes[i] = 0;
}
}
}
+ launcher_mark_loaded_snapshot_banks();
/* Clear the last_saved flag - we've synced state */
*SHIM_LAST_SAVED = 0xFF;
@@ -595,50 +681,15 @@ static void sync_from_reu_bitmap(void) {
/*---------------------------------------------------------------------------
* Slot contract helpers
*---------------------------------------------------------------------------*/
-static void compute_required_slot_bitmap(unsigned char *expected_lo,
- unsigned char *expected_hi,
- unsigned char *expected_xhi) {
- unsigned char i;
- unsigned char bank;
- unsigned char lo = 0;
- unsigned char hi = 0;
- unsigned char xhi = 0;
-
- for (i = launcher_first_app_index(); i < app_count; ++i) {
- bank = app_banks[i];
- if (bank == 0u) {
- continue;
- }
- if (bank < 8) {
- lo |= (unsigned char)(1U << bank);
- } else if (bank < 16) {
- hi |= (unsigned char)(1U << (bank - 8));
- } else if (bank < 24) {
- xhi |= (unsigned char)(1U << (bank - 16));
- }
- }
-
- *expected_lo = lo;
- *expected_hi = hi;
- *expected_xhi = xhi;
-}
-
static unsigned char required_slots_loaded(void) {
- unsigned char expected_lo;
- unsigned char expected_hi;
- unsigned char expected_xhi;
unsigned char i;
- compute_required_slot_bitmap(&expected_lo, &expected_hi, &expected_xhi);
- if (((*SHIM_REU_BITMAP_LO & expected_lo) != expected_lo) ||
- ((*SHIM_REU_BITMAP_HI & expected_hi) != expected_hi) ||
- ((*SHIM_REU_BITMAP_XHI & expected_xhi) != expected_xhi)) {
- return 0u;
- }
-
for (i = launcher_first_app_index(); i < app_count; ++i) {
if (launcher_is_app_slot(i) &&
- (app_banks[i] == 0u || !apps_loaded[i])) {
+ (app_banks[i] == 0u || !apps_loaded[i] ||
+ !(readyos_bank_read_byte((unsigned int)(REUCB_TOKEN_STATUS_OFF +
+ app_banks[i])) &
+ REUCB_TOKEN_LOADED))) {
return 0u;
}
}
@@ -1103,6 +1154,15 @@ static void catalog_init_defaults(void) {
launcher_variant_name[0] = 0;
launcher_variant_boot_name[0] = 0;
launcher_runappfirst_prg[0] = 0;
+#if !READYOS_LAUNCHER_VARIANT_EASYFLASH && LAUNCHER_DMA_LOAD
+ copy_text_limit(launcher_c64u_image_path, sizeof(launcher_c64u_image_path),
+ LAUNCHER_C64U_IMAGE_PATH_DEFAULT);
+ launcher_dma_available = 0u;
+ launcher_dma_used = 0u;
+ launcher_dma_image_ready = 0u;
+ launcher_uci_dma_assume_mounted = 0u;
+ launcher_dma_breadcrumb = 0u;
+#endif
launcher_notice[0] = 0;
launcher_notice_color = TUI_COLOR_GRAY3;
copy_text_limit(launcher_variant_name, sizeof(launcher_variant_name), "readyos");
@@ -1123,7 +1183,7 @@ static void catalog_rebind_views(void) {
static void launcher_resume_save(unsigned char selected,
unsigned char scroll_offset,
unsigned char suppress_startup_once) {
- static ResumeWriteSegment segs[15];
+ static ResumeWriteSegment segs[LAUNCHER_RESUME_SEG_COUNT];
if (!resume_ready) {
return;
@@ -1132,103 +1192,52 @@ static void launcher_resume_save(unsigned char selected,
launcher_resume_blob.selected = selected;
launcher_resume_blob.scroll_offset = scroll_offset;
launcher_resume_blob.suppress_startup_once = suppress_startup_once;
+#if !READYOS_LAUNCHER_VARIANT_EASYFLASH && LAUNCHER_DMA_LOAD
+ launcher_resume_blob.reserved = launcher_dma_used;
+#else
launcher_resume_blob.reserved = 0;
+#endif
segs[0].ptr = &launcher_resume_blob;
segs[0].len = sizeof(launcher_resume_blob);
- segs[1].ptr = &app_banks[0];
- segs[1].len = sizeof(app_banks);
- segs[2].ptr = &app_drives[0];
- segs[2].len = sizeof(app_drives);
- segs[3].ptr = &app_default_slots[0];
- segs[3].len = sizeof(app_default_slots);
- segs[4].ptr = &app_count;
- segs[4].len = sizeof(app_count);
- segs[5].ptr = &launcher_cfg_load_all_to_reu;
- segs[5].len = sizeof(launcher_cfg_load_all_to_reu);
- segs[6].ptr = &launcher_variant_name[0];
- segs[6].len = sizeof(launcher_variant_name);
- segs[7].ptr = &launcher_variant_boot_name[0];
- segs[7].len = sizeof(launcher_variant_boot_name);
- segs[8].ptr = &launcher_runappfirst_prg[0];
- segs[8].len = sizeof(launcher_runappfirst_prg);
- segs[9].ptr = &app_resource_sets[0];
- segs[9].len = sizeof(app_resource_sets);
- segs[10].ptr = &app_resource_loaded[0];
- segs[10].len = sizeof(app_resource_loaded);
- segs[11].ptr = &app_rs_bank1[0];
- segs[11].len = sizeof(app_rs_bank1);
- segs[12].ptr = &app_rs_bank2[0];
- segs[12].len = sizeof(app_rs_bank2);
- segs[13].ptr = &app_rs_bank3[0];
- segs[13].len = sizeof(app_rs_bank3);
- segs[14].ptr = &app_rs_bank4[0];
- segs[14].len = sizeof(app_rs_bank4);
- (void)resume_save_segments(segs, 15);
+#if !READYOS_LAUNCHER_VARIANT_EASYFLASH && LAUNCHER_DMA_LOAD
+ segs[1].ptr = &launcher_c64u_image_path[0];
+ segs[1].len = sizeof(launcher_c64u_image_path);
+#endif
+ (void)resume_save_segments(segs, LAUNCHER_RESUME_SEG_COUNT);
}
static unsigned char launcher_resume_restore(unsigned char *out_selected,
unsigned char *out_scroll_offset,
unsigned char *out_suppress_startup_once) {
unsigned int payload_len = 0;
- static ResumeReadSegment segs[15];
+ static ResumeReadSegment segs[LAUNCHER_RESUME_SEG_COUNT];
if (!resume_ready) {
return 0;
}
segs[0].ptr = &launcher_resume_blob;
segs[0].len = sizeof(launcher_resume_blob);
- segs[1].ptr = &app_banks[0];
- segs[1].len = sizeof(app_banks);
- segs[2].ptr = &app_drives[0];
- segs[2].len = sizeof(app_drives);
- segs[3].ptr = &app_default_slots[0];
- segs[3].len = sizeof(app_default_slots);
- segs[4].ptr = &app_count;
- segs[4].len = sizeof(app_count);
- segs[5].ptr = &launcher_cfg_load_all_to_reu;
- segs[5].len = sizeof(launcher_cfg_load_all_to_reu);
- segs[6].ptr = &launcher_variant_name[0];
- segs[6].len = sizeof(launcher_variant_name);
- segs[7].ptr = &launcher_variant_boot_name[0];
- segs[7].len = sizeof(launcher_variant_boot_name);
- segs[8].ptr = &launcher_runappfirst_prg[0];
- segs[8].len = sizeof(launcher_runappfirst_prg);
- segs[9].ptr = &app_resource_sets[0];
- segs[9].len = sizeof(app_resource_sets);
- segs[10].ptr = &app_resource_loaded[0];
- segs[10].len = sizeof(app_resource_loaded);
- segs[11].ptr = &app_rs_bank1[0];
- segs[11].len = sizeof(app_rs_bank1);
- segs[12].ptr = &app_rs_bank2[0];
- segs[12].len = sizeof(app_rs_bank2);
- segs[13].ptr = &app_rs_bank3[0];
- segs[13].len = sizeof(app_rs_bank3);
- segs[14].ptr = &app_rs_bank4[0];
- segs[14].len = sizeof(app_rs_bank4);
- if (!resume_load_segments(segs, 15, &payload_len)) {
+#if !READYOS_LAUNCHER_VARIANT_EASYFLASH && LAUNCHER_DMA_LOAD
+ segs[1].ptr = &launcher_c64u_image_path[0];
+ segs[1].len = sizeof(launcher_c64u_image_path);
+#endif
+ if (!resume_load_segments(segs, LAUNCHER_RESUME_SEG_COUNT, &payload_len)) {
return 0;
}
- if (payload_len != (sizeof(launcher_resume_blob) +
- sizeof(app_banks) +
- sizeof(app_drives) +
- sizeof(app_default_slots) +
- sizeof(app_count) +
- sizeof(launcher_cfg_load_all_to_reu) +
- sizeof(launcher_variant_name) +
- sizeof(launcher_variant_boot_name) +
- sizeof(launcher_runappfirst_prg) +
- sizeof(app_resource_sets) +
- sizeof(app_resource_loaded) +
- sizeof(app_rs_bank1) +
- sizeof(app_rs_bank2) +
- sizeof(app_rs_bank3) +
- sizeof(app_rs_bank4))) {
+ if (payload_len != (sizeof(launcher_resume_blob)
+#if !READYOS_LAUNCHER_VARIANT_EASYFLASH && LAUNCHER_DMA_LOAD
+ + sizeof(launcher_c64u_image_path)
+#endif
+ )) {
return 0;
}
catalog_rebind_views();
- if (out_selected != 0 && launcher_resume_blob.selected < launcher_menu_count()) {
+ /* app_count is still at its minimal pre-registry value here. Preserve
+ * the raw selection and validate it after the authoritative ReadyOS app
+ * registry has restored the real menu shape in launcher_init(). */
+ if (out_selected != 0) {
*out_selected = launcher_resume_blob.selected;
}
if (out_scroll_offset != 0) {
@@ -1449,6 +1458,9 @@ static unsigned char load_catalog_from_embedded(unsigned char *detail_a,
return err;
}
app_banks[(unsigned char)(app_count - 1)] = readyos_easyflash_app_banks[i];
+ launcher_bind_snapshot_token(readyos_easyflash_app_banks[i],
+ readyos_easyflash_app_physical_banks[i],
+ 1u);
}
*detail_a = 0;
@@ -1552,6 +1564,11 @@ static unsigned char load_catalog_from_disk(unsigned char *detail_a,
return err;
}
}
+#if LAUNCHER_DMA_LOAD
+ } else if (strcmp(key, "c64u_image_path") == 0) {
+ copy_text_limit(launcher_c64u_image_path,
+ sizeof(launcher_c64u_image_path), value);
+#endif
}
}
continue;
@@ -1817,11 +1834,85 @@ static void set_shim_reu(unsigned char bank, unsigned int size) {
}
/*---------------------------------------------------------------------------
- * Helper: Patch shim load/preload device for per-app drive
+ * Helper: Set the shim-global storage drive used by load and preload
*---------------------------------------------------------------------------*/
static void set_shim_drive(unsigned char drive) {
- *SHIM_LOAD_DISK_DEV_IMM = drive;
- *SHIM_PRELOAD_DEV_IMM = drive;
+ *SHIM_STORAGE_DRIVE = drive;
+}
+
+static void launcher_publish_settings(void) {
+ unsigned char i;
+
+ memset(catalog_text_buf, 0, REUCB_SETTINGS_SIZE);
+ catalog_text_buf[REUCB_SETTINGS_OFF_MAGIC0] = REUCB_SETTINGS_MAGIC0;
+ catalog_text_buf[REUCB_SETTINGS_OFF_MAGIC1] = REUCB_SETTINGS_MAGIC1;
+ catalog_text_buf[REUCB_SETTINGS_OFF_VERSION] = REUCB_SETTINGS_VERSION;
+ catalog_text_buf[REUCB_SETTINGS_OFF_FIRST_APP] = launcher_first_app_index();
+ catalog_text_buf[REUCB_SETTINGS_OFF_APP_COUNT] = app_count;
+ catalog_text_buf[REUCB_SETTINGS_OFF_LOAD_ALL] = launcher_cfg_load_all_to_reu;
+ for (i = 0u; i < (unsigned char)(REUCB_SETTINGS_VARIANT_SIZE - 1u) &&
+ launcher_variant_name[i] != 0; ++i) {
+ catalog_text_buf[(unsigned char)(REUCB_SETTINGS_OFF_VARIANT + i)] =
+ launcher_variant_name[i];
+ }
+ readyos_bank_write(REUCB_SETTINGS_OFF, catalog_text_buf, REUCB_SETTINGS_SIZE);
+}
+
+static unsigned char launcher_restore_registry_from_readyos(void) {
+ unsigned char i;
+ unsigned char app_id;
+ unsigned char first;
+ unsigned char restored_count;
+
+ readyos_bank_read(REUCB_SETTINGS_OFF, catalog_text_buf, REUCB_SETTINGS_SIZE);
+ if ((unsigned char)catalog_text_buf[REUCB_SETTINGS_OFF_MAGIC0] !=
+ REUCB_SETTINGS_MAGIC0 ||
+ (unsigned char)catalog_text_buf[REUCB_SETTINGS_OFF_MAGIC1] !=
+ REUCB_SETTINGS_MAGIC1 ||
+ (unsigned char)catalog_text_buf[REUCB_SETTINGS_OFF_VERSION] !=
+ REUCB_SETTINGS_VERSION) {
+ return 0u;
+ }
+ first = (unsigned char)catalog_text_buf[REUCB_SETTINGS_OFF_FIRST_APP];
+ restored_count = (unsigned char)catalog_text_buf[REUCB_SETTINGS_OFF_APP_COUNT];
+ if (first != launcher_first_app_index() || restored_count < first ||
+ restored_count > MAX_APPS ||
+ (unsigned char)(restored_count - first) > APP_SLOT_CAPACITY) {
+ return 0u;
+ }
+
+ app_count = restored_count;
+ launcher_cfg_load_all_to_reu =
+ (unsigned char)catalog_text_buf[REUCB_SETTINGS_OFF_LOAD_ALL];
+ copy_text_limit(launcher_variant_name, sizeof(launcher_variant_name),
+ &catalog_text_buf[REUCB_SETTINGS_OFF_VARIANT]);
+ copy_text_limit(launcher_variant_boot_name,
+ sizeof(launcher_variant_boot_name), launcher_variant_name);
+ launcher_runappfirst_prg[0] = 0;
+
+ for (i = first; i < app_count; ++i) {
+ app_id = (unsigned char)(i - first);
+ readyos_bank_read((unsigned int)(REUCB_APP_REG_OFF +
+ ((unsigned int)app_id * REUCB_APP_REG_SIZE)),
+ launcher_rsrc_rec_buf, REUCB_APP_REG_SIZE);
+ app_banks[i] = launcher_rsrc_rec_buf[REUCB_APP_REC_TOKEN];
+ app_drives[i] = launcher_rsrc_rec_buf[REUCB_APP_REC_DRIVE];
+ app_default_slots[i] = launcher_rsrc_rec_buf[REUCB_APP_REC_HOTKEY];
+ app_resource_sets[i] = launcher_rsrc_rec_buf[REUCB_APP_REC_RSRC_SET];
+ app_resource_loaded[i] = launcher_rsrc_rec_buf[REUCB_APP_REC_RSRC_READY];
+ app_rs_bank1[i] = launcher_rsrc_rec_buf[REUCB_APP_REC_RSRC1];
+ app_rs_bank2[i] = launcher_rsrc_rec_buf[REUCB_APP_REC_RSRC2];
+ app_rs_bank3[i] = launcher_rsrc_rec_buf[REUCB_APP_REC_RSRC3];
+ app_rs_bank4[i] = launcher_rsrc_rec_buf[REUCB_APP_REC_RSRC4];
+ apps_loaded[i] = (unsigned char)(
+ (launcher_rsrc_rec_buf[REUCB_APP_REC_FLAGS] &
+ REUCB_APP_FLAG_LOADED) != 0u);
+ app_sizes[i] =
+ (unsigned int)launcher_rsrc_rec_buf[REUCB_APP_REC_SIZE_LO] |
+ ((unsigned int)launcher_rsrc_rec_buf[REUCB_APP_REC_SIZE_HI] << 8);
+ }
+ catalog_rebind_views();
+ return 1u;
}
static void launcher_mirror_reu_control(void) {
@@ -1838,7 +1929,9 @@ static void launcher_mirror_reu_control(void) {
app_rs_bank2,
app_rs_bank3,
app_rs_bank4,
- apps_loaded);
+ apps_loaded,
+ app_sizes);
+ launcher_publish_settings();
}
static unsigned int launcher_control_dep_line_off(unsigned char index) {
@@ -1969,8 +2062,8 @@ static void launcher_free_app_owned_alloc_records(unsigned char index) {
if (launcher_rsrc_rec_buf[0] == app_id &&
launcher_rsrc_rec_buf[2] == REUCB_DEP_KIND_APP_ALLOC) {
bank = launcher_rsrc_rec_buf[3];
- if (bank != 0u && REU_ALLOC_TABLE[bank] == REU_APP_ALLOC) {
- REU_ALLOC_TABLE[bank] = REU_FREE;
+ if (bank != 0u && launcher_bank_type(bank) == REU_APP_ALLOC) {
+ launcher_free_physical_bank(bank);
}
}
}
@@ -2115,15 +2208,11 @@ static unsigned char launcher_restore_readyshell_meta(unsigned char index) {
#if !READYOS_LAUNCHER_VARIANT_EASYFLASH
static unsigned char launcher_alloc_physical_resource_bank(unsigned char type) {
unsigned int bank;
- unsigned int first;
- first = (unsigned int)(*SHIM_REU_BANK_SKIP) + 2u;
- if (first >= REU_TOTAL_BANKS) {
- return 0u;
- }
- for (bank = first; bank < REU_TOTAL_BANKS; ++bank) {
- if (REU_ALLOC_TABLE[bank] == REU_FREE) {
- REU_ALLOC_TABLE[bank] = type;
+ for (bank = REU_FIRST_DYNAMIC_PHYSICAL(); bank < 255u; ++bank) {
+ if ((unsigned char)bank != *SHIM_READYOS_BANK &&
+ launcher_bank_type((unsigned char)bank) == REU_FREE) {
+ launcher_set_bank_type((unsigned char)bank, type);
return (unsigned char)bank;
}
}
@@ -2140,14 +2229,76 @@ static void launcher_zero_readyshell_meta(unsigned char index) {
static void launcher_mark_readybasic_banks(unsigned char index) {
if (app_rs_bank1[index] != 0u) {
- REU_ALLOC_TABLE[app_rs_bank1[index]] = REU_RB_CORE;
+ launcher_set_bank_type(app_rs_bank1[index], REU_RB_CORE);
+ }
+ if (app_rs_bank2[index] != 0u) {
+ launcher_set_bank_type(app_rs_bank2[index], REU_RB_CODE);
+ }
+}
+
+static void launcher_mark_readyshell_banks(unsigned char index) {
+ unsigned int bank;
+
+ for (bank = 0u; bank < REU_TOTAL_BANKS; ++bank) {
+ if (launcher_bank_type((unsigned char)bank) == REU_RS_CACHE &&
+ (unsigned char)bank != app_rs_bank1[index] &&
+ (unsigned char)bank != app_rs_bank2[index] &&
+ (unsigned char)bank != app_rs_bank3[index]) {
+ launcher_free_physical_bank((unsigned char)bank);
+ } else if (launcher_bank_type((unsigned char)bank) == REU_RS_SCRATCH &&
+ (unsigned char)bank != app_rs_bank4[index]) {
+ launcher_free_physical_bank((unsigned char)bank);
+ }
+ }
+ if (app_rs_bank1[index] != 0u) {
+ launcher_set_bank_type(app_rs_bank1[index], REU_RS_CACHE);
}
if (app_rs_bank2[index] != 0u) {
- REU_ALLOC_TABLE[app_rs_bank2[index]] = REU_RB_CODE;
+ launcher_set_bank_type(app_rs_bank2[index], REU_RS_CACHE);
+ }
+ if (app_rs_bank3[index] != 0u) {
+ launcher_set_bank_type(app_rs_bank3[index], REU_RS_CACHE);
+ }
+ if (app_rs_bank4[index] != 0u) {
+ launcher_set_bank_type(app_rs_bank4[index], REU_RS_SCRATCH);
}
}
+static unsigned char launcher_validated_resource_bank(unsigned char bank,
+ unsigned char type) {
+ unsigned char alloc;
+
+ if (bank == 0u) {
+ return 0u;
+ }
+ alloc = launcher_bank_type(bank);
+ if (alloc != REU_FREE && alloc != type) {
+ return 0u;
+ }
+ return bank;
+}
+
static unsigned char launcher_ensure_readyshell_banks(unsigned char index) {
+ app_rs_bank1[index] =
+ launcher_validated_resource_bank(app_rs_bank1[index], REU_RS_CACHE);
+ app_rs_bank2[index] =
+ launcher_validated_resource_bank(app_rs_bank2[index], REU_RS_CACHE);
+ app_rs_bank3[index] =
+ launcher_validated_resource_bank(app_rs_bank3[index], REU_RS_CACHE);
+ app_rs_bank4[index] =
+ launcher_validated_resource_bank(app_rs_bank4[index], REU_RS_SCRATCH);
+ if (app_rs_bank2[index] == app_rs_bank1[index]) {
+ app_rs_bank2[index] = 0u;
+ }
+ if (app_rs_bank3[index] == app_rs_bank1[index] ||
+ app_rs_bank3[index] == app_rs_bank2[index]) {
+ app_rs_bank3[index] = 0u;
+ }
+ if (app_rs_bank4[index] == app_rs_bank1[index] ||
+ app_rs_bank4[index] == app_rs_bank2[index] ||
+ app_rs_bank4[index] == app_rs_bank3[index]) {
+ app_rs_bank4[index] = 0u;
+ }
if (app_rs_bank1[index] == 0u) {
app_rs_bank1[index] = launcher_alloc_physical_resource_bank(REU_RS_CACHE);
}
@@ -2160,6 +2311,7 @@ static unsigned char launcher_ensure_readyshell_banks(unsigned char index) {
if (app_rs_bank4[index] == 0u) {
app_rs_bank4[index] = launcher_alloc_physical_resource_bank(REU_RS_SCRATCH);
}
+ launcher_mark_readyshell_banks(index);
return (unsigned char)(app_rs_bank1[index] != 0u &&
app_rs_bank2[index] != 0u &&
app_rs_bank3[index] != 0u &&
@@ -2167,6 +2319,13 @@ static unsigned char launcher_ensure_readyshell_banks(unsigned char index) {
}
static unsigned char launcher_ensure_readybasic_banks(unsigned char index) {
+ app_rs_bank1[index] =
+ launcher_validated_resource_bank(app_rs_bank1[index], REU_RB_CORE);
+ app_rs_bank2[index] =
+ launcher_validated_resource_bank(app_rs_bank2[index], REU_RB_CODE);
+ if (app_rs_bank2[index] == app_rs_bank1[index]) {
+ app_rs_bank2[index] = 0u;
+ }
if (app_rs_bank1[index] == 0u) {
app_rs_bank1[index] = launcher_alloc_physical_resource_bank(REU_RB_CORE);
}
@@ -2175,11 +2334,11 @@ static unsigned char launcher_ensure_readybasic_banks(unsigned char index) {
}
if (app_rs_bank1[index] == 0u || app_rs_bank2[index] == 0u) {
if (app_rs_bank1[index] != 0u) {
- REU_ALLOC_TABLE[app_rs_bank1[index]] = REU_FREE;
+ launcher_free_physical_bank(app_rs_bank1[index]);
app_rs_bank1[index] = 0u;
}
if (app_rs_bank2[index] != 0u) {
- REU_ALLOC_TABLE[app_rs_bank2[index]] = REU_FREE;
+ launcher_free_physical_bank(app_rs_bank2[index]);
app_rs_bank2[index] = 0u;
}
return 0u;
@@ -2219,6 +2378,222 @@ static void launcher_zero_reu_range(unsigned char bank,
}
}
+#if !READYOS_LAUNCHER_VARIANT_EASYFLASH && LAUNCHER_DMA_LOAD
+static unsigned char launcher_dma_hex(unsigned char value) {
+ value &= 0x0Fu;
+ return (unsigned char)(value < 10u ? ('0' + value)
+ : (1u + (value - 10u)));
+}
+
+#define launcher_dma_check_available() (launcher_dma_available && launcher_dma_probe_ok)
+
+static void launcher_dma_reset_runtime_state(void) {
+ launcher_dma_probe_ok = 0u;
+ launcher_dma_used = 0u;
+ launcher_dma_image_ready = 0u;
+ launcher_uci_dma_assume_mounted = 0u;
+ launcher_dma_breadcrumb = 0u;
+}
+
+static void launcher_dma_init_from_config(void) {
+ launcher_dma_reset_runtime_state();
+ launcher_dma_available = (unsigned char)(launcher_c64u_image_path[0] != 0u);
+}
+
+static char *launcher_dma_prepare_image_path(unsigned char *restore_slash) {
+ char *slash;
+ char *cursor;
+ char *dir_start;
+
+ slash = 0;
+ cursor = launcher_c64u_image_path;
+ while (*cursor != 0) {
+ if (*cursor == '/') {
+ slash = cursor;
+ }
+ ++cursor;
+ }
+ if (slash == 0 || slash[1] == 0) {
+ return 0;
+ }
+
+ *restore_slash = 0u;
+ if (slash == launcher_c64u_image_path) {
+ dir_start = (char*)launcher_dma_root_dir;
+ } else {
+ dir_start = launcher_c64u_image_path;
+ *slash = 0;
+ *restore_slash = 1u;
+ }
+ launcher_uci_dma_image_dir = dir_start;
+ launcher_uci_dma_image_name = slash + 1;
+ return slash;
+}
+
+static void launcher_dma_probe_after_draw(void) {
+ char *slash;
+ unsigned char restore_slash;
+
+ if (launcher_c64u_image_path[0] == 0u) {
+ launcher_dma_available = 0u;
+ launcher_dma_reset_runtime_state();
+ return;
+ }
+ if (!launcher_uci_dma_detect()) {
+ launcher_dma_available = 0u;
+ launcher_dma_reset_runtime_state();
+ launcher_dma_breadcrumb = LAUNCHER_DMA_ERR_NO_UCI;
+ return;
+ }
+
+ slash = launcher_dma_prepare_image_path(&restore_slash);
+ if (slash == 0) {
+ launcher_dma_available = 0u;
+ launcher_dma_reset_runtime_state();
+ launcher_dma_breadcrumb = LAUNCHER_DMA_ERR_PATH_MIN;
+ launcher_set_notice_if_empty("dma image path invalid", TUI_COLOR_LIGHTRED);
+ launcher_uci_dma_quiesce();
+ return;
+ }
+ if (restore_slash) {
+ *slash = '/';
+ }
+
+ launcher_dma_available = 1u;
+ launcher_dma_probe_ok = 1u;
+ launcher_dma_image_ready = 0u;
+ launcher_uci_dma_assume_mounted = 0u;
+ if (launcher_dma_breadcrumb < 0x20u) {
+ launcher_dma_breadcrumb = 0u;
+ }
+ launcher_uci_dma_quiesce();
+}
+
+static unsigned char launcher_dma_try_prg_to_reu(unsigned char drive,
+ const char *name,
+ unsigned char bank,
+ unsigned int reu_off,
+ unsigned int max_len,
+ unsigned int load_addr) {
+ char *slash;
+ char *cursor;
+ char *dir_start;
+ unsigned char i;
+ unsigned char restore_slash;
+ unsigned char dma_ok;
+
+ /* Hardware note: these screen breadcrumbs are not just cosmetic.
+ * The C64U UCI/DOS transaction proved code-shape/pacing sensitive;
+ * replacing them with private RAM breadcrumbs made DMA fail or fall
+ * back on real hardware. Do not "clean this up" without retesting on
+ * the C64U. */
+ launcher_dma_breadcrumb = 0x31u;
+ (*(volatile unsigned char*)0x052D) = 0x31;
+ if ((drive != 8u && drive != 9u) || name[0] == 0u) {
+ return 0u;
+ }
+ for (i = 0u; i < MAX_FILE_LEN && name[i] != 0; ++i) {
+ launcher_dma_name_buf[i] = name[i];
+ }
+ if (name[i] != 0) {
+ return 0u;
+ }
+ launcher_dma_name_buf[i] = 0;
+ launcher_dma_breadcrumb = 0x32u;
+ (*(volatile unsigned char*)0x052D) = 0x32;
+ if (launcher_c64u_image_path[0] == 0u) {
+ return 0u;
+ }
+ launcher_dma_breadcrumb = 0x33u;
+ (*(volatile unsigned char*)0x052D) = 0x33;
+ if (!launcher_dma_check_available()) {
+ return 0u;
+ }
+ launcher_dma_breadcrumb = 0x34u;
+ (*(volatile unsigned char*)0x052D) = 0x34;
+
+ slash = 0;
+ cursor = launcher_c64u_image_path;
+ while (*cursor != 0) {
+ if (*cursor == '/') {
+ slash = cursor;
+ }
+ ++cursor;
+ }
+ if (slash == 0 || slash[1] == 0) {
+ return 0u;
+ }
+ restore_slash = 0u;
+ if (slash == launcher_c64u_image_path) {
+ dir_start = (char*)launcher_dma_root_dir;
+ } else {
+ dir_start = launcher_c64u_image_path;
+ if (slash == dir_start) {
+ return 0u;
+ }
+ *slash = 0;
+ restore_slash = 1u;
+ }
+ launcher_uci_dma_image_dir = dir_start;
+ launcher_uci_dma_image_name = slash + 1;
+ launcher_uci_dma_mount_name = slash + 1;
+ launcher_uci_dma_name = launcher_dma_name_buf;
+ launcher_uci_dma_reu_bank = bank;
+ launcher_uci_dma_reu_offset = reu_off;
+ launcher_uci_dma_max_len = max_len;
+ launcher_uci_dma_expected_load_addr = load_addr;
+ launcher_uci_dma_assume_mounted = launcher_dma_image_ready;
+ launcher_dma_breadcrumb = 0x35u;
+ (*(volatile unsigned char*)0x052D) = 0x35;
+ dma_ok = launcher_uci_dma_load_prg();
+ if (restore_slash) {
+ *slash = '/';
+ }
+ if (dma_ok) {
+ launcher_dma_available = 1u;
+ launcher_dma_used = 1u;
+ launcher_dma_image_ready = 1u;
+ launcher_uci_dma_assume_mounted = 1u;
+ launcher_uci_dma_quiesce();
+ launcher_uci_dma_clear_stage();
+ return 1u;
+ }
+ launcher_dma_breadcrumb = launcher_uci_dma_last_error;
+ (*(volatile unsigned char*)0x052E) =
+ launcher_dma_hex((unsigned char)(launcher_uci_dma_last_error >> 4));
+ (*(volatile unsigned char*)0x052F) =
+ launcher_dma_hex(launcher_uci_dma_last_error);
+ (*(volatile unsigned char*)0x0530) =
+ launcher_dma_hex((unsigned char)(launcher_uci_dma_dbg_stat0 >> 4));
+ (*(volatile unsigned char*)0x0531) =
+ launcher_dma_hex(launcher_uci_dma_dbg_stat0);
+ (*(volatile unsigned char*)0x0532) =
+ launcher_dma_hex((unsigned char)(launcher_uci_dma_dbg_stat1 >> 4));
+ (*(volatile unsigned char*)0x0533) =
+ launcher_dma_hex(launcher_uci_dma_dbg_stat1);
+ if (launcher_uci_dma_last_error == LAUNCHER_DMA_ERR_NO_UCI ||
+ (launcher_uci_dma_last_error >= LAUNCHER_DMA_ERR_PATH_MIN &&
+ launcher_uci_dma_last_error <= LAUNCHER_DMA_ERR_PATH_MAX)) {
+ launcher_dma_available = 0u;
+ launcher_dma_image_ready = 0u;
+ launcher_uci_dma_assume_mounted = 0u;
+ } else {
+ launcher_dma_image_ready = 1u;
+ launcher_uci_dma_assume_mounted = 1u;
+ }
+ launcher_uci_dma_quiesce();
+ return 0u;
+}
+
+static void launcher_disk_fallback_after_dma_failure(unsigned char bank) {
+ cbm_k_clrch();
+ cbm_k_clall();
+ *SHIM_LOAD_END_LO = 0u;
+ *SHIM_LOAD_END_HI = 0u;
+ launcher_set_snapshot_loaded(bank, 0u);
+}
+#endif
+
static unsigned char launcher_stream_prg_to_reu(unsigned char drive,
const char *name,
unsigned char bank,
@@ -2229,6 +2604,18 @@ static unsigned char launcher_stream_prg_to_reu(unsigned char drive,
unsigned int chunk;
int n;
+#if !READYOS_LAUNCHER_VARIANT_EASYFLASH && LAUNCHER_DMA_LOAD && LAUNCHER_DMA_LOAD_RESOURCES
+ if (launcher_dma_check_available()) {
+ launcher_zero_reu_range(bank, reu_off, READYSHELL_OVERLAY_SLOT_LEN);
+ if (launcher_dma_try_prg_to_reu(drive, name, bank, reu_off,
+ READYSHELL_OVERLAY_SLOT_LEN,
+ READYSHELL_OVERLAY_LOAD_ADDR)) {
+ return 1u;
+ }
+ return 0u;
+ }
+#endif
+
if (!launcher_build_resource_open_spec(name)) {
return 0u;
}
@@ -2423,6 +2810,7 @@ static unsigned char launcher_load_readybasic_resources(unsigned char index) {
launcher_mirror_reu_control();
return 1u;
}
+
#endif
static unsigned char launcher_prepare_app_resources(unsigned char index) {
@@ -2432,12 +2820,15 @@ static unsigned char launcher_prepare_app_resources(unsigned char index) {
if (app_resource_sets[index] == APP_RESOURCE_NONE) {
return 1u;
}
+#if !READYOS_LAUNCHER_VARIANT_EASYFLASH
+ launcher_mark_loaded_snapshot_banks();
+#endif
if (app_resource_loaded[index]) {
if (app_resource_sets[index] == APP_RESOURCE_READYSHELL_OVL) {
- if (app_rs_bank4[index] != 0u) {
- REU_ALLOC_TABLE[app_rs_bank4[index]] = REU_RS_SCRATCH;
- *READYSHELL_STATE_BANK_CACHE = app_rs_bank4[index];
- }
+#if !READYOS_LAUNCHER_VARIANT_EASYFLASH
+ launcher_mark_readyshell_banks(index);
+#endif
+ *READYSHELL_STATE_BANK_CACHE = app_rs_bank4[index];
return launcher_restore_readyshell_meta(index);
} else if (app_resource_sets[index] == APP_RESOURCE_READYBASIC_CORE) {
#if !READYOS_LAUNCHER_VARIANT_EASYFLASH
@@ -2461,6 +2852,12 @@ static unsigned char launcher_prepare_app_resources(unsigned char index) {
#endif
}
+static void launcher_invalidate_resource_preload(unsigned char index) {
+ if (index < app_count && app_resource_sets[index] != APP_RESOURCE_NONE) {
+ app_resource_loaded[index] = 0u;
+ }
+}
+
#if !READYOS_LAUNCHER_VARIANT_EASYFLASH
static void launcher_free_app_resources(unsigned char index) {
if (index >= app_count) {
@@ -2472,16 +2869,16 @@ static void launcher_free_app_resources(unsigned char index) {
launcher_free_app_owned_alloc_records(index);
launcher_control_clear_app_resource_records(index);
if (app_rs_bank1[index] != 0u) {
- REU_ALLOC_TABLE[app_rs_bank1[index]] = REU_FREE;
+ launcher_free_physical_bank(app_rs_bank1[index]);
}
if (app_rs_bank2[index] != 0u) {
- REU_ALLOC_TABLE[app_rs_bank2[index]] = REU_FREE;
+ launcher_free_physical_bank(app_rs_bank2[index]);
}
if (app_rs_bank3[index] != 0u) {
- REU_ALLOC_TABLE[app_rs_bank3[index]] = REU_FREE;
+ launcher_free_physical_bank(app_rs_bank3[index]);
}
if (app_rs_bank4[index] != 0u) {
- REU_ALLOC_TABLE[app_rs_bank4[index]] = REU_FREE;
+ launcher_free_physical_bank(app_rs_bank4[index]);
}
app_resource_loaded[index] = 0u;
app_rs_bank1[index] = 0u;
@@ -2493,7 +2890,7 @@ static void launcher_free_app_resources(unsigned char index) {
/*---------------------------------------------------------------------------
- * Save launcher state to REU bank 0
+ * Save the launcher snapshot into the first $B600 bytes of the ReadyOS bank
*---------------------------------------------------------------------------*/
static void save_launcher_to_reu(void) {
REU_C64_LO = 0x00;
@@ -2509,31 +2906,38 @@ static void save_launcher_to_reu(void) {
/*---------------------------------------------------------------------------
* Load single app from disk to REU
* Uses shim's preload routine at $C809 which:
- * 1. Stashes launcher to REU bank 0
+ * 1. Stashes launcher to the ReadyOS bank
* 2. Loads app from disk to $1000
* 3. Stashes app to target REU bank
- * 4. Fetches launcher back from REU bank 0
+ * 4. Fetches launcher back from the ReadyOS bank
* 5. Returns via RTS
*---------------------------------------------------------------------------*/
static unsigned int load_app_to_reu(unsigned char index) {
const char *filename;
unsigned char bank;
- unsigned char loaded_in_bitmap;
+ unsigned char loaded_in_readyos;
unsigned int end_addr;
unsigned int file_size;
+#if !READYOS_LAUNCHER_VARIANT_EASYFLASH && LAUNCHER_DMA_LOAD
+ unsigned char clean_disk_fallback = 0u;
+#endif
if (!launcher_is_app_slot(index)) {
return 0;
}
- filename = catalog_file_for_index(index);
- if (filename[0] == 0) {
- return 0;
- }
+ /* Allocation can publish the ReadyOS settings record through
+ * catalog_text_buf. Resolve the token first, then obtain the catalog
+ * filename so no pointer into that shared scratch buffer survives a
+ * metadata DMA. */
bank = launcher_resolve_snapshot_bank(index);
if (bank == 0) {
return 0;
}
+ filename = catalog_file_for_index(index);
+ if (filename[0] == 0) {
+ return 0;
+ }
/* Set target bank in shim data area */
*SHIM_APP_BANK = bank;
@@ -2543,6 +2947,65 @@ static unsigned int load_app_to_reu(unsigned char index) {
set_shim_drive(app_drives[index]);
+#if !READYOS_LAUNCHER_VARIANT_EASYFLASH && LAUNCHER_DMA_LOAD
+ {
+ unsigned char physical;
+ /* See launcher_dma_try_prg_to_reu(): these volatile stores preserve
+ * the hardware-proven UCI transaction shape. */
+ launcher_dma_breadcrumb = 0x41u;
+ (*(volatile unsigned char*)0x052C) = 0x31;
+ physical = launcher_logical_to_physical(bank);
+ launcher_dma_breadcrumb = 0x42u;
+ (*(volatile unsigned char*)0x052C) = 0x32;
+ if (physical != 0xFFu &&
+ launcher_dma_check_available() &&
+ (app_resource_sets[index] != APP_RESOURCE_READYSHELL_OVL ||
+ LAUNCHER_DMA_LOAD_READYSHELL)) {
+ launcher_dma_breadcrumb = 0x43u;
+ (*(volatile unsigned char*)0x052C) = 0x33;
+ if (launcher_dma_try_prg_to_reu(app_drives[index], filename,
+ physical, 0u, APP_SAVE_SIZE,
+ APP_LOAD_START)) {
+ file_size = launcher_uci_dma_loaded_size;
+ *SHIM_APP_SIZE = file_size;
+ launcher_set_snapshot_loaded(bank, 1u);
+ launcher_set_bank_type(physical, REU_APP_STATE);
+ apps_loaded[index] = 1;
+ app_sizes[index] = file_size;
+ launcher_invalidate_resource_preload(index);
+ if (!launcher_prepare_app_resources(index)) {
+ apps_loaded[index] = 0;
+ app_sizes[index] = 0;
+ launcher_set_snapshot_loaded(bank, 0u);
+ launcher_set_notice_if_empty("app resources failed",
+ TUI_COLOR_LIGHTRED);
+ launcher_mirror_reu_control();
+ return 0;
+ }
+ launcher_bind_default_hotkey_for_index(index);
+ launcher_mirror_reu_control();
+ return file_size;
+ }
+ if (launcher_dma_check_available()) {
+ return 0;
+ }
+ clean_disk_fallback = 1u;
+ }
+ }
+#endif
+
+#if !READYOS_LAUNCHER_VARIANT_EASYFLASH && LAUNCHER_DMA_LOAD
+ if (clean_disk_fallback) {
+ launcher_disk_fallback_after_dma_failure(bank);
+ /* The fallback can publish metadata and therefore reuse the catalog
+ * scratch buffer. Re-fetch the filename before copying it to the
+ * resident shim. */
+ filename = catalog_file_for_index(index);
+ set_shim_name(filename);
+ set_shim_drive(app_drives[index]);
+ }
+#endif
+
/* Call shim's preload routine - it handles everything and returns */
__asm__("jsr $C809");
@@ -2551,13 +3014,16 @@ static unsigned int load_app_to_reu(unsigned char index) {
* If this value is invalid, treat load as failure. */
end_addr = ((unsigned int)(*(unsigned char*)0xC831) << 8)
| (*(unsigned char*)0xC830);
- loaded_in_bitmap = (bank < 24u) ? shim_bitmap_has_bank(bank) : 0u;
+ loaded_in_readyos =
+ (unsigned char)(readyos_bank_read_byte(
+ (unsigned int)(REUCB_TOKEN_STATUS_OFF + bank)) & REUCB_TOKEN_LOADED);
if (end_addr <= APP_LOAD_START || end_addr > APP_LOAD_END_EXCL) {
/* Some preload paths can leave end_addr invalid while still stashing app. */
- if (loaded_in_bitmap) {
+ if (loaded_in_readyos) {
apps_loaded[index] = 1;
app_sizes[index] = APP_SAVE_SIZE;
+ launcher_invalidate_resource_preload(index);
if (!launcher_prepare_app_resources(index)) {
apps_loaded[index] = 0;
app_sizes[index] = 0;
@@ -2571,16 +3037,17 @@ static unsigned int load_app_to_reu(unsigned char index) {
}
apps_loaded[index] = 0;
app_sizes[index] = 0;
- shim_bitmap_clear_bank(bank);
+ launcher_set_snapshot_loaded(bank, 0u);
launcher_mirror_reu_control();
return 0;
}
file_size = end_addr - APP_LOAD_START;
if (file_size > APP_SAVE_SIZE) {
- if (loaded_in_bitmap) {
+ if (loaded_in_readyos) {
apps_loaded[index] = 1;
app_sizes[index] = APP_SAVE_SIZE;
+ launcher_invalidate_resource_preload(index);
if (!launcher_prepare_app_resources(index)) {
apps_loaded[index] = 0;
app_sizes[index] = 0;
@@ -2594,14 +3061,16 @@ static unsigned int load_app_to_reu(unsigned char index) {
}
apps_loaded[index] = 0;
app_sizes[index] = 0;
- shim_bitmap_clear_bank(bank);
+ launcher_set_snapshot_loaded(bank, 0u);
launcher_mirror_reu_control();
return 0;
}
- /* Treat bitmap as authoritative: only mark loaded if target bit is set. */
- loaded_in_bitmap = (bank < 24u) ? shim_bitmap_has_bank(bank) : 1u;
- if (bank < 24u && !loaded_in_bitmap) {
+ /* The ReadyOS-bank status commit is authoritative for every token. */
+ loaded_in_readyos =
+ (unsigned char)(readyos_bank_read_byte(
+ (unsigned int)(REUCB_TOKEN_STATUS_OFF + bank)) & REUCB_TOKEN_LOADED);
+ if (!loaded_in_readyos) {
apps_loaded[index] = 0;
app_sizes[index] = 0;
launcher_mirror_reu_control();
@@ -2611,6 +3080,7 @@ static unsigned int load_app_to_reu(unsigned char index) {
/* On return, launcher is back in memory and app is valid in REU. */
apps_loaded[index] = 1;
app_sizes[index] = file_size;
+ launcher_invalidate_resource_preload(index);
if (!launcher_prepare_app_resources(index)) {
apps_loaded[index] = 0;
app_sizes[index] = 0;
@@ -2688,7 +3158,7 @@ static unsigned char load_all_to_reu_internal(unsigned char interactive) {
unsigned char success;
static unsigned char missing_slots[MAX_APPS];
- sync_from_reu_bitmap();
+ sync_from_readyos_state();
/* Count how many apps need loading */
total_to_load = 0;
@@ -2743,11 +3213,11 @@ static unsigned char load_all_to_reu_internal(unsigned char interactive) {
/* Load app; retry once if target bank bit was not set. */
retried = 0;
size = load_app_to_reu(i);
- sync_from_reu_bitmap();
+ sync_from_readyos_state();
loaded_ok = apps_loaded[i];
if (!loaded_ok) {
size = load_app_to_reu(i);
- sync_from_reu_bitmap();
+ sync_from_readyos_state();
loaded_ok = apps_loaded[i];
retried = 1;
}
@@ -2791,7 +3261,7 @@ static unsigned char load_all_to_reu_internal(unsigned char interactive) {
}
/* Final authoritative check: all catalog-assigned banks must be present. */
- sync_from_reu_bitmap();
+ sync_from_readyos_state();
bitmap_complete = required_slots_loaded();
for (i = launcher_first_app_index(); i < app_count; ++i) {
@@ -2802,7 +3272,7 @@ static unsigned char load_all_to_reu_internal(unsigned char interactive) {
}
}
- tui_puts_n(2, counter_y, "", 38, TUI_COLOR_WHITE);
+ tui_puts_n(0, counter_y, "", TUI_SCREEN_WIDTH, TUI_COLOR_WHITE);
success = (unsigned char)(missing_count == 0 && bitmap_complete);
if (success) {
@@ -2835,8 +3305,8 @@ static void launcher_clear_hotkey_bank(unsigned char bank) {
return;
}
for (slot = 0u; slot < TUI_HOTKEY_SLOT_COUNT; ++slot) {
- if (TUI_HOTKEY_BINDINGS[slot] == bank) {
- TUI_HOTKEY_BINDINGS[slot] = 0u;
+ if (tui_hotkey_get_binding(slot) == bank) {
+ tui_hotkey_set_binding(slot, 0u);
}
}
}
@@ -2852,8 +3322,8 @@ static void launcher_bind_default_hotkey_for_index(unsigned char index) {
if (slot == 0u || slot > TUI_HOTKEY_SLOT_COUNT) {
return;
}
- if (TUI_HOTKEY_BINDINGS[(unsigned char)(slot - 1u)] == 0u) {
- TUI_HOTKEY_BINDINGS[(unsigned char)(slot - 1u)] = app_banks[index];
+ if (tui_hotkey_get_binding((unsigned char)(slot - 1u)) == 0u) {
+ tui_hotkey_set_binding((unsigned char)(slot - 1u), app_banks[index]);
}
}
@@ -2937,7 +3407,8 @@ static void launcher_mark_embedded_preloads_loaded(void) {
}
physical = launcher_logical_to_physical(bank);
if (physical != 0xFFu) {
- REU_ALLOC_TABLE[physical] = REU_APP_STATE;
+ launcher_set_bank_type(physical, REU_APP_STATE);
+ launcher_set_snapshot_loaded(bank, 1u);
}
if (app_resource_sets[i] == APP_RESOURCE_READYSHELL_OVL) {
app_rs_bank1[i] = READYOS_EASYFLASH_RS_CACHE_BANK1;
@@ -2994,7 +3465,7 @@ static void load_selected_to_reu(unsigned char index) {
unsigned char total;
total = (unsigned char)(app_count - launcher_first_app_index());
- sync_from_reu_bitmap();
+ sync_from_readyos_state();
loaded_ok = (unsigned char)(launcher_is_app_slot(index) && apps_loaded[index]);
tui_clear(TUI_COLOR_BLUE);
@@ -3024,7 +3495,7 @@ static void load_selected_to_reu(unsigned char index) {
return;
}
- sync_from_reu_bitmap();
+ sync_from_readyos_state();
if (apps_loaded[index]) {
return;
}
@@ -3042,11 +3513,11 @@ static void load_selected_to_reu(unsigned char index) {
/* Load the app (blocking) */
size = load_app_to_reu(index);
- sync_from_reu_bitmap();
+ sync_from_readyos_state();
loaded_ok = apps_loaded[index];
/* Show result */
- tui_puts_n(4, 7, "", 16, TUI_COLOR_WHITE);
+ tui_puts_n(4, 7, "", 32, TUI_COLOR_WHITE);
if (loaded_ok) {
tui_puts(4, 7, "OK", TUI_COLOR_LIGHTGREEN);
@@ -3289,7 +3760,7 @@ static void browse_and_load_manifest(void) {
menu.selected = launcher_app_to_menu_index(index);
launcher_sync_visible_window();
- sync_from_reu_bitmap();
+ sync_from_readyos_state();
if (existing) {
if (!apps_loaded[index]) {
@@ -3311,7 +3782,7 @@ static void browse_and_load_manifest(void) {
tui_puts(4u, 8u, "LOADING TO REU...", TUI_COLOR_YELLOW);
size = load_app_to_reu(index);
- sync_from_reu_bitmap();
+ sync_from_readyos_state();
if (!apps_loaded[index]) {
rollback_manifest_app(index);
launcher_show_message("LOAD FAILED", "APP PRG DID NOT LOAD",
@@ -3350,7 +3821,7 @@ static void launch_from_reu(unsigned char index) {
launcher_set_startup_suppressed();
launcher_resume_save(launcher_app_to_menu_index(index), menu.scroll_offset, 1);
- /* Save current launcher state to REU bank 0 first */
+ /* Save the current launcher snapshot to the ReadyOS bank first. */
save_launcher_to_reu();
/* Set REU params in shim */
@@ -3364,47 +3835,6 @@ static void launch_from_reu(unsigned char index) {
__asm__("jmp $C803");
}
-/*---------------------------------------------------------------------------
- * Launch app from disk (slow)
- *---------------------------------------------------------------------------*/
-#if !READYOS_LAUNCHER_VARIANT_EASYFLASH
-static void launch_from_disk(unsigned char index) {
- const char *filename;
- unsigned char bank;
-
- if (catalog_file_for_index(index)[0] == 0) return;
- bank = launcher_resolve_snapshot_bank(index);
- if (bank == 0) return;
- if (!launcher_prepare_app_resources(index)) {
- launcher_set_notice_if_empty("app resources failed", TUI_COLOR_LIGHTRED);
- return;
- }
- launcher_bind_default_hotkey_for_index(index);
-
- tui_clear(TUI_COLOR_BLUE);
- tui_puts(4, 5, "LOADING FROM DISK:", TUI_COLOR_WHITE);
- draw_drive_prefixed_name(23, 5, index, TUI_COLOR_CYAN, 12);
- tui_puts(4, 7, "PLEASE WAIT...", TUI_COLOR_YELLOW);
-
- /* Set filename in shim */
- filename = catalog_file_for_index(index);
- set_shim_name(filename);
- set_shim_drive(app_drives[index]);
-
- launcher_set_startup_suppressed();
- launcher_resume_save(launcher_app_to_menu_index(index), menu.scroll_offset, 1);
-
- /* Save launcher to REU first so we can return to it */
- save_launcher_to_reu();
-
- /* Set current app bank so apps can return to launcher */
- *SHIM_CURRENT_BANK = bank;
-
- /* Call shim to load and run - use jump table entry at $C800 */
- __asm__("jmp $C800");
-}
-#endif
-
/*---------------------------------------------------------------------------
* Launch app (from REU if available, else disk)
*---------------------------------------------------------------------------*/
@@ -3424,7 +3854,7 @@ static void launch_app(unsigned char index) {
}
/* Bitmap is authoritative for REU presence. */
- sync_from_reu_bitmap();
+ sync_from_readyos_state();
if (apps_loaded[index]) {
launch_from_reu(index);
@@ -3432,7 +3862,17 @@ static void launch_app(unsigned char index) {
#if READYOS_LAUNCHER_VARIANT_EASYFLASH
launcher_set_notice("preload missing for selected app", TUI_COLOR_LIGHTRED);
#else
- launch_from_disk(index);
+ tui_clear(TUI_COLOR_BLUE);
+ tui_puts(4, 5, "LOADING TO REU:", TUI_COLOR_WHITE);
+ draw_drive_prefixed_name(20, 5, index, TUI_COLOR_CYAN, 16);
+ tui_puts(4, 7, "PLEASE WAIT...", TUI_COLOR_YELLOW);
+ (void)load_app_to_reu(index);
+ sync_from_readyos_state();
+ if (apps_loaded[index]) {
+ launch_from_reu(index);
+ } else {
+ launcher_set_notice_if_empty("app load failed", TUI_COLOR_LIGHTRED);
+ }
#endif
}
}
@@ -3461,10 +3901,24 @@ static void draw_status(void) {
tui_window(&box, TUI_COLOR_LIGHTBLUE);
tui_puts(2, STATUS_Y + 1, "REU: 16MB", TUI_COLOR_WHITE);
+#if !READYOS_LAUNCHER_VARIANT_EASYFLASH && LAUNCHER_DMA_LOAD
+ tui_puts(12, STATUS_Y + 1, "DMA:", TUI_COLOR_GRAY3);
+ if (launcher_dma_used) {
+ tui_puts(16, STATUS_Y + 1, "ON ", TUI_COLOR_LIGHTGREEN);
+ } else if (launcher_dma_available) {
+ tui_puts(16, STATUS_Y + 1, "YES", TUI_COLOR_LIGHTGREEN);
+ } else {
+ tui_puts(16, STATUS_Y + 1, "NO ", TUI_COLOR_GRAY2);
+ }
+ /* Legend for REU indicator */
+ tui_putc(22, STATUS_Y + 1, REU_INDICATOR, TUI_COLOR_LIGHTGREEN);
+ tui_puts(23, STATUS_Y + 1, "=IN REU", TUI_COLOR_GRAY3);
+#else
/* Legend for REU indicator */
tui_putc(20, STATUS_Y + 1, REU_INDICATOR, TUI_COLOR_LIGHTGREEN);
tui_puts(21, STATUS_Y + 1, "=IN REU", TUI_COLOR_GRAY3);
+#endif
}
static void draw_help(void) {
@@ -3481,6 +3935,11 @@ static void draw_notice(void) {
LAUNCHER_NOTICE_LEN, launcher_notice_color);
}
+static void launcher_hide_kernal_cursor(void) {
+ cursor(0);
+ *KERNAL_BLNSW = 1u;
+}
+
static void draw_drive_field(unsigned int screen_offset, unsigned char drive) {
unsigned char tens = 32;
unsigned char ones;
@@ -3546,7 +4005,7 @@ static unsigned char launcher_hotkey_slot_for_bank(unsigned char bank) {
}
for (slot = 1; slot <= TUI_HOTKEY_SLOT_COUNT; ++slot) {
- if (TUI_HOTKEY_BINDINGS[(unsigned char)(slot - 1)] == bank) {
+ if (tui_hotkey_get_binding((unsigned char)(slot - 1)) == bank) {
return slot;
}
}
@@ -3760,8 +4219,8 @@ static void launcher_seed_default_hotkeys(void) {
if (slot == 0) {
continue;
}
- if (TUI_HOTKEY_BINDINGS[(unsigned char)(slot - 1)] == 0) {
- TUI_HOTKEY_BINDINGS[(unsigned char)(slot - 1)] = app_banks[i];
+ if (tui_hotkey_get_binding((unsigned char)(slot - 1)) == 0) {
+ tui_hotkey_set_binding((unsigned char)(slot - 1), app_banks[i]);
}
}
}
@@ -3827,6 +4286,7 @@ static void launcher_draw(void) {
draw_status();
draw_notice();
draw_help();
+ launcher_hide_kernal_cursor();
}
/*---------------------------------------------------------------------------
@@ -3846,7 +4306,9 @@ static void launcher_init(void) {
unsigned char detail_b;
unsigned char detail_c;
+ *KERNAL_BLNSW = 1u;
tui_init();
+ launcher_hide_kernal_cursor();
reu_phys_apply_to_alloc_table(reu_phys_detect_bank_count());
shim_suppress_startup_once =
(unsigned char)((*SHIM_LAUNCHER_FLAGS & SHIM_LAUNCHER_FLAG_SUPPRESS_STARTUP) != 0u);
@@ -3860,21 +4322,29 @@ static void launcher_init(void) {
resume_init_for_app(REU_BANK_LAUNCHER, REU_BANK_LAUNCHER,
LAUNCHER_RESUME_SCHEMA);
resume_ready = 1;
- restored_resume = launcher_resume_restore(&saved_selected, &saved_scroll_offset,
- &saved_suppress_startup_once);
+ if (shim_suppress_startup_once) {
+ restored_resume = launcher_resume_restore(&saved_selected,
+ &saved_scroll_offset,
+ &saved_suppress_startup_once);
+ }
- if (restored_resume) {
+ if (restored_resume && launcher_restore_registry_from_readyos()) {
err = validate_slot_contract(&detail_a, &detail_b, &detail_c);
if (err == 0) {
slot_contract_ok = 1;
used_cached_catalog = 1;
} else {
- catalog_init_defaults();
- catalog_rebind_views();
- saved_selected = 0;
- saved_scroll_offset = 0;
- saved_suppress_startup_once = 0;
+ restored_resume = 0u;
}
+ } else {
+ restored_resume = 0u;
+ }
+ if (!restored_resume) {
+ catalog_init_defaults();
+ catalog_rebind_views();
+ saved_selected = 0;
+ saved_scroll_offset = 0;
+ saved_suppress_startup_once = 0;
}
if (!used_cached_catalog) {
@@ -3902,6 +4372,13 @@ static void launcher_init(void) {
}
slot_contract_ok = 1;
}
+#if !READYOS_LAUNCHER_VARIANT_EASYFLASH && LAUNCHER_DMA_LOAD
+ launcher_dma_init_from_config();
+ if (used_cached_catalog && launcher_dma_available &&
+ launcher_resume_blob.reserved) {
+ launcher_dma_used = 1u;
+ }
+#endif
if (shim_suppress_startup_once) {
saved_suppress_startup_once = 1;
}
@@ -3932,7 +4409,7 @@ static void launcher_init(void) {
app_sizes[i] = 0;
}
set_shim_drive(8);
- sync_from_reu_bitmap();
+ sync_from_readyos_state();
#if READYOS_LAUNCHER_VARIANT_EASYFLASH
launcher_mark_embedded_preloads_loaded();
#endif
@@ -3956,9 +4433,17 @@ static void launcher_loop(void) {
}
launcher_draw();
+#if !READYOS_LAUNCHER_VARIANT_EASYFLASH && LAUNCHER_DMA_LOAD
+ launcher_dma_probe_after_draw();
+ draw_status();
+ draw_notice();
+ launcher_hide_kernal_cursor();
+#endif
while (running) {
+ launcher_hide_kernal_cursor();
key = tui_getkey();
+ launcher_hide_kernal_cursor();
if (key != 2 && key != TUI_KEY_NEXT_APP && key != TUI_KEY_PREV_APP) {
bank = tui_handle_global_hotkey(key, REU_BANK_LAUNCHER, 0);
diff --git a/src/apps/launcher/launcher_dir_page.c b/src/apps/launcher/launcher_dir_page.c
new file mode 100644
index 0000000..3da8c01
--- /dev/null
+++ b/src/apps/launcher/launcher_dir_page.c
@@ -0,0 +1,263 @@
+/*
+ * launcher_dir_page.c - Launcher-local paged CBM directory reader.
+ *
+ * The shared reader scans to EOF to count every matching file. On the C64U D81
+ * path this can leave the launcher sitting on "READING DISK..." for too long,
+ * so the launcher only reads enough entries for the requested page plus one.
+ */
+
+#include "../../lib/dir_page.h"
+
+#include
+#include
+
+#define DIR_PAGE_LFN_DIR 1
+#define DIR_PAGE_READ_CHUNK 96u
+#define KERNAL_ST_EOF 0x40u
+#define KERNAL_ST_NO_DEVICE 0x80u
+
+extern unsigned char launcher_resource_buf[];
+
+static unsigned char dir_page_buf_pos;
+static unsigned char dir_page_buf_len;
+static unsigned char dir_page_buf_eof;
+
+static void dir_page_cleanup_io(void) {
+ cbm_k_clrch();
+ cbm_k_clall();
+}
+
+static void dir_page_read_reset(void) {
+ dir_page_buf_pos = 0u;
+ dir_page_buf_len = 0u;
+ dir_page_buf_eof = 0u;
+}
+
+static unsigned char dir_page_read_byte(unsigned char *out) {
+ unsigned char raw;
+ int n;
+
+ while (dir_page_buf_pos >= dir_page_buf_len) {
+ if (dir_page_buf_eof) {
+ return 0u;
+ }
+
+ dir_page_buf_pos = 0u;
+ dir_page_buf_len = 0u;
+ n = cbm_read(DIR_PAGE_LFN_DIR, launcher_resource_buf,
+ DIR_PAGE_READ_CHUNK);
+ if (n <= 0) {
+ dir_page_buf_eof = 1u;
+ return 0u;
+ }
+ dir_page_buf_len = (unsigned char)n;
+ raw = cbm_k_readst();
+ if ((unsigned char)n < DIR_PAGE_READ_CHUNK ||
+ (raw & (KERNAL_ST_EOF | KERNAL_ST_NO_DEVICE)) != 0u) {
+ dir_page_buf_eof = 1u;
+ }
+ }
+
+ *out = launcher_resource_buf[dir_page_buf_pos++];
+ return 1u;
+}
+
+static unsigned char dir_page_read_bytes(unsigned char *out,
+ unsigned char count) {
+ unsigned char i;
+
+ for (i = 0u; i < count; ++i) {
+ if (!dir_page_read_byte(&out[i])) {
+ return 0u;
+ }
+ }
+ return 1u;
+}
+
+static unsigned char dir_page_upchar(unsigned char ch) {
+ ch &= 0x7Fu;
+ if (ch >= 'a' && ch <= 'z') {
+ return (unsigned char)(ch - ('a' - 'A'));
+ }
+ return ch;
+}
+
+static unsigned char dir_page_type_from_text(const char *type_text) {
+ unsigned char a;
+ unsigned char b;
+ unsigned char c;
+
+ a = dir_page_upchar((unsigned char)type_text[0]);
+ b = dir_page_upchar((unsigned char)type_text[1]);
+ c = dir_page_upchar((unsigned char)type_text[2]);
+
+ if (a == 'S' && b == 'E' && c == 'Q') return CBM_T_SEQ;
+ if (a == 'P' && b == 'R' && c == 'G') return CBM_T_PRG;
+ if (a == 'U' && b == 'S' && c == 'R') return CBM_T_USR;
+ if (a == 'R' && b == 'E' && c == 'L') return CBM_T_REL;
+ if (a == 'D' && b == 'I' && c == 'R') return CBM_T_DIR;
+ if (a == 'C' && b == 'B' && c == 'M') return CBM_T_CBM;
+ if (a == 'D' && b == 'E' && c == 'L') return CBM_T_DEL;
+ return CBM_T_DEL;
+}
+
+static unsigned char dir_page_type_matches(unsigned char filter_type,
+ unsigned char type) {
+ return (unsigned char)(filter_type == DIR_PAGE_TYPE_ANY || filter_type == type);
+}
+
+unsigned char dir_page_read(unsigned char device,
+ unsigned char start_index,
+ unsigned char filter_type,
+ DirPageEntry *entries,
+ unsigned char max_entries,
+ unsigned char *out_count,
+ unsigned char *out_total_count) {
+ unsigned char ptr[2];
+ unsigned char num[2];
+ unsigned char ch;
+ unsigned char count;
+ unsigned char total_count;
+ unsigned char first_line;
+ unsigned char in_quotes;
+ unsigned char name_pos;
+ unsigned char type_pos;
+ unsigned char past_space;
+ unsigned char entry_type;
+ char name_text[DIR_PAGE_NAME_LEN];
+ char type_text[4];
+
+ count = 0u;
+ total_count = 0u;
+ if (out_count != 0) {
+ *out_count = 0u;
+ }
+ if (out_total_count != 0) {
+ *out_total_count = 0u;
+ }
+
+ dir_page_cleanup_io();
+ if (cbm_open(DIR_PAGE_LFN_DIR, device, 0, "$") != 0) {
+ dir_page_cleanup_io();
+ return DIR_PAGE_RC_IO;
+ }
+
+ dir_page_read_reset();
+ (void)dir_page_read_bytes(ptr, 2u);
+ first_line = 1u;
+
+ while (1) {
+ if (!dir_page_read_bytes(ptr, 2u)) {
+ break;
+ }
+ if (!dir_page_read_bytes(num, 2u)) {
+ break;
+ }
+ if (ptr[0] == 0u && ptr[1] == 0u) {
+ break;
+ }
+
+ in_quotes = 0u;
+ name_pos = 0u;
+ name_text[0] = 0;
+ while (1) {
+ if (!dir_page_read_byte(&ch) || ch == 0u) {
+ break;
+ }
+ if (ch == 0x22u) {
+ if (in_quotes) {
+ break;
+ }
+ in_quotes = 1u;
+ continue;
+ }
+ if (in_quotes && name_pos + 1u < DIR_PAGE_NAME_LEN) {
+ name_text[name_pos++] = (char)ch;
+ }
+ }
+ name_text[name_pos] = 0;
+
+ type_pos = 0u;
+ past_space = 0u;
+ type_text[0] = 0;
+ type_text[1] = 0;
+ type_text[2] = 0;
+ type_text[3] = 0;
+
+ if (ch != 0u) {
+ while (1) {
+ if (!dir_page_read_byte(&ch) || ch == 0u) {
+ break;
+ }
+ if (!past_space) {
+ if (ch != ' ' && ch != 0xA0u) {
+ past_space = 1u;
+ if (type_pos < 3u) {
+ type_text[type_pos++] = (char)ch;
+ }
+ }
+ } else if (type_pos < 3u && ch != ' ' && ch != 0xA0u) {
+ type_text[type_pos++] = (char)ch;
+ }
+ }
+ }
+
+ if (first_line) {
+ first_line = 0u;
+ continue;
+ }
+ if (name_pos == 0u) {
+ continue;
+ }
+
+ entry_type = dir_page_type_from_text(type_text);
+ if (!dir_page_type_matches(filter_type, entry_type)) {
+ continue;
+ }
+
+ if (total_count >= start_index && count < max_entries && entries != 0) {
+ strcpy(entries[count].name, name_text);
+ entries[count].type = entry_type;
+ ++count;
+ }
+ if (total_count != 255u) {
+ ++total_count;
+ }
+ if (total_count > (unsigned char)(start_index + max_entries)) {
+ break;
+ }
+ }
+
+ cbm_close(DIR_PAGE_LFN_DIR);
+ dir_page_cleanup_io();
+
+ if (out_count != 0) {
+ *out_count = count;
+ }
+ if (out_total_count != 0) {
+ *out_total_count = total_count;
+ }
+ return DIR_PAGE_RC_OK;
+}
+
+const char *dir_page_type_text(unsigned char type) {
+ switch (type) {
+ case CBM_T_SEQ: return "SEQ";
+ case CBM_T_PRG: return "PRG";
+ case CBM_T_USR: return "USR";
+ case CBM_T_REL: return "REL";
+ case CBM_T_DIR: return "DIR";
+ case CBM_T_CBM: return "CBM";
+ case CBM_T_DEL: return "DEL";
+ default: return "???";
+ }
+}
+
+unsigned char dir_page_type_mode(unsigned char type) {
+ switch (type) {
+ case CBM_T_PRG: return 'p';
+ case CBM_T_USR: return 'u';
+ case CBM_T_REL: return 'l';
+ default: return 's';
+ }
+}
diff --git a/src/apps/launcher/launcher_uci_dma.s b/src/apps/launcher/launcher_uci_dma.s
new file mode 100644
index 0000000..a1f99e5
--- /dev/null
+++ b/src/apps/launcher/launcher_uci_dma.s
@@ -0,0 +1,1153 @@
+;
+; launcher_uci_dma.s - Launcher-local Ultimate DOS REU loader.
+;
+; This module deliberately uses Ultimate DOS UCI only. It does not use SoftIEC.
+; The experimental launcher supplies an Ultimate DOS directory path from
+; apps.cfg; this module changes into that path, then loads plain filenames from
+; inside the image filesystem.
+;
+
+ .export _launcher_uci_dma_detect
+ .export _launcher_uci_dma_load_prg
+ .export _launcher_uci_dma_quiesce
+ .export _launcher_uci_dma_clear_stage
+ .export _launcher_uci_dma_available
+ .export _launcher_uci_dma_name
+ .export _launcher_uci_dma_reu_bank
+ .export _launcher_uci_dma_reu_offset
+ .export _launcher_uci_dma_max_len
+ .export _launcher_uci_dma_expected_load_addr
+ .export _launcher_uci_dma_loaded_size
+ .export _launcher_uci_dma_last_error
+ .export _launcher_uci_dma_dbg_stat0
+ .export _launcher_uci_dma_dbg_stat1
+ .export _launcher_uci_dma_image_dir
+ .export _launcher_uci_dma_image_name
+ .export _launcher_uci_dma_mount_name
+ .export _launcher_uci_dma_assume_mounted
+
+CPU_PORT = $0001
+
+UCI_STAT_DATA = $80
+UCI_STAT_STAT = $40
+UCI_STATE_MASK = $30
+UCI_STATE_IDLE = $00
+UCI_STATE_LAST = $20
+UCI_STATE_MORE = $30
+UCI_STAT_ABORT = $04
+UCI_STAT_ERROR = $08
+
+ERR_NO_UCI = $01
+ERR_OPEN = $02
+ERR_STAT = $03
+ERR_SIZE = $04
+ERR_HEADER = $05
+ERR_SEEK = $06
+ERR_LOAD = $07
+ERR_PATH = $08
+ERR_CD_DIR = $09
+ERR_CD_DIR_STATUS = $0A
+ERR_MOUNT = $0B
+ERR_MOUNT_STATUS = $0C
+ERR_CD_IMAGE = $0D
+ERR_CD_IMAGE_STATUS = $0E
+ERR_CD_ROOT = $0F
+ERR_CD_ROOT_STATUS = $10
+
+ .macro BCC_FAR target
+ bcs :+
+ jmp target
+:
+ .endmacro
+
+ .macro BEQ_FAR target
+ bne :+
+ jmp target
+:
+ .endmacro
+
+ .macro BNE_FAR target
+ beq :+
+ jmp target
+:
+ .endmacro
+
+ .segment "CODE"
+
+_launcher_uci_dma_detect:
+ lda #<$DF1C
+ ldx #>$DF1C
+ jsr try_base
+ bcs detect_yes
+ lda #<$DE1C
+ ldx #>$DE1C
+ jsr try_base
+ bcs detect_yes
+ lda #<$DFFC
+ ldx #>$DFFC
+ jsr try_base
+ bcs detect_yes
+ lda #$00
+ sta _launcher_uci_dma_available
+ tax
+ rts
+detect_yes:
+ lda #$01
+ sta _launcher_uci_dma_available
+ tax
+ rts
+
+try_base:
+ jsr set_uci_base
+ jsr uci_id
+ and #$7F
+ cmp #$49
+ beq try_base_yes
+ clc
+ rts
+try_base_yes:
+ sec
+ rts
+
+_launcher_uci_dma_load_prg:
+ lda #'0'
+ jsr debug_stage
+ lda #$00
+ sta _launcher_uci_dma_loaded_size
+ sta _launcher_uci_dma_loaded_size+1
+ sta _launcher_uci_dma_last_error
+ sta clipped_load
+ jsr _launcher_uci_dma_detect
+ bne load_have_uci
+ lda #ERR_NO_UCI
+ jmp load_fail
+load_have_uci:
+ lda #'1'
+ jsr debug_stage
+ jsr dos_identify
+ BCC_FAR load_no_uci_fail
+ jsr ctrl_get_drvinfo
+ BCC_FAR load_no_uci_fail
+ lda _launcher_uci_dma_name
+ sta open_name_abs+1
+ lda _launcher_uci_dma_name+1
+ sta open_name_abs+2
+ lda _launcher_uci_dma_image_dir
+ ora _launcher_uci_dma_image_dir+1
+ beq load_path_missing
+ lda _launcher_uci_dma_image_name
+ ora _launcher_uci_dma_image_name+1
+ beq load_path_missing
+ lda _launcher_uci_dma_mount_name
+ ora _launcher_uci_dma_mount_name+1
+ bne load_have_image_path
+load_path_missing:
+ lda #ERR_PATH
+ jmp load_fail
+load_have_image_path:
+ lda _launcher_uci_dma_assume_mounted
+ beq load_mount_image_path
+ lda #'5'
+ jsr debug_stage
+ jmp load_open_current_dir
+load_mount_image_path:
+ lda #root_name
+ sta cd_name_abs+2
+ jsr dos_cd
+ BCC_FAR load_cd_root_fail
+
+ lda _launcher_uci_dma_image_dir
+ sta cd_dir_check_abs+1
+ sta cd_dir_retry_slash_abs+1
+ sta cd_name_abs+1
+ lda _launcher_uci_dma_image_dir+1
+ sta cd_dir_check_abs+2
+ sta cd_dir_retry_slash_abs+2
+ sta cd_name_abs+2
+ ldy #$00
+cd_dir_check_abs:
+ lda $FFFF,y
+ bne cd_dir_has_text
+ lda #ERR_PATH
+ jmp load_fail
+cd_dir_has_text:
+ lda #'2'
+ jsr debug_stage
+ jsr dos_cd
+ BCC_FAR load_cd_dir_fail
+ jsr status_ok
+ bcs cd_dir_ready
+ ldy #$00
+cd_dir_retry_slash_abs:
+ lda $FFFF,y
+ cmp #'/'
+ bne cd_dir_status_retry_fail
+ iny
+ lda _launcher_uci_dma_image_dir
+ clc
+ adc #$01
+ sta cd_name_abs+1
+ lda _launcher_uci_dma_image_dir+1
+ adc #$00
+ sta cd_name_abs+2
+ jsr dos_cd
+ BCC_FAR load_cd_dir_fail
+ jsr status_ok
+ bcs cd_dir_ready
+cd_dir_status_retry_fail:
+ jmp load_cd_dir_status_fail
+
+cd_dir_ready:
+ lda _launcher_uci_dma_image_name
+ sta cd_image_check_abs+1
+ sta cd_name_abs+1
+ lda _launcher_uci_dma_image_name+1
+ sta cd_image_check_abs+2
+ sta cd_name_abs+2
+ lda _launcher_uci_dma_mount_name
+ sta cd_mount_name_abs+1
+ lda _launcher_uci_dma_mount_name+1
+ sta cd_mount_name_abs+2
+ ldy #$00
+cd_image_empty_check:
+cd_image_check_abs:
+ lda $FFFF,y
+ bne cd_image_has_text
+ lda #ERR_PATH
+ jmp load_fail
+cd_image_has_text:
+ lda #'3'
+ jsr debug_stage
+ jsr dos_mount_image
+ BCC_FAR load_mount_fail
+ lda #'4'
+ jsr debug_stage
+ jsr dos_cd
+ BCC_FAR load_cd_image_fail
+ jsr status_ok
+ bcs cd_image_status_ok
+ lda stat_len
+ BEQ_FAR cd_image_status_ok
+ lda _launcher_uci_dma_mount_name
+ sta cd_name_abs+1
+ lda _launcher_uci_dma_mount_name+1
+ sta cd_name_abs+2
+ jsr dos_cd
+ BCC_FAR load_cd_image_fail
+ jsr status_ok
+ bcs cd_image_status_ok
+ lda stat_len
+ BEQ_FAR cd_image_status_ok
+ jmp load_cd_image_status_fail
+cd_image_status_ok:
+ lda #'5'
+ jsr debug_stage
+
+load_open_current_dir:
+ jsr dos_open_read
+ BCC_FAR load_open_fail
+ jsr status_ok
+ BCC_FAR load_open_fail
+ lda #'7'
+ jsr debug_stage
+
+ jsr dos_file_info
+ BCC_FAR load_stat_fail
+ jsr data_or_status_ok
+ BCC_FAR load_stat_fail
+ lda data_len
+ cmp #$04
+ BCC_FAR load_stat_fail
+ lda data_buf+2
+ ora data_buf+3
+ BNE_FAR load_size_fail
+ lda data_buf
+ sec
+ sbc #$02
+ sta remaining_lo
+ lda data_buf+1
+ sbc #$00
+ sta remaining_hi
+ BCC_FAR load_size_fail
+ lda remaining_lo
+ ora remaining_hi
+ BEQ_FAR load_size_fail
+ lda _launcher_uci_dma_max_len+1
+ cmp remaining_hi
+ bcc load_size_fail_local
+ bne load_size_ok
+ lda _launcher_uci_dma_max_len
+ cmp remaining_lo
+ bcs load_size_ok
+load_size_fail_local:
+ lda _launcher_uci_dma_expected_load_addr
+ cmp #$00
+ BNE_FAR load_size_fail
+ lda _launcher_uci_dma_expected_load_addr+1
+ cmp #$8E
+ BNE_FAR load_size_fail
+ lda _launcher_uci_dma_max_len
+ BNE_FAR load_size_fail
+ lda _launcher_uci_dma_max_len+1
+ cmp #$38
+ BNE_FAR load_size_fail
+ lda remaining_hi
+ cmp #$3A
+ bcc load_size_clip_overlay
+ BNE_FAR load_size_fail
+ lda remaining_lo
+ BNE_FAR load_size_fail
+load_size_clip_overlay:
+ lda #$00
+ sta remaining_lo
+ lda #$38
+ sta remaining_hi
+ lda #$01
+ sta clipped_load
+ jmp load_size_ok
+load_size_ok:
+ lda #$00
+ sta _launcher_uci_dma_loaded_size
+ sta _launcher_uci_dma_loaded_size+1
+
+ jsr dos_read_header
+ BCC_FAR load_header_fail
+ jsr data_or_status_ok
+ BCC_FAR load_header_fail
+ lda #'8'
+ jsr debug_stage
+ lda data_len
+ cmp #$02
+ BCC_FAR load_header_fail
+ lda data_buf
+ cmp _launcher_uci_dma_expected_load_addr
+ BNE_FAR load_header_fail
+ lda data_buf+1
+ cmp _launcher_uci_dma_expected_load_addr+1
+ BNE_FAR load_header_fail
+
+ jsr dos_seek_payload
+ BCC_FAR load_seek_fail
+ jsr status_ok
+ BCC_FAR load_seek_fail
+ lda #'9'
+ jsr debug_stage
+
+ lda _launcher_uci_dma_reu_offset
+ sta current_off_lo
+ lda _launcher_uci_dma_reu_offset+1
+ sta current_off_hi
+load_loop:
+ lda remaining_lo
+ ora remaining_hi
+ beq load_success
+ lda remaining_lo
+ sta chunk_lo
+ lda remaining_hi
+ sta chunk_hi
+ lda #'9'
+ jsr debug_stage
+ jsr dos_load_reu_chunk
+ BCC_FAR load_load_fail
+ jsr status_ok
+ bcs load_chunk_status_ok
+ lda clipped_load
+ BEQ_FAR load_load_fail
+load_chunk_status_ok:
+
+ lda current_off_lo
+ clc
+ adc chunk_lo
+ sta current_off_lo
+ lda current_off_hi
+ adc chunk_hi
+ sta current_off_hi
+
+ lda _launcher_uci_dma_loaded_size
+ clc
+ adc chunk_lo
+ sta _launcher_uci_dma_loaded_size
+ lda _launcher_uci_dma_loaded_size+1
+ adc chunk_hi
+ sta _launcher_uci_dma_loaded_size+1
+
+ lda remaining_lo
+ sec
+ sbc chunk_lo
+ sta remaining_lo
+ lda remaining_hi
+ sbc chunk_hi
+ sta remaining_hi
+ jmp load_loop
+
+load_success:
+ jsr dos_close
+ lda #$00
+ sta _launcher_uci_dma_last_error
+ lda #$01
+ tax
+ rts
+load_stat_fail:
+ lda #ERR_STAT
+ jmp load_fail_close
+load_size_fail:
+ lda data_buf
+ sta _launcher_uci_dma_dbg_stat0
+ lda data_buf+1
+ sta _launcher_uci_dma_dbg_stat1
+ jsr dos_close
+ lda #ERR_SIZE
+ sta _launcher_uci_dma_last_error
+ lda #$00
+ tax
+ rts
+load_open_fail:
+ lda #ERR_OPEN
+ jmp load_fail_close
+load_header_fail:
+ lda #ERR_HEADER
+ jmp load_fail_close
+load_seek_fail:
+ lda #ERR_SEEK
+ jmp load_fail_close
+load_load_fail:
+ lda #ERR_LOAD
+ jmp load_fail_close
+load_cd_root_fail:
+ lda #ERR_CD_ROOT
+ jmp load_fail_close
+load_cd_root_status_fail:
+ lda #ERR_CD_ROOT_STATUS
+ jmp load_fail_close
+load_cd_dir_fail:
+ lda #ERR_CD_DIR
+ jmp load_fail_close
+load_cd_dir_status_fail:
+ lda #ERR_CD_DIR_STATUS
+ jmp load_fail_close
+load_mount_fail:
+ lda #ERR_MOUNT
+ jmp load_fail_close
+load_mount_status_fail:
+ lda #ERR_MOUNT_STATUS
+ jmp load_fail_close
+load_cd_image_fail:
+ lda #ERR_CD_IMAGE
+ jmp load_fail_close
+load_cd_image_status_fail:
+ lda #ERR_CD_IMAGE_STATUS
+ jmp load_fail_close
+load_path_fail:
+ lda #ERR_PATH
+load_fail_close:
+ pha
+ jsr dos_close
+ pla
+load_fail:
+ sta _launcher_uci_dma_last_error
+ lda stat_buf
+ sta _launcher_uci_dma_dbg_stat0
+ lda stat_buf+1
+ sta _launcher_uci_dma_dbg_stat1
+ lda #$00
+ tax
+ rts
+load_no_uci_fail:
+ lda #ERR_NO_UCI
+ jmp load_fail
+
+dos_identify:
+ jsr sync_interface
+ BCC_FAR command_fail
+ lda #$01
+ jsr uci_write_cmd
+ lda #$01
+ jsr uci_write_cmd
+ jsr uci_push_cmd
+ jmp drain_response
+
+ctrl_get_drvinfo:
+ jsr sync_interface
+ BCC_FAR command_fail
+ lda #$04
+ jsr uci_write_cmd
+ lda #$29
+ jsr uci_write_cmd
+ lda #$00
+ jsr uci_write_cmd
+ jsr uci_push_cmd
+ jmp drain_response
+
+dos_close:
+ jsr sync_interface
+ BCC_FAR command_fail
+ lda #$01
+ jsr uci_write_cmd
+ lda #$03
+ jsr uci_write_cmd
+ jsr uci_push_cmd
+ jmp drain_response
+
+dos_cd:
+ jsr sync_interface
+ BCC_FAR command_fail
+ lda #$01
+ jsr uci_write_cmd
+ lda #$11
+ jsr uci_write_cmd
+ ldy #$00
+dos_cd_name:
+cd_name_abs:
+ lda $FFFF,y
+ beq dos_cd_push
+ jsr uci_write_path_cmd
+ iny
+ bne dos_cd_name
+dos_cd_push:
+ jsr uci_push_cmd
+ jmp drain_response
+
+dos_cd_path:
+ ldy #$00
+cd_path_read_abs:
+ lda $FFFF,y
+ beq dos_cd_path_done
+ cmp #'/'
+ bne dos_cd_path_segment
+ lda #$01
+ jsr cd_path_advance
+ jmp dos_cd_path
+dos_cd_path_segment:
+ jsr sync_interface
+ BCC_FAR command_fail
+ lda #$01
+ jsr uci_write_cmd
+ lda #$11
+ jsr uci_write_cmd
+ ldy #$00
+dos_cd_path_seg_loop:
+cd_path_seg_read_abs:
+ lda $FFFF,y
+ beq dos_cd_path_seg_push
+ cmp #'/'
+ beq dos_cd_path_seg_push
+ jsr uci_write_path_cmd
+ iny
+ bne dos_cd_path_seg_loop
+dos_cd_path_seg_push:
+ jsr uci_push_cmd
+ jsr drain_response
+ bcc dos_cd_path_fail
+ jsr status_ok
+ bcc dos_cd_path_fail
+ tya
+ jsr cd_path_advance
+ jmp dos_cd_path
+dos_cd_path_done:
+ sec
+ rts
+dos_cd_path_fail:
+ clc
+ rts
+
+cd_path_advance:
+ clc
+ adc cd_path_read_abs+1
+ sta cd_path_read_abs+1
+ sta cd_path_seg_read_abs+1
+ lda cd_path_read_abs+2
+ adc #$00
+ sta cd_path_read_abs+2
+ sta cd_path_seg_read_abs+2
+ rts
+
+dos_mount_image:
+ jsr sync_interface
+ BCC_FAR command_fail
+ lda #$01
+ jsr uci_write_cmd
+ lda #$23
+ jsr uci_write_cmd
+ lda #$08
+ jsr uci_write_cmd
+ ldy #$00
+dos_mount_name:
+cd_mount_name_abs:
+ lda $FFFF,y
+ beq dos_mount_push
+ jsr uci_write_path_cmd
+ iny
+ bne dos_mount_name
+dos_mount_push:
+ jsr uci_push_cmd
+ jmp drain_response
+
+dos_open_read:
+ jsr sync_interface
+ BCC_FAR command_fail
+ lda #$01
+ jsr uci_write_cmd
+ lda #$02
+ jsr uci_write_cmd
+ lda #$01
+ jsr uci_write_cmd
+ ldy #$00
+dos_open_name:
+open_name_abs:
+ lda $FFFF,y
+ beq dos_open_push
+ jsr uci_write_cmd
+ iny
+ bne dos_open_name
+dos_open_push:
+ jsr uci_push_cmd
+ jmp drain_response
+
+dos_read_header:
+ jsr sync_interface
+ BCC_FAR command_fail
+ lda #$01
+ jsr uci_write_cmd
+ lda #$04
+ jsr uci_write_cmd
+ lda #$02
+ jsr uci_write_cmd
+ lda #$00
+ jsr uci_write_cmd
+ jsr uci_push_cmd
+ jmp drain_response
+
+dos_file_info:
+ jsr sync_interface
+ BCC_FAR command_fail
+ lda #$01
+ jsr uci_write_cmd
+ lda #$07
+ jsr uci_write_cmd
+ jsr uci_push_cmd
+ jmp drain_response
+
+dos_seek_payload:
+ jsr sync_interface
+ BCC_FAR command_fail
+ lda #$01
+ jsr uci_write_cmd
+ lda #$06
+ jsr uci_write_cmd
+ lda #$02
+ jsr uci_write_cmd
+ lda #$00
+ jsr uci_write_cmd
+ jsr uci_write_cmd
+ jsr uci_write_cmd
+ jsr uci_push_cmd
+ jmp drain_response
+
+dos_load_reu_chunk:
+ jsr sync_interface
+ BCC_FAR command_fail
+ lda #$01
+ jsr uci_write_cmd
+ lda #$21
+ jsr uci_write_cmd
+ lda current_off_lo
+ jsr uci_write_cmd
+ lda current_off_hi
+ jsr uci_write_cmd
+ lda _launcher_uci_dma_reu_bank
+ jsr uci_write_cmd
+ lda #$00
+ jsr uci_write_cmd
+ lda chunk_lo
+ jsr uci_write_cmd
+ lda chunk_hi
+ jsr uci_write_cmd
+ lda #$00
+ jsr uci_write_cmd
+ jsr uci_write_cmd
+ jsr uci_push_cmd
+ jmp drain_response
+
+command_fail:
+ clc
+ rts
+
+uci_write_path_cmd:
+ cmp #'a'
+ bcc uci_write_path_raw
+ cmp #'z'+1
+ bcs uci_write_path_raw
+ and #$DF
+uci_write_path_raw:
+ jmp uci_write_cmd
+
+debug_stage:
+ ; Hardware note: this visible screen store is part of the
+ ; C64U-proven UCI transaction shape. Replacing the stage writes with
+ ; private BSS stores made the same logical loader fall back on real
+ ; hardware, so do not "clean this up" without retesting on C64U.
+ sta $052C
+ rts
+
+sync_interface:
+ lda #$40
+ sta timeout_hi
+sync_loop:
+ jsr uci_status
+ sta last_status
+ and #UCI_STAT_ERROR
+ beq sync_no_error
+ jsr uci_clear_error
+ lda #$40
+ sta timeout_hi
+ jmp sync_loop
+sync_no_error:
+ lda last_status
+ and #UCI_STAT_ABORT
+ beq sync_no_abort
+ jsr uci_abort
+ lda #$40
+ sta timeout_hi
+ jmp sync_loop
+sync_no_abort:
+ lda last_status
+ and #UCI_STAT_DATA
+ beq sync_no_data
+ jsr uci_read_data
+ lda #$40
+ sta timeout_hi
+ jmp sync_loop
+sync_no_data:
+ lda last_status
+ and #UCI_STAT_STAT
+ beq sync_no_stat
+ jsr uci_read_stat
+ lda #$40
+ sta timeout_hi
+ jmp sync_loop
+sync_no_stat:
+ lda last_status
+ and #UCI_STATE_MASK
+ cmp #UCI_STATE_LAST
+ beq sync_accept
+ cmp #UCI_STATE_MORE
+ beq sync_accept
+ lda last_status
+ and #$31
+ beq sync_ok
+ dec timeout_hi
+ bne sync_loop
+ jsr uci_abort
+ clc
+ rts
+sync_accept:
+ jsr uci_accept_data
+ lda #$40
+ sta timeout_hi
+ jmp sync_loop
+sync_ok:
+ sec
+ rts
+
+wait_data_state:
+ lda #$80
+ sta timeout_hi
+ ldy #$00
+wait_state_loop:
+ jsr uci_status
+ sta last_status
+ and #UCI_STAT_ERROR
+ bne wait_state_fail
+ lda last_status
+ and #UCI_STATE_MASK
+ cmp #UCI_STATE_LAST
+ beq wait_state_ok
+ cmp #UCI_STATE_MORE
+ beq wait_state_ok
+ cmp #UCI_STATE_IDLE
+ beq wait_state_ok
+ dey
+ bne wait_state_loop
+ dec timeout_hi
+ bne wait_state_loop
+wait_state_fail:
+ clc
+ rts
+wait_state_ok:
+ sec
+ rts
+
+wait_idle:
+ lda #$40
+ sta timeout_hi
+ ldy #$00
+wait_idle_loop:
+ jsr uci_status
+ sta last_status
+ lda last_status
+ and #$31
+ beq wait_idle_ok
+ dey
+ bne wait_idle_loop
+ dec timeout_hi
+ bne wait_idle_loop
+ clc
+ rts
+wait_idle_ok:
+ sec
+ rts
+
+drain_response:
+ lda #$00
+ sta data_len
+ sta stat_len
+ jsr wait_data_state
+ bcs drain_loop
+ clc
+ rts
+drain_loop:
+ jsr uci_status
+ sta last_status
+ and #UCI_STAT_ERROR
+ beq drain_no_error
+ clc
+ rts
+drain_no_error:
+ lda last_status
+ and #UCI_STATE_MASK
+ sta current_state
+ beq drain_done
+ cmp #UCI_STATE_LAST
+ beq drain_state_ok
+ cmp #UCI_STATE_MORE
+ beq drain_state_ok
+ jsr wait_data_state
+ bcs drain_loop
+ clc
+ rts
+drain_state_ok:
+ lda #$10
+ sta timeout_hi
+ ldy #$00
+drain_bytes:
+ jsr uci_status
+ sta last_status
+ and #UCI_STAT_DATA
+ beq drain_check_stat
+ jsr uci_read_data
+ ldx data_len
+ cpx #$20
+ bcs drain_data_count
+ sta data_buf,x
+drain_data_count:
+ lda data_len
+ cmp #$FF
+ beq drain_reset_guard
+ inc data_len
+ jmp drain_reset_guard
+drain_check_stat:
+ lda last_status
+ and #UCI_STAT_STAT
+ beq drain_wait_byte
+ jsr uci_read_stat
+ ldx stat_len
+ cpx #$08
+ bcs drain_reset_guard
+ sta stat_buf,x
+ inc stat_len
+drain_reset_guard:
+ lda #$10
+ sta timeout_hi
+ ldy #$00
+ jmp drain_bytes
+drain_wait_byte:
+ dey
+ bne drain_bytes
+ dec timeout_hi
+ bne drain_bytes
+ jsr uci_accept_data
+ lda current_state
+ cmp #UCI_STATE_LAST
+ bne drain_more
+ jsr wait_idle
+ sec
+ rts
+drain_more:
+ jsr wait_data_state
+ bcc drain_more_fail
+ jmp drain_loop
+drain_more_fail:
+ clc
+ rts
+drain_done:
+ sec
+ rts
+
+status_ok:
+ lda stat_len
+ beq status_not_ok
+ lda stat_buf
+ cmp #'0'
+ bne status_not_ok
+ lda stat_buf+1
+ cmp #'0'
+ bne status_not_ok
+status_is_ok:
+ sec
+ rts
+status_not_ok:
+ clc
+ rts
+
+data_or_status_ok:
+ lda stat_len
+ beq data_or_status_from_data
+ jmp status_ok
+data_or_status_from_data:
+ lda data_len
+ beq status_not_ok
+ sec
+ rts
+
+set_uci_base:
+ sta uci_base_lo
+ stx uci_base_hi
+ lda uci_base_lo
+ sta uci_status_abs+1
+ sta uci_push_abs+1
+ sta uci_accept_abs+1
+ sta uci_abort_abs+1
+ sta uci_clear_abs+1
+ clc
+ adc #$01
+ sta uci_write_abs+1
+ sta uci_id_abs+1
+ clc
+ adc #$01
+ sta uci_data_abs+1
+ clc
+ adc #$01
+ sta uci_stat_abs+1
+ lda uci_base_hi
+ sta uci_status_abs+2
+ sta uci_push_abs+2
+ sta uci_accept_abs+2
+ sta uci_abort_abs+2
+ sta uci_clear_abs+2
+ sta uci_write_abs+2
+ sta uci_id_abs+2
+ sta uci_data_abs+2
+ sta uci_stat_abs+2
+ rts
+
+uci_write_cmd:
+ sta uci_value
+ php
+ sei
+ lda CPU_PORT
+ pha
+ and #$F8
+ ora #$07
+ sta CPU_PORT
+ lda uci_value
+uci_write_abs:
+ sta $DF1D
+ pla
+ sta CPU_PORT
+ plp
+ lda uci_value
+ rts
+
+uci_id:
+ php
+ sei
+ lda CPU_PORT
+ pha
+ and #$F8
+ ora #$07
+ sta CPU_PORT
+uci_id_abs:
+ lda $DF1D
+ tax
+ pla
+ sta CPU_PORT
+ plp
+ txa
+ rts
+
+uci_status:
+ php
+ sei
+ lda CPU_PORT
+ pha
+ and #$F8
+ ora #$07
+ sta CPU_PORT
+uci_status_abs:
+ lda $DF1C
+ tax
+ pla
+ sta CPU_PORT
+ plp
+ txa
+ rts
+
+uci_read_data:
+ php
+ sei
+ lda CPU_PORT
+ pha
+ and #$F8
+ ora #$07
+ sta CPU_PORT
+uci_data_abs:
+ lda $DF1E
+ tax
+ pla
+ sta CPU_PORT
+ plp
+ txa
+ rts
+
+uci_read_stat:
+ php
+ sei
+ lda CPU_PORT
+ pha
+ and #$F8
+ ora #$07
+ sta CPU_PORT
+uci_stat_abs:
+ lda $DF1F
+ tax
+ pla
+ sta CPU_PORT
+ plp
+ txa
+ rts
+
+uci_push_cmd:
+ php
+ sei
+ lda CPU_PORT
+ pha
+ and #$F8
+ ora #$07
+ sta CPU_PORT
+ lda #$01
+uci_push_abs:
+ sta $DF1C
+ pla
+ sta CPU_PORT
+ plp
+ rts
+
+uci_accept_data:
+ php
+ sei
+ lda CPU_PORT
+ pha
+ and #$F8
+ ora #$07
+ sta CPU_PORT
+ lda #$02
+uci_accept_abs:
+ sta $DF1C
+ pla
+ sta CPU_PORT
+ plp
+ rts
+
+uci_abort:
+ php
+ sei
+ lda CPU_PORT
+ pha
+ and #$F8
+ ora #$07
+ sta CPU_PORT
+ lda #$04
+uci_abort_abs:
+ sta $DF1C
+ pla
+ sta CPU_PORT
+ plp
+ rts
+
+uci_clear_error:
+ php
+ sei
+ lda CPU_PORT
+ pha
+ and #$F8
+ ora #$07
+ sta CPU_PORT
+ lda #$08
+uci_clear_abs:
+ sta $DF1C
+ pla
+ sta CPU_PORT
+ plp
+ rts
+
+_launcher_uci_dma_quiesce:
+ lda _launcher_uci_dma_available
+ beq quiesce_done
+ jsr sync_interface
+ bcc quiesce_done
+ jsr wait_idle
+quiesce_done:
+ rts
+
+_launcher_uci_dma_clear_stage:
+ lda #' '
+ sta $052C
+ sta $052D
+ sta $052E
+ sta $052F
+ sta $0530
+ sta $0531
+ sta $0532
+ sta $0533
+ rts
+
+ .segment "RODATA"
+
+root_name: .byte "/", 0
+
+ .segment "BSS"
+
+_launcher_uci_dma_available: .res 1
+_launcher_uci_dma_name: .res 2
+_launcher_uci_dma_reu_bank: .res 1
+_launcher_uci_dma_reu_offset: .res 2
+_launcher_uci_dma_max_len: .res 2
+_launcher_uci_dma_expected_load_addr: .res 2
+_launcher_uci_dma_loaded_size: .res 2
+_launcher_uci_dma_last_error: .res 1
+_launcher_uci_dma_dbg_stat0: .res 1
+_launcher_uci_dma_dbg_stat1: .res 1
+_launcher_uci_dma_image_dir: .res 2
+_launcher_uci_dma_image_name: .res 2
+_launcher_uci_dma_mount_name: .res 2
+_launcher_uci_dma_assume_mounted: .res 1
+
+uci_base_lo: .res 1
+uci_base_hi: .res 1
+uci_value: .res 1
+last_status: .res 1
+current_state: .res 1
+timeout_hi: .res 1
+data_len: .res 1
+stat_len: .res 1
+remaining_lo: .res 1
+remaining_hi: .res 1
+chunk_lo: .res 1
+chunk_hi: .res 1
+current_off_lo: .res 1
+current_off_hi: .res 1
+clipped_load: .res 1
+data_buf: .res 32
+stat_buf: .res 8
diff --git a/src/apps/readme/readme_lite.md b/src/apps/readme/readme_lite.md
index 588c9e0..a42ed6e 100644
--- a/src/apps/readme/readme_lite.md
+++ b/src/apps/readme/readme_lite.md
@@ -1,19 +1,21 @@
-## ReadyOS PRECOG 0.2.4
+## ReadyOS PRECOG 0.2.5
The goal is **fast app switching** for Commodore 64 Ultimate use,
tuned to stay usable at both 1MHz and 48MHz while remaining
C64-class practical.
Current snapshot:
-- Base release: **0.2.4**
+- Base release: **0.2.5**
- Runtime target: clean behavior from stock-speed C64 use up through
Ultimate turbo workflows
- Media layout: profile-based release media under `Releases///` with external `helpme.md`
instructions for the selected build
-- Development artifacts use the plain **0.2.4** version stamp.
+- Development artifacts use the plain **0.2.5** version stamp.
Local development builds may still include an internal trailing letter.
- New since 0.1.5: **quicknotes**, **simple files**, **simple cells**,
**sidetris**, **deminer**, **system info**, and **EasyFlash**
+- Experimental C64U direct-to-REU disk loading exists as an opt-in
+ build; normal release builds retain the portable disk loader.
---
diff --git a/src/apps/readybasic/READYBASIC_CURRENT_DESIGN.md b/src/apps/readybasic/READYBASIC_CURRENT_DESIGN.md
index 9f5094a..516131e 100644
--- a/src/apps/readybasic/READYBASIC_CURRENT_DESIGN.md
+++ b/src/apps/readybasic/READYBASIC_CURRENT_DESIGN.md
@@ -23,6 +23,14 @@ That special report is generated from the current ReadyBASIC map/linker/source
facts and shows the proportional C64 RAM, cold-load seed, steady-state BASIC
workspace, under-ROM slot, and assigned ReadyBASIC core/code bank pictures.
+The current example inventory is build-owned rather than handwritten into disk
+images. `READYBASIC_GFX_DEMO_NAMES` in the Makefile contains 32 programs from
+`rbgfx01_modes` through `rbgfx32_convex_poly`; `READYBASIC_SOUND_DEMO_NAMES`
+contains 6 programs from `rbsnd01_sid_basics` through
+`rbsnd06_three_voice`. Regular and EasyFlash demo/probe wrappers are generated
+from the same sources, so documentation should refer to those lists instead of
+copying an older partial set.
+
## Current Module/Submodule Snapshot
This section is the current source of truth for ReadyBASIC's module/submodule
@@ -36,14 +44,20 @@ Measured from the current `obj/readybasic.map`:
|---|---:|
| `BASIC_START` | `$2AC1` |
| Empty BASIC free bytes | `30013` |
-| `ENTRY` | `$1000-$1102`, `$0103` / 259B |
-| `RESIDENT` | `$1200-$2ABE`, `$18BF` / 6335B |
+| `ENTRY` | `$1000-$11FF`, `$0200` / 512B |
+| `RESIDENT` | `$1200-$2ABF`, `$18C0` / 6336B |
| BASIC sentinel | `$2AC0` |
-| Common under-ROM helper | `$A000-$A364`, `$0365` / 869B |
-| Slot 0 / module 1 | `$A800-$AEC6`, `$06C7` / 1735B |
-| Slot 1 / module 2 | `$B000-$B238`, `$0239` / 569B |
-| Slot 2 / overlays | `$B800-$B83E`, proof slices |
-| `BRIDGE` | `$C000-$C1F8`, `$01F9` / 505B |
+| Common under-ROM helper | `$A000-$A78A`, `$078B` / 1931B |
+| Slot 0 / module 1 | `$A800-$AFDB`, `$07DC` / 2012B |
+| Slot 1 / module 2/GFXCORE | `$B000-$B540`, `$0541` / 1345B |
+| Slot 2 / GFXPRIM | `$B800-$BF37`, `$0738` / 1848B |
+| Slot 2 overlay 1 / GFXSPR | `$B800-$BA71` replacement overlay, `$0272` / 626B |
+| Slot 2 overlay 2 / INPUTEV | `$B800-$B86C` replacement overlay, `$006D` / 109B |
+| Slot 2 overlay 3 / GFXPOLY | `$B800-$BF78` replacement overlay, `$0779` / 1913B |
+| Slot 2 overlay 4 / GFXDL | `$B800-$BF82` replacement overlay, `$0783` / 1923B |
+| Slot 2 overlay 5 / GFXTILE | `$B800-$BCD9` replacement overlay, `$04DA` / 1242B |
+| Slot 2 overlay 6 / SIDCORE | `$B800-$BA0D` replacement overlay, `$020E` / 526B |
+| `BRIDGE` | `$C000-$C1FE`, `$01FF` / 511B |
| Shared frames/buffers | `$C200-$C5FF` |
| `REGSEED` load-only registry | `$5000-$600F`, `$1010` / 4112B |
@@ -75,6 +89,33 @@ SEQ packages named `rbm.` and streams them through the `$C500` page buffer
into REU, rather than loading them as PRG files. Current sample packages are
`rbm.sample1`, `rbm.sample2`, and `rbm.sample3`.
+Phase 1 through Phase 5 graphics commands are also built in and prestashed to the
+assigned code bank; they do not require `ZMODLD`. They use module id `3`: `GFXCORE`
+submodule `16` in slot 1, `GFXPRIM` submodule `17` in slot 2, `GFXSPR`
+submodule `18` as slot-2 overlay 1, and `INPUTEV` submodule `19` as slot-2
+overlay 2, `GFXPOLY` submodule `20` as slot-2 overlay 3, `GFXDL` submodule `21`
+as slot-2 overlay 4, and `GFXTILE` submodule `22` as slot-2 overlay 5. The
+surface handle entry points `GFXSURF` and `GFXBLIT` use the existing system slot
+allocator path so typed REU graphics handles can share the same handle directory
+as `BUFMAKE` and `SCRCAP`.
+
+Sound Phase 1 is also built in and does not require `ZMODLD`. It uses module id
+`4`: `SIDCORE` submodule `23` as slot-2 overlay 6, prestashed to the assigned
+code bank at `$7800`.
+
+`GFXSPR`, `INPUTEV`, `GFXPOLY`, `GFXDL`, `GFXTILE`, and `SIDCORE` are true slot-2 replacement overlays. They are
+loaded from the second cold-only command seed window (`CMDPACK2`) into fixed
+assigned code-bank offsets `$5000`, `$5800`, `$6000`, `$6800`, `$7000`, and `$7800`, then fetched into
+`$B800` only when their commands run. This removes the old slot-2 packing
+mismatch where `GFXPRIM`, `GFXSPR`, `INPUTEV`, and polygon work would otherwise
+consume one runtime strip.
+
+The graphics Bank D layout intentionally avoids ReadyBASIC/ReadyOS state:
+screen RAM is `$CC00-$CFFF`, sprite data is `$CA00-$CBFF`, bitmap/charset RAM
+is `$E000-$FFFF`, and color RAM is `$D800-$DBE7`. ReadyBASIC owns bridge/shared
+frames through `$C5FF`; the resident 1 KB shim owns `$C600-$C9FF`, with its
+expansion reserve below the stable ABI at `$C800`.
+
The naming nuance matters. A module is the logical command family identified by
module id. A module package/container is the disk SEQ file that carries
descriptors and payload records. A submodule is the runtime payload family that
@@ -190,9 +231,90 @@ the crunch hook to `IF 1 THEN :EXEC SHOW(7)`. `petcat`-built stored examples
should use the already-normalized `THEN :EXEC` form because they bypass the
interactive crunch hook.
-ReadyBASIC also recognizes manual prompt `EXIT` as the ReadyOS yield command.
-Program-line `EXIT` resume remains future work; the proven V1 path is direct
-prompt `EXIT`.
+ReadyBASIC recognizes manual prompt `EXIT` plus prompt-level `CTRL+B`, `F2`,
+and `F4` as ReadyOS navigation. Prompt hotkeys are detected by the KEYLOG
+preprocessing vector at `$028F/$0290` only after ReadyBASIC's IMAIN hook at
+`$0302/$0303` has marked the direct prompt active, input is coming from the
+keyboard, and BASIC is not executing a program statement. The execute hook clears
+that prompt-active flag before direct commands and stored program lines run. A
+legacy `TXTPTR < BASIC_START` check remains as a fallback for partially typed
+prompt lines, but it is not the sole proof of prompt state because `CURLIN` and
+`TXTPTR` can still point into the just-run program after `RUN` returns to
+`READY.`. KEYLOG records the requested ReadyOS action, consumes the decoded key
+state, and queues only Return. The CHRIN hook at `$0324/$0325` then discards the
+editor-returned character and dispatches the pending action before BASIC can
+store or execute any partial line. This keeps ordinary key repeat, cursor blink,
+line editing, and space handling owned by the ROM editor; ReadyBASIC no longer
+installs a CINV/IRQ scanner for prompt hotkeys and no longer injects visible
+`REM` text.
+ReadyBASIC also quarantines any still-held ReadyOS hotkey on cold/warm entry and
+waits, with a jiffy-bounded timeout, for the selected physical chord to be
+released before yielding through `CTRL+B`, `F2`, or `F4`. That release wait is
+what prevents one held function key from being seen by both the outgoing and
+incoming app.
+Program-line `EXIT` resume and running-program hotkeys remain future work; the
+proven paths are direct prompt `EXIT` and prompt-level navigation keys.
+
+## Phase 1, 2, And 3 Graphics Commands
+
+The current command catalog includes the command-only Phase 1 graphics surface
+plus the Phase 2 visible primitive/sprite-control additions and Phase 3 polygon
+overlay:
+
+| Command | Form | Notes |
+|---|---|---|
+| `GFXMODE` | `GFXMODE("HIRES")`, `M%=GFXMODE()` | Supports `TEXT`, `HIRES`, `MBITMAP`, `TILE`, and `MTILE`. |
+| `GFXTEXT` | `GFXTEXT()` | Restores ordinary text mode. |
+| `GFXCLEAR` | `GFXCLEAR(C)` | Clears Bank D screen/color RAM and bitmap RAM for bitmap modes. |
+| `GFXSURF` | `H%=GFXSURF("HIRES")` | Allocates typed graphics-surface handle `3` in the REU heap. |
+| `GFXTGT` | `GFXTGT(0)`, `GFXTGT(H%)` | Selects visible target `0` or records a typed graphics-surface handle. Immediate primitives still draw visible Bank D. |
+| `GFXBLIT` | `GFXBLIT(H%)` | Copies a typed graphics-surface handle's bitmap/screen/color layout from REU to Bank D. |
+| `GFXSYNC` | `GFXSYNC()` | Snapshots the current visible Bank D bitmap/screen/color layout into the selected `GFXTGT(H%)` surface. No dirty-rect queue yet. |
+| `PLOT` / `PNT` | `PLOT(X,Y,C)`, `PNT(X,Y,P%)` | Hires bitmap bit plot/read, multicolor bitmap pair plot/read, or tile cell write/read depending on mode. |
+| `LINE` / `RECT` / `FBOX` | five numeric args | Immediate primitive workers in `GFXPRIM`. |
+| `CIRCLE` / `FCIRCLE` | `CIRCLE(X,Y,R,C)`, `FCIRCLE(X,Y,R,C)` | Phase 2 immediate primitive additions. `CIRCLE` uses a compact midpoint outline worker; `FCIRCLE` currently proves the fill path with a bounding filled rectangle. |
+| `POLY` / `FPOLY` | `POLY(A%(0),COUNT,C)`, `FPOLY(A%(0),COUNT,C)` | Phase 3 array-backed polygons from BASIC integer array pairs. `FPOLY` is a conservative convex fan fill, not full scanline/concave fill yet. |
+| `PBMAKE` / `PBUFSET` / `PBDROP` | point-buffer handle lifecycle | Allocates typed REU point-buffer handle `4`, writes zero-based little-endian `x,y` point pairs, and releases the handle. |
+| `POLYH` / `FPOLYH` | `POLYH(H%,COUNT,C)`, `FPOLYH(H%,COUNT,C)` | Phase 3 REU point-buffer polygon handle forms. The originally proposed same-name `POLY(H%,...)` overload was not added so `BASIC_START` and bytes free stay fixed. |
+| `TILE` / `CHARAT` | `TILE(X,Y,CH,C)`, `CHARAT(X,Y,CH,C)` | Phase 2 cell write commands for Bank D tile modes and ordinary text mode demo output. |
+| `DLMAKE` / `DLRST` / `DLPLOT` / `DLLINE` / `DLRECT` / `DLFBOX` / `DLDRAW` | retained display-list handle commands | Phase 4 `GFXDL` overlay. `DLMAKE` allocates a one-page typed REU display list; `DLDRAW` replays plot/line/rectangle records. |
+| `CHRMAKE` / `CHRROW` / `CHRUSE` | charset handle commands | Phase 4 `GFXTILE` overlay. Creates an 8-page charset handle, writes individual character rows, and copies the charset to Bank D. Phase 5 screenshots prove visible Bank D tile rendering. |
+| `TSMAKE` / `TSSET` / `TMMAKE` / `TMSET` / `TMDRAW` | tileset/tilemap handle commands | Phase 4 `GFXTILE` overlay. Fixed 1-page tilesets and 4-page 40x25 tilemaps; no external resource loader yet. |
+| `MCELL` / `MCBG` | `MCELL(CX,CY,S1,S2,S3)`, `MCBG(C)` | Phase 4 explicit multicolor bitmap cell attributes and background color. |
+| `SIDRST` / `SIDOFF` | `SIDRST()` | Phase 1 sound `SIDCORE` overlay. Clears SID registers `$D400-$D418`. |
+| `VOL` | `VOL(VOL)` | Sets SID master volume `0..15`, preserving filter mode bits. |
+| `FRQ` / `PITCH` | `FRQ(V,F)`, `PITCH(V,N,O)` | Raw SID frequency or PAL note table frequency for voice `1..3`. `PITCH` sets frequency only; use `GATE`, `WAVE`, or `VOICE` to start sound. |
+| `PULSE` / `ADSR` | pulse width and envelope setup | `PULSE(V,W)` writes 12-bit pulse width. `ADSR(V,A,D,S,R)` writes SID nibble envelope values. |
+| `WAVE` / `GATE` | control register helpers | `WAVE(V,M)` writes the SID control byte; `GATE(V,ON)` sets or clears bit 0 without disturbing the other waveform/control bits. |
+| `VOICE` | `VOICE(V,F,W,AD,SR)` | Fast packed voice setup: frequency, control/wave byte, packed attack/decay byte, and packed sustain/release byte. This intentionally reuses an existing five-number parser signature to avoid resident growth. |
+| `FILTER` | `FILTER(CUTOFF,RES,ROUTE,MODE)` | Writes SID cutoff, resonance, route, and filter mode. Mode uses logical bits `1` low-pass, `2` band-pass, `4` high-pass, `8` voice-3-off. |
+| `SOUND` | `SOUND(V,F,D,W)` | Blocking tone helper: gates wave `W` on for `D` spin-delay units and gates it off. No IRQ music engine yet. |
+| `SPRSET` / `SPRMOVE` / `SPRCOL` / `SPRROW` | sprite config/move/color/pixels | Uses eight 64-byte Bank D sprite definitions at `$CA00`; `SPRROW` writes explicit 24-bit sprite rows. |
+| `SPRSIZE` | `SPRSIZE(N,XON,YON)` | Phase 2 VIC sprite X/Y expansion. |
+| `SPRPRI` | `SPRPRI(N,BEHIND)` | Phase 2 VIC sprite priority bit control. |
+| `SPRMUL` | `SPRMUL(N,ON)` | Phase 2 VIC sprite multicolor enable. |
+| `SPRMCO` | `SPRMCO(C1,C2)` | Phase 2 shared sprite multicolor registers. |
+
+This alpha build intentionally keeps one public spelling per command behavior.
+ReadyBASIC can create aliases by adding extra 32-byte descriptors that share a
+command id, parser signature, payload, and entrypoint, but duplicate spellings
+consume registry slots and preserve tokenizer hazards. New demos and stored
+programs use only the canonical names because C64 BASIC V2 can tokenize embedded
+words such as `FN`, `FRE`, `INT`, `CLR`, `LEN`, and `NOT`.
+
+In `GFXMODE("MBITMAP")`, immediate primitives use 160x200 logical
+coordinates. `C=0` clears a pixel pair, `C=1..15` draws pair code `3` and
+writes color RAM, `C=16..31` draws pair code `1` and writes the screen high
+nibble, `C=32..47` draws pair code `2` and writes the screen low nibble, and
+`C=48..63` draws pair code `3` with an explicit color-RAM write.
+`PNT` returns pair code `0..3`; it does not resolve the final VIC color
+through the per-cell attributes. The demos `rbgfx21_mbitmap_prims.bas` and
+`rbgfx22_mbitmap_point.bas` exercise this path.
+| `SPRSCAN` / `SPRCOLL` | `SPRSCAN()`, `SPRCOLL(N,C%)` | Polls VIC collision latches; no IRQ sampler. |
+| `JOY` / `KEYP` / `KEYSCAN` / `KEYLAST` | output/polling forms | Polling only, no resident input event queue. |
+
+See `READYBASIC_GRAPHICS_COMMAND_DESIGN.md` for mode tradeoffs, memory layout,
+implemented phases, REU surface/display-list behavior, and remaining limits.
## Native Flow Control And Error Introspection
@@ -248,11 +370,11 @@ support, not the final product command catalog.
| String Transfer/Transform | `UPPER`, `LOWER` | Prove string input capture and resident-owned BASIC string output allocation. |
| Under-ROM Worker | `ZHIDDENRAM` | Prove worker code can run behind BASIC ROM in the shared slot-0 module payload. |
| Integer Array Transfer | `ZSUMNUMARRAY`, `ZRANGENUMARRAY` | Prove array input/output via explicit base element plus count. |
-| Persistent REU Handles | `BUFNEW`, `BUFFILL`, `BUFFREE`, `SCRCAP`, `SCRPUT` | Prove stable BASIC-visible handles for persistent REU-backed data, including typed screen text+color resources. |
+| Persistent REU Handles | `BUFMAKE`, `BUFFILL`, `BUFDROP`, `SCRCAP`, `SCRPUT` | Prove stable BASIC-visible handles for persistent REU-backed data, including typed screen text+color resources. |
| Temporary REU Workspace | `ZTEMPSCRATCH` | Prove temporary page allocation and cleanup. |
| Error/Failure Contract | `ZFAIL` | Prove outputs are cleared before execution and stale results are not committed. |
| Timing/Delay | `ZPAUSE` | Prove a small timing command can wait for a number of jiffies without command overlay growth elsewhere. |
-| Runtime Introspection | `FREEMEM`, `ERRCODE`, `ERRLINE` | Prints live BASIC free memory, refreshes the header value, and exposes the last ReadyBASIC runtime error. |
+| Runtime Introspection | `MEMAVL`, `ERRCODE`, `ERRLINE` | Prints live BASIC free memory and exposes the last ReadyBASIC runtime error. |
| Module/Submodule Proofs | `ZSLOT0`, `ZSLOT1`, `ZSLOT2`, `ZSPAN`, `ZOVL1`, `ZOVL2`, `ZCPYRST`, `ZCOPY`, `ZMODLD`, `ZDM1`, `ZDM2S`, `ZDOV1`, `ZDOV2`, `ZSAA`-`ZUEB` | Prove slot dispatch, multi-slot span loading, overlay replacement, no-recopy behavior, SEQ package streaming, and disk-loaded module registration. |
| ReadyOS Yield | `EXIT` | Save BASIC runtime state, restore vectors, and return through the ReadyOS shim. |
@@ -269,16 +391,16 @@ support, not the final product command catalog.
| `ZHIDDENRAM(S$,OUT%)` / `ZHIDDENRAM(S$)` | Module 1 slot 0 at `$A800+`, unified under-ROM dispatch | string variable or quoted literal, output integer or expression integer | Returns a simple uppercase-byte checksum. |
| `ZSUMNUMARRAY(A%(0),COUNT,OUT%)` / `ZSUMNUMARRAY(A%(0),COUNT)` | Module 1 slot 0 at `$A800+`, descriptor-backed slice | integer array base, count, output integer or expression integer | Sums integer array elements. |
| `ZRANGENUMARRAY(START,COUNT,A%(0))` | Module 1 slot 0 at `$A800+`, descriptor-backed slice | start value, count, output array base | Stages consecutive integers, then resident code writes them to the array. |
-| `BUFNEW(LEN,H%)` / `BUFNEW(LEN)` | Module 1 slot 0, copies full `$06C7` slot-0 payload | byte length, output handle or expression handle | Allocates buffer pages in the assigned core bank and returns a one-based handle. |
-| `BUFFILL(H%,BYTE)` | Module 1 slot 0, copies full `$06C7` slot-0 payload | buffer handle, fill byte | Fills buffer handles through the `$C500` page buffer and rejects non-buffer handles. |
-| `BUFFREE(H%)` | Module 1 slot 0, copies full `$06C7` slot-0 payload | handle | Frees any valid handle type and clears metadata/page bitmap state. |
-| `ZTEMPSCRATCH(LEN,OUT%)` / `ZTEMPSCRATCH(LEN)` | Module 1 slot 0, copies full `$06C7` slot-0 payload | byte length, output integer or expression integer | Allocates and frees temporary pages, returning page count. |
+| `BUFMAKE(LEN,H%)` / `BUFMAKE(LEN)` | Module 1 slot 0, copies full `$07DC` slot-0 payload | byte length, output handle or expression handle | Allocates buffer pages in the assigned core bank and returns a one-based handle. |
+| `BUFFILL(H%,BYTE)` | Module 1 slot 0, copies full `$07DC` slot-0 payload | buffer handle, fill byte | Fills buffer handles through the `$C500` page buffer and rejects non-buffer handles. |
+| `BUFDROP(H%)` | Module 1 slot 0, copies full `$07DC` slot-0 payload | handle | Frees any valid handle type and clears metadata/page bitmap state. |
+| `ZTEMPSCRATCH(LEN,OUT%)` / `ZTEMPSCRATCH(LEN)` | Module 1 slot 0, copies full `$07DC` slot-0 payload | byte length, output integer or expression integer | Allocates and frees temporary pages, returning page count. |
| `ZFAIL(CODE,OUT%)` | Module 1 slot 0 at `$A800+`, descriptor-backed slice | error code, output integer | Clears output first, then reports `?RB ERROR code`. |
-| `FREEMEM()` | Module 1 slot 0 at `$A800+`, descriptor-backed slice | none | Prints current live BASIC free bytes and refreshes the header. |
-| `SCRCAP(H%)` / `SCRCAP()` | Slot 14 descriptor; module 1 slot 0, copies full `$06C7` slot-0 payload | output handle or expression handle | Captures screen text `$0400-$07E7` and color RAM `$D800-$DBE7` into a typed screen handle. |
+| `MEMAVL()` | Module 1 slot 0 at `$A800+`, descriptor-backed slice | none | Prints current live BASIC free bytes. |
+| `SCRCAP(H%)` / `SCRCAP()` | Slot 14 descriptor; module 1 slot 0, copies full `$07DC` slot-0 payload | output handle or expression handle | Captures screen text `$0400-$07E7` and color RAM `$D800-$DBE7` into a typed screen handle. |
| `ERRCODE(OUT%)` / `ERRCODE()` | Resident-precomputed result; legacy low stub remains in `LOWPACK` | output integer, or expression integer | Returns the last ReadyBASIC runtime error code. |
| `ERRLINE(OUT%)` / `ERRLINE()` | Resident-precomputed result; legacy low stub remains in `LOWPACK` | output integer, or expression integer | Returns the line number of the last ReadyBASIC runtime error, or `0` for direct mode. |
-| `SCRPUT(H%)` | Slot 128 descriptor; module 1 slot 0, copies full `$06C7` slot-0 payload | screen handle | Validates the screen handle type and restores text plus color RAM. |
+| `SCRPUT(H%)` | Slot 128 descriptor; module 1 slot 0, copies full `$07DC` slot-0 payload | screen handle | Validates the screen handle type and restores text plus color RAM. |
| `ZSLOT0()` / `ZSLOT1()` / `ZSLOT2()` | Built-in module proof payloads in slot 0, slot 1, and slot 2 | none | Prove each 2K submodule slot can dispatch independently. |
| `ZSPAN()` | Built-in module 2 two-slot span payload for slots 1+2 | none | Proves a payload can claim adjacent slots. |
| `ZOVL1()` / `ZOVL2()` | Built-in module 2 slot-2 overlay proof payloads | none | Prove overlay replacement in slot 2. |
@@ -321,20 +443,28 @@ inside that one PRG load image:
| `READYBASIC_MAKING_COMMAND_GUIDE.md` / `readybasic_making_command_guide.html` | Walkthrough for adding commands using the current demo, string, array, hidden, and REU-handle examples. |
The linker puts packed command bytes in the PRG load image at `CMDPACK`
-`$2B00-$3FFF`, but their runtime addresses are different:
+`$2B00-$3FFF` and `CMDPACK2` `$6200-$7FFF`, but their runtime addresses are
+different:
| Segment | Size | Load/source role | Runtime role |
|---|---:|---|---|
-| `LOWPACK` | `$06C7` (1.7K, 1735 exact bytes) | Historical segment name for the built-in module 1 slot-0 payload loaded from `CMDPACK` and prestashed to assigned code-bank offset `$0000`. | Fetched on demand into `$A800-$AEC6`. |
-| `SLOTPACK1` | `$0239` (569B) | Built-in module 2 proof and streaming `ZMODLD` loader payload, prestashed to assigned code-bank offset `$06C7`. | Fetched on demand into `$B000-$B238`. |
-| `SLOTPACK2` / `SPANPACK` / `OVL1PACK` / `OVL2PACK` | `$0015` each (21B) | Built-in module 2 slot, span, and overlay proof payloads, prestashed after `SLOTPACK1`. | Fetched into slot 2, slots 1+2, or slot-2 overlay target addresses. |
-| `HIDLOAD` | `$0365` (0.8K, 869 exact bytes) | Load-only hidden helper seed starting at `$4000`. | Copied on cold boot into `$A000-$A364` and the visible `$C280` warm-resume shadow. |
-| `BRLOAD` | `$01F7` (503B) | Load-only bridge seed starting at `$4800`. | Copied on cold boot into `$C000-$C1F6`. |
+| `LOWPACK` | `$07DC` (2.0K, 2012 exact bytes) | Historical segment name for the built-in module 1 slot-0 payload loaded from `CMDPACK` and prestashed to assigned code-bank offset `$0000`. | Fetched on demand into `$A800-$AFDB`. |
+| `SLOTPACK1` | `$0541` (1.3K, 1345 exact bytes) | Built-in module 2 proof, streaming `ZMODLD` loader, and `GFXCORE` payload, prestashed to assigned code-bank offset `$07DC`. | Fetched on demand into `$B000-$B540`. |
+| `SLOTPACK2` | `$0738` (1.8K, 1848 exact bytes) | Built-in module 2 slot proof plus `GFXPRIM`, prestashed to assigned code-bank offset `$0D1D`. | Fetched on demand into `$B800-$BF37`. |
+| `SPANPACK` | `$0015` (21B) | Built-in two-slot span proof payload. | Fetched into slots 1+2 at `$B000-$B014`. |
+| `OVL1PACK` | `$0272` (626B) | Built-in slot-2 overlay proof plus `GFXSPR`, loaded from `CMDPACK2` `$6200` and prestashed to assigned code-bank offset `$5000`. | Fetched as a replacement overlay into `$B800-$BA71`. |
+| `OVL2PACK` | `$006D` (109B) | Built-in slot-2 overlay proof plus `INPUTEV`, loaded from `CMDPACK2` `$6472` and prestashed to assigned code-bank offset `$5800`. | Fetched as a replacement overlay into `$B800-$B86C`. |
+| `OVL3PACK` | `$0779` (1.9K, 1913 exact bytes) | Built-in slot-2 overlay proof plus `GFXPOLY`, loaded from `CMDPACK2` and prestashed to assigned code-bank offset `$6000`. | Fetched as a replacement overlay into `$B800-$BF78`. |
+| `OVL4PACK` | `$0783` (1.9K, 1923 exact bytes) | Built-in `GFXDL` display-list overlay, prestashed to assigned code-bank offset `$6800`. | Fetched as a replacement overlay into `$B800-$BF82`. |
+| `OVL5PACK` | `$04DA` (1.2K, 1242 exact bytes) | Built-in `GFXTILE` charset/tilemap/multicolor-cell overlay, prestashed to assigned code-bank offset `$7000`. | Fetched as a replacement overlay into `$B800-$BCD9`. |
+| `OVL6PACK` | `$020E` (526B) | Built-in `SIDCORE` immediate sound overlay, prestashed to assigned code-bank offset `$7800`. | Fetched as a replacement overlay into `$B800-$BA0D`. |
+| `HIDLOAD` | `$078B` (1.9K, 1931 exact bytes) | Load-only hidden helper seed starting at `$4000`. | Copied on cold boot into `$A000-$A78A` and stashed to the assigned core-bank hidden shadow at `$3000`. |
+| `BRLOAD` | `$01FF` (511B) | Load-only bridge seed starting at `$4800`. | Copied on cold boot into `$C000-$C1FE`. |
| `REGSEED` | `$1010` (4.0K, 4112 exact bytes) | Load-only registry header and 128 command descriptors at `$5000-$600F`. | Copied on cold boot into assigned core-bank offsets `$0000` and `$1000`. |
Cold boot is the only time the load-image command pack and `REGSEED` are trusted.
The hidden helper copies the registry/header to the assigned core bank and
-copies the built-in module/submodule payloads from `CMDPACK` to the assigned code bank. After
+copies the built-in module/submodule payloads from `CMDPACK` and `CMDPACK2` to the assigned code bank. After
that, BASIC may own the former load-image addresses, so warm resume reuses the
REU copies and does not reseed from `$2B00+`, `$4000+`, `$4800+`, or `$5000+`.
@@ -350,38 +480,46 @@ to fetch:
`$B000`, `$B800`, or a multi-slot span, calls the entry, then returns to
visible resident code for result commit.
5. Commands can fetch a small slice or a full slot payload. The current handle
- and screen-handle commands fetch the whole `$06C7` slot-0 payload because
+ and screen-handle commands fetch the whole `$07DC` slot-0 payload because
their shared allocator and screen-copy helpers live there.
## C64 RAM Layout
-ReadyBASIC runs inside the ReadyOS app working region `$1000-$C5FF`. ReadyOS
-metadata and shim space above that are not general ReadyBASIC scratch.
+ReadyBASIC is captured by the ReadyOS `$1000-$C5FF` app snapshot. Its custom
+assembler/linker shape intentionally uses runtime bytes only through `$C5FF`;
+the full `$C600-$C9FF` region is resident shim space.
| Region | Current range | Size | Owner and role |
|---|---:|---:|---|
-| `ENTRY` | `$1000-$1102` | `$0103` (259B) | Tiny entry, cold/warm discriminator, early hidden/bridge copies. |
-| `RESIDENT` | `$1200-$2ABB` | `$18BC` (6.2K, 6332 exact bytes) | Visible parser, vector hooks, BASIC ROM calls, REU DMA wrappers, result commit, bare command dispatch, expression hook, native `PROC`/`FUNC`/`RET`, `REPEAT`/`UNTIL`, `LABEL`/`JUMP`, error introspection, proper nested term state, and float helpers. |
+| `ENTRY` | `$1000-$11FF` | `$0200` (512B) | Tiny entry, cold/warm discriminator, early hidden/bridge copies, and prompt hotkey helpers. |
+| `RESIDENT` | `$1200-$2ABF` | `$18C0` (6.2K, 6336 exact bytes) | Visible parser, vector hooks, BASIC ROM calls, REU DMA wrappers, result commit, bare command dispatch, expression hook, native `PROC`/`FUNC`/`RET`, `REPEAT`/`UNTIL`, `LABEL`/`JUMP`, error introspection, proper nested term state, float helpers, and prompt hotkey dispatch. |
| BASIC sentinel | `$2AC0` | 1 byte | Must stay zero before stored-program `RUN`. |
| BASIC workspace | `$2AC1-$9FFF` | `$753F` region, `30013` formula free bytes (29.3K) | Program text, variables, arrays, string heap. |
| Command pack load image | `$2B00-$3FFF` | `$1500` (5.25K) file range | Built-in module/submodule payload seed bytes before cold prestash. |
-| Hidden helper load image | `$4000+` | `$0365` (0.8K, 869 exact bytes) load-only | Hidden helper seed copied to `$A000` and `$C280`. |
-| Bridge load image | `$4800+` | `$01F9` (505B) load-only | Bridge seed copied to `$C000`. |
+| Hidden helper load image | `$4000+` | `$078B` (1.9K, 1931 exact bytes) load-only | Hidden helper seed copied to `$A000` and stashed to assigned core-bank offset `$3000`. |
+| Bridge load image | `$4800+` | `$01FF` (511B) load-only | Bridge seed copied to `$C000`. |
| Registry seed load image | `$5000-$600F` | `$1010` (4.0K, 4112 exact bytes) load-only | Header and 128 descriptors copied to the assigned core bank. |
+| Command pack 2 load image | `$6200-$7FFF` | `$1E00` (7.5K) file range | Built-in replacement overlay seed bytes before cold prestash. |
| Runtime snapshot | Assigned core bank offsets `$0A00-$0BFF` | `$0200` (0.5K) plus bridge metadata | Saved zero page, stack page, SP, resume mode, line-chain guards. |
-| Common under-ROM helper | `$A000-$A364` | `$0365` (869B) | Helper code run with RAM mapped under BASIC ROM. |
-| Slot 0 module payload | `$A800-$AEC6` | `$06C7` (1735B) | Module 1 system/default payload fetched from the assigned code bank. |
-| Slot 1 module payload | `$B000-$B238` | `$0239` (569B) | Module 2 proof and streaming `ZMODLD` loader payload. |
-| Slot 2 proof/overlays | `$B800-$B83E` | `$003F` (63B) | Current slot-2 base and overlay proof slices. |
-| `BRIDGE` | `$C000-$C1F8` | `$01F9` (505B) | Persistent bridge state, saved vectors, overlay variables, current handle scratch, debug bytes, native routine return stack, and flow-control scratch. |
+| Common under-ROM helper | `$A000-$A78A` | `$078B` (1931B) | Helper code run with RAM mapped under BASIC ROM. |
+| Slot 0 module payload | `$A800-$AFDB` | `$07DC` (2012B) | Module 1 system/default payload fetched from the assigned code bank. |
+| Slot 1 module payload | `$B000-$B540` | `$0541` (1345B) | Module 2 proof, streaming `ZMODLD` loader, and `GFXCORE` payload. |
+| Slot 2 `GFXPRIM` image | `$B800-$BF37` | `$0738` (1848B) | Slot-2 base/proof plus `GFXPRIM`; replacement overlays load over this when called. |
+| Slot 2 `GFXSPR` overlay image | `$B800-$BA71` | `$0272` (626B) | Replacement overlay for sprite commands. |
+| Slot 2 `INPUTEV` overlay image | `$B800-$B86C` | `$006D` (109B) | Replacement overlay for polling input commands. |
+| Slot 2 `GFXPOLY` overlay image | `$B800-$BF78` | `$0779` (1913B) | Replacement overlay for polygon and REU point-buffer commands. |
+| Slot 2 `GFXDL` overlay image | `$B800-$BF82` | `$0783` (1923B) | Replacement overlay for display-list commands. |
+| Slot 2 `GFXTILE` overlay image | `$B800-$BCD9` | `$04DA` (1242B) | Replacement overlay for charset, tileset, tilemap, and multicolor-cell commands. |
+| Slot 2 `SIDCORE` overlay image | `$B800-$BA0D` | `$020E` (526B) | Replacement overlay for immediate SID sound commands. |
+| `BRIDGE` | `$C000-$C1FE` | `$01FF` (511B) | Persistent bridge state, saved vectors, overlay variables, current handle scratch, debug bytes, native routine return stack, and flow-control scratch. |
| Shared frames | `$C200-$C5FF` | `$0400` (1.0K) | Call frame, result frame, descriptor buffer, command-name buffer, page/runtime buffers. |
-| Hidden shadow | `$C280-$C5F6` | `$0377` (0.9K) | Visible-RAM source for restoring `$A000` helper on warm resume; refreshed during `EXIT`. |
-| ReadyOS REU metadata | `$C600-$C7FF` | `$0200` (0.5K) shared | ReadyBASIC only marks REU bank ownership here. |
-| ReadyOS shim ABI | `$C800-$C9FF` | `$0200` (0.5K) shared | ReadyOS jump table and data; not ReadyBASIC RAM. |
+| Hidden helper shadow | Assigned core bank `$3000+` | `$078B` (1931B) | REU source for restoring `$A000` helper on warm resume; refreshed during `EXIT` and cold seed. |
+| ReadyOS shim expansion reserve | `$C600-$C7FF` | `$0200` (0.5K) shared | Resident capacity for future shim functionality; not ReadyBASIC RAM. |
+| ReadyOS shim ABI | `$C800-$C9FF` | `$0200` (0.5K) shared | Stable ReadyOS jump table and data; the full shim region is 1 KB. |
The PRG load image is larger than the live resident core. On cold entry,
-ReadyBASIC copies the hidden helper seed from the load image to `$A000` and
-the visible shadow at `$C280`, copies the bridge seed to `$C000`, and prestashes
+ReadyBASIC copies the hidden helper seed from the load image to `$A000`, stashes
+the helper shadow in the assigned core bank at `$3000`, copies the bridge seed to `$C000`, and prestashes
registry/code seed data into REU. After that, BASIC owns `$2AC1-$9FFF`. Warm resume must therefore
not reread load-only seed tables at `$4000+`, because that address range may now
be BASIC program or variable storage.
@@ -393,10 +531,10 @@ not a contradiction; it is a time-of-use distinction.
| Stage | C64 RAM ownership | BASIC-visible effect |
|---|---|---|
-| PRG load / cold seed | `CMDPACK` is loaded at `$2B00-$3FFF`, `HIDLOAD` at `$4000+`, `BRLOAD` at `$4800+`, and `REGSEED` at `$5000-$600F`. These ranges are inside the future BASIC workspace but BASIC is not live there yet. | No user BASIC program or variables exist yet, so the load image can safely occupy this space temporarily. |
-| End of cold seed | Built-in module/submodule payloads have been copied from `CMDPACK` to the assigned code bank; the registry has been copied to the assigned core bank; hidden and bridge live copies are in their runtime homes. | `$2AC1-$9FFF` becomes the BASIC workspace. The former load-image bytes are now disposable. |
-| Ready prompt / running BASIC | BASIC owns `$2AC1-$9FFF`, including the old `$2B00-$600F` load ranges. Command code is fetched from REU into `$A800`, `$B000`, and/or `$B800` under BASIC ROM only while a command runs. | Empty BASIC free space is `30013` formula bytes. Warm resume never trusts the old load-image addresses. |
-| Future command growth | The current `CMDPACK` reservation is `$1500` (5.25K). Today it carries `$085C` / 2.1K of built-in module/submodule payloads. | The remaining reserved `CMDPACK` capacity can absorb `$0CA4` / 3.2K more built-in payload seed bytes without reducing steady-state BASIC free bytes. Growing beyond the reserved load-only area may increase PRG size or require another cold-only seed range, but it should still be reclaimed before BASIC owns the workspace. |
+| PRG load / cold seed | `CMDPACK` is loaded at `$2B00-$3FFF`, `HIDLOAD` at `$4000+`, `BRLOAD` at `$4800+`, `REGSEED` at `$5000-$600F`, and `CMDPACK2` at `$6200-$7FFF`. These ranges are inside the future BASIC workspace but BASIC is not live there yet. | No user BASIC program or variables exist yet, so the load image can safely occupy this space temporarily. |
+| End of cold seed | Built-in module/submodule payloads have been copied from `CMDPACK` and `CMDPACK2` to the assigned code bank; the registry has been copied to the assigned core bank; hidden and bridge live copies are in their runtime homes. | `$2AC1-$9FFF` becomes the BASIC workspace. The former load-image bytes are now disposable. |
+| Ready prompt / running BASIC | BASIC owns `$2AC1-$9FFF`, including the old `$2B00-$7FFF` load ranges. Command code is fetched from REU into `$A800`, `$B000`, and/or `$B800` under BASIC ROM only while a command runs. | Empty BASIC free space is `30013` formula bytes. Warm resume never trusts the old load-image addresses. |
+| Future command growth | `CMDPACK` carries `$1455` / 5205B of base built-ins and has `$00AB` / 171B free. `CMDPACK2` carries `$18C3` / 6339B of overlay built-ins and has `$053D` / 1341B free. | Both cold-load windows are reclaimed before BASIC owns the workspace, so growing within them does not reduce steady-state BASIC free bytes. Runtime growth is still bounded by each 2K execution image. |
The visual way to read this: `CMDPACK` looks like it overlaps BASIC RAM in the
link/load map because it really does during cold loading. It does not reduce the
@@ -406,9 +544,11 @@ store a BASIC program.
`CMDPACK` is only the current C64 cold-load seed window. It is not the total
command-code capacity of the architecture. The current descriptor format points
into the assigned code bank with 16-bit offsets and sizes, so the current single code
-bank can hold up to `$10000` bytes (64.0K) of packed command bodies. The built-in
-payloads currently use `$085C` (2.1K, 2140 exact bytes), leaving `$F7A4`
-(61.9K, 63396 exact bytes) available in the assigned code bank. To actually seed beyond the current 5.25K
+bank can hold up to `$10000` bytes (64.0K) of packed command bodies. The base
+built-in payloads currently use `$1455` (5.1K, 5205 exact bytes) and the fixed
+built-in overlay reservations occupy through `$77FF`, leaving the contiguous
+tail `$7800-$FFFF` (`$8800`, 34816 exact bytes) available in the assigned code
+bank. To actually seed beyond the current 5.25K
`CMDPACK` linker window, the cold-load layout would need a larger or additional
load-only seed range, copied to REU before BASIC owns `$2AC1-$9FFF`. Going
beyond one 64K code bank would require a descriptor/loader extension for
@@ -475,6 +615,9 @@ ReadyBASIC saves the original BASIC vectors, then installs:
| Crunch | `$0304/$0305` | Calls ROM crunch first, then normalizes tokenized `THEN EXEC ...` and `THEN JUMP ...` into colon-prefixed statements. |
| Execute | `$0308/$0309` | Peeks for `EXIT`, `PROC`, `FUNC`, `EXEC`, `ENDP`, or a bare descriptor command; otherwise tail-calls the original execute vector without advancing `TXTPTR`. |
| Eval | `$030A/$030B` | Recognizes selected `COMMAND(...)` and `FUNC(...)` expression returns, then falls back to ROM expression evaluation. |
+| IMAIN | `$0302/$0303` | Marks the BASIC direct prompt active when ROM BASIC returns to `READY.`. |
+| KEYLOG | `$028F/$0290` | Catches KERNAL-decoded prompt hotkeys only while ReadyBASIC owns the direct prompt, records the pending ReadyOS action, clears the consumed key state, and queues Return. |
+| CHRIN | `$0324/$0325` | Wraps the original CHRIN, preserves normal return semantics for ordinary input, and abort-dispatches pending prompt hotkeys before BASIC stores or executes the partial line. |
| List | `$0306/$0307` | Saved/restored, but V1 leaves normal ROM listing behavior. |
Page-3 vectors are global machine state. `EXIT` restores the original vectors
@@ -581,24 +724,26 @@ table at `$C600-$C6FF`. ReadyBASIC scans that table at startup and does not use
| `$0A00` | Saved zero page for ReadyOS suspend/resume. |
| `$0B00` | Saved stack page for ReadyOS suspend/resume. |
| `$0C00-$0CFF` | 192-byte heap page bitmap plus reserved bytes. |
-| `$1000-$1FFF` | 128 command descriptor slots, 32 bytes each. Slot 14 is `SCRCAP`; slot 128 is `SCRPUT`; zero-filled slots are unused fillers. |
+| `$1000-$1FFF` | 128 command descriptor slots, 32 bytes each. Current build has 94 real descriptors, 34 zero-filled filler descriptors, and `SCRPUT` deliberately kept in slot 128. |
| `$2000-$3FFF` | Reserved common/system space for future ReadyBASIC metadata. |
| `$4000-$FFFF` | Typed handle heap: 192 pages / 48KB. |
-The descriptor table intentionally leaves a large filler span between the two
-screen commands:
+The descriptor table keeps `SCRPUT` in the final slot to prove full-table lookup.
+Every duplicate public spelling would consume a real 32-byte descriptor in the
+assigned core bank, so the source filler count must track the actual descriptor
+count:
| Descriptor range | REU offset | Role | Slots | Size |
|---|---:|---|---:|---:|
-| Slots 1-14 | `$1000-$11BF` | Current front commands from `ZECHO1` through `SCRCAP`. | 14 | `$01C0` / 448B |
-| Slots 15-127 | `$11C0-$1FDF` | Zero-filled filler descriptors available for future commands. | 113 | `$0E20` / 3.5K / 3616 exact bytes |
+| Slots 1-93 | `$1000-$1B9F` | Current built-in descriptors from `ZECHO1` through `SOUND`. | 93 | `$0BA0` / 2976B |
+| Slots 94-127 | `$1BA0-$1FDF` | Zero-filled filler descriptors available for future commands. | 34 | `$0440` / 1088B |
| Slot 128 | `$1FE0-$1FFF` | `SCRPUT`, deliberately placed at the end to prove full-table lookup. | 1 | `$0020` / 32B |
The persistent handle model supports 128 live handles. Each handle is
represented to BASIC as a small integer from `1` to `128`, while canonical
metadata lives in REU and bridge RAM keeps only the current descriptor scratch.
Type `1` is a byte buffer, and type `2` is a screen text+color buffer.
-`BUFFILL` accepts only buffer handles; `BUFFREE` frees any valid handle;
+`BUFFILL` accepts only buffer handles; `BUFDROP` frees any valid handle;
`SCRPUT` accepts only screen handles. The typed heap uses assigned core-bank pages
`$40-$FF`; future large or long-lived objects should allocate additional REU
banks and keep the same small handle model.
@@ -607,19 +752,34 @@ banks and keep the same small handle model.
| Offset | Region |
|---:|---|
-| `$0000-$06C6` | Built-in module 1 slot-0 payload copied into `$A800-$AEC6` (`$06C7`, 1735B). |
-| `$06C7-$08FF` | Built-in module 2 slot-1 proof and streaming `ZMODLD` loader payload copied into `$B000-$B238` (`$0239`, 569B). |
-| `$0900-$0953` | Built-in slot-2, span, and overlay proof slices (`$0054`, 84B total). |
-| `$0954-$14FF` | Free gap before current disk-module descriptor proof offsets (`$0BAC`, 2988B). |
+| `$0000-$07DB` | Built-in module 1 slot-0 payload copied into `$A800-$AFDB` (`$07DC`, 2012B). |
+| `$07DC-$0D1C` | Built-in module 2 slot-1 proof, streaming `ZMODLD` loader, and `GFXCORE` payload copied into `$B000-$B540` (`$0541`, 1345B). |
+| `$0D1D-$1454` | Built-in slot-2 proof plus `GFXPRIM` copied into `$B800-$BF37` (`$0738`, 1848B). |
+| `$13AA-$13BE` | Built-in two-slot span proof payload (`$0015`, 21B). |
+| `$1455-$14FF` | Free gap before current disk-module descriptor proof offsets (`$00AB`, 171B). |
| `$1500-$151F` | `rbm.sample1` descriptor for `ZDM1`. |
| `$1600-$165F` | `rbm.sample2` descriptors for `ZDM2S`, `ZDOV1`, and `ZDOV2`. |
| `$1700-$1ABF` | `rbm.sample3` descriptors for `ZSAA`-`ZUEB`. |
| `$3000-$3014`, `$3200-$3214`, `$3300-$3314`, `$3400-$3414` | Small sample disk-loaded payload proofs. |
| `$3800-$463C` | `rbm.sample3` payload records for `ZSAA`-`ZUEB`, stored on `$100`-byte strides. |
+| `$463D-$4FFF` | Free gap before fixed built-in replacement overlay offsets (`$09C3`, 2499B). |
+| `$5000-$5271` | Built-in slot-2 replacement overlay plus `GFXSPR` (`$0272`, 626B). |
+| `$5272-$57FF` | Reserved `GFXSPR` overlay growth headroom (`$058E`, 1422B). |
+| `$5800-$586C` | Built-in slot-2 replacement overlay plus `INPUTEV` (`$006D`, 109B). |
+| `$586D-$5FFF` | Reserved `INPUTEV` overlay growth headroom (`$0793`, 1939B). |
+| `$6000-$6778` | Built-in slot-2 replacement overlay plus `GFXPOLY` (`$0779`, 1913B). |
+| `$6779-$67FF` | Reserved `GFXPOLY` overlay growth headroom (`$0087`, 135B). |
+| `$6800-$6F82` | Built-in `GFXDL` replacement overlay (`$0783`, 1923B). |
+| `$6F83-$6FFF` | Reserved `GFXDL` overlay growth headroom (`$007D`, 125B). |
+| `$7000-$74D9` | Built-in `GFXTILE` replacement overlay (`$04DA`, 1242B). |
+| `$74DA-$77FF` | Reserved `GFXTILE` overlay growth headroom (`$0326`, 806B). |
+| `$7800-$7A0D` | Built-in `SIDCORE` replacement overlay (`$020E`, 526B). |
+| `$7A0E-$7FFF` | Reserved `SIDCORE` overlay growth headroom (`$05F2`, 1522B). |
+| `$8000-$FFFF` | Free tail after fixed built-in replacement overlay reservations (`$8000`, 32768B). |
Descriptors point into these packed bytes with payload offset, payload size,
slot mask, runtime destination, and entry offset. Heap and screen-handle
-commands currently fetch the whole `$06C7` slot-0 payload because shared
+commands currently fetch the whole `$07DC` slot-0 payload because shared
allocator and screen-copy helpers live there.
## Cold Boot Lifecycle
@@ -627,10 +787,11 @@ allocator and screen-copy helpers live there.
1. ReadyOS loads `readybasic.prg` at `$1000`.
2. Entry code checks its local warm/cold magic.
3. On cold path, it maps RAM under BASIC ROM long enough to copy the hidden
- helper seed to `$A000`, then copies a visible helper shadow to `$C280`.
+ helper seed to `$A000`, then stashes the helper shadow to assigned core-bank
+ offset `$3000`.
4. It copies bridge seed bytes from the load image to `$C000`.
5. The resident core resets KERNAL/BASIC vectors, saves originals, and installs
- ReadyBASIC crunch/execute/eval hooks.
+ ReadyBASIC crunch/execute/eval, KEYLOG, and CHRIN hooks.
6. BASIC is relocated to `TXTTAB=$2AC1` with top at `$A000`.
7. `$2AC0`, `$2AC1`, and `$2AC2` are cleared. `$2AC0` is the sentinel byte
required by BASIC `RUN`.
@@ -641,7 +802,22 @@ allocator and screen-copy helpers live there.
## EXIT, Suspend, And Warm Resume
-Manual prompt `EXIT` is the supported V1 ReadyOS return path.
+Manual prompt `EXIT` and prompt-level `CTRL+B` share the launcher-return path.
+Prompt-level `F2`/`F4` use the same state-save/vector-restore setup, then write
+the selected loaded app bank to `$C820` and jump through `$C80F`. The selected
+bank is first copied into bridge state before yield preparation, then replayed
+after the hidden save/vector/channel cleanup has run; scratch bytes used by the
+loaded-bank scan are not trusted across the yield path. The keyboard path
+records a pending action, queues only Return, then lets the CHRIN hook dispatch
+before BASIC stores or executes the editor line. READY-mode hotkey yields force
+the saved resume stack to a clean BASIC-ready value instead of preserving the
+transient CHRIN/editor call depth.
+Before a prompt hotkey yield, ReadyBASIC waits for the exact physical chord that
+selected the action to be released, then clears editor/KERNAL key state again.
+Cold and warm entry also scan the physical matrix and suppress the same
+still-held ReadyOS hotkey until it has been released. This keeps one F2/F4 press
+from double-switching through the next app and keeps the resumed BASIC editor
+keyboard-live.
On `EXIT`, ReadyBASIC:
@@ -652,15 +828,24 @@ On `EXIT`, ReadyBASIC:
4. Saves zero page `$0000-$00FF` to assigned core-bank offset `$0A00`.
5. Saves stack page `$0100-$01FF` to assigned core-bank offset `$0B00`.
6. Saves SP, mode, runtime magic, and line-chain guards in bridge metadata.
-7. Refreshes the visible hidden-helper shadow at `$C280`.
-8. Restores the original page-3 BASIC/KERNAL vectors.
-9. Jumps to the ReadyOS shim return entry at `$C80C`.
+7. Refreshes the assigned-core-bank hidden-helper shadow at `$3000`.
+8. Clears pending ReadyBASIC/KERNAL keyboard state and calls `CLRCHN`.
+9. Restores the original page-3 BASIC/KERNAL vectors.
+10. Jumps to the ReadyOS shim return entry at `$C80C`.
+
+For `F2`/`F4`, ReadyBASIC scans the authoritative schema-v5 loaded flags at
+ReadyOS-bank offset `$B840 + token`, using the direct physical ReadyOS bank in
+`$C83B`, and starts from the current token in `$C834`. If a neighbor app is found, it performs the same
+READY-mode save/restore setup, persists the target bank in bridge state, clears
+editor hotkey state, restores channels/vectors, writes the saved target to
+`$C820`, and jumps to the shim switch entry `$C80F`. If no neighbor is loaded,
+the key is consumed and the BASIC editor continues waiting.
On warm resume, ReadyOS restores the app window and jumps back to `$1000`.
ReadyBASIC:
1. Sees entry-local warm magic.
-2. Restores the hidden helper at `$A000` from the preserved `$C280` shadow.
+2. Restores the hidden helper at `$A000` from the preserved assigned-core-bank `$3000` shadow.
3. Reinstalls ReadyBASIC-owned vectors.
4. Re-marks REU bank ownership for the assigned ReadyBASIC core/code banks.
5. Does not reread cold-only `REGSEED` or command-pack load images.
@@ -677,8 +862,8 @@ ReadyBASIC uses hidden code in two places:
| Code | Range | Purpose |
|---|---:|---|
-| Hidden helper | `$A000-$A336` | REU prestash, save/restore helpers, bank-sensitive work. |
-| Hidden overlay | `$A800-$A84C` | Current `ZHIDDENRAM` worker example. |
+| Hidden helper | `$A000-$A6C7` | REU prestash, save/restore helpers, bank-sensitive work. |
+| Command slots | `$A800-$BFFF` | Module/submodule payload slots fetched from the assigned code bank. |
Before calling hidden code, ReadyBASIC saves flags, disables interrupts, forces
the low CPU data-direction bits in `$0000` to outputs, saves `$0001`, maps RAM
@@ -694,9 +879,9 @@ KERNAL-visible calls safe where needed.
- `$2AC0` must remain zero before stored-program `RUN`.
- `RESIDENT` must stay below `$2AC0`.
- `BRIDGE` must stay below `$C200`, leaving `$C200-$C5FF` for relocated frames.
-- `$C600-$C7FF` is shared ReadyOS REU metadata, not ReadyBASIC scratch.
-- `$C800-$C9FF` is ReadyOS shim ABI, not app RAM.
-- Warm resume restores `$A000` from the `$C280` visible shadow before hidden helper calls.
+- `$C600-$C7FF` is resident ReadyOS shim expansion capacity, not app RAM.
+- `$C800-$C9FF` is the stable ReadyOS shim ABI; together the shim owns 1 KB.
+- Warm resume restores `$A000` from the assigned-core-bank hidden-helper shadow before hidden helper calls.
- Warm resume must not cold-reset `FRETOP`, `VARTAB`, `ARYTAB`, or `STREND`.
- ReadyBASIC-owned vectors are restored before yielding to ReadyOS.
- Non-ReadyBASIC statements tail-call the original execute vector without
@@ -706,6 +891,12 @@ KERNAL-visible calls safe where needed.
- Acceptance re-entry uses launcher menu navigation, not direct app-bank
hotkeys.
+The assembler and linker config are a coupled ABI: `readybasic.s` is assembled
+with ca65 and linked only with `cfg/ready_app_readybasic.cfg`. Cold-load seed
+regions, under-ROM run slots, bridge/shared frames, and the exact `$1000-$7FFF`
+compact PRG span must move together. `verify_readybasic_plugin.py` enforces both
+sides of that dependency.
+
## Current Verification Evidence
Static guardrails:
@@ -718,14 +909,20 @@ Current static layout:
| Segment | Range | Size |
|---|---:|---:|
-| `ENTRY` | `$1000-$1102` | `$0103` (259B) |
-| `RESIDENT` | `$1200-$2ABE` | `$18BF` (6.2K, 6335 exact bytes) |
+| `ENTRY` | `$1000-$11FF` | `$0200` (512B) |
+| `RESIDENT` | `$1200-$2ABF` | `$18C0` (6.2K, 6336 exact bytes) |
| `REGSEED` | `$5000-$600F` | `$1010` (4.0K, 4112 exact bytes) |
-| `HIDDEN` | `$A000-$A364` | `$0365` (869B) |
-| `LOWPACK` / slot 0 payload | `$A800-$AEC6` | `$06C7` (1735B) |
-| `SLOTPACK1` / slot 1 payload | `$B000-$B238` | `$0239` (569B) |
-| slot 2 proof/overlays | `$B800-$B83E` | `$003F` (63B) |
-| `BRIDGE` | `$C000-$C1F8` | `$01F9` (505B) |
+| `HIDDEN` | `$A000-$A78A` | `$078B` (1931B) |
+| `LOWPACK` / slot 0 payload | `$A800-$AFDB` | `$07DC` (2012B) |
+| `SLOTPACK1` / slot 1 payload | `$B000-$B540` | `$0541` (1345B) |
+| `SLOTPACK2` / GFXPRIM | `$B800-$BF37` | `$0738` (1848B) |
+| `OVL1PACK` / GFXSPR | `$B800-$BA71` | `$0272` (626B) |
+| `OVL2PACK` / INPUTEV | `$B800-$B86C` | `$006D` (109B) |
+| `OVL3PACK` / GFXPOLY | `$B800-$BF78` | `$0779` (1913B) |
+| `OVL4PACK` / GFXDL | `$B800-$BF82` | `$0783` (1923B) |
+| `OVL5PACK` / GFXTILE | `$B800-$BCD9` | `$04DA` (1242B) |
+| `OVL6PACK` / SIDCORE | `$B800-$BA0D` | `$020E` (526B) |
+| `BRIDGE` | `$C000-$C1FE` | `$01FF` (511B) |
Current measured guardrails:
@@ -733,11 +930,16 @@ Current measured guardrails:
|---|---:|
| `BASIC_START` | `$2AC1` |
| Empty BASIC free bytes | `30013` |
-| `bin/readybasic.prg` size | `20994` |
-| `RESIDENT` | `$18BC` / 6332B |
-| `LOWPACK` | `$06C7` / 1735B |
-| `BRIDGE` | `$01F7` / 503B |
+| `bin/readybasic.prg` size | `28674` |
+| `RESIDENT` | `$18C0` / 6336B |
+| `LOWPACK` | `$07DC` / 2012B |
+| `HIDDEN` | `$078B` / 1931B |
+| `BRIDGE` | `$01FF` / 511B |
| `REGSEED` | `$1010` / 4112B |
+| `GFXPOLY` overlay | `$0779` / 1913B |
+| `GFXDL` overlay | `$0783` / 1923B |
+| `GFXTILE` overlay | `$04DA` / 1242B |
+| `SIDCORE` overlay | `$020E` / 526B |
Recent VICE coverage includes:
@@ -745,10 +947,20 @@ The broad external command/program/lifecycle/state wrappers have been refreshed
for bare parenthesized syntax. The demo suite is intentionally viewer-paced;
the regression probes stay shorter and more assertion-heavy.
+`make readybasic-vice-suites` is the complete 26-target regular acceptance
+aggregate. It includes the core lifecycle/program/state/hotkey/resume probes,
+the minimum-resume and screen/REU temporary-state probes, all current graphics
+phases and sprite-step examples, sound, ReadyOS loaded-app visibility, and the
+full visual verification. New official ReadyBASIC probes must be added to both
+`READYBASIC_VICE_SCRIPTS` and this aggregate so plan generation and execution
+cannot silently diverge. `verify_readybasic_plugin.py` enforces the exact
+26-target aggregate and the plan-only script coverage for the formerly omitted
+resume/screen/graphics examples.
+
| Probe | Coverage |
|---|---|
| Full expression probe | Direct bare command statements, command expressions, parenthesized `EXEC PROC`, `FUNC` with later assignment plus `RET`, numeric `FUNC` expression return/assignment, string `FUNC` expression return, and readable `LIST`. |
-| Plugin command probe | Direct command statements, `IF ... THEN` assignment/expression coverage, `UPPER`/`LOWER`, old-name rejection, string/REM safety, leading-comma rejection, `SCRCAP`/`SCRPUT`, slot-128 lookup, 128-handle edge, 48KB heap edge, screen heap exhaustion, wrong-handle-type rejection, screen-handle free, resume. |
+| Plugin command probe | Direct command statements, `IF ... THEN` assignment/expression coverage, `UPPER`/`LOWER`, old-name rejection, string/REM safety, leading-comma rejection, `SCRCAP`/`SCRPUT`, slot-128 lookup, descriptor filler-count guardrails, 128-handle edge, 48KB heap edge, screen heap exhaustion, wrong-handle-type rejection, screen-handle free, resume. |
| Program probe | Stored line start, colon chains, true/false `IF ... THEN` assignment/expression coverage, `FOR/NEXT`, strings, REM, DATA, arrays, hidden worker, handles, failure clearing. |
| `rbproc1` probe | Stored positive `PROC`/`FUNC`: no-param PROC, `%`, `$`, explicit `RET%`/`RET$`, colon chain, normalized `IF THEN :EXEC`, nested depth 2, int/string/float command and FUNC returns, `FADD` expression and statement forms, nested ReadyBASIC actuals, string concatenation, and readable `LIST`. |
| `rbprocerr` probe | Stored negative `PROC`/`FUNC`: unknown routine, wrong count/type, statement `EXEC` to `FUNC`, PROC extra actual, `ENDP` without `EXEC`, return-stack overflow, malformed nested actuals, and return/context type errors. |
@@ -759,7 +971,7 @@ the regression probes stay shorter and more assertion-heavy.
| Large-vars probe | BASIC workspace and variable behavior under heavier state. |
| Cross-app resume stress | ReadyBASIC survives repeated app switches. |
| Second-entry/editor stress | ReadyBASIC survives editor/launcher round trips and later re-entry. |
-| Demo automation suite | Viewer-paced walkthrough covering `FREEMEM`, editor round trip, assembler commands, `PROC`/`FUNC`, parameter groups, expected errors, REU handles, and nested expression forms. |
+| Demo automation suite | Viewer-paced walkthrough covering `MEMAVL`, editor round trip, assembler commands, `PROC`/`FUNC`, parameter groups, expected errors, REU handles, and nested expression forms. |
Some harness wrappers can report a process-level `partial` status even when
every step is `ok` and `FailedStep` is `null`; for ReadyBASIC these were treated
diff --git a/src/apps/readybasic/READYBASIC_FUTURE_GOALS.md b/src/apps/readybasic/READYBASIC_FUTURE_GOALS.md
index fa6146f..dbb5822 100644
--- a/src/apps/readybasic/READYBASIC_FUTURE_GOALS.md
+++ b/src/apps/readybasic/READYBASIC_FUTURE_GOALS.md
@@ -104,14 +104,21 @@ overlay choice, and command-family helpers lives in under-ROM module code.
## Graphics Memory Goals
-Graphics commands are intentionally deferred until the command-module model is
-stable. When they arrive, they should use the same proportional memory thinking:
+Graphics commands now exist as descriptor-backed built-in modules and overlays.
+Future graphics work should keep the same proportional memory thinking:
- keep BASIC workspace pressure low by storing large buffers, sprite sheets,
character sets, and bitmap resources in REU-backed handles;
- use VIC bank D and memory behind ROM only in ways compatible with the ReadyOS
shim and the app contract;
-- never use `$C800-$C9FF` unless deliberately calling the ReadyOS shim ABI;
-- avoid `$C600-$C7FF` except for ReadyOS REU allocation metadata;
+- never use `$C600-$C9FF` as app storage; the lower half is resident shim
+ expansion capacity and the upper half is the stable ReadyOS shim ABI;
- make graphics modes explicit about which C64 RAM ranges they claim while
active, especially screen RAM, color RAM, character sets, and bitmap pages.
+
+Implemented graphics already cover immediate bitmap/tile primitives, sprites,
+polling input, polygon and convex fill helpers, retained display lists, REU
+surface handles, charset/tileset/tilemap handles, and multicolor bitmap cell
+semantics. Future work should focus on resource-file loading into REU, richer
+asset packaging, more efficient dirty-region blits, and any new commands that
+fit the existing overlay budgets.
diff --git a/src/apps/readybasic/READYBASIC_GRAPHICS_COMMAND_DESIGN.md b/src/apps/readybasic/READYBASIC_GRAPHICS_COMMAND_DESIGN.md
new file mode 100644
index 0000000..c8ac07c
--- /dev/null
+++ b/src/apps/readybasic/READYBASIC_GRAPHICS_COMMAND_DESIGN.md
@@ -0,0 +1,916 @@
+# ReadyBASIC Graphics And Event Command Design
+
+This note reframes the old BASIC-extender command audit for the current
+ReadyBASIC architecture: bare parenthesized commands, expression-capable
+commands where useful, descriptor-backed assembler payloads, module/submodule
+loading, and REU-backed handles.
+
+It intentionally avoids native language features such as `WHILE`, `LABEL`,
+`JUMP`, `PROC`, `EXEC`, and `FUNC`, and it does not design general error
+handling. The focus is the command infrastructure: what can be done by resident
+parsing plus under-ROM command modules, while protecting resident RAM and BASIC
+bytes free.
+
+## Current Constraints
+
+ReadyBASIC's current command architecture has the right shape for a large
+graphics catalog:
+
+- User syntax is visible BASIC text: `COMMAND(arg,arg)` and selected
+ expression forms such as `A%=COMMAND(arg,arg)`.
+- Command descriptors live in the assigned ReadyBASIC core bank, not in the
+ BASIC workspace.
+- Command implementation code lives in the assigned code bank and is fetched
+ into under-ROM slots at `$A800`, `$B000`, and `$B800`.
+- Resident code should only parse BASIC-facing parameters, call BASIC ROM
+ helpers, clear output variables, and commit results.
+- Module code should do the heavy work: direct VIC/SID/CIA access, REU DMA,
+ graphics drawing, input/event sampling, buffer traversal, and blits.
+- Persistent objects should be typed REU handles, not BASIC arrays or resident
+ RAM structures.
+
+The current steady-state BASIC workspace is `$2AC1-$9FFF`, with about 30013
+empty BASIC bytes. Every permanent resident byte pushes that start upward.
+Graphics must therefore be a resource-command system, not a resident library.
+
+## Design Principles
+
+1. Keep graphics modes explicit. A graphics command must know exactly which VIC
+ bank, screen memory, bitmap memory, charset memory, color RAM, and REU
+ handles it owns.
+2. Keep BASIC-visible state tiny. BASIC sees mode numbers, small integers,
+ strings, and handles. REU holds bitmaps, display lists, sprite sheets,
+ tile maps, dirty rectangles, and command-private state.
+3. Separate immediate drawing from retained drawing. Plot/line/circle commands
+ should exist, but a retained display-list model is better for complex scenes.
+4. Prefer module-local managers over resident managers. The resident core should
+ not grow for sprite collision history, key states, display lists, or graphics
+ allocators.
+5. Treat Bank D as the default graphics/video bank. This keeps the visible
+ graphics framebuffer out of the BASIC workspace and out of ReadyBASIC's
+ under-ROM command slots.
+6. Use REU as the large backing store. Use small C64 buffers only for a scanline,
+ tile row, sprite record page, command page, or dirty-rect batch.
+
+## VIC Bank D Baseline
+
+On a C64, a VIC bank is 16KB. "Bank D" here means the VIC sees the `$C000-$FFFF`
+physical 64KB range as its video bank.
+
+That is attractive because ReadyBASIC's BASIC workspace ends at `$9FFF`, and
+command code runs under BASIC ROM at `$A000-$BFFF`. The Bank D visible region
+uses:
+
+| Range | Role |
+|---:|---|
+| `$C000-$C5FF` | ReadyBASIC bridge/shared-frame area while BASIC runs. Do not use for visible graphics state. |
+| `$C600-$C7FF` | Resident ReadyOS shim expansion reserve. Never use as graphics scratch. |
+| `$C800-$C9FF` | Stable ReadyOS shim ABI. Never use as graphics scratch. |
+| `$CA00-$CFFF` | Candidate screen/charset/sprite-pointer area, but must be allocated intentionally. |
+| `$D000-$DFFF` | I/O when CPU sees I/O, but VIC fetches video data from underlying RAM in this bank. Good for bitmap/charset data from the VIC side, awkward for CPU writes unless banking is controlled carefully. |
+| `$E000-$FFFF` | KERNAL ROM from CPU by default, but VIC can fetch underlying RAM. Good for bitmap/screen data if command modules write with ROM hidden. |
+
+The safest Bank D rule is:
+
+- CPU-visible graphics state at `$C000-$C9FF` remains off-limits by the current
+ ReadyBASIC contract; `$C600-$C9FF` is resident shim-owned memory.
+- Screen RAM, bitmaps, charsets, and sprite data are placed at or above `$CA00`,
+ preferably with layouts that avoid `$C000-$C9FF`.
+- Commands that write into `$D000-$FFFF` must explicitly manage `$01` banking
+ and restore it before returning.
+
+## Potential Graphics Modes
+
+These are the practical mode families ReadyBASIC should expose. The command API
+should hide the VIC register details but not hide the tradeoffs.
+
+| Mode | Resolution/shape | Memory | Strengths | Costs |
+|---|---|---:|---|---|
+| Text 40x25 | 1000 chars + color RAM | 1KB screen + 1KB color | Fast, readable, works with BASIC text habits, cheap snapshots. | Cell-based; not pixel graphics. |
+| Custom charset text | 40x25 with user glyphs | 1KB screen + 2KB charset + color | Best for tile games, dashboards, UI, maps. | Glyph upload and charset bank management; per-cell color limits remain. |
+| Extended background color text | 40x25, four background choices by char bits | 1KB screen + charset + color | Useful for coarse tile worlds. | Only 64 chars available per charset bank mode. |
+| Multicolor text | 40x25, chunky cells | 1KB screen + charset + color | Colorful tile/sprite-like scenes at low memory cost. | Half horizontal resolution inside chars; color rules are quirky. |
+| Standard bitmap hi-res | 320x200, 1 bit per pixel | 8KB bitmap + 1KB screen | Crisp line art, UI panels, graphs. | Two colors per 8x8 cell; full clears/blits cost time. |
+| Multicolor bitmap | 160x200 logical pixels | 8KB bitmap + 1KB screen + color | More color per cell, good for game/art screens. | Chunky pixels; color rules and per-cell attributes complicate drawing. |
+| Sprite overlay mode | 8 hardware sprites over any mode | Sprite data + pointers | Fast moving objects, cursors, player/enemies. | Only 8 visible sprites per raster line; multiplexing needs IRQ work. |
+| Hybrid retained scene | Any above plus REU display list | REU list + optional backing buffer | High-level scenes, redraw optimization, mode-independent commands. | Needs a renderer per target mode; more design up front. |
+
+### Recommended Public Mode Names
+
+Avoid names tied too tightly to old extenders. Use clear mode constants and one
+canonical spelling per behavior:
+
+```basic
+GFXMODE("TEXT")
+GFXMODE("TILE")
+GFXMODE("MTILE")
+GFXMODE("HIRES")
+GFXMODE("MBITMAP")
+```
+
+The statement form should set the mode. The expression form can return the
+current mode:
+
+```basic
+GFXMODE("HIRES")
+M%=GFXMODE()
+```
+
+## Implemented Phase 1 Snapshot
+
+Phase 1 is implemented as command infrastructure only. It adds built-in
+descriptor-backed commands and command-only parser signatures; it does not
+change ReadyBASIC control flow, native routine syntax, crunch normalization, or
+general BASIC expression parsing.
+
+Built-in graphics payloads are prestashed in the ReadyBASIC code bank:
+
+| Family | Module/submodule | Runtime area | Commands |
+|---|---:|---:|---|
+| `GFXCORE` | module `3`, submodule `16` | slot 1 `$B000-$B540` | `GFXMODE`, `GFXTEXT`, `GFXCLEAR`, `GFXTGT`, `GFXSYNC` |
+| `GFXPRIM` | module `3`, submodule `17` | slot 2 `$B800-$BF37` | `PLOT`, `PNT`, `LINE`, `RECT`, `FBOX`; Phase 2 also adds `CIRCLE`, `FCIRCLE`, `TILE`, `CHARAT`; the current worker includes real multicolor-bitmap plotting for those immediate primitives |
+| `GFXSPR` | module `3`, submodule `18` | slot-2 replacement overlay at `$B800-$BA71`, stored at REU code offset `$5000` | `SPRSET`, `SPRMOVE`, `SPRCOL`, `SPRROW`, `SPRSCAN`, `SPRCOLL`; Phase 2 also adds size/priority/multicolor controls |
+| `INPUTEV` | module `3`, submodule `19` | slot-2 replacement overlay at `$B800-$B86C`, stored at REU code offset `$5800` | `JOY`, `KEYP`, `KEYSCAN`, `KEYLAST` |
+| `GFXPOLY` | module `3`, submodule `20` | slot-2 replacement overlay at `$B800-$BF78`, stored at REU code offset `$6000` | `POLY`, `FPOLY`, `POLYH`, `FPOLYH`, `PBMAKE`, `PBUFSET`, `PBDROP` |
+| `GFXDL` | module `3`, submodule `21` | slot-2 replacement overlay at `$B800-$BF82`, stored at REU code offset `$6800` | `DLMAKE`, `DLRST`, `DLPLOT`, `DLLINE`, `DLRECT`, `DLFBOX`, `DLDRAW` |
+| `GFXTILE` | module `3`, submodule `22` | slot-2 replacement overlay at `$B800-$BCD9`, stored at REU code offset `$7000` | `CHRMAKE`, `CHRROW`, `CHRUSE`, `TSMAKE`, `TSSET`, `TMMAKE`, `TMSET`, `TMDRAW`, `MCELL`, `MCBG` |
+| Surface handle stubs | system slot 0 | slot 0 `$A800-$AFFF` | `GFXSURF`, `GFXBLIT` |
+
+The surface handle commands use the existing typed REU handle allocator and
+therefore live in the default command slot for Phase 1. They allocate and
+validate handle type `3` (`RB_HANDLE_TYPE_GFXSURF`) using 40 heap pages.
+`GFXBLIT(H%)` copies a full surface layout from REU to the visible Bank D
+bitmap, screen, and color ranges. `GFXTGT(H%)` records the selected surface
+handle, but the current immediate primitive workers still draw to the visible
+Bank D target. `GFXSYNC()` snapshots the current visible Bank D layout into the
+selected `GFXTGT(H%)` surface; `GFXBLIT(H%)` restores it. The REU surface path
+uses an I/O-visible `$35` memory configuration while programming the REU so Bank
+D RAM and REU registers are both reachable. The speed-first path for REU-backed
+rendering is therefore:
+build compact retained/tile resources in REU, render/copy them in command
+workers, then use full-surface blits rather than BASIC-level per-pixel writes.
+
+Implemented syntax:
+
+```basic
+GFXMODE("HIRES") : rem also "MBITMAP", "TILE", "MTILE", "TEXT"
+M%=GFXMODE()
+GFXTEXT()
+GFXCLEAR(C)
+H%=GFXSURF("HIRES")
+GFXTGT(0) : rem visible target
+GFXBLIT(H%)
+GFXSYNC()
+PLOT(X,Y,C)
+PNT(X,Y,P%) : rem readback
+LINE(X1,Y1,X2,Y2,C)
+RECT(X1,Y1,X2,Y2,C)
+FBOX(X1,Y1,X2,Y2,C)
+CIRCLE(X,Y,R,C)
+FCIRCLE(X,Y,R,C)
+TILE(X,Y,CH,C)
+CHARAT(X,Y,CH,C)
+SPRSET(N,ON,COLOR,PATTERN)
+SPRMOVE(N,X,Y)
+SPRCOL(N,COLOR)
+SPRROW(N,ROW,B1,B2,B3)
+SPRSIZE(N,XON,YON)
+SPRPRI(N,BEHIND)
+SPRMUL(N,ON)
+SPRMCO(C1,C2)
+SPRSCAN()
+SPRCOLL(N,C%)
+JOY(PORT,J%)
+KEYP(K%)
+KEYSCAN()
+KEYLAST(L%)
+```
+
+Bank D Phase 1 layout:
+
+| Range | Phase 1 use |
+|---:|---|
+| `$C000-$C5FF` | ReadyBASIC bridge/shared frames; never used by graphics. |
+| `$C600-$C7FF` | ReadyOS shim expansion reserve; graphics-owned symbols are forbidden here. |
+| `$C800-$C9FF` | ReadyOS shim ABI; graphics-owned symbols are forbidden here. |
+| `$CA00-$CBFF` | Hardware sprite data, eight 64-byte definitions. |
+| `$CC00-$CFFF` | Graphics screen RAM and sprite pointer table at `$CFF8`. |
+| `$D800-$DBE7` | Color RAM. |
+| `$E000-$FFFF` | Bitmap/charset RAM, written with BASIC/KERNAL ROM hidden. |
+
+Mode tradeoffs in the implemented renderer:
+
+| Mode | What Phase 1 does | Tradeoff |
+|---|---|---|
+| `TEXT` / `GFXTEXT()` | Restores ordinary VIC bank and text-ish control registers. | Returns the user to readable BASIC output. |
+| `HIRES` | Sets Bank D bitmap mode and draws one-bit pixels into `$E000`. | Crisp 320x200 plotting; color attributes are still coarse and minimal. |
+| `MBITMAP` | Sets Bank D multicolor bitmap mode and draws two-bit pixels into `$E000`. | 160x200 logical plotting; each 8x8 cell has shared color attributes, so later writes can recolor earlier pixels in the same cell. |
+| `TILE` | Sets Bank D text/tile screen and treats `PLOT(X,Y,C)` as cell write. | Fast cell graphics; `PNT()` returns the cell byte. |
+| `MTILE` | Sets tile screen plus multicolor control bit. | Establishes the mode; Phase 1 keeps the same cell-level primitive behavior. |
+
+Known Phase 1 limits:
+
+- `PNT(X,Y,OUT%)` is the Phase 1 readback spelling in demos and stored
+ programs.
+- Primitive coordinate callers are expected to stay in range: hires bitmap
+ `0<=X<320`, `0<=Y<200`; multicolor bitmap `0<=X<160`,
+ `0<=Y<200`; tile `0<=X<40`, `0<=Y<25`.
+- `LINE` is a small step-toward-endpoint worker, not full Bresenham. It is good
+ for horizontal, vertical, 45-degree, fans, and demos, but uneven slopes are
+ approximate.
+- `MBITMAP` immediate primitives expose the VIC-II multicolor bitmap slots
+ through the color argument. `C=0` clears the pixel pair. `C=1..15` is the
+ convenient direct-color form, drawing slot 3 and writing color RAM.
+ `C=16..31` draws slot 1 and writes the screen high nibble, `C=32..47` draws
+ slot 2 and writes the screen low nibble, and `C=48..63` draws slot 3 and
+ writes color RAM. `PNT` returns the pixel pair code `0..3`, not the
+ final VIC color number. `MTILE` still uses cell-level behavior.
+- `SPRROW(N,ROW,B1,B2,B3)` is the Phase 1 explicit sprite-pixel path. It
+ writes one 24-bit sprite row into Bank D sprite memory at `$CA00 + N*64`,
+ where `ROW` is `0..20`. This is intentionally simple and demo-friendly until
+ Phase 2 adds sprite-sheet/REU definitions.
+- `SPRSCAN()` polls and clears the VIC collision latches. There is no IRQ
+ sampler in Phase 1.
+- `KEYP()`, `KEYSCAN()`, and `KEYLAST()` read the ROM keyboard buffer
+ opportunistically. They do not reserve resident RAM or install a background
+ event queue.
+
+## Implemented Multicolor Bitmap Primitive Update
+
+The current `GFXPRIM` payload adds a mode-specific worker for
+`GFXMODE("MBITMAP")`. The existing immediate draw commands now use the
+multicolor bitmap memory layout when the current mode is MBITMAP:
+
+```basic
+10 rem x is 0..159 in mbitmap
+20 gfxmode("mbitmap"):gfxclear(0)
+30 line(4,18,155,18,17) : rem slot 1, color 1
+40 line(4,30,155,70,34) : rem slot 2, color 2
+50 fbox(86,82,148,144,37) : rem slot 2, color 5
+60 circle(46,112,28,51) : rem slot 3, color 3
+70 fcircle(118,112,22,58) : rem slot 3, color 10
+80 pnt(46,112,p%) : rem p% is 0..3 pair code
+```
+
+The same commands continue to use normal 320x200 one-bit plotting in `HIRES`,
+and cell writes in `TILE`/`MTILE`.
+
+Color argument meanings in `MBITMAP`:
+
+| Color argument | Bitmap pair code | Attribute touched | Notes |
+|---:|---:|---|---|
+| `0` | `0` | none | Clears that logical pixel pair to the background. |
+| `1..15` | `3` | color RAM `$D800-$DBE7` | Convenient direct-color form for quick BASIC demos. |
+| `16..31` | `1` | screen RAM high nibble at `$CC00-$CFE7` | Use `16+color`. |
+| `32..47` | `2` | screen RAM low nibble at `$CC00-$CFE7` | Use `32+color`. |
+| `48..63` | `3` | color RAM `$D800-$DBE7` | Explicit slot-3 form, equivalent to direct color plus 48. |
+
+The color attributes are still VIC-II cell attributes. A later primitive in the
+same 8x8 cell can change the displayed color of earlier slot-1, slot-2, or
+slot-3 pixels in that cell. This is a hardware tradeoff, not a ReadyBASIC
+parser issue.
+
+The MBITMAP-specific demos are `rbgfx21_mbitmap_prims.bas`,
+`rbgfx22_mbitmap_point.bas`, `rbgfx25_mbcells.bas`, the broader
+`rbgfx26_mode_matrix.bas`, and retained-list `rbgfx30_mbitmap_dlist.bas`.
+`make readybasic-gfx-mbitmap-vice`, `make readybasic-gfx-phase4-vice`, and
+`make readybasic-gfx-phase5-vice` boot ReadyOS, load ReadyBASIC, load the BASIC
+demos from ReadyBASIC, capture screenshots, and verify the focused readback
+checks such as `PNT` returning `1 2 3` for the three colored slots.
+
+## Demo Coverage Matrix
+
+Readable graphics demos are built with `petcat -w2 -l 2ac1` and included in the
+ReadyBASIC-capable D81 profiles:
+
+| Demo | Main coverage |
+|---|---|
+| `rbgfx01` | `GFXMODE`, `GFXCLEAR`, `GFXTEXT` across `HIRES`, `MBITMAP`, `TILE`, `MTILE`. |
+| `rbgfx02`-`rbgfx05` | HIRES `PLOT`, `PNT`, `LINE`, `RECT`, `FBOX`. |
+| `rbgfx06`, `rbgfx27`, `rbgfx31` | `GFXSURF`, `GFXTGT`, `GFXSYNC`, `GFXBLIT`, visible target restore. |
+| `rbgfx07`, `rbgfx21`, `rbgfx22`, `rbgfx25` | MBITMAP primitive slot semantics, `PNT` pair-code readback, `MCELL`, `MCBG`. |
+| `rbgfx08`, `rbgfx15`, `rbgfx24`, `rbgfx28`, `rbgfx29` | Tile/cell commands, charset rows, tilesets, tilemaps, and visible Bank D `TILE`/`MTILE` immediate primitives. |
+| `rbgfx09`, `rbgfx10`, `rbgfx13`, `rbgfx16` | Sprite setup, movement, pixels, collision polling, expansion, priority, multicolor. |
+| `rbgfx11` | `JOY`, `KEYP`, `KEYSCAN`, `KEYLAST` polling. |
+| `rbgfx14` | HIRES `CIRCLE` and `FCIRCLE`. |
+| `rbgfx17`-`rbgfx20` | Array and REU-handle polygons. |
+| `rbgfx23` | Retained display-list creation and replay. |
+| `rbgfx26` | Mode matrix for immediate primitives in `HIRES`, `MBITMAP`, `TILE`, and `MTILE`. |
+| `rbgfx30` | `GFXDL` retained display-list replay in `MBITMAP`. |
+| `rbgfx32` | Convex polygon outline/fill showcase. |
+
+## Implemented Phase 2 Snapshot
+
+Phase 2 is also command-only. It does not add any ReadyBASIC syntax or control
+flow. The implementation adds visible, demoable primitives and sprite controls
+inside the existing built-in graphics module structure:
+
+| Command | Module | Current behavior |
+|---|---|---|
+| `CIRCLE(X,Y,R,C)` | `GFXPRIM` | Draws a compact midpoint outline circle in the active primitive mode. |
+| `FCIRCLE(X,Y,R,C)` | `GFXPRIM` | Draws a filled circular placeholder as the bounding filled rectangle. This proves the command path and mode targeting; a true midpoint/disk fill is still future work. |
+| `TILE(X,Y,CH,C)` | `GFXPRIM` | Writes a character/color cell in Bank D tile modes, and also writes ordinary `$0400` text cells after `GFXTEXT()` so demos can show ROM charset output. |
+| `CHARAT(X,Y,CH,C)` | `GFXPRIM` | Alias for `TILE`; intended for text-cell style programs. |
+| `SPRSIZE(N,XON,YON)` | `GFXSPR` | Controls VIC sprite X/Y expansion bits. |
+| `SPRPRI(N,BEHIND)` | `GFXSPR` | Controls the VIC sprite-background priority bit. |
+| `SPRMUL(N,ON)` | `GFXSPR` | Controls VIC sprite multicolor enable bits. |
+| `SPRMCO(C1,C2)` | `GFXSPR` | Sets the two shared sprite multicolor registers. |
+| `SPRCOL(N,C)` | `GFXSPR` | Sets the per-sprite primary color register. |
+
+Phase 2 demo programs:
+
+- `rbgfx14_phase2_prims.bas`: `CIRCLE`, `FCIRCLE`, `RECT`, and `LINE`.
+- `rbgfx15_phase2_tiles.bas`: `TILE` and `CHARAT` in visible text cells.
+- `rbgfx16_phase2_sprite_ctrl.bas`: explicit `SPRROW` sprite pixels, movement,
+ expansion, priority, multicolor, and recolor stages.
+
+Phase 2 deliberately did not implement retained REU display lists,
+sprite-sheet loaders, true REU offscreen drawing, dirty-rect `GFXSYNC`, or true
+circular fill. `SCROLL` was also deferred. Phase 3 adds polygon commands in a
+separate `GFXPOLY` overlay rather than consuming the remaining `GFXPRIM`
+runtime headroom.
+After the `CMDPACK2`/replacement-overlay rework, `GFXSPR` and `INPUTEV` no
+longer consume `GFXPRIM`'s slot-2 runtime headroom, but every individual
+overlay still has a hard 2KB execution-image budget.
+
+## Implemented Phase 3 Snapshot
+
+Phase 3 is polygon-first and command-only. It adds one built-in slot-2
+replacement overlay, `GFXPOLY`, with runtime address `$B800-$BF78`, cold-load
+source `OVL3PACK`, and assigned code-bank offset `$6000`. `GFXPRIM` stays at
+`$B800-$BF37`; polygon bodies do not consume the remaining `GFXPRIM` headroom.
+
+Implemented syntax:
+
+```basic
+POLY(A%(0),COUNT,C)
+FPOLY(A%(0),COUNT,C)
+PBMAKE(COUNT,H%)
+PBUFSET(H%,INDEX,X,Y)
+POLYH(H%,COUNT,C)
+FPOLYH(H%,COUNT,C)
+PBDROP(H%)
+```
+
+Array-backed `POLY` and `FPOLY` read BASIC integer array pairs:
+`x0,y0,x1,y1,...`. `COUNT` is the number of points and currently accepts
+`3..32`. The array stores ordinary BASIC `%` values; the command reads the
+array storage as 16-bit coordinates and the plotting worker maps them to the
+active mode.
+
+REU-backed point buffers use typed handle type `4`
+(`RB_HANDLE_TYPE_PNTBUF`). `PBMAKE(COUNT,H%)` allocates one REU heap page,
+currently supporting up to 64 points. `PBUFSET(H%,INDEX,X,Y)` writes zero-based
+little-endian `x,y` pairs into that page. `PBDROP(H%)` releases the typed
+handle.
+
+The originally proposed same-name handle overloads,
+`POLY(H%,COUNT,C)` and `FPOLY(H%,COUNT,C)`, were not implemented in Phase 3.
+The resident parser was already constrained against the fixed
+`BASIC_START=$2AC1` boundary, so the handle forms use explicit commands
+`POLYH` and `FPOLYH`. This keeps BASIC bytes free unchanged and keeps overload
+dispatch out of the resident parser.
+
+`POLY`/`POLYH` draw each edge by using the same compact step-toward-endpoint
+line behavior as the current immediate primitives, then close the final point
+back to the first. In bitmap modes this plots to Bank D bitmap RAM at
+`$E000-$FFFF`; in tile modes it writes cell-space approximations through the
+same tile plotting path.
+
+`FPOLY`/`FPOLYH` currently use a conservative convex fan fill: the first point
+is treated as the anchor, each successive edge is stepped, and lines are drawn
+from the anchor to those edge points. This gives demoable filled triangles and
+convex polygons while staying inside the 2KB overlay. A full scanline fill with
+intersection sorting, concave polygon handling, and larger edge buffers remains
+future work.
+
+## Command Families
+
+### 1. Mode And Surface Commands
+
+These commands own VIC setup, Bank D allocation, and visible/backing surface
+selection.
+
+| Command | Meaning |
+|---|---|
+| `GFXMODE(mode$)` | Switch to a text/tile/bitmap/sprite-capable mode. |
+| `GFXTEXT()` | Return to ordinary text mode and restore expected screen pointers. |
+| `GFXCLEAR(color)` | Clear the current visible surface using mode-aware fill logic. |
+| `GFXSURF(mode$,H%)` / `H%=GFXSURF(mode$)` | Allocate a REU-backed surface handle compatible with a mode. |
+| `GFXTGT(H%)` | Draw subsequent immediate commands into a REU surface instead of the visible Bank D surface. |
+| `GFXTGT(0)` | Draw subsequent immediate commands directly to the visible surface. |
+| `GFXBLIT(H%)` | Copy a compatible REU surface to the visible Bank D layout. |
+| `GFXSYNC()` | Apply dirty rectangles or pending blit work. |
+| `GFXINFO(H%,A%(0))` | Return handle/mode/width/height/stride metadata into an array. |
+
+The key split is visible target versus REU target. `GFXTGT(0)` is simple and
+direct. `GFXTGT(H%)` records an off-screen target handle and `GFXBLIT(H%)`
+makes a compatible surface visible. Immediate primitives still draw visible
+Bank D; the speed-first path is to render or copy
+larger retained resources in command workers and blit complete surfaces.
+
+### 2. Immediate Pixel/Primitive Commands
+
+These are the classic BASIC-extender graphics commands. They operate on the
+current target.
+
+| Command | Applies to | Notes |
+|---|---|---|
+| `PLOT(x,y,c)` | Bitmap, multicolor bitmap, maybe tile modes | Pixel semantics depend on current mode. |
+| `PNT(x,y)` | Bitmap modes | Expression-safe color/readback command. |
+| `LINE(x1,y1,x2,y2,c)` | Bitmap modes; tile fallback optional | Bresenham-style worker in module code. |
+| `RECT(x1,y1,x2,y2,c)` | Bitmap and tile modes | Outline rectangle. |
+| `FBOX(x1,y1,x2,y2,c)` | Bitmap and tile modes | Filled rectangle. |
+| `CIRCLE(x,y,r,c)` | Bitmap modes | Implemented as a compact midpoint outline worker in `GFXPRIM`; further variants may move to overlays. |
+| `FCIRCLE(x,y,r,c)` | Bitmap modes | More expensive; likely overlay. |
+| `POLY(A%(0),count,c)` / `POLYH(H%,count,c)` | Bitmap modes; tile approximation | Phase 3 outline polygon from BASIC integer array pairs or a REU point-buffer handle. |
+| `FPOLY(A%(0),count,c)` / `FPOLYH(H%,count,c)` | Bitmap modes; tile approximation | Phase 3 conservative convex fan fill from BASIC integer array pairs or a REU point-buffer handle. |
+| `FILL(x,y,c)` | Bitmap modes | Flood fill needs REU/stack workspace, not resident stack. |
+
+Tradeoff: immediate commands are intuitive but can be slow if each command maps
+banking, fetches a module, updates visible RAM, and returns to BASIC. They are
+still essential because users expect them and they make small programs pleasant.
+
+### 3. Tile/Text Graphics Commands
+
+These should not be treated as second-class. On a C64 they are often the best
+performance/clarity tradeoff.
+
+| Command | Meaning |
+|---|---|
+| `TILESET(H%)` | Set active REU-backed charset/tile resource. |
+| `TILEDEF(index,dataH%)` | Define one tile from a handle or byte array. |
+| `TILE(x,y,index,color)` | Put one tile/cell. |
+| `TILEMAP(H%)` | Set active REU-backed tilemap. |
+| `TILEDRAW(H%,x,y,w,h)` | Draw tilemap region to visible screen. |
+| `SCROLL(dx,dy)` | Scroll text/tile screen with mode-aware memory copies. |
+| `CHARAT(x,y,ch,color)` | Text cell put. |
+| `TEXTAT(x,y,text$,color)` | Text string put. |
+
+Tile modes should be first-class because they are fast, compact, and do not
+require full 8KB bitmap blits for most game/UI screens.
+
+### 4. Sprite Commands
+
+Hardware sprites are independent of the bitmap/text choice, so the sprite module
+should be mostly mode-agnostic.
+
+| Command | Meaning |
+|---|---|
+| `SPRDEF(n,H%,offset)` | Copy sprite data from a REU sprite-sheet handle into Bank D sprite memory. |
+| `SPRSET(n,on,color,multi,priority)` | Configure sprite flags. |
+| `SPRMOVE(n,x,y)` | Set sprite position. |
+| `SPRXY(n,X%,Y%)` / `X%=SPRX(n)` | Read sprite position. |
+| `SPRSIZE(n,xon,yon)` | Set X/Y expansion flags. |
+| `SPRCOL(n,c)` | Set primary color. |
+| `SPRROW(n,row,b1,b2,b3)` | Phase 1 direct row write for an 8-sprite Bank D pattern. |
+| `SPRMCO(c1,c2)` | Set shared multicolor registers. |
+| `SPRCOLL(n)` | Read and optionally clear collision state for sprite n. |
+| `SPRSCAN()` | Poll collision registers and latch results into REU event state. |
+
+Sprite memory in Bank D should be allocated from a known high region, with the
+sprite pointer table placed in the selected screen RAM page. A sprite-sheet
+handle in REU can store many 64-byte definitions; only the currently needed
+eight, or a small active set, need to be copied to visible Bank D RAM.
+
+### 5. Retained Display-List Commands
+
+This is the richer model and should be a separate graphics module family, not
+mixed into the primitive module. It lets BASIC build a scene description once,
+store it in REU, and ask the renderer to draw it efficiently for the current
+mode.
+
+| Command | Meaning |
+|---|---|
+| `DLNEW(H%)` / `H%=DLNEW()` | Allocate a display-list handle. |
+| `DLCLEAR(H%)` | Clear all records. |
+| `DLADDLINE(H%,x1,y1,x2,y2,c,z)` | Append a line record. |
+| `DLADDRECT(H%,x1,y1,x2,y2,c,fill,z)` | Append a rectangle record. |
+| `DLADDPOLY(H%,pointsH%,count,c,fill,z)` | Append a polygon record. |
+| `DLADDSPR(H%,sprite,x,y,z)` | Append a logical sprite/object record. |
+| `DLADDTEXT(H%,x,y,text$,color,z)` | Append text record. |
+| `DLDRAW(H%)` | Render the list top-to-bottom into the current target. |
+| `DLDRAW(H%,surfaceH%)` | Render into a REU surface. |
+| `DLBLIT(H%)` | Render to backing surface, then blit to visible. |
+
+Recommended display-list record shape in REU:
+
+| Field | Size | Meaning |
+|---|---:|---|
+| Type | 1 | Line, rect, circle, poly, sprite, text, tilemap, command. |
+| Flags | 1 | Filled, visible, dirty, mode hints. |
+| Z/order | 1 | Draw order bucket. |
+| Color/style | 1 | Mode-specific pen/style index. |
+| X/Y/W/H or first args | 8 | Four 16-bit fields. |
+| Aux handle/id | 2 | Points handle, sprite id, text handle, tilemap handle. |
+| Aux offset/count | 4 | Record-specific detail. |
+
+Keep records fixed-size for v1, even if a few bytes are wasted. Fixed records
+make REU paging and sorting predictable. A later module can add compact variable
+records if it is worth the complexity.
+
+The renderer should support two strategies:
+
+1. Preserve order: draw records in append order. Fast, simple, predictable.
+2. Z-bucket: sort or bucket by small `z` values into REU scratch, then draw
+ back-to-front/top-to-bottom. More expensive, better for scenes.
+
+Do not make resident code understand display lists. Resident code should only
+parse `DLDRAW(H%)`; the graphics module owns traversal.
+
+## REU Surface Strategies
+
+### Direct Visible Drawing
+
+Command draws straight into Bank D.
+
+Pros:
+
+- Lowest memory use.
+- Immediate visual feedback.
+- Good for `PLOT`, `LINE`, cursor, simple drawing tools.
+
+Cons:
+
+- Flicker/tearing risk.
+- Slow BASIC loops show partial drawing.
+- Commands must handle ROM/I/O banking every time.
+
+### Full REU Backing Surface Then Blit
+
+Commands draw into a REU surface handle. `GFXBLIT(H%)` copies to Bank D.
+
+Pros:
+
+- No visible partial drawing.
+- Easy redraw from a clean backing buffer.
+- Surfaces can be saved, restored, double-buffered, or composed.
+
+Cons:
+
+- A full bitmap is about 8KB plus attribute/screen data.
+- REU-to-C64 blit still takes time and must stage around color RAM/I/O quirks.
+- Mode-specific blitters are required.
+
+### Small RAM Buffer Plus REU
+
+Commands use `$C500` or another small page/row buffer to render chunks, then DMA
+or copy chunks into Bank D.
+
+Pros:
+
+- Low resident/RAM cost.
+- Good for scanlines, tile rows, dirty rectangles, and color RAM staging.
+- Keeps complex temporary state out of the stack.
+
+Cons:
+
+- More bookkeeping.
+- Random pixel writes into REU are awkward unless the module has helpers for
+ addressing and page fetch/store.
+
+### Dirty Rectangle Blit
+
+Immediate or retained drawing records dirty rectangles in REU. `GFXSYNC()`
+copies only touched areas.
+
+Pros:
+
+- Huge win for UI, tile games, cursors, sprites, and small animations.
+- Avoids full 8KB bitmap copies when only a panel changes.
+
+Cons:
+
+- Merging rectangles takes code.
+- Worst case is slower than a full blit if everything is dirty.
+- Color RAM and bitmap data have different layouts, so dirty copying is
+ mode-specific.
+
+## Mode Effects On Command Semantics
+
+The same command name should behave predictably, but not all modes can support
+the same semantics cheaply.
+
+| Command | Text/tile | Hi-res bitmap | Multicolor bitmap |
+|---|---|---|---|
+| `PLOT` | Cell-level write, not true pixel | Natural 320x200 pixel | Natural 160x200 logical pixel |
+| `LINE` | Optional char approximation | Strong | Strong but chunky |
+| `FILL` | Tile flood fill possible | Expensive but normal | Expensive and color-rule-sensitive |
+| `TEXTAT` | Natural | Requires glyph renderer | Requires chunky glyph renderer |
+| `TILE` | Natural | Could blit tile graphics | Could blit chunky tile graphics |
+| `SPRITE` | Natural overlay | Natural overlay | Natural overlay |
+| `DLADD*` | Renderer chooses cell/tile or bitmap implementation | Renderer draws primitives | Renderer maps coordinates/colors to chunky layout |
+
+The command contract should return a mode error for unsupported combinations
+rather than silently doing a bad approximation. Optional approximations can be
+separate commands or flags.
+
+## Module Layout Proposal
+
+Use multiple modules so a user can load only what they need.
+
+| Module | Slot shape | Purpose |
+|---|---|---|
+| `GFXCORE` | Slot 1 stable manager | Mode state, handle validation, target selection, Bank D layout, blit dispatcher. |
+| `GFXPRIM` | Slot 2 base image | Plot, line, rect, circle, and tile/cell workers. |
+| `GFXPOLY` | Slot 2 replacement overlay | Polygon and REU point-buffer workers. |
+| `GFXTILE` | Slot 2 overlays | Text/tile/charset/tilemap operations. |
+| `GFXSPR` | Slot 2 or slot 1+2 | Sprite definition, movement, collision polling. |
+| `GFXDL` | Slot 1+2 span or stable+overlay | Display-list traversal, z-buckets, renderer dispatch. |
+| `INPUTEV` | Slot 2 small module | Key/joystick/paddle polling and event-state access. |
+
+`GFXCORE` should be sticky while graphics mode is active. Other modules can
+rotate through slot 2. A larger display-list renderer may span slots 1+2 and
+temporarily evict `GFXCORE`, but only if it includes the helpers it needs.
+
+## Resident Parser Signatures To Reuse
+
+Keep new resident parser growth low by designing commands around a small set of
+shared signatures:
+
+| Signature shape | Examples |
+|---|---|
+| No args, optional integer expression result | `GFXMODE()`, `SPRSCAN()`, `KEYSCAN()` |
+| String input | `GFXMODE("HIRES")`, `ZMODLD("RBM.GFX")` |
+| Handle input | `GFXBLIT(H%)`, `DLDRAW(H%)`, `TILESET(H%)` |
+| Numeric pair | `PLOT(x,y,c)`, `SPRMOVE(n,x,y)` |
+| Four numeric coords | `LINE(x1,y1,x2,y2,c)`, `RECT(...)` |
+| Array base plus count | `POLY(A%(0),count,c)`, `FPOLY(A%(0),count,c)` |
+| Point-buffer handle plus count | `POLYH(H%,count,c)`, `FPOLYH(H%,count,c)` |
+| Handle plus numeric args | `DLADDLINE(H%,x1,y1,x2,y2,c,z)` |
+| Optional output handle | `GFXSURF("HIRES",H%)` and `H%=GFXSURF("HIRES")` |
+
+If many graphics commands arrive, a compact REU-backed signature table becomes
+important. The resident parser should not gain one custom case per primitive.
+
+## Event Detection Without Resident RAM Growth
+
+There are three viable strategies for keypress, joystick, and sprite collision
+state.
+
+### Strategy A: Pure Polling Commands
+
+Commands read hardware state only when called:
+
+```basic
+J%=JOY(2)
+K%=KEYP()
+C%=SPRCOLL(0)
+```
+
+Pros:
+
+- Almost no resident growth.
+- No IRQ lifecycle risk.
+- Easy to keep compatible with BASIC and ReadyOS.
+
+Cons:
+
+- Misses short key/collision events between polls.
+- BASIC loops can be too slow for action games.
+
+Use this first. It is the simplest and most robust.
+
+### Strategy B: Command-Installed IRQ Sampler With REU Event Ring
+
+A command installs a small IRQ routine, but the routine writes only tiny event
+state and queues to a fixed or handle-backed REU area:
+
+```basic
+EVINIT(H%)
+EVON()
+EVOFF()
+KEYGET(K%)
+JOYGET(2,J%)
+COLLGET(C%)
+```
+
+Possible state layout:
+
+| Location | Meaning |
+|---|---|
+| Bridge byte | IRQ installed/enabled flag and previous vector pointer. |
+| Small C64 shadow | Last key byte, joystick byte, collision latch. |
+| REU event handle | Ring buffer of key/collision/joystick timestamp records. |
+
+Pros:
+
+- Captures short events.
+- Keeps history in REU, not BASIC arrays.
+- Commands can read and clear event records later.
+
+Cons:
+
+- Any IRQ hook is global machine state and must be disabled/restored on `EXIT`.
+- REU DMA from IRQ is risky; better to keep IRQ writes in a tiny C64 shadow and
+ flush to REU from a command.
+- More edge cases with ROM editor, prompt hotkeys, and ReadyOS navigation.
+
+Recommended variant: IRQ stores only tiny state in existing bridge/scratch bytes;
+`EVFLUSH()` copies batches to REU from normal command context. Do not perform
+REU DMA inside the IRQ in v1.
+
+### Strategy C: Raster/Sprite Manager Module
+
+A graphics module owns a frame loop helper:
+
+```basic
+GFXFRAME()
+SPRSCAN()
+EVSCAN()
+```
+
+The BASIC program calls `GFXFRAME()` once per loop. That command samples keys,
+joystick, sprite collisions, updates sprite positions, renders dirty display-list
+records, and blits.
+
+Pros:
+
+- No global IRQ install required.
+- One command can amortize module fetch/banking overhead.
+- Good fit for BASIC game loops.
+
+Cons:
+
+- Events are still sampled once per frame.
+- User must structure code around the frame command.
+
+This is the best middle path. It avoids resident growth and IRQ lifecycle
+fragility while providing a clear high-level model.
+
+## Sprite Collision Handling
+
+The VIC collision registers are latch-like; reading them clears them. A direct
+`SPRCOLL(n)` command is fine for simple programs, but a richer sprite module
+should centralize reads so one command does not accidentally clear state before
+another sees it.
+
+Recommended model:
+
+- `SPRSCAN()` reads sprite-sprite and sprite-background collision registers once.
+- The module writes the latched result into module event state in REU or a small
+ C64 shadow.
+- `SPRCOLL(n)` reads the stored state, not necessarily the raw VIC register.
+- `SPRCLEAR(n)` or `SPRCLEAR()` clears stored state.
+- `GFXFRAME()` calls `SPRSCAN()` internally.
+
+This keeps collision behavior deterministic and avoids hidden coupling between
+multiple collision query commands.
+
+## Keypress Detection
+
+Do not expand the existing prompt hotkey system into a full game keyboard
+scanner. Prompt navigation and running-program input have different contracts.
+
+Recommended commands:
+
+| Command | Meaning |
+|---|---|
+| `KEYP()` | Return current decoded key or 0, polling only. |
+| `KEYDOWN(code)` | Return current matrix state for a key code. |
+| `KEYSCAN()` | Update module-owned keyboard state snapshot. |
+| `KEYGET(K%)` / `K%=KEYGET()` | Return last scanned key/event. |
+| `KEYCLR()` | Clear module keyboard event state. |
+
+For action use, `GFXFRAME()` should call `KEYSCAN()` and store a stable state
+snapshot. Programs can then query `KEYDOWN()` without each query rescanning or
+mutating the state.
+
+## Recommended Command Set By Phase
+
+### Phase 1: Safe Visible Results
+
+- `GFXMODE`, `GFXTEXT`, `GFXCLEAR`
+- `PLOT`, `PNT`, `LINE`, `RECT`, `FBOX`
+- `GFXSURF`, `GFXTGT`, `GFXBLIT`
+- `SPRSET`, `SPRMOVE`, `SPRCOL`, `SPRROW`, `SPRSCAN`, `SPRCOLL`
+- `KEYP`, `JOY`, `KEYSCAN`, `KEYGET`
+
+This gives useful graphics without display-list complexity or IRQ hooks.
+
+### Phase 2: REU Resources
+
+- Implemented now: `TILE`, `CHARAT`, midpoint outline `CIRCLE`, `FCIRCLE`, sprite expansion,
+ sprite priority, sprite multicolor enable, and shared sprite multicolor
+ registers.
+- Deferred: `TILESET`, `TILEDEF`, `TILEMAP`, `TILEDRAW`, `SPRDEF`, `SPRLOAD`,
+ sprite-sheet handles, `GFXSYNC` dirty-rect blits, and `FILL`.
+
+This phase starts using overlay-heavy primitive and sprite workers while keeping
+REU resource/rendering work out of resident RAM. Full REU-backed tilemaps,
+sprite sheets, and retained resources remain a later phase.
+
+### Phase 3: Polygon Overlay
+
+- Implemented now: `POLY`, `FPOLY`, `POLYH`, `FPOLYH`, `PBMAKE`, `PBUFSET`,
+ and `PBDROP`.
+- `GFXPOLY` is a built-in slot-2 replacement overlay, prestashed at code-bank
+ offset `$6000` and fetched into `$B800-$BF78`.
+- BASIC integer array polygons and typed REU point-buffer polygons are both
+ supported.
+- Deferred: same-name handle overloads, full scanline/concave fill, and larger
+ point-buffer paging.
+
+### Phase 4: Speed-First Retained And Tile Resources
+
+Implemented now, command-only:
+
+- `DLMAKE(MAX,H%)`, `DLRST(H%)`, `DLPLOT(H%,X,Y,C)`, `DLLINE(H%,X1,Y1,X2,Y2)`,
+ `DLRECT(H%,X1,Y1,X2,Y2)`, `DLFBOX(H%,X1,Y1,X2,Y2)`, and `DLDRAW(H%)`.
+- `CHRMAKE(N,H%)`, `CHRROW(H%,CH,ROW,BYTE)`, and `CHRUSE(H%)`.
+- `TSMAKE(N,H%)`, `TSSET(H%,TILE,CH,C)`, `TMMAKE(N,H%)`,
+ `TMSET(H%,INDEX,TILE,0)`, and `TMDRAW(MAP%,TILESET%)`.
+- `MCELL(CX,CY,S1,S2,S3)` and `MCBG(C)` for explicit multicolor bitmap cell
+ attributes.
+
+The public constructor names use `MAKE`, not `NEW`, because command text is
+still passing through the existing BASIC tokenizer and embedded BASIC keywords
+inside command names can produce surprising syntax failures. This keeps the
+language unchanged.
+
+Display lists are deliberately tiny: one REU page, up to 31 eight-byte records.
+The current record renderer supports plot, line, outline rectangle, and filled
+rectangle records. `DLLINE`, `DLRECT`, and `DLFBOX` default to color `1`
+because adding a six-argument parser signature would grow resident code; color
+variants should be added only when the parser budget is deliberately expanded.
+
+Tile resources are fixed-format Phase 4 handles: charset handles allocate 8
+pages, tilesets allocate 1 page, and tilemaps allocate 4 pages for a 40x25 map.
+There is no loader yet. The intended future resource-file type should be a
+build-owned binary/SEQ package that can be stashed directly into REU before
+BASIC init or loaded later into these same typed handles:
+
+```text
+RBR header: magic/version/type/mode/pages/checksum
+payloads: charset pages, tileset records, tilemap pages, sprite sheets,
+ display-list records, optional palette/cell-attribute tables
+```
+
+Phase 5 fixed the previous Bank D tile visibility bug: the four-character
+`GFXMODE("TILE")` parser branch now selects tile mode instead of falling through
+to `TEXT`, and `rbgfx28`/`rbgfx29` screenshots prove visible tile and multicolor
+tile cells inside ReadyBASIC running under ReadyOS.
+
+Polygon fill remains the Phase 3 conservative convex fan fill. That keeps the
+overlay small and avoids concave/intersection sorting cost on a 1MHz 6502. The
+next improvement should replace the fan with a convex-only scanline fill inside
+`GFXPOLY`; concave support is intentionally out of scope until there is a
+strong use case.
+
+### Phase 5: Mode Visibility, REU Surface Blit, And Coverage
+
+Phase 5 is still command-only. It hardens the graphics command path rather than
+adding language behavior:
+
+- `GFXMODE("TILE")` and `GFXMODE("TEXT")` are now distinct four-character
+ modes.
+- Under-ROM command overlays execute with BASIC ROM hidden and I/O visible.
+ `GFXSYNC`/`GFXBLIT` use `$35` during REU DMA so Bank D RAM and REU registers
+ are both reachable.
+- `GFXCLEAR` seeds default solid tile glyphs for immediate `TILE`/`MTILE`
+ primitive demos. Custom charsets still use `CHRMAKE`, `CHRROW`, and
+ `CHRUSE`.
+- `DLPLOT` preserves its color argument during retained replay, and display-list
+ plotting has an `MBITMAP` path.
+- `make readybasic-gfx-phase5-vice` captures visible tile, visible multicolor
+ tile, MBITMAP retained-list, REU sync/blit source/clear/restore, and polygon
+ screenshots.
+
+### Future Phase: Optional Event IRQ
+
+- `EVINIT`, `EVON`, `EVOFF`, `EVFLUSH`, `EVGET`
+- Only after pure polling and `GFXFRAME()` are proven.
+- IRQ must be restored before ReadyOS yield and must not perform REU DMA in v1.
+
+## Tradeoff Summary
+
+| Choice | Wins | Costs |
+|---|---|---|
+| Bank D visible graphics | Avoids BASIC workspace; VIC can see ROM-underlying RAM. | Must avoid `$C000-$C9FF`; CPU writes to ROM/I/O ranges need careful banking. |
+| Direct drawing | Simple and immediate. | Flicker and visible partial renders. |
+| REU backing surfaces | Clean redraws, double-buffering, handle-based resources. | More blit code and mode-specific layout handling. |
+| Small RAM buffer | Minimal resident pressure. | More complex chunked algorithms. |
+| Display lists | High-level scene model, renderer can optimize. | More REU data structures and renderer code. |
+| Pure polling events | Safest and smallest. | Can miss fast events. |
+| IRQ event sampler | Captures short events. | Global-state lifecycle risk; must avoid REU DMA in IRQ. |
+| Module-per-family | Low resident cost and scalable catalog. | Module fetch/overlay management becomes important for performance. |
+| Many command-specific parser signatures | Simple workers. | Resident growth. Prefer shared or data-driven signatures. |
+
+## Bottom Line
+
+ReadyBASIC should not clone old extenders command-for-command. It should expose
+familiar graphics vocabulary, but implement it as a handle-oriented graphics
+runtime:
+
+1. Bank D is the visible video bank.
+2. REU handles hold surfaces, spritesheets, tilemaps, display lists, and event
+ history.
+3. Immediate commands exist for simple programs.
+4. Display-list commands exist for richer programs.
+5. `GFXFRAME()` becomes the high-level command that samples input, scans sprite
+ collisions, renders dirty state, and blits.
+6. IRQ/event support is optional and late, with tiny C64 shadows and command-time
+ REU flushing.
+
+This gives ReadyBASIC the feel of a powerful BASIC extender without paying for
+hundreds of features in resident RAM or BASIC bytes free.
diff --git a/src/apps/readybasic/READYBASIC_LIFECYCLE_AND_REU_ARCHITECTURE.md b/src/apps/readybasic/READYBASIC_LIFECYCLE_AND_REU_ARCHITECTURE.md
index fc7f36b..c61158d 100644
--- a/src/apps/readybasic/READYBASIC_LIFECYCLE_AND_REU_ARCHITECTURE.md
+++ b/src/apps/readybasic/READYBASIC_LIFECYCLE_AND_REU_ARCHITECTURE.md
@@ -53,13 +53,12 @@ being mistaken for the latest slot layout:
| Segment | Runtime range | Size | Role |
|---|---:|---:|---|
-| `ENTRY` | `$1000-$1102` | `$0103` (259B) | App entry, cold/warm discriminator, early copies. |
-| `RESIDENT` | `$1200-$2AB9` | `$18BA` (6.2K, 6330 exact bytes) | Visible parser, ROM calls, REU DMA wrappers, result commit, bare command dispatch, eval hook, native `PROC`/`FUNC`/`RET`, `REPEAT`/`UNTIL`, `LABEL`/`JUMP`, error introspection, proper nested term state, and float helpers. |
+| `ENTRY` | `$1000-$11FF` | `$0200` (512B) | App entry, cold/warm discriminator, early copies, and small visible trampolines. |
+| `RESIDENT` | `$1200-$2ABD` | `$18BE` (6.2K, 6334 exact bytes) | Visible parser, ROM calls, REU DMA wrappers, result commit, bare command dispatch, eval hook, native `PROC`/`FUNC`/`RET`, `REPEAT`/`UNTIL`, `LABEL`/`JUMP`, error introspection, proper nested term state, float helpers, and prompt navigation hooks. |
| `REGSEED` | `$5000-$600F` | `$1010` (4.0K, 4112 exact bytes) | Load-only registry header and 128 command descriptors used on cold seed. |
-| `HIDDEN` | `$A000-$A376` | `$0377` (0.9K, 887 exact bytes) | Hidden helper routines under BASIC ROM. |
-| `HIDDENPACK` | `$A800-$A84C` | `$004D` (77B) | Hidden worker overlay image, loaded to the assigned ReadyBASIC code bank. |
-| `LOWPACK` | `$A900-$AF3C` | `$063D` (1.6K, 1597 exact bytes) | Banked low overlay image under BASIC ROM, loaded from the assigned ReadyBASIC code bank. |
-| `BRIDGE` | `$C000-$C1F3` | `$01F4` (500B) | Persistent bridge/state bytes plus the four-entry native routine return stack and flow-control scratch. |
+| `HIDDEN` | `$A000-$A6E9` | `$06EA` (1.7K, 1770 exact bytes) | Hidden helper routines under BASIC ROM. |
+| `LOWPACK` | `$A800-$AECD` | `$06CE` (1.7K, 1742 exact bytes) | Banked low overlay image under BASIC ROM, loaded from the assigned ReadyBASIC code bank. |
+| `BRIDGE` | `$C000-$C1FE` | `$01FF` (511B) | Persistent bridge/state bytes plus the four-entry native routine return stack and flow-control scratch. |
Module/submodule update: the table above is preserved as the detailed
pre-module plugin-spine snapshot. The current post-BASIC runtime map is:
@@ -68,26 +67,26 @@ pre-module plugin-spine snapshot. The current post-BASIC runtime map is:
|---|---|---|
| `$0000-$00FF` | C64/BASIC/KERNAL zero page | Saved to assigned core bank offset `$0A00` on suspend/resume. |
| `$0100-$01FF` | Hardware stack | Saved to assigned core bank offset `$0B00`. |
-| `$0200-$03FF` | BASIC/KERNAL vectors and buffers | ReadyBASIC hooks `$0308` and `$030A` while active. |
+| `$0200-$03FF` | BASIC/KERNAL vectors and buffers | ReadyBASIC hooks execute/eval plus KEYLOG and CHRIN while active. |
| `$0400-$07E7` | Screen RAM | Can be captured by `SCRCAP`. |
| `$0800-$0FFF` | Low BASIC/system RAM | Outside ReadyBASIC app-owned region. |
-| `$1000-$1102` | ReadyBASIC entry | Cold/warm discriminator and handoff. |
-| `$1200-$2ABB` | ReadyBASIC resident | Parser, ROM calls, dispatch, commit, native language runtime. |
+| `$1000-$11FF` | ReadyBASIC entry | Cold/warm discriminator, handoff, hotkey quarantine, and small visible trampolines. |
+| `$1200-$2ABD` | ReadyBASIC resident | Parser, ROM calls, dispatch, commit, native language runtime. |
| `$2AC0` | Sentinel | Must remain zero before stored-program `RUN`. |
| `$2AC1-$9FFF` | BASIC workspace | Program text, variables, arrays, strings, and reclaimed seed space. |
-| `$A000-$A7FF` | RAM behind BASIC ROM | Common helper, current use `$A000-$A364`. |
+| `$A000-$A7FF` | RAM behind BASIC ROM | Common helper, current use `$A000-$A6E9`; `$0116` / 278B remain free. |
| `$A800-$AFFF` | RAM behind BASIC ROM | Submodule slot 0, current module 1/system payload. |
| `$B000-$B7FF` | RAM behind BASIC ROM | Submodule slot 1, current module 2 proof/loader payload. |
| `$B800-$BFFF` | RAM behind BASIC ROM | Submodule slot 2 and overlay target. |
-| `$C000-$C1F6` | ReadyBASIC bridge | Small state below shared frames. |
+| `$C000-$C1FE` | ReadyBASIC bridge | Small state below shared frames. |
| `$C200-$C5FF` | ReadyBASIC frames/buffers | Call frame, result frame, descriptor/name/page buffers, disk-module load page. |
-| `$C600-$C7FF` | ReadyOS REU metadata | Not ReadyBASIC scratch; ReadyBASIC may only observe/re-mark assigned bank ownership through the defined ReadyOS type-table contract. |
-| `$C800-$C9FF` | ReadyOS shim ABI | Not ReadyBASIC scratch. |
+| `$C600-$C7FF` | ReadyOS shim expansion reserve | Resident capacity; not ReadyBASIC scratch. |
+| `$C800-$C9FF` | ReadyOS shim ABI | Stable public half of the 1 KB shim; not ReadyBASIC scratch. |
| `$D000-$DFFF` | I/O or character ROM | REU registers are in I/O space. |
| `$E000-$FFFF` | KERNAL ROM normally visible | KERNAL calls remain available after normal banking is restored. |
-Current measured values are `BASIC_START=$2AC1`, `RESIDENT=$18BC`,
-`BRIDGE=$01F7`, common helper `$0365`, slot 0 `$06C7`, slot 1 `$0141`, and
+Current measured values are `BASIC_START=$2AC1`, `RESIDENT=$18BE`,
+`BRIDGE=$01FF`, common helper `$06EA`, slot 0 `$06CE`, slot 1 `$023B`, and
formula empty BASIC free bytes `30013`.
The older low/hidden command overlay vocabulary is now implemented as a
@@ -134,26 +133,26 @@ The V1 spine intentionally avoids a few attractive but expensive abstractions:
## Full RAM Layout
-The ReadyOS app working region is `$1000-$C5FF`; `$C600-$C7FF` is shared
-ReadyOS REU metadata and `$C800-$C9FF` is shim ABI territory. ReadyBASIC must
-live inside that contract while also hosting BASIC.
+The ReadyOS app working region is `$1000-$C5FF`; the resident 1 KB shim owns
+`$C600-$C9FF`, with its public ABI in the upper half.
+ReadyBASIC must preserve its custom assembler/linker shape while hosting BASIC.
```mermaid
flowchart TB
- A["$1000-$1102 ENTRY load entry and cold/warm cookie"]
- B["$1200-$2ABB RESIDENT visible parser, vector hooks, REU DMA, commit, PROC/FUNC/RET, flow control, float terms"]
+ A["$1000-$11FF ENTRY load entry, cold/warm cookie, hotkey quarantine"]
+ B["$1200-$2ABD RESIDENT visible parser, vector hooks, REU DMA, commit, PROC/FUNC/RET, flow control, float terms"]
C["$2AC0 SENTINEL must be zero for BASIC RUN"]
D["$2AC1-$9FFF BASIC WORKSPACE 30013 formula free bytes / 29.3K"]
E["$2B00-$3FFF CMDPACK LOAD IMAGE module/submodule payload seed bytes before cold prestash"]
F["Assigned core bank $0A00-$0BFF RUNTIME SNAPSHOT zero page and stack / 0.5K"]
G["$C200-$C5FF SHARED FRAMES call/result/descriptor/name/page buffers / 1.0K"]
- I["$C280 HIDDEN SHADOW refreshed on EXIT"]
- J["$A000-$A364 COMMON HELPER runs under BASIC ROM RAM"]
- K["$A800-$AEC6 SLOT 0 PAYLOAD module 1 system/default payload"]
- O["$B000-$B140 SLOT 1 PAYLOAD module 2 proof and ZMODLD loader"]
- P["$B800-$B83E SLOT 2 / OVERLAYS proof and overlay slices"]
- L["$C000-$C1F6 BRIDGE STATE magic, saved vectors, overlay vars, handle scratch, PROC/FUNC stack"]
- M["$C600-$C7FF READYOS REU METADATA hot bank table/system metadata, not app scratch"]
+ I["Assigned core bank $3000 HIDDEN SHADOW refreshed on EXIT"]
+ J["$A000-$A6E9 COMMON HELPER runs under BASIC ROM RAM"]
+ K["$A800-$AECD SLOT 0 PAYLOAD module 1 system/default payload"]
+ O["$B000-$B23A SLOT 1 PAYLOAD module 2 proof and ZMODLD loader"]
+ P["$B800-$B814 SLOT 2 / OVERLAYS proof and overlay slices"]
+ L["$C000-$C1FE BRIDGE STATE magic, saved vectors, overlay vars, handle scratch, PROC/FUNC stack"]
+ M["$C600-$C7FF SHIM EXPANSION RESERVE resident ReadyOS capacity, not app RAM"]
N["$C800-$C9FF SHIM ABI ReadyOS jump table/data, not app RAM"]
A --> B --> C --> D --> G
@@ -168,10 +167,10 @@ runtime-visible resident core:
| Load-time range | Purpose |
|---:|---|
| `$1000-$11FF` | Entry image, including entry-local warm cookie. |
-| `$1200-$2ABF` | Resident core image budget. Current linked core ends at `$2AB9`. |
+| `$1200-$2ABF` | Resident core image budget. Current linked core ends at `$2AB8`. |
| `$2AC0-$2AFF` | Sentinel plus cold padding gap before command-pack seed bytes. |
| `$2B00-$3FFF` | Command pack seed bytes, copied to the assigned code bank only on cold entry. |
-| `$4000+` | Hidden helper seed bytes, copied to `$A000` and the visible `$C280` shadow. |
+| `$4000+` | Hidden helper seed bytes, copied to `$A000` and stashed to assigned core-bank offset `$3000`. |
| `$4800+` | Bridge seed bytes, copied to `$C000`. |
| `$5000-$600F` | Registry seed bytes, copied to the assigned core bank only on cold entry. |
@@ -229,11 +228,11 @@ the raw `$2AC0-$9FFF` cold-load span:
| `$6200-$9FFF` | Future BASIC bytes after `REGSEED`. | `$3E00` | 15.5K | 15872 |
Inside `CMDPACK`, the current packed built-in content is slot 0 payload
-`$2B00-$31C6` (`$06C7`, 1735B), slot 1 payload `$31C7-$33FF`
-(`$0239`, 569B), slot 2 base payload `$3400-$3414` (`$0015`, 21B), span
-payload `$3415-$3429` (`$0015`, 21B), overlay 1 `$342A-$343E`
-(`$0015`, 21B), overlay 2 `$343F-$3453` (`$0015`, 21B), and reserved room
-`$3454-$3FFF` (`$0BAC`, 2.9K, 2988 exact bytes).
+`$2B00-$31CD` (`$06CE`, 1742B), slot 1 payload `$31CE-$3408`
+(`$023B`, 571B), slot 2 base payload `$3409-$341D` (`$0015`, 21B), span
+payload `$341E-$3432` (`$0015`, 21B), overlay 1 `$3433-$3447`
+(`$0015`, 21B), overlay 2 `$3448-$345C` (`$0015`, 21B), and reserved room
+`$345D-$3FFF` (`$0BA3`, 2.9K, 2979 exact bytes).
## REU Layout
@@ -313,9 +312,9 @@ byte buffer, and type `2` is a screen text+color buffer.
```mermaid
flowchart LR
- S0["$0000-$06C6 Slot 0 payload copied into $A800-$AEC6"]
- S1["$06C7-$0807 Slot 1 payload copied into $B000-$B140"]
- S2["$0808-$085B Slot 2/span/overlay proofs copied into $B800/$B000 as needed"]
+ S0["$0000-$06CD Slot 0 payload copied into $A800-$AECD"]
+ S1["$06CE-$0908 Slot 1 payload copied into $B000-$B23A"]
+ S2["$0909-$095C Slot 2/span/overlay proofs copied into $B800/$B000 as needed"]
D1["$1500/$1600 Disk module descriptors"]
DP["$3000+ Disk module proof payloads"]
S0 --> S1 --> S2 --> D1 --> DP
@@ -330,10 +329,10 @@ Exact assigned code-bank suballocation sizes:
| Offset range | Role | Hex size | Display size | Exact bytes |
|---|---|---:|---:|---:|
-| `$0000-$06C6` | Built-in module 1 slot-0 payload fetched into `$A800-$AEC6`. | `$06C7` | 1.7K | 1735 |
-| `$06C7-$08FF` | Built-in module 2 slot-1 proof and streaming `ZMODLD` loader payload fetched into `$B000-$B238`. | `$0239` | 569B | 569 |
-| `$0900-$0953` | Built-in slot-2, span, and overlay proof slices. | `$0054` | 84B | 84 |
-| `$0954-$14FF` | Free gap before current disk-module descriptor proof offsets. | `$0BAC` | 2.9K | 2988 |
+| `$0000-$06CD` | Built-in module 1 slot-0 payload fetched into `$A800-$AECD`. | `$06CE` | 1.7K | 1742 |
+| `$06CE-$0908` | Built-in module 2 slot-1 proof and streaming `ZMODLD` loader payload fetched into `$B000-$B23A`. | `$023B` | 571B | 571 |
+| `$0909-$095C` | Built-in slot-2, span, and overlay proof slices. | `$0054` | 84B | 84 |
+| `$095D-$14FF` | Free gap before current disk-module descriptor proof offsets. | `$0BA3` | 2.9K | 2979 |
| `$1500-$151F` | `rbm.sample1` descriptor proof for `ZDM1`. | `$0020` | 32B | 32 |
| `$1600-$165F` | `rbm.sample2` descriptors for `ZDM2S`, `ZDOV1`, and `ZDOV2`; submodule 5 appears twice because those entries are overlays 1 and 2. | `$0060` | 96B | 96 |
| `$1700-$1ABF` | `rbm.sample3` descriptors for `ZSAA`-`ZUEB`. | `$03C0` | 960B | 960 |
@@ -373,7 +372,7 @@ flowchart TD
C["Cold path"]
H1["Map RAM under BASIC ROM"]
H2["Copy hidden helper seed $4000 -> $A000"]
- H3["Copy hidden helper seed -> $C280 shadow"]
+ H3["Stash hidden helper -> assigned core bank $3000"]
B1["Copy bridge seed $4800 -> $C000"]
RB["Jump to rb_boot"]
V["Reset KERNAL/BASIC vectors"]
@@ -389,8 +388,8 @@ flowchart TD
The cold setup performs these important operations:
1. It copies hidden helper code before BASIC owns `$2AC1+`.
-2. It stores a visible shadow copy at `$C280` because `$A000` code cannot be trusted
- after a ReadyOS app switch.
+2. It stores a REU shadow copy at assigned core-bank offset `$3000` because
+ `$A000` code cannot be trusted after a ReadyOS app switch.
3. It copies bridge state to `$C000`.
4. It resets KERNAL and BASIC vectors, then installs the execute vector hook at
`$0308/$0309` and the eval hook at `$030A/$030B`.
@@ -411,7 +410,7 @@ flowchart TD
R0["ReadyOS restores app window and jumps to $1000"]
E["ENTRY sees entry-local warm magic"]
RH["Map RAM under BASIC ROM"]
- RS["Copy $C280 shadow -> $A000 hidden helper"]
+ RS["Fetch assigned core bank $3000 shadow -> $A000 hidden helper"]
RB["Jump to rb_boot"]
M["Bridge magic says READY or RUN"]
IV["Install $0308 execute hook"]
@@ -431,7 +430,7 @@ flowchart TD
Warm resume is intentionally different from cold boot:
-- It restores the hidden helper from `$C280`, not from the old load image.
+- It restores the hidden helper from the assigned core-bank `$3000` shadow, not from the old load image.
- It reinstalls ReadyBASIC-owned vectors.
- It re-marks REU ownership for the assigned ReadyBASIC core/code banks.
- It does **not** rebuild the registry/code banks from load-only RAM.
@@ -443,8 +442,19 @@ Warm resume is intentionally different from cold boot:
## EXIT And Suspend Management
-The supported V1 return path is manual prompt `EXIT`. The execute hook detects
-`EXIT` before falling back to ROM BASIC.
+The supported prompt navigation paths are manual prompt `EXIT`, prompt-level
+`CTRL+B`, and prompt-level `F2`/`F4`. The execute hook detects `EXIT` before
+falling back to ROM BASIC. Prompt hotkeys are detected by the KEYLOG
+preprocessing hook at `$028F/$0290` only after ReadyBASIC's IMAIN hook at
+`$0302/$0303` has marked the direct prompt active and input is coming from the
+keyboard. The execute hook clears that prompt-active flag before direct commands
+and stored program lines run. This avoids relying solely on `CURLIN`/`TXTPTR`,
+which can still describe the just-run program after BASIC has visibly returned
+to `READY.`. KEYLOG records the pending action, consumes the decoded key state,
+and queues only Return. The CHRIN hook discards the editor-returned character
+and dispatches the pending action before BASIC can store or execute a partial
+prompt line. Ordinary line editing, key repeat, cursor state, and space handling
+stay owned by the ROM screen editor.
```mermaid
flowchart TD
@@ -462,11 +472,32 @@ flowchart TD
X --> D --> M --> S --> Z --> ST --> META --> V --> SHIM --> L
```
+`F2`/`F4` perform the same save/vector-restore setup, then scan authoritative
+schema-v5 loaded flags at ReadyOS-bank offset `$B840 + token`, copy the selected
+target token into bridge state, and
+only write `$C820` after hidden save, `CLRCHN`, and vector restore have
+completed. This keeps the switch target independent of scratch bytes used by
+the loaded-bank scan. If no other loaded app is available, the key is consumed
+and the BASIC editor keeps waiting.
+
The vector restore is not optional. Page-3 vectors are global machine state, not
ReadyOS app-private RAM. If ReadyBASIC yielded with `$0308` still pointing into
its resident core, the launcher or another app could dispatch through stale
ReadyBASIC state.
+ReadyBASIC also clears its pending hotkey byte, the KERNAL keyboard buffer
+count, the first keyboard-buffer byte, `SHFLAG`, `LSTX`, and `SFDX` before every
+ReadyOS yield. `prepare_shim_yield` calls `CLRCHN` so destination apps do not
+inherit an open BASIC logical channel from the ROM editor.
+
+The hotkey release contract is deliberately stronger than simple state clear.
+On cold and warm entry, ReadyBASIC scans the physical CIA1 matrix and quarantines
+any still-held `CTRL+B`, `F2`, or `F4` chord until it is released. Before
+yielding for a prompt hotkey, it waits for that exact selected chord to release
+with a jiffy-clock timeout, then clears the editor/KERNAL key state again. This
+prevents a single F-key press from being consumed once by ReadyBASIC and again
+by the destination app after the ReadyOS switch.
+
The runtime snapshot lives here:
| Range | Meaning |
@@ -474,7 +505,7 @@ The runtime snapshot lives here:
| Assigned core bank `$0A00-$0AFF` | Saved zero page. |
| Assigned core bank `$0B00-$0BFF` | Saved hardware stack page. |
| Bridge metadata | Runtime magic, saved SP, resume mode, line-chain validation. |
-| `$C280-$C5B6` | Hidden helper shadow, refreshed during `EXIT`. |
+| Assigned core bank `$3000+` | Hidden helper shadow, refreshed during `EXIT` and cold seed. |
## Bare Command And Routine Dispatch
@@ -607,18 +638,18 @@ BASIC's string heap.
| `ZHIDDENRAM(S$,OUT%)` / `ZHIDDENRAM(S$)` | Module 1 slot 0 under-ROM worker | small slice | string variable or literal, output/expression int | Sums uppercase bytes. |
| `ZSUMNUMARRAY(A%(0),COUNT,OUT%)` / `ZSUMNUMARRAY(A%(0),COUNT)` | Module 1 slot 0 payload | small slice | integer array base/count, output/expression int | Sums integer array values. |
| `ZRANGENUMARRAY(START,COUNT,A%(0))` | Module 1 slot 0 payload | small slice | start/count, output array | Stages consecutive integers. |
-| `BUFNEW(LEN,H%)` / `BUFNEW(LEN)` | Module 1 slot 0 payload | `$06C7` (1.7K) | length, output/expression handle | Allocates persistent buffer pages in the assigned core bank. |
-| `BUFFILL(H%,BYTE)` | Module 1 slot 0 payload | `$06C7` (1.7K) | buffer handle, byte | Fills buffer handle pages using `$C500` page buffer. |
-| `BUFFREE(H%)` | Module 1 slot 0 payload | `$06C7` (1.7K) | handle | Frees any valid handle type and clears metadata. |
-| `ZTEMPSCRATCH(LEN,OUT%)` / `ZTEMPSCRATCH(LEN)` | Module 1 slot 0 payload | `$06C7` (1.7K) | length, output/expression int | Allocates then frees pages, returns page count. |
+| `BUFMAKE(LEN,H%)` / `BUFMAKE(LEN)` | Module 1 slot 0 payload | `$06CE` (1.7K) | length, output/expression handle | Allocates persistent buffer pages in the assigned core bank. |
+| `BUFFILL(H%,BYTE)` | Module 1 slot 0 payload | `$06CE` (1.7K) | buffer handle, byte | Fills buffer handle pages using `$C500` page buffer. |
+| `BUFDROP(H%)` | Module 1 slot 0 payload | `$06CE` (1.7K) | handle | Frees any valid handle type and clears metadata. |
+| `ZTEMPSCRATCH(LEN,OUT%)` / `ZTEMPSCRATCH(LEN)` | Module 1 slot 0 payload | `$06CE` (1.7K) | length, output/expression int | Allocates then frees pages, returns page count. |
| `ZFAIL(CODE,OUT%)` | Module 1 slot 0 payload | small slice | code, output int | Clears output first, then returns `?RB ERROR code`. |
-| `FREEMEM()` | Module 1 slot 0 payload | small slice | none | Prints live free BASIC bytes and refreshes the header. |
-| `SCRCAP(H%)` / `SCRCAP()` | Slot 14; module 1 slot 0 payload | `$06C7` (1.7K) | output/expression screen handle | Captures screen text and color RAM into a type-2 handle. |
+| `MEMAVL()` | Module 1 slot 0 payload | small slice | none | Prints live free BASIC bytes. |
+| `SCRCAP(H%)` / `SCRCAP()` | Slot 14; module 1 slot 0 payload | `$06CE` (1.7K) | output/expression screen handle | Captures screen text and color RAM into a type-2 handle. |
| `ERRCODE(OUT%)` / `ERRCODE()` | Resident-precomputed result; legacy low stub remains in `LOWPACK` | 0 copied on current path | output int or expression int | Returns the last ReadyBASIC runtime error code. |
| `ERRLINE(OUT%)` / `ERRLINE()` | Resident-precomputed result; legacy low stub remains in `LOWPACK` | 0 copied on current path | output int or expression int | Returns the last ReadyBASIC runtime error line, or 0 in direct mode. |
-| `SCRPUT(H%)` | Slot 128; module 1 slot 0 payload | `$06C7` (1.7K) | screen handle | Restores screen text and color RAM after type validation. |
+| `SCRPUT(H%)` | Slot 128; module 1 slot 0 payload | `$06CE` (1.7K) | screen handle | Restores screen text and color RAM after type validation. |
-The heap-oriented commands copy the full `$06C7` slot-0 payload because allocator,
+The heap-oriented commands copy the full `$06CE` slot-0 payload because allocator,
REU descriptor, bitmap, and screen-copy helpers live in the same module payload.
That is an implementation choice to keep resident RAM lean; a later pass could
split a smaller allocator resident helper or use finer overlay slices.
@@ -639,12 +670,12 @@ flowchart LR
SCRATCH --> BITMAP --> DATA
```
-`BUFNEW` converts byte length to 256-byte pages, finds contiguous free pages,
+`BUFMAKE` converts byte length to 256-byte pages, finds contiguous free pages,
records type-1 metadata, and returns a one-based handle. `BUFFILL` accepts only
type-1 buffer handles, fills `$C500` with the byte, and stashes it page by page
into the assigned core bank at page offsets `$40-$FF`. `SCRCAP` creates a type-2 handle and
stashes screen text plus color RAM; `SCRPUT` validates type `2` before restore.
-`BUFFREE` clears both the handle descriptor and bitmap for any valid handle type.
+`BUFDROP` clears both the handle descriptor and bitmap for any valid handle type.
`ZTEMPSCRATCH` proves temporary allocation by finding pages without persisting a
live descriptor.
@@ -657,8 +688,8 @@ extra banks while keeping the same small BASIC-visible handle.
ReadyBASIC uses two kinds of hidden code:
-- Hidden helper at `$A000-$A336`.
-- Hidden worker overlay at `$A800-$A84C`.
+- Hidden helper at `$A000-$A6C7`.
+- Command/module payload slots at `$A800-$BFFF`.
Before calling hidden code, ReadyBASIC:
@@ -693,13 +724,15 @@ older dated measurements remain in `READYBASIC_PLUGIN_PROGRESS.md`.
| Segment | Range | Size |
|---|---:|---:|
-| `RESIDENT` | `$1200-$2AB9` | `$18BA` / 6330B |
+| `ENTRY` | `$1000-$11FF` | `$0200` / 512B |
+| `RESIDENT` | `$1200-$2ABD` | `$18BE` / 6334B |
| `PADLOW` | `$2AC0-$2AFF` | `$0040` / 64B |
| `REGSEED` | `$5000-$600F` | `$1010` / 4112B |
-| `HIDDEN` | `$A000-$A376` | `$0377` / 887B |
-| `HIDDENPACK` | `$A800-$A84C` | `$004D` / 77B |
-| `LOWPACK` | `$A900-$AF3C` | `$063D` / 1597B |
-| `BRIDGE` | `$C000-$C1F3` | `$01F4` / 500B |
+| `HIDDEN` | `$A000-$A6E9` | `$06EA` / 1770B |
+| `LOWPACK` | `$A800-$AECD` | `$06CE` / 1742B |
+| `SLOTPACK1` | `$B000-$B23A` | `$023B` / 571B |
+| `SLOTPACK2` | `$B800-$B814` | `$0015` / 21B |
+| `BRIDGE` | `$C000-$C1FE` | `$01FF` / 511B |
Formula empty BASIC free bytes are `30013`, a `1728` byte reduction from the
expression-style `$2401` layout. Command overlays grow to `$063D` and the REU
@@ -707,9 +740,9 @@ descriptor layout remains fixed.
- `$2AC0` stays zero before stored-program `RUN`.
- `RESIDENT` stays below `$2AC0`.
- `BRIDGE` stays below `$C200`, leaving `$C200-$C5FF` for shared frames.
-- `$C600-$C7FF` is ReadyOS REU metadata, not ReadyBASIC scratch.
-- `$C800-$C9FF` remains shim ABI.
-- Warm resume must restore `$A000` from `$C280` before hidden helper calls.
+- `$C600-$C7FF` is resident ReadyOS shim expansion capacity.
+- `$C800-$C9FF` remains the stable shim ABI.
+- Warm resume must restore `$A000` from the assigned-core-bank hidden-helper shadow before hidden helper calls.
- Warm resume must not reset `FRETOP`, `VARTAB`, `ARYTAB`, or `STREND`.
- ReadyBASIC-owned vectors must be restored before yielding to ReadyOS.
- Non-ReadyBASIC BASIC statements must tail-call the original `$0308` vector
diff --git a/src/apps/readybasic/READYBASIC_MAKING_COMMAND_GUIDE.md b/src/apps/readybasic/READYBASIC_MAKING_COMMAND_GUIDE.md
index 55a9109..b83004d 100644
--- a/src/apps/readybasic/READYBASIC_MAKING_COMMAND_GUIDE.md
+++ b/src/apps/readybasic/READYBASIC_MAKING_COMMAND_GUIDE.md
@@ -3,7 +3,8 @@
This guide explains how current ReadyBASIC commands are made in
`src/apps/readybasic/readybasic.s`. It uses the current names and layout:
128 descriptor slots in the assigned ReadyBASIC core bank, packed command code in the assigned code bank,
-`SCRCAP` in slot 14, `SCRPUT` in slot 128, and zero-filled filler slots 15-127.
+94 real command descriptors, 34 zero-filled filler descriptors, and `SCRPUT`
+kept in slot 128 to prove full-table lookup.
Native `PROC`/`FUNC` routines are new ReadyBASIC language features, not BASIC V2
functions and not plugin commands. Users can write them directly in their own
@@ -74,13 +75,14 @@ language statement is a resident parser and lifecycle task.
ReadyBASIC's built-in command set is intended to include the core commands and
the 100+ additional file, graphics, sound, REU, and utility commands that are
-similar in spirit to other BASIC extensions. The current single code bank still
-leaves about 62.4K of addressable REU command-code space; today's C64 `CMDPACK`
-cold-load window has about 3.6K of unused seed room before it would need a
-larger or additional cold-load seed range. Beyond that built-in set, ReadyBASIC
-will also support dynamically loaded command modules that can use additional REU
-banks, so other authors can add hundreds more commands without forcing
-everything into the core command bank.
+similar in spirit to other BASIC extensions. The current built-in code-bank
+reservations leave the contiguous tail `$8000-$FFFF` free for future built-in
+payloads; today's first C64 `CMDPACK` cold-load window has about `$00AB` / 171
+bytes of unused seed room, while replacement overlays are seeded from
+`CMDPACK2`. Beyond that built-in set, ReadyBASIC will also support
+dynamically loaded command modules that can use additional REU banks, so other
+authors can add hundreds more commands without forcing everything into the core
+command bank.
## Naming Rules
@@ -89,6 +91,21 @@ Current code prefers bare `COMMAND(...)` statements and selected
`COMMAND(...)` expressions.
Avoid substrings that C64 BASIC can tokenize inside the command name. That is
why the array examples use `NUM` instead of `INT`.
+This is a hard rule for new command names: do not embed native BASIC words or
+functions such as `CLR`, `FRE`, `NOT`, `INT`, `FN`, `LEN`, `OR`, `TO`,
+`LOAD`, `SAVE`, `PRINT`, `INPUT`, `DATA`, `REM`, `LEFT$`, `RIGHT$`, or `MID$`.
+`petcat` will tokenize those substrings even when they appear inside a longer
+identifier, and plain BASIC `LIST` will then show misleading keyword fragments
+or fail. Host `.bas` demo sources should also spell ReadyBASIC commands in
+lowercase so `petcat` writes ordinary PETSCII letters rather than shifted
+uppercase bytes.
+
+This alpha build does not keep duplicate public command spellings. ReadyBASIC
+can alias a command by registering another 32-byte descriptor that points at the
+same command id, parser signature, payload, and entrypoint, but that costs one
+registry slot, increases documentation and test surface, and can preserve names
+that BASIC V2 tokenizes badly. Current demos and tests must use only the
+canonical spellings.
Prefix conventions:
@@ -101,7 +118,7 @@ Prefix conventions:
Current public names include `ZECHO1`, `ZADD16`, `UPPER`, `LOWER`,
`ZHIDDENRAM`, `ZSUMNUMARRAY`, `ZRANGENUMARRAY`, `ZTEMPSCRATCH`, `ZPAUSE`,
-`ZFAIL`, `FREEMEM`, `ERRCODE`, `ERRLINE`, `BUFNEW`, `BUFFILL`, `BUFFREE`,
+`ZFAIL`, `MEMAVL`, `ERRCODE`, `ERRLINE`, `BUFMAKE`, `BUFFILL`, `BUFDROP`,
`SCRCAP`, `SCRPUT`, `FADD`, `ZSLOT0`, `ZSLOT1`, `ZSLOT2`, `ZSPAN`, `ZOVL1`,
`ZOVL2`, `ZCPYRST`, `ZCOPY`, and `ZMODLD`. Disk-module samples add `ZDM1`,
`ZDM2S`, `ZDOV1`, and `ZDOV2` after `ZMODLD("RBM.SAMPLE1")` or
@@ -172,6 +189,255 @@ or interpreter state. `REPEAT`/`UNTIL` stores and restores `TXTPTR`/`CURLIN`;
runtime state. Those shapes are intentionally outside the command descriptor
ABI.
+## Graphics Command Tutorial
+
+The built-in graphics commands are examples of descriptor-backed command
+families. They are intentionally commands, not language extensions: they use
+ordinary `COMMAND(...)` syntax, parser signatures fill the command call frame,
+and assembler workers do the Bank D/VIC/REU work.
+
+The current visible graphics memory map is:
+
+| Range | Use |
+|---:|---|
+| `$CA00-$CBFF` | Eight hardware sprite definitions. |
+| `$CC00-$CFFF` | Bank D screen RAM and sprite pointers at `$CFF8`. |
+| `$D800-$DBE7` | Color RAM. |
+| `$E000-$FFFF` | Bitmap/charset RAM, written with ROM hidden. |
+
+Mode setup:
+
+```basic
+10 gfxmode("hires") : rem 320x200 one-bit bitmap
+20 gfxmode("mbitmap") : rem 160x200 multicolor bitmap
+30 gfxmode("tile") : rem Bank D text/tile screen
+40 gfxmode("mtile") : rem Bank D multicolor text/tile screen
+50 gfxtext() : rem return to normal readable text
+```
+
+`GFXCLEAR(C)` clears the active graphics screen. In bitmap modes it clears the
+bitmap at `$E000`; in tile modes it clears the Bank D screen cells and color
+RAM. `GFXTEXT()` is the command to call before printing normal BASIC text after
+a graphics demo.
+
+### Surface Handles And Blit
+
+`GFXSURF(mode$)` allocates a typed REU graphics-surface handle. `GFXTGT(H%)`
+selects a graphics target; use `GFXTGT(0)` to return to
+the visible Bank D target. Phase 4 keeps immediate primitive drawing visible for
+speed, while `GFXSYNC()` and `GFXBLIT(H%)` exercise the REU surface path and
+copy a compatible surface layout to Bank D:
+
+```basic
+10 rem see readybasic_graphics_command_design.md
+20 gfxmode("hires"):gfxclear(0)
+30 line(20,20,300,170,1):rect(40,50,140,130,1)
+40 h%=gfxsurf("hires")
+50 gfxtgt(h%):gfxsync():gfxtgt(0)
+60 gfxclear(0):gfxblit(h%)
+```
+
+`GFXSYNC()` snapshots the current visible Bank D bitmap/screen/color layout into
+the selected surface. `GFXBLIT(H%)` restores that snapshot. This is a
+full-surface copy, not a dirty-rectangle queue and not live offscreen primitive
+drawing yet.
+
+### Hires Primitives
+
+In `HIRES`, the immediate primitive commands use 320x200 coordinates:
+
+```basic
+10 rem see readybasic_graphics_command_design.md
+20 gfxmode("hires"):gfxclear(0)
+30 plot(20,20,1)
+40 line(20,30,300,160,1)
+50 rect(40,50,130,120,1)
+60 fbox(180,60,240,130,1)
+70 circle(82,82,38,1)
+80 fcircle(210,92,26,1)
+90 pnt(20,20,p%):print p%
+```
+
+`LINE` is compact and command-slot friendly rather than full Bresenham. It is
+good for horizontal, vertical, 45-degree, fan, and demo lines; uneven slopes are
+approximate. `CIRCLE` uses a compact midpoint outline worker, and `FCIRCLE`
+currently fills the bounding rectangle as a
+placeholder for a later true disk fill.
+
+### Multicolor Bitmap Primitives
+
+In `MBITMAP`, the same primitive commands use 160x200 logical coordinates
+because each multicolor bitmap pixel is two hardware pixels wide:
+
+```basic
+10 rem see readybasic_graphics_command_design.md
+20 gfxmode("mbitmap"):gfxclear(0)
+30 line(4,18,155,18,17) : rem pair 1, color 1
+40 line(4,30,155,70,34) : rem pair 2, color 2
+50 rect(8,82,72,144,20) : rem pair 1, color 4
+60 fbox(86,82,148,144,37) : rem pair 2, color 5
+70 circle(46,112,28,51) : rem pair 3, color 3
+80 fcircle(118,112,22,58) : rem pair 3, color 10
+90 pnt(46,112,p%) : rem p% is 0..3 pair code
+```
+
+The color argument maps to VIC-II multicolor bitmap slots:
+
+| Argument | Pair code | Attribute written |
+|---:|---:|---|
+| `0` | `0` | none; clears that pixel pair |
+| `1..15` | `3` | color RAM, convenient direct-color form |
+| `16..31` | `1` | screen RAM high nibble, use `16+color` |
+| `32..47` | `2` | screen RAM low nibble, use `32+color` |
+| `48..63` | `3` | color RAM, explicit slot-3 form |
+
+The color attributes are per 8x8 cell. If two later commands draw different
+slot-1 colors inside the same cell, the later screen high nibble changes the
+visible color of every slot-1 pixel in that cell. `PNT` returns the
+pair code `0..3`, not the resolved VIC color.
+
+### Tile And Text Cells
+
+`TILE(X,Y,CH,C)` and `CHARAT(X,Y,CH,C)` write one cell. In `TILE` and `MTILE`
+they target the Bank D screen at `$CC00`; after `GFXTEXT()` they target ordinary
+text screen RAM so demos can label themselves:
+
+```basic
+10 gfxmode("tile"):gfxclear(0)
+20 plot(4,4,5):plot(5,4,6):plot(6,4,7)
+30 line(1,1,38,20,3)
+40 rect(3,5,20,16,10):fbox(24,8,34,18,12)
+50 get a$:if a$="" then 50
+60 gfxtext():print "tile demo"
+```
+
+Tile coordinates are `0..39,0..24`; the color argument is the low nibble written
+to color RAM. `GFXCLEAR` seeds simple solid glyphs for immediate `PLOT`/`LINE`/
+`RECT`/`FBOX` tile demos. Use `CHRMAKE`, `CHRROW`, and `CHRUSE` when a program
+needs custom character shapes.
+
+### Sprites
+
+Sprites use Bank D sprite data at `$CA00`. The direct pixel path is
+`SPRROW(N,ROW,B1,B2,B3)`, where `ROW` is `0..20` and the three bytes are the
+24-bit sprite row:
+
+```basic
+10 gfxmode("hires"):gfxclear(0)
+20 sprset(0,1,7,0)
+30 for r=0 to 20
+40 sprrow(0,r,60,126,60)
+50 next r
+60 sprmove(0,120,100)
+70 sprsize(0,1,1)
+80 sprmul(0,1):sprmco(2,5):sprcol(0,10)
+```
+
+`SPRSIZE` controls expansion, `SPRMUL` enables sprite multicolor, `SPRMCO`
+sets the shared multicolor registers, and `SPRCOL` sets the primary sprite
+color. `SPRSCAN()` polls and clears VIC collision
+latches; Phase 1/2 input and collision commands do not install an IRQ sampler.
+
+### Polygons And Point Buffers
+
+Phase 3 polygon commands live in the `GFXPOLY` slot-2 replacement overlay.
+Array-backed polygons read BASIC integer array pairs:
+
+```basic
+10 dim p%(7)
+20 p%(0)=40:p%(1)=20:p%(2)=120:p%(3)=42
+30 p%(4)=98:p%(5)=130:p%(6)=18:p%(7)=110
+40 gfxmode("hires"):gfxclear(0)
+50 poly(p%(0),4,1)
+60 fpoly(p%(0),4,1)
+```
+
+REU point buffers keep the point list out of BASIC arrays:
+
+```basic
+10 pbmake(4,h%)
+20 pbufset(h%,0,40,20):pbufset(h%,1,120,42)
+30 pbufset(h%,2,98,130):pbufset(h%,3,18,110)
+40 polyh(h%,4,1)
+50 fpolyh(h%,4,1)
+60 pbdrop(h%)
+```
+
+`POLYH` and `FPOLYH` are explicit handle-form commands. The originally proposed
+same-name handle overloads were avoided so the resident parser and BASIC bytes
+free stay unchanged. `FPOLY`/`FPOLYH` currently use a conservative convex fan
+fill; concave scanline filling remains future work.
+
+### SID Sound
+
+Sound Phase 1 commands live in module id `4`, submodule `SIDCORE` id `23`, as a
+slot-2 replacement overlay at runtime `$B800-$BA0D`. The overlay is prestashed
+to the ReadyBASIC assigned code bank at `$7800`.
+
+The main lesson for new command authors is parser discipline. A friendlier
+seven-argument `VOICE(V,F,W,A,D,S,R)` shape was tested, but it grew fixed
+resident parser code. The implemented form reuses the existing five-number
+signature:
+
+```basic
+10 sidrst():vol(15):pulse(1,2048)
+20 voice(1,4455,65,9,195)
+30 zpause(80):wave(1,64)
+```
+
+`VOICE(V,F,W,AD,SR)` maps directly to SID registers: raw frequency, control
+byte, packed attack/decay, and packed sustain/release. Friendlier setup remains
+available with `ADSR(V,A,D,S,R)`, `PULSE(V,W)`, `FRQ(V,F)`, `WAVE(V,M)`, and
+`GATE(V,ON)`. Use the canonical `frq` and `pitch` spellings in stored source.
+
+### Retained Lists, Tilesets, And Multicolor Cells
+
+Phase 4 keeps richer graphics data in typed REU handles and lets command
+overlays do the traversal work:
+
+```basic
+10 gfxmode("mbitmap"):gfxclear(0):mcbg(0)
+20 dlmake(12,h%)
+30 dlplot(h%,20,20,17)
+40 dlline(h%,4,30,155,70)
+50 dlrect(h%,8,82,72,144)
+60 dlfbox(h%,86,82,148,144)
+70 dldraw(h%)
+```
+
+Display-list records are intentionally compact. `DLPLOT` stores and replays its
+color argument; line and rectangle records currently replay with color `1` to
+keep the overlay small. `DLDRAW` understands the current `HIRES`, `TILE`/`MTILE`,
+and `MBITMAP` mode-specific plot paths.
+
+Tile resources are fixed-format for now. `CHRMAKE` creates an 8-page charset,
+`TSMAKE` creates a 1-page tileset, and `TMMAKE` creates a 4-page 40x25 tilemap:
+
+```basic
+10 gfxmode("tile"):gfxclear(0)
+20 chrmake(256,c%):chrrow(c%,1,0,255):chruse(c%)
+30 tsmake(64,t%):tsset(t%,1,1,2)
+40 tmmake(1000,m%):tmset(m%,0,1,0)
+50 tmdraw(m%,t%)
+```
+
+Current VICE automation proves visible Bank D tile and multicolor-tile rendering
+for immediate primitives. `TMDRAW` writes the Bank D screen/color bytes from REU
+tile resources; the next resource phase should add a file format and loader for
+stashing charset, tileset, and tilemap payloads directly into REU.
+
+For multicolor bitmap cell attributes, use:
+
+```basic
+10 gfxmode("mbitmap"):gfxclear(0):mcbg(0)
+20 mcell(2,2,6,10,2)
+30 fbox(8,16,31,47,17)
+```
+
+Future resource files should be able to carry charset, tileset, tilemap,
+sprite-sheet, and display-list payloads that can be stashed directly into REU
+before BASIC init or loaded later into the same typed handles.
+
## Descriptor Shape
Each command has a 32-byte descriptor in the cold `REGSEED` image. On cold boot,
@@ -726,7 +992,7 @@ Nested expression examples from the verified probe path:
220 ENDP
```
-## BUFNEW, BUFFILL, BUFFREE, SCRCAP, SCRPUT: REU Handle Commands
+## BUFMAKE, BUFFILL, BUFDROP, SCRCAP, SCRPUT: REU Handle Commands
The handle commands are the main future-facing pattern. BASIC sees a small
integer handle; canonical metadata lives in the assigned core bank.
@@ -734,18 +1000,18 @@ integer handle; canonical metadata lives in the assigned core bank.
Basic invocation examples:
```basic
-10 BUFNEW(64,H%)
+10 BUFMAKE(64,H%)
20 BUFFILL(H%,170)
-30 BUFFREE(H%)
-40 H%=BUFNEW(64)
-50 BUFFREE(H%)
+30 BUFDROP(H%)
+40 H%=BUFMAKE(64)
+50 BUFDROP(H%)
```
```basic
10 H%=SCRCAP()
20 PRINT CHR$(147);"CHANGED"
30 SCRPUT(H%)
-40 BUFFREE(H%)
+40 BUFDROP(H%)
```
```asm
@@ -791,9 +1057,9 @@ cmd_scrput_low:
Descriptors:
```asm
-CMD_LOW_ALL CMD_BUFNEW, SIG_BUFNEW, cmd_bufnew_low, "BUFNEW"
+CMD_LOW_ALL CMD_BUFNEW, SIG_BUFNEW, cmd_bufnew_low, "BUFMAKE"
CMD_LOW_ALL CMD_BUFFILL, SIG_BUFFILL, cmd_buffill_low, "BUFFILL"
-CMD_LOW_ALL CMD_BUFFREE, SIG_BUFFREE, cmd_buffree_low, "BUFFREE"
+CMD_LOW_ALL CMD_BUFFREE, SIG_BUFFREE, cmd_buffree_low, "BUFDROP"
CMD_LOW_ALL CMD_SCRCAP, SIG_SCRCAP, cmd_scrcap_low, "SCRCAP"
CMD_LOW_ALL CMD_SCRPUT, SIG_SCRPUT, cmd_scrput_low, "SCRPUT"
```
@@ -816,7 +1082,7 @@ Line-by-line commentary:
Why it matters: this is how future large objects should work. Keep BASIC-visible
values small, keep canonical resource metadata in REU, and validate handle type
at command boundaries. `BUFFILL` accepts only type-1 buffer handles; `SCRPUT`
-accepts only type-2 screen text+color handles; `BUFFREE` frees any valid type.
+accepts only type-2 screen text+color handles; `BUFDROP` frees any valid type.
## Other Current Command Invocations
@@ -824,7 +1090,7 @@ These current descriptor commands are smaller utility or probe commands. They
use the same descriptor/parser/worker contract as the larger examples above.
```basic
-10 FREEMEM()
+10 MEMAVL()
20 P%=ZTEMPSCRATCH(512)
30 PRINT "PAGES";P%
40 ZTEMPSCRATCH(512,Q%)
@@ -861,9 +1127,12 @@ before the command reports `?RB ERROR code`:
4. Add a low or hidden worker that only writes the result frame on success.
5. Add a descriptor entry; use `CMD_LOW_ALL` only when shared helpers require the
full slot-0 payload.
-6. Keep resident changes minimal. Prefer REU metadata and existing scratch pages.
-7. Add direct and stored-program VICE coverage, including error behavior.
-8. Update Markdown and HTML docs after static and VICE verification, using
+6. Update the descriptor filler count so real descriptors plus filler still fit
+ exactly in `RB_CMD_DESC_COUNT`; `make readybasic-plugin-static-check` now
+ enforces this.
+7. Keep resident changes minimal. Prefer REU metadata and existing scratch pages.
+8. Add direct and stored-program VICE coverage, including error behavior.
+9. Update Markdown and HTML docs after static and VICE verification, using
measured map values rather than predicted sizes.
## Appendix A: Descriptor And Registry Terms
@@ -873,6 +1142,7 @@ before the command reports `?RB ERROR code`:
| `REGSEED` | Cold-load descriptor image in C64 RAM during startup. It is copied to REU and then reclaimed, so it does not reduce empty BASIC free bytes. |
| `RB_CMD_DESC_COUNT` | Registry capacity, currently 128 descriptors. |
| Assigned core bank `$1000-$1FFF` | REU location of the 128 descriptor table. Runtime lookup pages through this table. |
+| Descriptor filler count | The `.res (RB_CMD_DESC_COUNT - N) * RB_CMD_DESC_SIZE` expression must use the current real descriptor count. If it is too large, later commands fall outside lookup range and look like native BASIC syntax errors. |
| `RB_PAGEBUF` | C64 RAM page buffer used to fetch one 256-byte descriptor page, eight descriptors at a time. |
| `RB_DESC_BUF` | Resident buffer containing the single descriptor selected by lookup. |
| `RB_MODULE_SYSTEM` | Built-in system/default module id used by the current slot-0 command payload. |
@@ -942,7 +1212,7 @@ This is intentionally not automatic for every command descriptor. The resident
parser currently recognizes only command signatures that can return safely
inside BASIC expressions without output variables. Commands with array outputs
or no scalar result stay statement-only; handle-producing commands such as
-`BUFNEW(n)` and `SCRCAP()` are expression-enabled because their scalar return is
+`BUFMAKE(n)` and `SCRCAP()` are expression-enabled because their scalar return is
the handle.
Native routines also accept parenthesized `EXEC` and definitions:
diff --git a/src/apps/readybasic/READYBASIC_MICROMODULE_SYNC.md b/src/apps/readybasic/READYBASIC_MICROMODULE_SYNC.md
index d5cde24..750f2bf 100644
--- a/src/apps/readybasic/READYBASIC_MICROMODULE_SYNC.md
+++ b/src/apps/readybasic/READYBASIC_MICROMODULE_SYNC.md
@@ -11,12 +11,12 @@ under-ROM command layout:
|---|---:|
| `BASIC_START` | `$2AC1` |
| Formula empty BASIC bytes | `30013` |
-| `RESIDENT` | `$1200-$2ABB`, `$18BC` |
-| Common under-ROM helper | `$A000-$A7FF`, current use `$A000-$A364` |
-| Submodule slot 0 | `$A800-$AFFF`, current module 1 payload `$A800-$AEC6` |
-| Submodule slot 1 | `$B000-$B7FF`, current module 2 payload `$B000-$B140` |
-| Submodule slot 2 | `$B800-$BFFF`, current proof/overlay payloads through `$B83E` |
-| `BRIDGE` | `$C000-$C1F6`, `$01F7` |
+| `RESIDENT` | `$1200-$2ABE`, `$18BF` |
+| Common under-ROM helper | `$A000-$A7FF`, current use `$A000-$A6C7` |
+| Submodule slot 0 | `$A800-$AFFF`, current module 1 payload `$A800-$AECD` |
+| Submodule slot 1 | `$B000-$B7FF`, current module 2 payload `$B000-$B23A` |
+| Submodule slot 2 | `$B800-$BFFF`, current proof/overlay payloads through `$B814` |
+| `BRIDGE` | `$C000-$C1FD`, `$01FE` |
| Shared frames | `$C200-$C5FF` |
Descriptor byte 1 is now module id, not a `LOW`/`HIDDEN` flag. Descriptor bytes
@@ -63,30 +63,45 @@ uppercase name field.
- ReadyBASIC still uses:
- `SHIM_RETURN = $C80C`
- - bridge state at `$C000-$C1F3`
- - shared frames and visible helper shadow at `$C200-$C5FF`
+ - bridge state at `$C000-$C1FD`
+ - shared frames at `$C200-$C5FF`
+ - hidden-helper warm-resume shadow in the assigned core bank at `$3000`
- app runtime zero-page/stack save in the assigned core bank offsets
`$0A00/$0B00`
-- Do not place ReadyBasic state in `$C800-$C9FF`; that remains shim ABI territory.
-- Do not use `$C600-$C7FF` as ReadyBASIC scratch; it remains ReadyOS REU metadata.
+- Do not place ReadyBasic state anywhere in `$C600-$C9FF`; the lower half is
+ resident shim expansion capacity and the upper half is the stable shim ABI.
## Current ReadyBASIC Memory Snapshot
- `BASIC_START = $2AC1`; BASIC owns `$2AC1-$9FFF`, with `30013` formula empty free bytes.
-- `ENTRY` lives at `$1000-$1102`.
-- `RESIDENT` lives at `$1200-$2ABB` (`$18BC`, 6332B) and must stay below `$2AC0`.
+- `ENTRY` lives at `$1000-$11FC`, size `$01FD` / 509B.
+- `RESIDENT` lives at `$1200-$2ABE` (`$18BF`, 6335B) and must stay below `$2AC0`; that leaves `$01` / 1B of visible headroom at `$2ABF`.
- `CMDPACK` load-only seed space is `$2B00-$3FFF`; it is copied to the assigned
ReadyBASIC code bank on cold entry.
- `HIDLOAD` load-only helper seed starts at `$4000`.
- `BRLOAD` load-only bridge seed starts at `$4800`.
- `REGSEED` load-only registry seed is `$5000-$600F`, size `$1010`.
-- Runtime common under-ROM helper code is `$A000-$A364`, size `$0365` / 869B.
-- Runtime submodule slot 0 is `$A800-$AFFF`; current module 1/default payload uses `$A800-$AEC6`, size `$06C7` / 1735B.
-- Runtime submodule slot 1 is `$B000-$B7FF`; current module 2 proof/streaming loader payload uses `$B000-$B238`, size `$0239` / 569B.
-- Runtime submodule slot 2 is `$B800-$BFFF`; current proof/overlay payloads use `$B800-$B83E` in 21B slices.
-- Runtime `BRIDGE` is `$C000-$C1F8`, size `$01F9` / 505B; the native `PROC`/`FUNC`
+- Runtime common under-ROM helper code is `$A000-$A6C7`, size `$06C8` / 1736B, leaving `$0138` / 312B free in `$A000-$A7FF`.
+- Runtime submodule slot 0 is `$A800-$AFFF`; current module 1/default payload uses `$A800-$AECD`, size `$06CE` / 1742B.
+- Runtime submodule slot 1 is `$B000-$B7FF`; current module 2 proof/streaming loader payload uses `$B000-$B23A`, size `$023B` / 571B.
+- Runtime submodule slot 2 is `$B800-$BFFF`; current proof/overlay payloads use `$B800-$B814` in 21B slices.
+- Runtime `BRIDGE` is `$C000-$C1FD`, size `$01FE` / 510B; the native `PROC`/`FUNC`
return stack and flow-control scratch live here and must stay below shared frames at `$C200`.
+Hotkey release branch delta, measured against checkpoint `fe169a8`:
+
+| Segment | Before | After | Delta |
+|---|---:|---:|---:|
+| `ENTRY` | `$01EB` / 491B | `$01FD` / 509B | `+18B` |
+| `RESIDENT` | `$18B7` / 6327B | `$18BF` / 6335B | `+8B` |
+| `HIDDEN` | `$06A8` / 1704B | `$06C8` / 1736B | `+32B` |
+| `BRIDGE` | `$01FE` / 510B | `$01FE` / 510B | `0B` |
+| BASIC free | `30013` | `30013` | `0B` |
+
+The code cost is intentionally paid mostly in entry/setup and the `$A000-$A7FF`
+helper area. BASIC free bytes are unchanged, and the 2K helper area still has
+`$0138` / 312B free for more small ReadyOS/BASIC glue.
+
## Assigned Core Bank ReadyBASIC Layout
- `$0000`: registry header.
@@ -99,6 +114,7 @@ uppercase name field.
- `$0C00-$0CFF`: heap page bitmap, 192 pages tracked in REU.
- `$1000-$1FFF`: 128 command descriptor slots, 32 bytes each. Slots 1-16 are current front commands, slots 17-127 are filler, and slot 128 is `SCRPUT`.
- `$2000-$3FFF`: reserved common/system expansion space.
+- `$3000`: current hidden-helper warm-resume shadow (`$06A8` bytes).
- `$4000-$FFFF`: typed handle heap, 48KB.
Command lookup fetches one 256-byte descriptor page at a time into `$C500`,
@@ -107,12 +123,12 @@ scans eight descriptors locally, and copies the matched descriptor into
## Assigned Code Bank Command Code Layout
-- `$0000-$06C6`: built-in module 1/default slot-0 payload, fetched to `$A800-$AEC6`.
-- `$06C7-$08FF`: built-in module 2 slot-1 proof and streaming `ZMODLD` loader payload, fetched to `$B000-$B238`.
-- `$0900-$0914`: built-in module 2 slot-2 proof payload, fetched to `$B800-$B814`.
-- `$0915-$0929`: built-in two-slot span proof payload, fetched to `$B000-$B014`.
-- `$092A-$093E`: built-in slot-2 overlay proof 1, fetched to `$B815-$B829`.
-- `$093F-$0953`: built-in slot-2 overlay proof 2, fetched to `$B82A-$B83E`.
+- `$0000-$06CD`: built-in module 1/default slot-0 payload, fetched to `$A800-$AECD`.
+- `$06CE-$0908`: built-in module 2 slot-1 proof and streaming `ZMODLD` loader payload, fetched to `$B000-$B23A`.
+- `$0909-$091D`: built-in module 2 slot-2 proof payload, fetched to `$B800-$B814`.
+- `$091E-$0932`: built-in two-slot span proof payload, fetched to `$B000-$B014`.
+- `$0933-$0947`: built-in slot-2 overlay proof 1, fetched to `$B815-$B829`.
+- `$0948-$095C`: built-in slot-2 overlay proof 2, fetched to `$B82A-$B83E`.
- `$1500-$151F`: `rbm.sample1` disk-module descriptor sample for `ZDM1`.
- `$1600-$165F`: `rbm.sample2` disk-module descriptor samples for `ZDM2S`, `ZDOV1`, and `ZDOV2`.
- `$1700-$1ABF`: `rbm.sample3` disk-module descriptors for `ZSAA`-`ZUEB`.
@@ -158,7 +174,8 @@ dispatch wrappers over existing descriptors.
commands.
- Command expressions cover scalar/string-result signatures such as
`ZECHO1()`, `ZADD16(a,b)`, `UPPER(s$)`, `LOWER(s$)`, `ZHIDDENRAM(s$)`,
- `BUFNEW(n)`, `ZTEMPSCRATCH(n)`, `SCRCAP()`, and `ZSUMNUMARRAY(a%(0),n)`.
+ `BUFMAKE(n)`, `ZTEMPSCRATCH(n)`, `SCRCAP()`, and
+ `ZSUMNUMARRAY(a%(0),n)`.
- String and numeric `FUNC` calls return through `RET`, `RET%`, or `RET$`.
`FUNC` is expression-only; calls scan the body, execute simple scalar
assignments before `RET`, and evaluate
@@ -171,7 +188,8 @@ dispatch wrappers over existing descriptors.
- Type `1` is a byte buffer.
- Type `2` is a screen text+color buffer.
- `BUFFILL` accepts only type `1`.
-- `BUFFREE` frees any valid handle type.
+- `BUFDROP` frees any valid handle type. Duplicate buffer-free spellings are not
+ registered in the alpha command catalog.
- `SCRPUT` accepts only type `2`.
## Banking Discipline
diff --git a/src/apps/readybasic/READYBASIC_PLUGIN_ARCH.md b/src/apps/readybasic/READYBASIC_PLUGIN_ARCH.md
index a239f87..db9db51 100644
--- a/src/apps/readybasic/READYBASIC_PLUGIN_ARCH.md
+++ b/src/apps/readybasic/READYBASIC_PLUGIN_ARCH.md
@@ -8,9 +8,10 @@ same ReadyOS and REU discipline.
- `BASIC_START = $2AC1`; BASIC owns `$2AC1-$9FFF`, with `30013` formula empty
free bytes.
-- `RESIDENT` is `$1200-$2ABE` (`$18BF`, 6335B).
-- `BRIDGE` is `$C000-$C1F8` (`$01F9`, 505B), still below `$C200`.
-- Under BASIC ROM, `$A000-$A7FF` is the common helper area; `$A800-$AFFF`,
+- `RESIDENT` is `$1200-$2ABF` (`$18C0`, 6336B).
+- `BRIDGE` is `$C000-$C1FE` (`$01FF`, 511B), still below `$C200`.
+- Under BASIC ROM, `$A000-$A7FF` is the common helper area, currently using
+ `$A000-$A78A`; `$A800-$AFFF`,
`$B000-$B7FF`, and `$B800-$BFFF` are three 2KB submodule slots.
- ReadyBASIC uses two launcher-assigned REU resource banks. The core bank is
registry/runtime storage; the code bank is built-in and disk-loaded module
@@ -22,6 +23,15 @@ same ReadyOS and REU discipline.
- The disk-loader proof command is `ZMODLD(name$)` in module 2/slot 1. It opens
ReadyBasicModule SEQ packages named `rbm.` and streams them into REU.
Sample packages add `ZDM1`, `ZDM2S`, `ZDOV1`, `ZDOV2`, and `ZSAA`-`ZUEB`.
+- Graphics commands are built-in module id `3`: `GFXCORE` submodule `16` in
+ slot 1, `GFXPRIM` submodule `17` in the base slot-2 image, `GFXSPR`
+ submodule `18` as a slot-2 replacement overlay prestashed at code-bank offset
+ `$5000`, `INPUTEV` submodule `19` as a slot-2 replacement overlay prestashed
+ at code-bank offset `$5800`, `GFXPOLY` submodule `20` as a slot-2 replacement
+ overlay prestashed at `$6000`, `GFXDL` submodule `21` at `$6800`, and
+ `GFXTILE` submodule `22` at `$7000`.
+- Sound commands are built-in module id `4`: `SIDCORE` submodule `23` as a
+ slot-2 replacement overlay prestashed at code-bank offset `$7800`.
## Pre-Module V1 Layout Snapshot
@@ -34,7 +44,8 @@ same ReadyOS and REU discipline.
- `$C200-$C5FF`: fixed call frame, result frame, descriptor buffer, command-name buffer, page buffer, and warm-resume staging (`$0400`, 1.0K).
- `$A000-$A376`: hidden helper code (`$0377`, 887B), restored from the visible `$C280` shadow.
- `$A800-$A84C`: hidden worker overlay slot (`$004D`, 77B) used by `ZHIDDENRAM`.
-- `$C000-$C1F3`: bridge state plus native routine return stack and flow-control scratch (`$01F4`, 500B); the implementation stays below `$C200`.
+- `$C000` bridge state plus native routine return stack and flow-control
+ scratch; this pre-module snapshot also stayed below `$C200`.
## REU Banks
@@ -63,21 +74,23 @@ same ReadyOS and REU discipline.
- `$0A00`: ReadyOS suspend/resume zero-page snapshot.
- `$0B00`: ReadyOS suspend/resume stack-page snapshot.
- `$0C00-$0CFF`: 192-page heap bitmap plus reserved bytes.
-- `$1000-$1FFF`: 128 compact command descriptor slots, 32 bytes each. Slot 14 is `SCRCAP`, slot 128 is `SCRPUT`, and zero-filled filler slots are unused.
+- `$1000-$1FFF`: 128 compact command descriptor slots, 32 bytes each. The current build has 94 real descriptors, 34 zero-filled filler descriptors, and `SCRPUT` deliberately kept in slot 128.
- `$2000-$3FFF`: reserved common/system expansion space.
-- `$4000-$FFFF`: typed 48KB heap for buffer and screen handles.
+- `$4000-$FFFF`: typed 48KB heap for buffer, screen, and Phase 1 graphics
+ surface handles.
## Assigned Code Bank Regions
-- `$0000-$06C6`: built-in module 1 slot-0 payload, fetched into
- `$A800-$AEC6` (`$06C7`, 1735B). The linker symbol is still named
+- `$0000-$07DB`: built-in module 1 slot-0 payload, fetched into
+ `$A800-$AFDB` (`$07DC`, 2012B). The linker symbol is still named
`LOWPACK` for compatibility, but the current runtime slot base is `$A800`.
-- `$06C7-$08FF`: built-in module 2 slot-1 proof and streaming `ZMODLD` loader
- payload, fetched into `$B000-$B238` (`$0239`, 569B).
-- `$0900-$0953`: built-in slot-2, span, and overlay proof slices (`$0054`,
- 84B total). Each proof slice is 21B.
-- `$0954-$14FF`: free gap before the current disk-module proof offsets
- (`$0BAC`, 2988B).
+- `$07DC-$0D1C`: built-in module 2 slot-1 proof, streaming `ZMODLD` loader,
+ and `GFXCORE`, fetched into `$B000-$B540` (`$0541`, 1345B).
+- `$0D1D-$1454`: built-in slot-2 proof plus `GFXPRIM`, fetched into
+ `$B800-$BF37` (`$0738`, 1848B).
+- `$13AA-$13BE`: two-slot span proof payload (`$0015`, 21B).
+- `$1455-$14FF`: free gap before the current disk-module proof offsets
+ (`$00AB`, 171B).
- `$1500-$151F`: `rbm.sample1` descriptor proof for `ZDM1`.
- `$1600-$165F`: `rbm.sample2` descriptors for `ZDM2S`, `ZDOV1`, and `ZDOV2`;
submodule 5 appears twice because those entries are overlays 1 and 2.
@@ -85,6 +98,27 @@ same ReadyOS and REU discipline.
- `$3000-$3014`, `$3200-$3214`, `$3300-$3314`, `$3400-$3414`: small
disk-loaded module payload proofs.
- `$3800-$463C`: `rbm.sample3` payload records for `ZSAA`-`ZUEB`.
+- `$5000-$5271`: built-in `GFXSPR` replacement overlay, loaded from cold-only
+ `CMDPACK2` and fetched into `$B800-$BA71` when sprite commands run.
+- `$5272-$57FF`: reserved `GFXSPR` growth headroom inside the assigned code bank.
+- `$5800-$586C`: built-in `INPUTEV` replacement overlay, loaded from cold-only
+ `CMDPACK2` and fetched into `$B800-$B86C` when input commands run.
+- `$586D-$5FFF`: reserved `INPUTEV` growth headroom.
+- `$6000-$6778`: built-in `GFXPOLY` replacement overlay, loaded from cold-only
+ `CMDPACK2` and fetched into `$B800-$BF78` when polygon commands run.
+- `$6779-$67FF`: reserved `GFXPOLY` growth headroom.
+- `$6800-$6F82`: built-in `GFXDL` replacement overlay, loaded from cold-only
+ `CMDPACK2` and fetched into `$B800-$BF82` when display-list commands run.
+- `$6F83-$6FFF`: reserved `GFXDL` growth headroom.
+- `$7000-$74D9`: built-in `GFXTILE` replacement overlay, loaded from cold-only
+ `CMDPACK2` and fetched into `$B800-$BCD9` when charset, tileset, tilemap, or
+ explicit multicolor-cell commands run.
+- `$74DA-$77FF`: reserved `GFXTILE` growth headroom.
+- `$7800-$7A0D`: built-in `SIDCORE` replacement overlay, loaded from cold-only
+ `CMDPACK2` and fetched into `$B800-$BA0D` when immediate sound commands run.
+- `$7A0E-$7FFF`: reserved `SIDCORE` growth headroom.
+- `$8000-$FFFF`: currently unreserved assigned code-bank tail for future
+ built-in command payloads or a later resource-loader/codebank split.
Descriptors store payload offsets, payload sizes, slot masks, runtime
destinations, and entry offsets. Heap and screen commands currently fetch the
@@ -135,12 +169,12 @@ Each descriptor is 32 bytes:
- `ZHIDDENRAM(S$,OUT%)` / `ZHIDDENRAM(S$)`: module 1 slot 0 under-ROM worker proof, returns a simple checksum.
- `ZSUMNUMARRAY(A%(0),COUNT,OUT%)` / `ZSUMNUMARRAY(A%(0),COUNT)`: module 1 slot 0 payload, sums integer array elements.
- `ZRANGENUMARRAY(START,COUNT,A%(0))`: module 1 slot 0 payload, stages integer array output and resident commit writes it.
-- `BUFNEW(LEN,H%)` / `BUFNEW(LEN)`: module 1 slot 0 payload, creates a persistent handle in bank `$44`.
+- `BUFMAKE(LEN,H%)` / `BUFMAKE(LEN)`: module 1 slot 0 payload, creates a persistent handle in bank `$44`.
- `BUFFILL(H%,BYTE)`: module 1 slot 0 payload, fills buffer handle pages and rejects non-buffer handles.
-- `BUFFREE(H%)`: module 1 slot 0 payload, frees any valid handle type.
+- `BUFDROP(H%)`: module 1 slot 0 payload, frees any valid handle type.
- `ZTEMPSCRATCH(LEN,OUT%)` / `ZTEMPSCRATCH(LEN)`: module 1 slot 0 payload, allocates and frees temporary pages, returning page count.
- `ZFAIL(CODE,OUT%)`: module 1 slot 0 payload, exercises the error path after output clearing.
-- `FREEMEM()`: module 1 slot 0 payload, prints the current live BASIC free-byte count and refreshes the header.
+- `MEMAVL()`: module 1 slot 0 payload, prints the current live BASIC free-byte count.
- `SCRCAP(H%)` / `SCRCAP()`: module 1 slot 0 payload, captures screen text plus color RAM into a typed screen handle.
- `FADD(A,B,OUT)` / `FADD(A,B)`: resident-computed demo command, returns a plain C64 BASIC float.
- `ZPAUSE(TICKS)`: module 1 slot 0 payload, waits for a number of jiffies.
@@ -151,6 +185,49 @@ Each descriptor is 32 bytes:
`ZCOPY`: built-in slot/span/overlay proof commands.
- `ZMODLD(name$)`: module 2 slot 1 SEQ package loader proof command.
- `ZDM1`, `ZDM2S`, `ZDOV1`, `ZDOV2`, and `ZSAA`-`ZUEB`: disk-loaded sample module commands.
+- `GFXMODE(mode$)` / `GFXMODE()`: module 3 `GFXCORE`, switches or reads
+ `TEXT`, `HIRES`, `MBITMAP`, `TILE`, and `MTILE`.
+- `GFXTEXT()`, `GFXCLEAR(C)`, `GFXTGT(H%)`, and
+ `GFXSYNC()`: module 3 `GFXCORE` Bank D setup/control commands.
+ `GFXTGT(0)` selects the visible target.
+- `GFXSURF(mode$)` and `GFXBLIT(H%)`: slot-0 allocator-backed surface handle
+ commands. They allocate/validate typed handle `3`; full REU drawing/blitting
+ is future work.
+- `PLOT(X,Y,C)`, `PNT(X,Y,OUT%)`, `LINE(X1,Y1,X2,Y2,C)`,
+ `RECT(X1,Y1,X2,Y2,C)`, `FBOX(X1,Y1,X2,Y2,C)`, `CIRCLE(X,Y,R,C)`,
+ `FCIRCLE(X,Y,R,C)`, `TILE(X,Y,CH,C)`, and `CHARAT(X,Y,CH,C)`: module 3
+ `GFXPRIM` immediate primitive/cell commands. In `MBITMAP`, these primitives
+ use 160x200 logical coordinates and color-slot encoding: `0` clears, `1..15`
+ writes color RAM and draws pair code `3`, `16..31` draws pair code `1`,
+ `32..47` draws pair code `2`, and `48..63` explicitly draws pair code `3`.
+- `POLY(A%(0),COUNT,C)`, `FPOLY(A%(0),COUNT,C)`, `POLYH(H%,COUNT,C)`,
+ `FPOLYH(H%,COUNT,C)`, `PBMAKE(COUNT,H%)`, `PBUFSET(H%,INDEX,X,Y)`, and
+ `PBDROP(H%)`: module 3 `GFXPOLY` overlay commands. Point buffers are typed
+ REU handle type `4`; `POLYH`/`FPOLYH` are explicit handle forms because the
+ same-name handle overload was not added to the resident parser.
+- `SPRSET(N,ON,COLOR,PATTERN)`, `SPRMOVE(N,X,Y)`, `SPRCOL(N,COLOR)`,
+ `SPRROW(N,ROW,B1,B2,B3)`, `SPRSIZE(N,XON,YON)`, `SPRPRI(N,BEHIND)`,
+ `SPRMUL(N,ON)`, `SPRMCO(C1,C2)`, `SPRSCAN()`, and
+ `SPRCOLL(N,OUT%)`:
+ module 3 `GFXSPR` overlay commands.
+- `JOY(PORT,OUT%)`, `KEYP(OUT%)`, `KEYSCAN()`, and `KEYLAST(OUT%)`: module 3
+ `INPUTEV` polling input commands.
+- `SIDRST()`, `SIDOFF()`, `VOL(VOL)`, `FRQ(V,F)`, `PITCH(V,N,O)`,
+ `PULSE(V,W)`, `ADSR(V,A,D,S,R)`, `WAVE(V,M)`, `GATE(V,ON)`,
+ `VOICE(V,F,W,AD,SR)`, `FILTER(CUTOFF,RES,ROUTE,MODE)`, and
+ `SOUND(V,F,D,W)`:
+ module 4 `SIDCORE` immediate SID sound commands. `VOICE` uses packed SID
+ attack/decay and sustain/release bytes to avoid resident parser growth; no
+ IRQ playback engine is installed.
+
+This alpha build registers no duplicate public command spellings. ReadyBASIC
+can implement an alias by adding a second 32-byte descriptor that points at the
+same command id, signature, payload, and entrypoint, so the command body cost is
+usually zero. The descriptor cost is still real: each alias consumes one of the
+128 searchable slots, increases generated documentation/test surface, and can
+preserve BASIC V2 tokenization hazards such as embedded `FN`, `FRE`, `INT`,
+`CLR`, `LEN`, and `NOT`. Current stored programs and demos must use only the
+canonical names above, and static verification rejects removed aliases.
Native reusable BASIC routines:
@@ -204,9 +281,17 @@ The current design includes resident flow control and error introspection:
ReadyBASIC runtime error code and line.
Measured current layout: `BASIC_START=$2AC1`; BASIC owns `$2AC1-$9FFF`, for
-`30013` formula empty free bytes. `RESIDENT` is `$1200-$2ABB` (`6332` bytes),
-`BRIDGE` is `$C000-$C1F6` (`503` bytes), `LOWPACK` is `$06C7` (`1735` bytes),
-and `bin/readybasic.prg` remains `20994` bytes.
+`30013` formula empty free bytes. `ENTRY` is `$1000-$11FF` (`512` bytes),
+`RESIDENT` is `$1200-$2ABF` (`6336` bytes), `HIDDEN` is `$A000-$A78A`
+(`1931` bytes), `BRIDGE` is `$C000-$C1FE` (`511` bytes), `LOWPACK` is `$07DC`
+(`2012` bytes), `SLOTPACK1` is `$0541` (`1345` bytes), `SLOTPACK2` is `$0738`
+(`1848` bytes), `OVL1PACK` is `$0272` (`626` bytes), `OVL2PACK` is `$006D`
+(`109` bytes), `OVL3PACK` is `$0779` (`1913` bytes), `OVL4PACK` is `$0783`
+(`1923` bytes), `OVL5PACK` is `$04DA` (`1242` bytes), `OVL6PACK` is `$020E`
+(`526` bytes), and `bin/readybasic.prg`
+is `28674` bytes because `CMDPACK2` extends the cold-load seed image through
+`$7FFF`. BASIC free bytes remain
+unchanged because the seed image is reclaimed before BASIC initialization.
## Current Nested-Term Support
@@ -240,7 +325,7 @@ recognizes a small allow-list of expression-safe command calls and selected
numeric/string `FUNC` calls.
- Command expressions: `ZECHO1()`, `ZADD16(a,b)`, `ZHIDDENRAM(s$)`,
- `ZSUMNUMARRAY(a%(0),n)`, `BUFNEW(n)`, `ZTEMPSCRATCH(n)`, and `SCRCAP()`
+ `ZSUMNUMARRAY(a%(0),n)`, `BUFMAKE(n)`, `ZTEMPSCRATCH(n)`, and `SCRCAP()`
return integers or handles; `UPPER(s$)` and `LOWER(s$)` return strings.
- Parenthesized routine syntax: `PROC NAME(P%,S$)`, `FUNC NAME(S$)`, and
`EXEC NAME(actuals...)` for non-empty argument lists.
diff --git a/src/apps/readybasic/READYBASIC_PLUGIN_PROGRESS.md b/src/apps/readybasic/READYBASIC_PLUGIN_PROGRESS.md
index a22ea50..9d6c5f2 100644
--- a/src/apps/readybasic/READYBASIC_PLUGIN_PROGRESS.md
+++ b/src/apps/readybasic/READYBASIC_PLUGIN_PROGRESS.md
@@ -1,12 +1,17 @@
# ReadyBASIC Plugin Progress
+> Chronology note: entries below record the contract that existed when each
+> experiment ran. The current schema-v5 contract uses a `$1000-$C5FF` (`$B600`)
+> app snapshot and a combined ReadyOS bank at physical `Skip`; the resident
+> 1 KB shim owns `$C600-$C9FF`.
+
This is a chronological progress log. Older entries intentionally preserve the
layout and addresses that were current when the tests were run. For the current
memory map, use `READYBASIC_CURRENT_DESIGN.md`.
Current runtime command names use `ZECHO1`, `ZADD16`, `UPPER`, `LOWER`,
`ZHIDDENRAM`, `ZSUMNUMARRAY`, `ZRANGENUMARRAY`, `ZTEMPSCRATCH`, `ZPAUSE`,
-`ZFAIL`, `FREEMEM`, `ERRCODE`, and `ERRLINE` for the core demo/proof commands.
+`ZFAIL`, `MEMAVL`, `ERRCODE`, and `ERRLINE` for the core demo/proof commands.
The module/submodule branch also includes `ZSLOT0`, `ZSLOT1`, `ZSLOT2`,
`ZSPAN`, `ZOVL1`, `ZOVL2`, `ZCPYRST`, `ZCOPY`, `ZMODLD`, and disk-loaded sample
commands `ZDM1`, `ZDM2S`, `ZDOV1`, and `ZDOV2`. Native language features also include `PROC`/`FUNC`,
@@ -77,7 +82,7 @@ as `PING`, `ADD16`, `STRUP`, `HCRC`, `SUMAI`, `RANGEAI`, `TEMPSCRATCH`, and
and `NGS HI`.
- Broad external command/program/lifecycle/state wrappers were later refreshed
to the bare parenthesized syntax on this branch.
- - Added a viewer-paced ReadyBASIC demo automation suite covering `FREEMEM`,
+ - Added a viewer-paced ReadyBASIC demo automation suite covering `MEMAVL`,
editor round trips, command groups, `PROC`/`FUNC`, expected errors, REU
handles, and nested expression forms.
@@ -115,7 +120,7 @@ as `PING`, `ADD16`, `STRUP`, `HCRC`, `SUMAI`, `RANGEAI`, `TEMPSCRATCH`, and
natural BASIC syntax lean.
- Added `$030A/$030B` eval-vector hook for selected expression returns:
`ZECHO1()`, `ZADD16(a,b)`, `UPPER(s$)`, `LOWER(s$)`, `ZHIDDENRAM(s$)`,
- `ZSUMNUMARRAY(a%(0),n)`, `BUFNEW(n)`, `ZTEMPSCRATCH(n)`, and `SCRCAP()`.
+ `ZSUMNUMARRAY(a%(0),n)`, `BUFMAKE(n)`, `ZTEMPSCRATCH(n)`, and `SCRCAP()`.
- Added parenthesized `PROC`/`FUNC` definitions and parenthesized non-empty
`EXEC` actual lists. Zero-argument routines still use `EXEC NAME`; `EXEC
NAME()` was cut for resident size.
@@ -232,7 +237,9 @@ as `PING`, `ADD16`, `STRUP`, `HCRC`, `SUMAI`, `RANGEAI`, `TEMPSCRATCH`, and
byte values because C64 visual case is charset-dependent.
- Old names are rejected with the existing unknown-command error.
- `SCRCAP` remains near the front in slot 14 and `SCRPUT` remains in slot
- 128, with 113 filler descriptors between them.
+ 128. Later built-in graphics/sound aliases reduced the filler span to 11
+ descriptors; static verification now enforces that real descriptors plus
+ filler remain exactly 128.
## 2026-05-22: REU-Backed 128 Handles And 48KB Typed Heap
@@ -314,7 +321,7 @@ as `PING`, `ADD16`, `STRUP`, `HCRC`, `SUMAI`, `RANGEAI`, `TEMPSCRATCH`, and
- Existing live handle count remains eight.
- Type `1` is a byte buffer; type `2` is screen text+color.
- `BUFFILL` rejects non-buffer handles with `?RB ERROR 40`.
- - `BUFFREE` frees any valid handle type.
+ - `BUFDROP` frees any valid handle type.
- `SCRCAP H%` captures `$0400-$07E7` and `$D800-$DBE7`.
- `SCRPUT H%` validates type `2` and restores screen text plus color RAM.
- The originally proposed `SCRSAVE`/`SCRLOAD` names were changed to
@@ -446,7 +453,7 @@ as `PING`, `ADD16`, `STRUP`, `HCRC`, `SUMAI`, `RANGEAI`, `TEMPSCRATCH`, and
- Result: pass, 44/44 steps.
- Key trace:
- Cold boot reached `READYBASIC REU PLUGINS`.
- - Direct command probes passed for `PING`, `ADD16`, `STRUP`, `HCRC`, `SUMAI`, `RANGEAI`, `BUFNEW`, `BUFFILL`, `BUFFREE`, `TEMPSCRATCH`, `FAIL`, and unknown-command error.
+ - Direct command probes passed for the current proof commands, including scalar, string, hidden-worker, array, REU-buffer, temporary-scratch, failure, and unknown-command cases.
- `EXIT` returned to the launcher.
- ReadyBasic was relaunched by menu navigation, not `CTRL+3`.
- READY-mode resume cleared/redrew the ReadyBasic screen and `!PING` still worked after resume.
@@ -515,7 +522,7 @@ as `PING`, `ADD16`, `STRUP`, `HCRC`, `SUMAI`, `RANGEAI`, `TEMPSCRATCH`, and
- String input/output works: `!STRUP S$,T$`.
- Hidden `$A000` worker works: `!HCRC "AB",H%`.
- Integer array input/output works: `SUMAI` and `RANGEAI`.
- - Persistent REU handle lifecycle works: `BUFNEW`, `BUFFILL`, `BUFFREE`.
+ - Persistent REU handle lifecycle works: `BUFMAKE`, `BUFFILL`, `BUFDROP`.
- Error path works: `!FAIL 7,X%` reports `?RB ERROR 7` and leaves the pre-cleared output variable at zero.
- Regression command: `READYBASIC_SKIP_BUILD=1 READYBASIC_VISIBLE=1 bash build_support/run_readybasic_plugin_command_probe.sh`
- Regression run dir: `../agenticdevharness/logs/vice_auto_20260511_204727`
@@ -537,7 +544,7 @@ as `PING`, `ADD16`, `STRUP`, `HCRC`, `SUMAI`, `RANGEAI`, `TEMPSCRATCH`, and
- Cold ReadyOS boot autoloaded ReadyBasic through the generated app config.
- Direct-mode sample commands passed across scalar, string, hidden worker, array, REU handle, temporary heap, failure, and unknown-command paths.
- Launcher round trip used menu navigation, not `CTRL+3`; ReadyBasic redrew on return and variables plus registry state survived.
- - Stored BASIC program tests passed for `PING`, same-line `ADD16`, `STRUP`, hidden `HCRC`, `SUMAI`, `RANGEAI`, `BUFNEW/BUFFILL/BUFFREE`, and failure output clearing.
+ - Stored BASIC program tests passed for scalar, same-line numeric, string, hidden-worker, array, `BUFMAKE`/`BUFFILL`/`BUFDROP`, and failure output clearing.
- First failing step/code: none.
- Next hypothesis:
- Keep this script as the human-watchable acceptance suite while shorter direct/program probes remain better for tight edit-run loops.
diff --git a/src/apps/readybasic/READYBASIC_SOUND_COMMAND_DESIGN.md b/src/apps/readybasic/READYBASIC_SOUND_COMMAND_DESIGN.md
new file mode 100644
index 0000000..077ab90
--- /dev/null
+++ b/src/apps/readybasic/READYBASIC_SOUND_COMMAND_DESIGN.md
@@ -0,0 +1,173 @@
+# ReadyBASIC Sound Command Design
+
+## Phase 1 Summary
+
+ReadyBASIC Sound Phase 1 is command-only SID support. It does not change
+ReadyBASIC language syntax, tokenization, control flow, native expression rules,
+`BASIC_START`, or BASIC free bytes.
+
+The implementation adds built-in module id `4`, submodule `SIDCORE` id `23`, as
+a slot-2 replacement overlay. `SIDCORE` is stored in the ReadyBASIC assigned
+code REU bank at offset `$7800`, loaded from cold-only `OVL6PACK`, and fetched
+to `$B800-$BA0D` when a sound command runs.
+
+There is no IRQ music engine in Phase 1. Commands either write SID registers
+immediately or, in the case of `SOUND`, perform a simple blocking tone.
+This keeps all persistent behavior out of resident ReadyBASIC RAM.
+
+## Design Rules
+
+- Use SID-native concepts: voice, frequency, waveform/control, pulse width,
+ ADSR, volume, and filter.
+- Keep voice number explicit. Hidden current-voice state would be shorter to
+ type, but it is less clear in stored programs and harder to reason about.
+- Reuse existing parser signatures. A trial `VOICE(V,F,W,A,D,S,R)` signature
+ grew the fixed resident area by 31 bytes, so Phase 1 uses the packed SID form
+ `VOICE(V,F,W,AD,SR)`.
+- Prefer fast hardware-shaped commands for loops. `ADSR` is friendlier for
+ setup; `VOICE` is the compact 1 MHz path.
+- Do not install interrupts for playback yet.
+- Command names used in stored BASIC demos must be BASIC-token-safe and should
+ be written lowercase in host `.bas` sources before `petcat`. This alpha build
+ does not register duplicate legacy spellings, so demos use `sidrst`,
+ `sidoff`, `frq`, and `pitch` and avoid names that contain BASIC V2 tokens
+ such as `CLR`, `LEN`, `FRE`, and `NOT`.
+
+## SID Register Mapping
+
+SID lives at `$D400-$D418`.
+
+Each voice has seven registers:
+
+| Register role | Voice 1 | Voice 2 | Voice 3 |
+|---|---:|---:|---:|
+| Frequency low/high | `$D400/$D401` | `$D407/$D408` | `$D40E/$D40F` |
+| Pulse width low/high | `$D402/$D403` | `$D409/$D40A` | `$D410/$D411` |
+| Control/wave/gate | `$D404` | `$D40B` | `$D412` |
+| Attack/decay | `$D405` | `$D40C` | `$D413` |
+| Sustain/release | `$D406` | `$D40D` | `$D414` |
+
+Filter and volume use:
+
+| Register | Role |
+|---|---|
+| `$D415/$D416` | 11-bit filter cutoff |
+| `$D417` | resonance and voice/external routing |
+| `$D418` | filter mode high nibble and master volume low nibble |
+
+Wave/control bits:
+
+| Bit | Decimal | Meaning |
+|---:|---:|---|
+| 0 | 1 | Gate |
+| 1 | 2 | Sync |
+| 2 | 4 | Ring modulation |
+| 3 | 8 | Test |
+| 4 | 16 | Triangle |
+| 5 | 32 | Saw |
+| 6 | 64 | Pulse |
+| 7 | 128 | Noise |
+
+## Commands
+
+| Command | Syntax | Behavior |
+|---|---|---|
+| `SIDRST` / `SIDOFF` | `SIDRST()` | Reset/off commands. Clears SID registers `$D400-$D418`. |
+| `VOL` | `VOL(VOL)` | Sets master volume `0..15`, preserving filter mode bits in `$D418`. |
+| `FRQ` | `FRQ(VOICE,FREQ16)` | Writes raw 16-bit SID frequency for voice `1..3`. |
+| `PITCH` | `PITCH(VOICE,SEMI,OCT)` | Sets frequency from semitone `0..11` (`C..B`) and octave `0..7`, using a compact PAL C0 table shifted by octave. It does not gate the voice. |
+| `PULSE` | `PULSE(VOICE,WIDTH)` | Writes 12-bit pulse width `0..4095`. |
+| `ADSR` | `ADSR(VOICE,A,D,S,R)` | Writes attack, decay, sustain, and release nibbles `0..15`. |
+| `WAVE` | `WAVE(VOICE,MASK)` | Writes the SID voice control byte directly. Use bit `1` for gate, or use `GATE`. |
+| `GATE` | `GATE(VOICE,ON)` | Sets or clears bit 0 in the current voice control register. |
+| `VOICE` | `VOICE(VOICE,FREQ16,WAVE,AD,SR)` | Fast packed setup. Writes frequency, packed attack/decay byte, packed sustain/release byte, and control/wave byte. |
+| `FILTER` | `FILTER(CUTOFF,RES,ROUTE,MODE)` | Writes cutoff `0..2047`, resonance `0..15`, route bitmask, and mode bitmask. |
+| `SOUND` | `SOUND(VOICE,FREQ16,DURATION,WAVE)` | Blocking helper. Writes frequency, gates `WAVE` on, waits for `DURATION` spin-delay units, then gates off. |
+
+`FILTER` mode uses a logical low-nibble mask before shifting into `$D418`:
+
+| Mode bit | Meaning |
+|---:|---|
+| 1 | Low-pass |
+| 2 | Band-pass |
+| 4 | High-pass |
+| 8 | Voice 3 off |
+
+`FILTER` route is written to the low nibble of `$D417`; bit 0 routes voice 1,
+bit 1 routes voice 2, bit 2 routes voice 3, and bit 3 routes external input.
+
+## Examples
+
+Simple blocking tones:
+
+```basic
+10 sidrst():vol(15):adsr(1,0,5,12,3)
+20 sound(1,4455,45,16):rem triangle c4
+30 sound(1,4455,45,32):rem saw c4
+40 pulse(1,2048):sound(1,4455,45,64):rem pulse c4
+50 sound(1,4455,45,128):rem noise
+60 sidoff()
+```
+
+Manual voice control:
+
+```basic
+10 sidrst():vol(15)
+20 adsr(1,0,9,12,6):pulse(1,3072):frq(1,4455)
+30 wave(1,64):gate(1,1):zpause(70):gate(1,0)
+```
+
+Packed fast path:
+
+```basic
+10 sidrst():vol(15):pulse(1,2048)
+20 voice(1,4455,65,9,195)
+30 zpause(80):wave(1,64)
+```
+
+Here `65` is pulse plus gate, `9` is packed attack/decay `$09`, and `195` is
+packed sustain/release `$C3`.
+
+Filter example:
+
+```basic
+10 sidrst():vol(15):adsr(1,0,9,15,4)
+20 frq(1,2230):wave(1,33)
+30 for c=150 to 950 step 200:filter(c,8,1,1):zpause(35):next
+40 filter(700,12,1,2):zpause(90)
+50 filter(700,12,1,4):zpause(90)
+60 sidoff()
+```
+
+## Demos
+
+The Phase 1 demos are built with `petcat -w2 -l 2ac1` and run inside
+ReadyBASIC under ReadyOS:
+
+- `rbsnd01_sid_basics.bas`: triangle, saw, pulse, and noise.
+- `rbsnd02_voice_state.bas`: explicit ADSR, pulse width, frequency, wave, and gate.
+- `rbsnd03_notes.bas`: chromatic `PITCH` command.
+- `rbsnd04_filter.bas`: filter route/mode/cutoff changes.
+- `rbsnd05_voice_batch.bas`: packed `VOICE` fast path.
+- `rbsnd06_three_voice.bas`: three SID voices.
+
+Automation target:
+
+```sh
+make readybasic-sound-phase1-vice
+```
+
+The automation verifies ReadyOS boot, ReadyBASIC load, stored BASIC demo loading,
+listing, running, and absence of BASIC error prompts. It cannot prove audio
+quality; the demos print the expected listening result before each step.
+
+## Phase 2 Direction
+
+Likely next sound work:
+
+- String/MML-style `PLAY(...)`.
+- REU-backed tune handles.
+- Polling `SNDSTEP()` playback before considering IRQ playback.
+- Optional PAL/NTSC note-clock selection.
+- More compact sound-effect macros that compile into REU resources before BASIC
+ begins running.
diff --git a/src/apps/readybasic/REadyBASICCommandModuleAndSubmodulePlan.MD b/src/apps/readybasic/REadyBASICCommandModuleAndSubmodulePlan.MD
index a9fee1d..bd2069a 100644
--- a/src/apps/readybasic/REadyBASICCommandModuleAndSubmodulePlan.MD
+++ b/src/apps/readybasic/REadyBASICCommandModuleAndSubmodulePlan.MD
@@ -21,7 +21,7 @@ after the internal module model was stable.
module payloads, and command helpers in REU-backed under-ROM code.
- Keep ReadyBASIC compatible with the ReadyOS app memory contract:
- app-owned RAM is `$1000-$C5FF`;
- - `$C600-$C7FF` is ReadyOS REU metadata and must not be used as scratch;
+ - `$C600-$C7FF` is ReadyOS resident shim expansion capacity and must not be used as scratch;
- `$C800-$C9FF` is the ReadyOS shim ABI area and must not be used by
ReadyBASIC modules.
- Keep built-in ReadyBASIC modules bundled into `readybasic.prg` and prestashed
@@ -41,7 +41,7 @@ ReadyBASIC continues to use the existing app layout discipline:
| `$A000-$BFFF` | RAM under BASIC ROM | New common area plus three 2KB submodule slots. |
| `$C000-$C1FF` | ReadyBASIC bridge | Persistent bridge/state only; must stay below shared frames. |
| `$C200-$C5FF` | ReadyBASIC shared frames | Call/result/descriptor/name/page buffers and hidden helper shadow. |
-| `$C600-$C7FF` | ReadyOS REU metadata | Do not use as ReadyBASIC scratch. |
+| `$C600-$C7FF` | ReadyOS shim expansion reserve | Do not use as ReadyBASIC scratch. |
| `$C800-$C9FF` | ReadyOS shim ABI | Do not place ReadyBASIC module code/data here. |
The under-BASIC-ROM area is divided into four 2KB regions:
diff --git a/src/apps/readybasic/rbgfx01_modes.bas b/src/apps/readybasic/rbgfx01_modes.bas
new file mode 100644
index 0000000..3f70006
--- /dev/null
+++ b/src/apps/readybasic/rbgfx01_modes.bas
@@ -0,0 +1,12 @@
+10 rem see graphics design md
+20 print chr$(147);"rbgfx01 modes"
+30 gfxmode("hires"):m%=gfxmode():print "hires mode";m%
+40 gfxclear(0)
+50 gfxmode("mbitmap"):m%=gfxmode():print "mbitmap mode";m%
+60 gfxclear(1)
+70 gfxmode("tile"):m%=gfxmode():print "tile mode";m%
+80 gfxclear(2)
+90 gfxmode("mtile"):m%=gfxmode():print "mtile mode";m%
+100 gfxclear(3)
+110 gfxtext()
+120 print "back to text"
diff --git a/src/apps/readybasic/rbgfx02_hires_plot.bas b/src/apps/readybasic/rbgfx02_hires_plot.bas
new file mode 100644
index 0000000..c7a34ec
--- /dev/null
+++ b/src/apps/readybasic/rbgfx02_hires_plot.bas
@@ -0,0 +1,13 @@
+10 rem see graphics design md
+20 print chr$(147);"rbgfx02 hires plot"
+30 gfxmode("hires"):gfxclear(0)
+40 for x=0 to 319 step 16
+50 plot(x,0,1):plot(x,199,1)
+60 next x
+70 for y=0 to 199 step 16
+80 plot(0,y,1):plot(319,y,1)
+90 next y
+100 for i=0 to 199
+110 plot(i,i,1)
+120 next i
+130 print "grid and diagonal"
diff --git a/src/apps/readybasic/rbgfx03_hires_lines.bas b/src/apps/readybasic/rbgfx03_hires_lines.bas
new file mode 100644
index 0000000..defb93c
--- /dev/null
+++ b/src/apps/readybasic/rbgfx03_hires_lines.bas
@@ -0,0 +1,11 @@
+10 rem see graphics design md
+20 print chr$(147);"rbgfx03 hires lines"
+30 gfxmode("hires"):gfxclear(0)
+40 for y=0 to 199 step 20
+50 line(0,0,319,y,1)
+60 next y
+70 for x=0 to 319 step 32
+80 line(319,199,x,0,1)
+90 next x
+100 line(0,199,319,0,1)
+110 print "fan lines"
diff --git a/src/apps/readybasic/rbgfx04_rects.bas b/src/apps/readybasic/rbgfx04_rects.bas
new file mode 100644
index 0000000..34d7f0b
--- /dev/null
+++ b/src/apps/readybasic/rbgfx04_rects.bas
@@ -0,0 +1,10 @@
+10 rem see graphics design md
+20 print chr$(147);"rbgfx04 rects"
+30 gfxmode("hires"):gfxclear(0)
+40 rect(8,8,311,191,1)
+50 rect(32,24,288,176,1)
+60 fbox(64,48,128,96,1)
+70 fbox(192,96,256,160,1)
+80 line(0,0,319,199,1)
+90 line(0,199,319,0,1)
+100 print "outline and filled rects"
diff --git a/src/apps/readybasic/rbgfx05_point_read.bas b/src/apps/readybasic/rbgfx05_point_read.bas
new file mode 100644
index 0000000..c251f01
--- /dev/null
+++ b/src/apps/readybasic/rbgfx05_point_read.bas
@@ -0,0 +1,11 @@
+10 rem see graphics design md
+20 print chr$(147);"rbgfx05 pnt read"
+30 gfxmode("hires"):gfxclear(0)
+40 plot(40,40,1)
+50 pnt(40,40,a%)
+60 pnt(41,40,b%)
+70 print "pnt 40,40";a%
+80 print "pnt 41,40";b%
+90 plot(40,40,0)
+100 pnt(40,40,c%)
+110 print "after clear";c%
diff --git a/src/apps/readybasic/rbgfx06_reu_surface.bas b/src/apps/readybasic/rbgfx06_reu_surface.bas
new file mode 100644
index 0000000..59aeefc
--- /dev/null
+++ b/src/apps/readybasic/rbgfx06_reu_surface.bas
@@ -0,0 +1,9 @@
+10 rem see graphics design md
+20 print chr$(147);"rbgfx06 reu surface"
+30 h%=gfxsurf("hires")
+40 print "surface handle";h%
+50 gfxmode("hires"):gfxclear(0)
+60 line(0,0,319,199,1)
+70 gfxblit(h%)
+80 print "blit validates handle in phase 1"
+90 gfxtext()
diff --git a/src/apps/readybasic/rbgfx07_mbitmap.bas b/src/apps/readybasic/rbgfx07_mbitmap.bas
new file mode 100644
index 0000000..76d8e65
--- /dev/null
+++ b/src/apps/readybasic/rbgfx07_mbitmap.bas
@@ -0,0 +1,10 @@
+10 rem see graphics design md
+20 print chr$(147);"rbgfx07 mbitmap"
+30 gfxmode("mbitmap"):gfxclear(0)
+40 for y=10 to 190 step 12
+50 line(0,y,159,199-y,7)
+60 next y
+70 for x=16 to 144 step 16
+80 plot(x,100,55)
+90 next x
+100 print "multicolor bitmap register path"
diff --git a/src/apps/readybasic/rbgfx08_tile.bas b/src/apps/readybasic/rbgfx08_tile.bas
new file mode 100644
index 0000000..8bd06c1
--- /dev/null
+++ b/src/apps/readybasic/rbgfx08_tile.bas
@@ -0,0 +1,11 @@
+10 rem see graphics design md
+20 print chr$(147);"rbgfx08 tile"
+30 gfxmode("tile"):gfxclear(0)
+40 for y=0 to 23 step 2
+50 for x=0 to 38 step 2
+60 plot(x,y,1):plot(x+1,y+1,1)
+70 next x
+80 next y
+90 rect(2,2,37,22,5)
+100 pnt(3,3,a%)
+110 print "tile cells use plot";a%
diff --git a/src/apps/readybasic/rbgfx09_sprites.bas b/src/apps/readybasic/rbgfx09_sprites.bas
new file mode 100644
index 0000000..fd024bf
--- /dev/null
+++ b/src/apps/readybasic/rbgfx09_sprites.bas
@@ -0,0 +1,11 @@
+10 rem see graphics design md
+20 print chr$(147);"rbgfx09 sprites"
+30 gfxmode("tile"):gfxclear(0)
+40 sprset(0,1,2,0)
+50 sprset(1,1,7,1)
+60 sprmove(0,80,80)
+70 sprmove(1,180,110)
+80 sprcol(0,5)
+90 for t=1 to 60000:next t
+100 sprset(0,0,0,0):sprset(1,0,0,1)
+110 gfxtext():print "rbgfx09 complete"
diff --git a/src/apps/readybasic/rbgfx10_collision.bas b/src/apps/readybasic/rbgfx10_collision.bas
new file mode 100644
index 0000000..0363e20
--- /dev/null
+++ b/src/apps/readybasic/rbgfx10_collision.bas
@@ -0,0 +1,11 @@
+10 rem see graphics design md
+20 print chr$(147);"rbgfx10 collision"
+30 gfxmode("tile"):gfxclear(0)
+40 sprset(0,1,2,0)
+50 sprset(1,1,3,0)
+60 sprmove(0,120,100)
+70 sprmove(1,124,104)
+80 for t=1 to 60000:next t
+90 sprcoll(0,c%):gfxtext()
+100 print "sprite collision";c%
+110 sprscan()
diff --git a/src/apps/readybasic/rbgfx11_input.bas b/src/apps/readybasic/rbgfx11_input.bas
new file mode 100644
index 0000000..eeb633a
--- /dev/null
+++ b/src/apps/readybasic/rbgfx11_input.bas
@@ -0,0 +1,10 @@
+10 rem see graphics design md
+20 print chr$(147);"rbgfx11 input"
+30 for i=1 to 30
+40 joy(2,j%)
+50 keyp(k%)
+60 keylast(l%)
+70 print "joy";j%;" key";k%;" last";l%
+80 keyscan()
+90 next i
+100 print "polling only, no irq sampler"
diff --git a/src/apps/readybasic/rbgfx12_showcase.bas b/src/apps/readybasic/rbgfx12_showcase.bas
new file mode 100644
index 0000000..69aa1cb
--- /dev/null
+++ b/src/apps/readybasic/rbgfx12_showcase.bas
@@ -0,0 +1,12 @@
+10 rem see graphics design md
+20 print chr$(147);"rbgfx12 showcase"
+30 gfxmode("hires"):gfxclear(0)
+40 rect(4,4,315,195,1)
+50 for y=16 to 184 step 16
+60 line(8,y,311,199-y,1)
+70 next y
+80 fbox(136,72,184,120,1)
+90 sprset(0,1,6,2):sprmove(0,160,100)
+100 pnt(160,100,p%)
+110 print "center pnt";p%
+120 print "showcase done"
diff --git a/src/apps/readybasic/rbgfx13_sprite_steps.bas b/src/apps/readybasic/rbgfx13_sprite_steps.bas
new file mode 100644
index 0000000..673c974
--- /dev/null
+++ b/src/apps/readybasic/rbgfx13_sprite_steps.bas
@@ -0,0 +1,36 @@
+10 rem see graphics design md
+20 print chr$(147);"rbgfx13 sprite steps"
+30 gfxmode("tile"):gfxclear(0)
+40 sprset(0,1,2,0):sprset(1,1,7,0)
+50 sprrow(0,0,0,24,0):sprrow(0,1,0,60,0)
+60 sprrow(0,2,0,126,0):sprrow(0,3,0,255,0)
+70 sprrow(0,4,1,255,128):sprrow(0,5,3,255,192)
+80 sprrow(0,6,7,255,224):sprrow(0,7,15,255,240)
+90 sprrow(0,8,31,255,248):sprrow(0,9,63,255,252)
+100 sprrow(0,10,127,255,254):sprrow(0,11,63,255,252)
+110 sprrow(0,12,31,255,248):sprrow(0,13,15,255,240)
+120 sprrow(0,14,7,255,224):sprrow(0,15,3,255,192)
+130 sprrow(0,16,1,255,128):sprrow(0,17,0,255,0)
+140 sprrow(0,18,0,126,0):sprrow(0,19,0,60,0)
+150 sprrow(0,20,0,24,0)
+160 sprrow(1,0,255,255,0):sprrow(1,1,128,1,0)
+170 sprrow(1,2,191,253,0):sprrow(1,3,160,5,0)
+180 sprrow(1,4,175,245,0):sprrow(1,5,168,21,0)
+190 sprrow(1,6,171,85,0):sprrow(1,7,170,85,0)
+200 sprrow(1,8,171,85,0):sprrow(1,9,168,21,0)
+210 sprrow(1,10,175,245,0):sprrow(1,11,160,5,0)
+220 sprrow(1,12,191,253,0):sprrow(1,13,128,1,0)
+230 sprrow(1,14,255,255,0):sprrow(1,15,0,0,0)
+240 sprrow(1,16,255,255,0):sprrow(1,17,128,1,0)
+250 sprrow(1,18,255,255,0):sprrow(1,19,0,0,0)
+260 sprrow(1,20,255,255,0)
+270 sprmove(0,60,70):sprmove(1,190,110)
+280 zpause(30)
+290 get a$:if a$="" then 280
+300 sprmove(0,120,88):sprmove(1,145,110)
+310 zpause(30)
+320 get a$:if a$="" then 310
+330 sprset(0,1,5,0):sprset(1,1,3,0)
+340 zpause(30)
+350 get a$:if a$="" then 340
+360 gfxtext():print "sprite demo done"
diff --git a/src/apps/readybasic/rbgfx14_phase2_prims.bas b/src/apps/readybasic/rbgfx14_phase2_prims.bas
new file mode 100644
index 0000000..09d6b4e
--- /dev/null
+++ b/src/apps/readybasic/rbgfx14_phase2_prims.bas
@@ -0,0 +1,10 @@
+10 rem see graphics design md
+20 print chr$(147);"rbgfx14 phase2 prims"
+30 gfxmode("hires"):gfxclear(0)
+40 circle(82,82,38,1)
+50 fcircle(210,92,26,1)
+60 rect(180,58,240,126,1)
+70 line(20,170,300,170,1)
+80 zpause(30)
+90 get a$:if a$="" then 80
+100 gfxtext():print "phase2 prims done"
diff --git a/src/apps/readybasic/rbgfx15_phase2_tiles.bas b/src/apps/readybasic/rbgfx15_phase2_tiles.bas
new file mode 100644
index 0000000..43c3cd3
--- /dev/null
+++ b/src/apps/readybasic/rbgfx15_phase2_tiles.bas
@@ -0,0 +1,15 @@
+10 rem see graphics design md
+20 print chr$(147);"rbgfx15 phase2 tiles"
+30 gfxtext():print chr$(147)
+40 for y=4 to 16
+50 for x=6 to 33
+60 tile(x,y,160,1+(x+y)-int((x+y)/8)*8)
+70 next x
+80 next y
+90 charat(10,7,160,2):charat(11,7,160,3)
+100 charat(12,7,160,4):charat(13,7,160,5)
+110 charat(10,9,160,6):charat(11,9,160,7)
+120 charat(12,9,160,8):charat(13,9,160,9)
+130 zpause(30)
+140 get a$:if a$="" then 130
+150 gfxtext():print "phase2 tiles done"
diff --git a/src/apps/readybasic/rbgfx16_phase2_sprite_ctrl.bas b/src/apps/readybasic/rbgfx16_phase2_sprite_ctrl.bas
new file mode 100644
index 0000000..004bd0a
--- /dev/null
+++ b/src/apps/readybasic/rbgfx16_phase2_sprite_ctrl.bas
@@ -0,0 +1,32 @@
+10 rem see graphics design md
+20 print chr$(147);"rbgfx16 sprite controls"
+30 gfxmode("tile"):gfxclear(0)
+40 for y=7 to 12
+50 for x=13 to 24
+60 tile(x,y,160,6)
+70 next x
+80 next y
+90 sprset(0,1,2,0):sprmove(0,120,86)
+100 sprrow(0,0,0,60,0):sprrow(0,1,0,126,0)
+110 sprrow(0,2,0,255,0):sprrow(0,3,1,255,128)
+120 sprrow(0,4,3,255,192):sprrow(0,5,7,255,224)
+130 sprrow(0,6,15,255,240):sprrow(0,7,31,255,248)
+140 sprrow(0,8,63,255,252):sprrow(0,9,127,255,254)
+150 sprrow(0,10,255,255,255):sprrow(0,11,127,255,254)
+160 sprrow(0,12,63,255,252):sprrow(0,13,31,255,248)
+170 sprrow(0,14,15,255,240):sprrow(0,15,7,255,224)
+180 sprrow(0,16,3,255,192):sprrow(0,17,1,255,128)
+190 sprrow(0,18,0,255,0):sprrow(0,19,0,126,0)
+200 sprrow(0,20,0,60,0)
+210 zpause(30)
+220 get a$:if a$="" then 210
+230 sprsize(0,1,1):sprmove(0,134,92)
+240 zpause(30)
+250 get a$:if a$="" then 240
+260 sprmco(5,14)
+270 sprmul(0,1)
+280 sprpri(0,1)
+290 sprcol(0,3)
+300 zpause(30)
+310 get a$:if a$="" then 300
+320 gfxtext():print "phase2 sprites done"
diff --git a/src/apps/readybasic/rbgfx17_poly_array.bas b/src/apps/readybasic/rbgfx17_poly_array.bas
new file mode 100644
index 0000000..f86b8d2
--- /dev/null
+++ b/src/apps/readybasic/rbgfx17_poly_array.bas
@@ -0,0 +1,15 @@
+10 rem see graphics design md
+20 rem demo 17
+30 dim p%(7),q%(9)
+40 gfxmode("hires"):gfxclear(0)
+50 p%(0)=50:p%(1)=35:p%(2)=140:p%(3)=35
+60 p%(4)=170:p%(5)=105:p%(6)=85:p%(7)=145
+70 poly(p%(0),4,1)
+80 q%(0)=190:q%(1)=30:q%(2)=235:q%(3)=55
+90 q%(4)=245:q%(5)=125:q%(6)=220:q%(7)=155
+100 q%(8)=175:q%(9)=95
+110 poly(q%(0),5,1)
+120 line(20,175,250,175,1)
+130 zpause(30)
+140 get a$:if a$="" then 130
+150 gfxtext():print "phase3 done 17"
diff --git a/src/apps/readybasic/rbgfx18_fpoly_array.bas b/src/apps/readybasic/rbgfx18_fpoly_array.bas
new file mode 100644
index 0000000..e99c09a
--- /dev/null
+++ b/src/apps/readybasic/rbgfx18_fpoly_array.bas
@@ -0,0 +1,14 @@
+10 rem see graphics design md
+20 rem demo 18
+30 dim p%(7),q%(7)
+40 gfxmode("hires"):gfxclear(0)
+50 p%(0)=45:p%(1)=48:p%(2)=130:p%(3)=34
+60 p%(4)=165:p%(5)=118:p%(6)=70:p%(7)=150
+70 fpoly(p%(0),4,1)
+80 q%(0)=185:q%(1)=42:q%(2)=245:q%(3)=70
+90 q%(4)=230:q%(5)=150:q%(6)=175:q%(7)=115
+100 fpoly(q%(0),4,1)
+110 rect(18,22,252,176,1)
+120 zpause(30)
+130 get a$:if a$="" then 120
+140 gfxtext():print "phase3 done 18"
diff --git a/src/apps/readybasic/rbgfx19_poly_reu.bas b/src/apps/readybasic/rbgfx19_poly_reu.bas
new file mode 100644
index 0000000..4d8febc
--- /dev/null
+++ b/src/apps/readybasic/rbgfx19_poly_reu.bas
@@ -0,0 +1,16 @@
+10 rem see graphics design md
+20 rem demo 19
+30 gfxmode("hires"):gfxclear(0)
+40 pbmake(5,h%)
+50 pbufset(h%,0,70,40):pbufset(h%,1,155,45)
+60 pbufset(h%,2,180,115):pbufset(h%,3,105,155)
+70 pbufset(h%,4,45,95)
+80 polyh(h%,5,1)
+90 pbmake(3,g%)
+100 pbufset(g%,0,215,45):pbufset(g%,1,245,135)
+110 pbufset(g%,2,190,150)
+120 polyh(g%,3,1)
+130 rem demo
+140 zpause(30)
+150 get a$:if a$="" then 140
+160 gfxtext():print "phase3 done 19"
diff --git a/src/apps/readybasic/rbgfx20_fpoly_reu_showcase.bas b/src/apps/readybasic/rbgfx20_fpoly_reu_showcase.bas
new file mode 100644
index 0000000..c68883f
--- /dev/null
+++ b/src/apps/readybasic/rbgfx20_fpoly_reu_showcase.bas
@@ -0,0 +1,17 @@
+10 rem see graphics design md
+20 rem demo 20
+30 gfxmode("hires"):gfxclear(0)
+40 pbmake(4,h%)
+50 pbufset(h%,0,42,58):pbufset(h%,1,118,35)
+60 pbufset(h%,2,168,120):pbufset(h%,3,72,156)
+70 fpolyh(h%,4,1)
+80 pbmake(5,g%)
+90 pbufset(g%,0,185,42):pbufset(g%,1,244,55)
+100 pbufset(g%,2,248,112):pbufset(g%,3,226,158)
+110 pbufset(g%,4,170,106)
+120 fpolyh(g%,5,1)
+130 line(15,182,250,182,1):rect(176,24,252,170,1)
+140 rem demo
+150 zpause(30)
+160 get a$:if a$="" then 150
+170 gfxtext():print "phase3 done 20"
diff --git a/src/apps/readybasic/rbgfx21_mbitmap_prims.bas b/src/apps/readybasic/rbgfx21_mbitmap_prims.bas
new file mode 100644
index 0000000..a5341f2
--- /dev/null
+++ b/src/apps/readybasic/rbgfx21_mbitmap_prims.bas
@@ -0,0 +1,15 @@
+10 rem see graphics design md
+20 print chr$(147);"rbgfx21 mbitmap prims"
+30 gfxmode("mbitmap"):gfxclear(0)
+40 line(4,18,155,18,17)
+50 line(4,22,155,70,34)
+60 rect(8,82,72,144,20)
+70 fbox(86,82,148,144,37)
+80 circle(46,112,28,51)
+90 fcircle(118,112,22,58)
+100 for x=0 to 159 step 8
+110 plot(x,170,16+(x/8)-int((x/8)/15)*15)
+120 next x
+130 zpause(30)
+140 get a$:if a$="" then 130
+150 gfxtext():print "mbitmap prims done"
diff --git a/src/apps/readybasic/rbgfx22_mbitmap_point.bas b/src/apps/readybasic/rbgfx22_mbitmap_point.bas
new file mode 100644
index 0000000..b81dc04
--- /dev/null
+++ b/src/apps/readybasic/rbgfx22_mbitmap_point.bas
@@ -0,0 +1,13 @@
+10 rem see graphics design md
+20 print chr$(147);"rbgfx22 mbitmap pnt"
+30 gfxmode("mbitmap"):gfxclear(0)
+40 plot(20,40,17):plot(24,40,34):plot(28,40,51)
+50 pnt(20,40,a%):pnt(24,40,b%):pnt(28,40,c%)
+60 line(12,80,148,80,17)
+70 line(12,92,148,124,34)
+80 line(12,150,148,108,51)
+90 zpause(30)
+100 get a$:if a$="" then 90
+110 gfxtext():print chr$(147);"mbitmap pnt:";a%;b%;c%
+120 if a%<>1 or b%<>2 or c%<>3 then print "?mbitmap pnt fail":stop
+130 print "mbitmap pnt done"
diff --git a/src/apps/readybasic/rbgfx23_dlist.bas b/src/apps/readybasic/rbgfx23_dlist.bas
new file mode 100644
index 0000000..73d215a
--- /dev/null
+++ b/src/apps/readybasic/rbgfx23_dlist.bas
@@ -0,0 +1,11 @@
+10 rem see graphics design md
+20 print chr$(147);"rbgfx23 dlist"
+30 gfxmode("hires"):gfxclear(0)
+40 dlmake(12,h%)
+50 dlplot(h%,80,60,1)
+60 dlline(h%,20,20,300,160)
+70 dlrect(h%,40,50,140,130)
+80 dlfbox(h%,180,70,260,140)
+90 dldraw(h%)
+100 get a$:if a$="" then 100
+110 gfxtext():print "phase4 dlist done"
diff --git a/src/apps/readybasic/rbgfx24_tilemap.bas b/src/apps/readybasic/rbgfx24_tilemap.bas
new file mode 100644
index 0000000..4b4eaa6
--- /dev/null
+++ b/src/apps/readybasic/rbgfx24_tilemap.bas
@@ -0,0 +1,34 @@
+10 rem see graphics design md
+20 print chr$(147);"rbgfx24 tilemap"
+30 gfxmode("tile"):gfxclear(0)
+40 chrmake(256,c%)
+50 for r=0 to 7:chrrow(c%,1,r,255):next
+60 chrrow(c%,2,0,255):chrrow(c%,2,1,129)
+70 chrrow(c%,2,2,189):chrrow(c%,2,3,165)
+80 chrrow(c%,2,4,165):chrrow(c%,2,5,189)
+90 chrrow(c%,2,6,129):chrrow(c%,2,7,255)
+100 chrrow(c%,3,0,24):chrrow(c%,3,1,60)
+110 chrrow(c%,3,2,126):chrrow(c%,3,3,219)
+120 chrrow(c%,3,4,24):chrrow(c%,3,5,24)
+130 chrrow(c%,3,6,60):chrrow(c%,3,7,0)
+140 for r=0 to 7:chrrow(c%,4,r,170):next
+150 chruse(c%)
+160 tsmake(64,t%):tmmake(1000,m%)
+170 tsset(t%,0,32,0)
+180 tsset(t%,1,1,2)
+190 tsset(t%,2,2,5)
+200 tsset(t%,3,3,7)
+210 tsset(t%,4,4,1)
+220 for x=0 to 39
+230 tmset(m%,x,1,0):tmset(m%,960+x,1,0)
+240 next
+250 for y=0 to 24
+260 i=y*40:tmset(m%,i,1,0):tmset(m%,i+39,1,0)
+270 next
+280 for x=6 to 33
+290 tmset(m%,160+x,2,0):tmset(m%,320+x,3,0)
+300 tmset(m%,480+x,4,0)
+310 next
+320 tmdraw(m%,t%)
+330 get a$:if a$="" then 330
+340 gfxtext():print "phase4 tilemap done"
diff --git a/src/apps/readybasic/rbgfx25_mbcells.bas b/src/apps/readybasic/rbgfx25_mbcells.bas
new file mode 100644
index 0000000..1f206c4
--- /dev/null
+++ b/src/apps/readybasic/rbgfx25_mbcells.bas
@@ -0,0 +1,13 @@
+10 rem see graphics design md
+20 print chr$(147);"rbgfx25 mbitmap cells"
+30 gfxmode("mbitmap"):gfxclear(0):mcbg(0)
+40 fbox(8,16,31,47,17)
+50 fbox(40,16,63,47,34)
+60 fbox(72,16,95,47,51)
+70 mcell(2,2,6,10,2)
+80 mcell(10,2,4,12,7)
+90 mcell(18,2,1,14,5)
+100 line(4,120,150,170,49)
+110 rect(20,72,140,112,50)
+120 get a$:if a$="" then 120
+130 gfxtext():print "phase4 mbitmap cells done"
diff --git a/src/apps/readybasic/rbgfx26_mode_matrix.bas b/src/apps/readybasic/rbgfx26_mode_matrix.bas
new file mode 100644
index 0000000..7a39836
--- /dev/null
+++ b/src/apps/readybasic/rbgfx26_mode_matrix.bas
@@ -0,0 +1,24 @@
+10 rem see graphics design md
+20 print chr$(147);"rbgfx26 mode matrix"
+30 gfxmode("hires"):gfxclear(0)
+40 plot(20,20,1):line(4,36,300,180,1)
+50 rect(32,48,138,112,1):fbox(178,72,260,140,1)
+60 circle(82,150,28,1):pnt(20,20,a%)
+70 get a$:if a$="" then 70
+80 gfxmode("mbitmap"):gfxclear(0):mcbg(0)
+90 plot(20,20,17):line(4,36,155,180,34)
+100 rect(8,70,70,128,20):fbox(88,78,148,142,51)
+110 circle(48,150,24,49):pnt(20,20,b%)
+120 get a$:if a$="" then 120
+130 gfxmode("tile"):gfxclear(0)
+140 plot(4,4,5):line(1,1,38,20,6)
+150 rect(3,5,20,16,7):fbox(24,8,34,18,2)
+160 pnt(4,4,c%)
+170 get a$:if a$="" then 170
+180 gfxmode("mtile"):gfxclear(0)
+190 plot(4,4,9):line(1,22,38,2,10)
+200 rect(5,4,21,17,11):fbox(25,7,35,19,12)
+210 pnt(4,4,d%)
+220 get a$:if a$="" then 220
+230 gfxtext():print "matrix";a%;b%;c%;d%
+240 print "mode matrix done"
diff --git a/src/apps/readybasic/rbgfx27_target_blit.bas b/src/apps/readybasic/rbgfx27_target_blit.bas
new file mode 100644
index 0000000..a040ad5
--- /dev/null
+++ b/src/apps/readybasic/rbgfx27_target_blit.bas
@@ -0,0 +1,12 @@
+10 rem see graphics design md
+20 print chr$(147);"rbgfx27 target blit"
+30 h%=gfxsurf("hires")
+40 print "surf";h%;" err";errcode()
+50 gfxtgt(h%):print "target surf err";errcode()
+60 gfxsync():print "sync err";errcode()
+70 gfxblit(h%):print "blit err";errcode()
+80 gfxtgt(0):print "target visible err";errcode()
+90 gfxmode("hires"):gfxclear(0)
+100 line(0,0,319,199,1):rect(40,40,220,150,1)
+110 get a$:if a$="" then 110
+120 gfxtext():print "target blit done"
diff --git a/src/apps/readybasic/rbgfx28_tile_visible.bas b/src/apps/readybasic/rbgfx28_tile_visible.bas
new file mode 100644
index 0000000..4c518c6
--- /dev/null
+++ b/src/apps/readybasic/rbgfx28_tile_visible.bas
@@ -0,0 +1,9 @@
+10 rem see graphics design md
+20 print chr$(147);"rbgfx28 tile visible"
+30 gfxmode("tile"):gfxclear(0)
+40 plot(4,4,5):plot(5,4,6):plot(6,4,7)
+50 line(1,1,38,20,3)
+60 rect(3,5,20,16,10):fbox(24,8,34,18,12)
+70 pnt(4,4,a%)
+80 get a$:if a$="" then 80
+90 gfxtext():print "tile visible";a%
diff --git a/src/apps/readybasic/rbgfx29_mtile_visible.bas b/src/apps/readybasic/rbgfx29_mtile_visible.bas
new file mode 100644
index 0000000..d566a5a
--- /dev/null
+++ b/src/apps/readybasic/rbgfx29_mtile_visible.bas
@@ -0,0 +1,9 @@
+10 rem see graphics design md
+20 print chr$(147);"rbgfx29 mtile visible"
+30 gfxmode("mtile"):gfxclear(0)
+40 plot(4,4,9):plot(5,4,10):plot(6,4,11)
+50 line(1,22,38,2,6)
+60 rect(5,4,21,17,13):fbox(25,7,35,19,15)
+70 pnt(4,4,a%)
+80 get a$:if a$="" then 80
+90 gfxtext():print "mtile visible";a%
diff --git a/src/apps/readybasic/rbgfx30_mbitmap_dlist.bas b/src/apps/readybasic/rbgfx30_mbitmap_dlist.bas
new file mode 100644
index 0000000..95138bf
--- /dev/null
+++ b/src/apps/readybasic/rbgfx30_mbitmap_dlist.bas
@@ -0,0 +1,11 @@
+10 rem see graphics design md
+20 print chr$(147);"rbgfx30 mbitmap dlist"
+30 gfxmode("mbitmap"):gfxclear(0):mcbg(0)
+40 dlmake(12,h%)
+50 dlplot(h%,20,28,17)
+60 dlline(h%,4,38,155,66)
+70 dlrect(h%,12,82,72,144)
+80 dlfbox(h%,88,86,148,148)
+90 dldraw(h%)
+100 get a$:if a$="" then 100
+110 gfxtext():print "mbitmap dlist done"
diff --git a/src/apps/readybasic/rbgfx31_sync_blit.bas b/src/apps/readybasic/rbgfx31_sync_blit.bas
new file mode 100644
index 0000000..6d4218a
--- /dev/null
+++ b/src/apps/readybasic/rbgfx31_sync_blit.bas
@@ -0,0 +1,12 @@
+10 rem see graphics design md
+20 print chr$(147);"rbgfx31 sync blit"
+30 gfxmode("hires"):gfxclear(0)
+40 line(0,0,319,199,1):rect(42,38,220,150,1)
+50 h%=gfxsurf("hires")
+60 gfxtgt(h%):gfxsync():gfxtgt(0)
+70 get a$:if a$="" then 70
+80 gfxclear(0)
+90 get a$:if a$="" then 90
+100 gfxblit(h%)
+110 get a$:if a$="" then 110
+120 gfxtext():print "sync blit done";errcode()
diff --git a/src/apps/readybasic/rbgfx32_convex_poly.bas b/src/apps/readybasic/rbgfx32_convex_poly.bas
new file mode 100644
index 0000000..59b574a
--- /dev/null
+++ b/src/apps/readybasic/rbgfx32_convex_poly.bas
@@ -0,0 +1,14 @@
+10 rem see graphics design md
+20 print chr$(147);"rbgfx32 convex poly"
+30 gfxmode("hires"):gfxclear(0)
+40 dim a%(7)
+50 a%(0)=32:a%(1)=32:a%(2)=146:a%(3)=24
+60 a%(4)=184:a%(5)=120:a%(6)=64:a%(7)=170
+70 poly(a%(0),4,1)
+80 dim b%(9)
+90 b%(0)=196:b%(1)=36:b%(2)=278:b%(3)=58
+100 b%(4)=292:b%(5)=132:b%(6)=238:b%(7)=178
+110 b%(8)=178:b%(9)=108
+120 fpoly(b%(0),5,1)
+130 get a$:if a$="" then 130
+140 gfxtext():print "convex poly done"
diff --git a/src/apps/readybasic/rbsnd01_sid_basics.bas b/src/apps/readybasic/rbsnd01_sid_basics.bas
new file mode 100644
index 0000000..c355e2f
--- /dev/null
+++ b/src/apps/readybasic/rbsnd01_sid_basics.bas
@@ -0,0 +1,15 @@
+10 rem readybasic sound design: sound design md
+20 print chr$(147);"rbsnd01 sid basics"
+30 print "you should hear triangle, saw, pulse,"
+40 print "then noise. each tone is separate."
+50 sidrst():vol(15):adsr(1,0,5,12,3)
+60 print:print "triangle tone"
+70 sound(1,4455,45,16):zpause(20)
+80 print "saw tone"
+90 sound(1,4455,45,32):zpause(20)
+100 print "pulse tone"
+110 pulse(1,2048):sound(1,4455,45,64):zpause(20)
+120 print "noise burst"
+130 sound(1,4455,45,128):zpause(20)
+140 sidoff()
+150 print:print "rbsnd01 done"
diff --git a/src/apps/readybasic/rbsnd02_voice_state.bas b/src/apps/readybasic/rbsnd02_voice_state.bas
new file mode 100644
index 0000000..dd2deda
--- /dev/null
+++ b/src/apps/readybasic/rbsnd02_voice_state.bas
@@ -0,0 +1,14 @@
+10 rem readybasic sound design: sound design md
+20 print chr$(147);"rbsnd02 voice state"
+30 print "manual sid voice setup."
+40 print "listen for a pulse pitch, then changed"
+50 print "pulse width and envelope."
+60 sidrst():vol(15)
+70 print:print "wide pulse, soft release"
+80 adsr(1,0,9,12,6):pulse(1,3072):frq(1,4455)
+90 wave(1,64):gate(1,1):zpause(70):gate(1,0):zpause(50)
+100 print "narrow pulse, snappier release"
+110 adsr(1,0,3,15,2):pulse(1,512):frq(1,5612)
+120 wave(1,64):gate(1,1):zpause(70):gate(1,0):zpause(50)
+130 sidoff()
+140 print:print "rbsnd02 done"
diff --git a/src/apps/readybasic/rbsnd03_notes.bas b/src/apps/readybasic/rbsnd03_notes.bas
new file mode 100644
index 0000000..1b78d9a
--- /dev/null
+++ b/src/apps/readybasic/rbsnd03_notes.bas
@@ -0,0 +1,12 @@
+10 rem readybasic sound design: sound design md
+20 print chr$(147);"rbsnd03 pitchs"
+30 print "chromatic pitch command."
+40 print "you should hear c through b, then c"
+50 print "one octave higher."
+60 sidrst():vol(15):adsr(1,0,5,12,3):wave(1,32)
+70 for n=0 to 11
+80 pitch(1,n,4):gate(1,1):zpause(22):gate(1,0):zpause(6)
+90 next n
+100 pitch(1,0,5):gate(1,1):zpause(45):gate(1,0)
+110 sidoff()
+120 print:print "rbsnd03 done"
diff --git a/src/apps/readybasic/rbsnd04_filter.bas b/src/apps/readybasic/rbsnd04_filter.bas
new file mode 100644
index 0000000..455177d
--- /dev/null
+++ b/src/apps/readybasic/rbsnd04_filter.bas
@@ -0,0 +1,15 @@
+10 rem readybasic sound design: sound design md
+20 print chr$(147);"rbsnd04 filter"
+30 print "saw wave through sid filter."
+40 print "listen for low-pass, band-pass,"
+50 print "then high-pass color changes."
+60 sidrst():vol(15):adsr(1,0,9,15,4)
+70 frq(1,2230):wave(1,33)
+80 print:print "low-pass sweep-ish steps"
+90 for c=150 to 950 step 200:filter(c,8,1,1):zpause(35):next c
+100 print "band-pass"
+110 filter(700,12,1,2):zpause(90)
+120 print "high-pass"
+130 filter(700,12,1,4):zpause(90)
+140 gate(1,0):sidoff()
+150 print:print "rbsnd04 done"
diff --git a/src/apps/readybasic/rbsnd05_voice_batch.bas b/src/apps/readybasic/rbsnd05_voice_batch.bas
new file mode 100644
index 0000000..d112c5e
--- /dev/null
+++ b/src/apps/readybasic/rbsnd05_voice_batch.bas
@@ -0,0 +1,14 @@
+10 rem readybasic sound design: sound design md
+20 print chr$(147);"rbsnd05 voice batch"
+30 print "voice uses packed sid envelope bytes:"
+40 print "voice(v,f,wave,ad,sr)."
+50 print "ad=$09 and sr=$c3 in decimal."
+60 sidrst():vol(15):pulse(1,2048)
+70 print:print "one batch command starts the voice"
+80 voice(1,4455,65,9,195):zpause(80)
+90 print "now raw ctrl turns gate off"
+100 wave(1,64):zpause(50)
+110 print "same voice, higher frquency"
+120 voice(1,6672,65,9,195):zpause(80)
+130 gate(1,0):sidoff()
+140 print:print "rbsnd05 done"
diff --git a/src/apps/readybasic/rbsnd06_three_voice.bas b/src/apps/readybasic/rbsnd06_three_voice.bas
new file mode 100644
index 0000000..a4f1a0b
--- /dev/null
+++ b/src/apps/readybasic/rbsnd06_three_voice.bas
@@ -0,0 +1,15 @@
+10 rem readybasic sound design: sound design md
+20 print chr$(147);"rbsnd06 three voice"
+30 print "three sid voices: c major, then"
+40 print "a lower pulse bass with a high saw."
+50 sidrst():vol(15)
+60 adsr(1,0,5,12,4):adsr(2,0,5,12,4):adsr(3,0,5,12,4)
+70 print:print "c major chord"
+80 pitch(1,0,4):pitch(2,4,4):pitch(3,7,4)
+90 wave(1,33):wave(2,33):wave(3,33):zpause(100)
+100 gate(1,0):gate(2,0):gate(3,0):zpause(45)
+110 print "pulse bass plus high saw"
+120 pulse(1,1536):pitch(1,7,2):pitch(2,2,5)
+130 wave(1,65):wave(2,33):zpause(110)
+140 gate(1,0):gate(2,0):sidoff()
+150 print:print "rbsnd06 done"
diff --git a/src/apps/readybasic/readyBASICrefactorguidelines.md b/src/apps/readybasic/readyBASICrefactorguidelines.md
index 6c8fc40..7780b2f 100644
--- a/src/apps/readybasic/readyBASICrefactorguidelines.md
+++ b/src/apps/readybasic/readyBASICrefactorguidelines.md
@@ -49,7 +49,7 @@ BASIC workspace. Treat these as hard boundaries:
| Range | Contract |
| --- | --- |
-| `$1000-$C5FF` | ReadyOS app working region. REU app save/restore targets this span. |
+| `$1000-$C5FF` | ReadyOS app working region. REU app save/restore targets this `$B600` span. |
| `$1000-$11FF` | ReadyBASIC entry/cold-warm handoff area. Keep small. |
| `$1200-$2AC0` | ReadyBASIC resident code plus sentinel. Visible resident code owns BASIC-facing parser and commit work. |
| `$2AC1-$9FFF` | User BASIC program, variables, arrays, strings, and reclaimed cold-load seed space. Must remain the steady-state BASIC workspace. |
@@ -59,8 +59,8 @@ BASIC workspace. Treat these as hard boundaries:
| `$B800-$BFFF` | Submodule slot 2 and overlay target. |
| `$C000-$C1FF` | ReadyBASIC bridge/state. Keep persistent control state here only when it is part of the defined bridge contract. |
| `$C200-$C5FF` | Shared frames and buffers, including call/result frames and the `$C500` disk-module page buffer. |
-| `$C600-$C7FF` | ReadyOS REU metadata. Do not use as ReadyBASIC scratch. |
-| `$C800-$C9FF` | ReadyOS shim ABI. Do not place ReadyBASIC assumptions here unless intentionally using the shim ABI. |
+| `$C600-$C7FF` | Reserved resident ReadyOS shim expansion capacity. This is not ReadyBASIC or app RAM. |
+| `$C800-$C9FF` | ReadyOS shim ABI. Together with the lower reserve, the shim owns `$C600-$C9FF`; do not place ReadyBASIC assumptions there unless intentionally using the ABI. |
Cold-load seed bytes may appear inside what later becomes the BASIC workspace.
After cold setup, those bytes must be considered gone from C64 RAM and copied to
@@ -69,10 +69,14 @@ REU. Warm resume must not reread seed tables from BASIC-owned memory.
## REU Contracts
ReadyBASIC uses launcher-assigned REU resource banks. The launcher marks those
-physical banks in `$C600-$C6FF` with `REU_RB_CORE` and `REU_RB_CODE`;
+physical banks in the ReadyOS bank-type table at `$B640` with `REU_RB_CORE` and `REU_RB_CODE`;
ReadyBASIC resolves the bank ids at startup and must not assume fixed `$44/$45`
addresses.
+`readybasic.s` and `cfg/ready_app_readybasic.cfg` form a coupled ca65/ld65
+load/run ABI. Do not substitute the generic app config; run
+`verify_readybasic_plugin.py` after changing either side.
+
| REU bank/area | Contract |
| --- | --- |
| Assigned core bank | Runtime metadata: command descriptors, registry data, handles, snapshots, state tables, and small persistent proof state. |
@@ -249,6 +253,12 @@ make bin/readybasic.prg readybasic-plugin-static-check
READYBASIC_SKIP_BUILD=1 READYBASIC_VISIBLE=0 make readybasic-vice-suites
```
+The aggregate contains all 26 official regular ReadyBASIC targets, including
+graphics/sprite/sound examples and the minimum-resume, screen/REU temporary,
+loaded-app, lifecycle, hotkey, cross-app, and full visual probes. Keep
+`READYBASIC_VICE_SCRIPTS` and the aggregate dependency list synchronized when
+adding a new official probe.
+
Important targeted probes:
- `build_support/vice_readybasic_repeat_label_probe.sh`
diff --git a/src/apps/readybasic/readybasic.s b/src/apps/readybasic/readybasic.s
index b2213a1..a3adca8 100644
--- a/src/apps/readybasic/readybasic.s
+++ b/src/apps/readybasic/readybasic.s
@@ -6,13 +6,23 @@
; Low command overlay: $A900-$BFFF, under BASIC ROM
; Shared call/result buffers: $C200-$C5FF
; BASIC workspace: $2AC1-$9FFF
-; Runtime zero page/stack snapshot: REU bank $44 offsets $0A00/$0B00
+; Runtime zero page/stack snapshot: loader-assigned core bank, $0A00/$0B00
; Hidden helper shadow: ReadyBASIC core REU bank offset $3000
; Bridge state/trampolines: $C000-$C1FF
+; $C600-$C9FF: resident ReadyOS shim area; public ABI remains at $C800
+;
+; BUILD CONTRACT: this source depends on ca65 plus the custom
+; cfg/ready_app_readybasic.cfg load/run layout. Its cold-load seed is a compact
+; $1000-$7FFF PRG whose bytes are relocated at startup into $A000-$C5FF and
+; loader-assigned REU resource banks. Do not build it with ready_app.cfg or
+; move a run segment without updating both the seed region and
+; build_support/verify_readybasic_plugin.py.
;
.setcpu "6502"
+ .export rb_hotkey_pending
+
; ---------------------------------------------------------------------------
; ROM/KERNAL entry points
; ---------------------------------------------------------------------------
@@ -69,6 +79,7 @@ CURLIN = $39
TXTPTR = $7A
DFLTN = $99
MSGFLG = $9D
+KBD_SCREEN_MODE = $D0
VARPNT = $47
SUBFLG = $10
DSCPTR = $64
@@ -77,9 +88,27 @@ FAC_EXP = $61
FAC_MANT1 = $62
FAC_MANT2 = $63
KEYD_COUNT = $00C6
+LSTX = $00C5
+SFDX = $00CB
+RPTFLG = $028A
+KOUNT = $028B
+DELAY = $028C
+SHFLAG = $028D
+LSTSHF = $028E
+KEYLOG_VEC = $028F
+KEYD_BUFFER = $0277
COLOR_CODE = $0286
KERNAL_MEMTOP = $0281
KERNAL_MEMBOT = $0283
+IMAIN_VEC = $0302
+KERNAL_CHRIN_VEC = $0324
+KERNAL_GETIN_VEC = $032A
+CIA1_PRA = $DC00
+CIA1_PRB = $DC01
+CIA1_DDRA = $DC02
+CIA1_DDRB = $DC03
+CIA2_PRA = $DD00
+CIA2_DDRA = $DD02
BASIC_START = $2AC1
BASIC_SENTINEL = BASIC_START - 1
@@ -95,11 +124,41 @@ CPU_PORT = $0001
SCREEN = $0400
COLOR_RAM = $D800
VIC_MEM = $D018
+VIC_CTRL1 = $D011
+VIC_CTRL2 = $D016
+VIC_SPR_X_MSB = $D010
+VIC_SPR_ENABLE = $D015
+VIC_SPR_EXP_Y = $D017
+VIC_SPR_PRIORITY= $D01B
+VIC_SPR_MCOLOR = $D01C
+VIC_SPR_EXP_X = $D01D
+VIC_SPR_COLL = $D01E
+VIC_BG_COLL = $D01F
+VIC_SPR_MCOLOR0 = $D025
+VIC_SPR_MCOLOR1 = $D026
+VIC_SPR_COLOR0 = $D027
VIC_BORDER = $D020
VIC_BG = $D021
+SID_BASE = $D400
+SID_V1_FREQ_LO = $D400
+SID_V1_FREQ_HI = $D401
+SID_V1_PW_LO = $D402
+SID_V1_PW_HI = $D403
+SID_V1_CTRL = $D404
+SID_V1_AD = $D405
+SID_V1_SR = $D406
+SID_FILTER_LO = $D415
+SID_FILTER_HI = $D416
+SID_FILTER_RES = $D417
+SID_MODE_VOL = $D418
SHIM_RETURN = $C80C
-SHIM_REU_BANK_SKIP = $C83B
+SHIM_SWITCH = $C80F
+SHIM_TARGET_BANK = $C820
+SHIM_CURRENT_BANK = $C834
+SHIM_READYOS_BANK = $C83B
+SHIM_LAUNCHER_FLAGS = $C83C
+SHIM_LAUNCHER_FLAG_SUPPRESS_STARTUP = $01
; Scratch pointers outside cc65's reserved zero-page runtime.
rb_ptr_lo = $FB
@@ -119,6 +178,18 @@ TOKEN_END = $80
TOKEN_REM = $8F
TOKEN_PLUS = $AA
TOKEN_EQUAL = $B2
+KEY_CTRL_B = 2
+KEY_F2 = 137
+KEY_F4 = 138
+KEY_MATRIX_B = $1C
+KEY_MATRIX_F1 = $04
+KEY_MATRIX_F3 = $05
+SHFLAG_SHIFT = $01
+SHFLAG_CTRL = $04
+JIFFY_LOW = $00A2
+RB_HOTKEY_RELEASE_TIMEOUT = 120
+APP_BANK_MIN = 1
+APP_BANK_MAX_PLUS_ONE = 65
RAM_UNDER_BASIC = $FD
RAM_UNDER_BASIC_KEEP_KERNAL = $FE
@@ -148,6 +219,12 @@ CF_NUM1_LO = RB_CF + $12
CF_NUM1_HI = RB_CF + $13
CF_NUM2_LO = RB_CF + $14
CF_NUM2_HI = RB_CF + $15
+CF_NUM3_LO = RB_CF + $16
+CF_NUM3_HI = RB_CF + $17
+CF_NUM4_LO = RB_CF + $18
+CF_NUM4_HI = RB_CF + $19
+CF_NUM5_LO = RB_CF + $1A
+CF_NUM5_HI = RB_CF + $1B
CF_FLOAT0 = RB_CF + $20
CF_FLOAT1 = RB_CF + $25
CF_FLOAT2 = RB_CF + $2A
@@ -169,6 +246,7 @@ RF_FLOAT = RB_RF + $08
RF_STR_LEN = RB_RF + $10
RF_STR_BUF = RB_RF + $20
RF_ARRAY_BUF = RB_RF + $80
+RF_RECT_BUF = RF_ARRAY_BUF + $20
RB_VAL_NONE = 0
RB_VAL_INT = 1
@@ -183,12 +261,22 @@ RB_OUT_ARRAYI = 3
RB_OUT_FLOAT = 4
RB_MODULE_SYSTEM = 1
+RB_MODULE_GFX = 3
+RB_MODULE_SID = 4
RB_SUBMOD_COMMON = 0
RB_SUBMOD_LEGACY_LOW = 1
RB_SUBMOD_PROOF_SLOT1 = 2
RB_SUBMOD_PROOF_SLOT2 = 3
RB_SUBMOD_PROOF_SPAN = 4
RB_SUBMOD_PROOF_OVERLAY = 5
+RB_SUBMOD_GFXCORE = 16
+RB_SUBMOD_GFXPRIM = 17
+RB_SUBMOD_GFXSPR = 18
+RB_SUBMOD_INPUTEV = 19
+RB_SUBMOD_GFXPOLY = 20
+RB_SUBMOD_GFXDL = 21
+RB_SUBMOD_GFXTILE = 22
+RB_SUBMOD_SIDCORE = 23
RB_SLOT_LEGACY_LOW = $01
RB_SLOT_PROOF_1 = $02
RB_SLOT_PROOF_2 = $04
@@ -198,9 +286,12 @@ RB_SLOT_INVALID = $FF
RB_REU_TYPE_CORE= 14
RB_REU_TYPE_CODE= 15
-RB_REU_ALLOC_TABLE = $C600
RB_REU_HEADER_OFF = $0000
-RB_REUCB_BANK_TYPE_OFF = $0100
+RB_REUCB_BANK_TYPE_OFF = $B640
+RB_REUCB_TOKEN_STATUS_OFF = $B840
+RB_REUCB_TOKEN_APP_OFF = $BE00
+RB_REUCB_APP_REG_OFF = $BA00
+RB_REUCB_APP_REG_COUNT = 64
RB_REU_DESC_OFF = $1000
RB_REU_SLOT_STATE_OFF = $2000
RB_REU_CALL_OFF = $0400
@@ -213,6 +304,12 @@ RB_REU_RUNTIME_STACK_OFF = $0B00
RB_REU_HIDDEN_SHADOW_OFF = $3000
RB_REU_COMMON_LIMIT= $4000
RB_REU_DATA_OFF = $4000
+RB_CODE_GFXSPR_OFF = $5000
+RB_CODE_INPUTEV_OFF= $5800
+RB_CODE_GFXPOLY_OFF= $6000
+RB_CODE_GFXDL_OFF = $6800
+RB_CODE_GFXTILE_OFF= $7000
+RB_CODE_SIDCORE_OFF= $7800
RB_CMD_DESC_SIZE = 32
RB_CMD_DESC_COUNT = 128
@@ -226,9 +323,35 @@ RB_HEAP_PAGES = 192
RB_HEAP_PAGE_BASE = >RB_REU_DATA_OFF
RB_HANDLE_TYPE_BUFFER = 1
RB_HANDLE_TYPE_SCREEN_TC = 2
+RB_HANDLE_TYPE_GFXSURF = 3
+RB_HANDLE_TYPE_POINTBUF = 4
+RB_HANDLE_TYPE_DLIST = 5
+RB_HANDLE_TYPE_CHARSET = 6
+RB_HANDLE_TYPE_TILESET = 7
+RB_HANDLE_TYPE_TILEMAP = 8
RB_SCREEN_BYTES = $03E8
RB_SCREEN_HANDLE_PAGES = 8
+RB_GFX_MODE_TEXT = 0
+RB_GFX_MODE_HIRES = 1
+RB_GFX_MODE_MBITMAP= 2
+RB_GFX_MODE_TILE = 3
+RB_GFX_MODE_MTILE = 4
+RB_GFX_SURF_PAGES = 40
+RB_GFX_SCREEN = $CC00
+RB_GFX_SPRITES = $CA00
+RB_GFX_BITMAP = $E000
+RB_GFX_COLOR = $D800
+RB_GFX_SPR_PTRS = $CFF8
+RB_GFX_VICMEM = $38
+RB_GFX_TARGET_HANDLE = $C4F0
+RB_GFX_TARGET_BANK = $C4F1
+RB_GFX_TARGET_PAGE = $C4F2
+RB_GFX_TARGET_PAGES = $C4F3
+RB_GFX_MODE_STATE = $C4F4
+RB_DL_MAX_RECORDS = 31
+RB_DL_REC_SIZE = 8
+
SIG_ZECHO1 = 1
SIG_ZADD16 = 2
SIG_UPPER = 3
@@ -248,6 +371,13 @@ SIG_FADD = 16
SIG_ZPAUSE = SIG_BUFFREE
SIG_ERRCODE = 17
SIG_ERRLINE = 18
+SIG_GFXMODE = 19
+SIG_GFXSURF = 20
+SIG_PLOT = 21
+SIG_LINE = 22
+SIG_SPRSET = 23
+SIG_KEYNONE = 24
+SIG_POLY = 25
CMD_ZECHO1 = 1
CMD_ZADD16 = 2
@@ -281,6 +411,82 @@ CMD_ZDM1 = 29
CMD_ZDM2S = 30
CMD_ZDOV1 = 31
CMD_ZDOV2 = 32
+CMD_GFXMODE = 33
+CMD_GFXTEXT = 34
+CMD_GFXCLEAR = 35
+CMD_GFXSURF = 36
+CMD_GFXTARGET = 37
+CMD_GFXBLIT = 38
+CMD_GFXSYNC = 39
+CMD_PLOT = 40
+CMD_POINT = 41
+CMD_LINE = 42
+CMD_RECT = 43
+CMD_FRECT = 44
+CMD_SPRSET = 45
+CMD_SPRMOVE = 46
+CMD_SPRCOLOR = 47
+CMD_SPRSCAN = 48
+CMD_SPRCOLL = 49
+CMD_JOY = 50
+CMD_KEYP = 51
+CMD_KEYSCAN = 52
+CMD_KEYLAST = 53
+CMD_PNT = 54
+CMD_SPRROW = 55
+CMD_CIRCLE = 56
+CMD_FCIRCLE = 57
+CMD_TILE = 58
+CMD_CHARAT = 59
+CMD_SPREXPAND = 60
+CMD_SPRPRI = 61
+CMD_SPRMULTI = 62
+CMD_SPRMCOLOR = 63
+CMD_SPRSIZE = 64
+CMD_SPRCOL = 65
+CMD_SPRMCLR = 66
+CMD_SPRMUL = 67
+CMD_SPRMCO = 68
+CMD_POLY = 69
+CMD_FPOLY = 70
+CMD_PBUFNEW = 71
+CMD_PBUFSET = 72
+CMD_PBUFFREE = 73
+CMD_POLYH = 74
+CMD_FPOLYH = 75
+CMD_DLNEW = 76
+CMD_DLCLR = 77
+CMD_DLPLOT = 78
+CMD_DLLINE = 79
+CMD_DLRECT = 80
+CMD_DLFRECT = 81
+CMD_DLDRAW = 82
+CMD_CHRNEW = 83
+CMD_CHRROW = 84
+CMD_CHRUSE = 85
+CMD_TSNEW = 86
+CMD_TSSET = 87
+CMD_TMNEW = 88
+CMD_TMSET = 89
+CMD_TMDRAW = 90
+CMD_MCELL = 91
+CMD_MCBG = 92
+CMD_SIDCLR = 93
+CMD_SILENCE = 94
+CMD_VOL = 95
+CMD_FREQ = 96
+CMD_NOTE = 97
+CMD_PULSE = 98
+CMD_ADSR = 99
+CMD_ENV = 100
+CMD_WAVE = 101
+CMD_GATE = 102
+CMD_CTRL = 103
+CMD_VOICE = 104
+CMD_FILTER = 105
+CMD_FILT = 106
+CMD_SOUND = 107
+CMD_SND = 108
; REU registers.
REU_CMD = $DF01
@@ -309,6 +515,10 @@ REU_LEN_HI = $DF08
.import __SPANPACK_LOAD__, __SPANPACK_RUN__, __SPANPACK_SIZE__
.import __OVL1PACK_LOAD__, __OVL1PACK_RUN__, __OVL1PACK_SIZE__
.import __OVL2PACK_LOAD__, __OVL2PACK_RUN__, __OVL2PACK_SIZE__
+ .import __OVL3PACK_LOAD__, __OVL3PACK_RUN__, __OVL3PACK_SIZE__
+ .import __OVL4PACK_LOAD__, __OVL4PACK_RUN__, __OVL4PACK_SIZE__
+ .import __OVL5PACK_LOAD__, __OVL5PACK_RUN__, __OVL5PACK_SIZE__
+ .import __OVL6PACK_LOAD__, __OVL6PACK_RUN__, __OVL6PACK_SIZE__
rb_entry_src = $FB
rb_entry_dst = $FD
@@ -427,6 +637,215 @@ rb_entry_magic: .byte 0
rb_entry_magic2:.byte 0
rb_entry_cpu: .byte 0
+ .segment "RESIDENT"
+
+rb_imain:
+ lda #1
+ sta rb_prompt_active
+ jmp (rb_orig_imain_lo)
+
+rb_chrin:
+ jsr rb_call_orig_chrin
+ php
+ pha
+ lda #0
+ lda rb_hotkey_pending
+ bne @dispatch
+ pla
+ plp
+ rts
+@dispatch:
+ pla
+ plp
+ lda #1
+ sta rb_hotkey_chrin_dispatch
+ jmp rb_dispatch_pending_hotkey
+
+rb_call_orig_chrin:
+ jmp (rb_orig_chrin_lo)
+
+ .segment "ENTRY"
+
+rb_queue_hotkey_line:
+ stx rb_hotkey_pending
+ lda #1
+ sta KEYD_COUNT
+ lda #13
+ sta KEYD_BUFFER
+ rts
+
+ .segment "RESIDENT"
+
+rb_clear_hotkey_input_state:
+ lda #0
+ sta rb_hotkey_pending
+ sta rb_prompt_active
+ sta KEYD_COUNT
+ ldx #9
+@keyd:
+ sta KEYD_BUFFER,x
+ dex
+ bpl @keyd
+ ldx #4
+@scan:
+ sta RPTFLG,x
+ dex
+ bpl @scan
+ sta KBD_SCREEN_MODE
+ lda #$40
+ sta LSTX
+ sta SFDX
+ jsr rb_scan_hotkey_matrix
+ sta rb_hotkey_suppress
+ rts
+
+ .segment "ENTRY"
+
+rb_scan_hotkey_matrix:
+ lda CIA1_PRA
+ pha
+ lda CIA1_DDRA
+ pha
+ lda CIA1_DDRB
+ pha
+ lda #$FF
+ sta CIA1_DDRA
+ lda #0
+ sta CIA1_DDRB
+ lda #$7F
+ sta CIA1_PRA
+ lda CIA1_PRB
+ and #$04
+ bne @function_keys
+ lda #$F7
+ sta CIA1_PRA
+ lda CIA1_PRB
+ and #$10
+ bne @function_keys
+ ldx #KEY_CTRL_B
+ jmp @restore
+@function_keys:
+ lda #$FD
+ sta CIA1_PRA
+ lda CIA1_PRB
+ and #$80
+ beq @shifted
+ lda #$BF
+ sta CIA1_PRA
+ lda CIA1_PRB
+ and #$10
+ bne @none
+@shifted:
+ lda #$FE
+ sta CIA1_PRA
+ lda CIA1_PRB
+ and #$10
+ beq @f2
+ lda CIA1_PRB
+ and #$20
+ beq @f4
+@none:
+ ldx #0
+ jmp @restore
+@f2:
+ ldx #KEY_F2
+ jmp @restore
+@f4:
+ ldx #KEY_F4
+@restore:
+ pla
+ sta CIA1_DDRB
+ pla
+ sta CIA1_DDRA
+ pla
+ sta CIA1_PRA
+ txa
+ rts
+
+rb_wait_hotkey_release:
+ lda CPU_PORT
+ pha
+ and #RAM_UNDER_BASIC_KEEP_KERNAL
+ sta CPU_PORT
+ cli
+ jsr hidden_wait_hotkey_release
+ pla
+ sta CPU_PORT
+ jmp rb_clear_hotkey_input_state
+
+ .segment "HIDDEN"
+
+hidden_wait_hotkey_release:
+ lda rb_hotkey_suppress
+ beq @done
+ sta rb_hotkey_release_key
+ lda JIFFY_LOW
+ sta rb_hotkey_release_start
+@wait:
+ jsr rb_scan_hotkey_matrix
+ cmp rb_hotkey_release_key
+ bne @done
+ lda JIFFY_LOW
+ sec
+ sbc rb_hotkey_release_start
+ cmp #RB_HOTKEY_RELEASE_TIMEOUT
+ bcc @wait
+@done:
+ rts
+
+ .segment "ENTRY"
+
+rb_dispatch_pending_hotkey:
+ lda rb_hotkey_pending
+ tax
+ lda #0
+ sta rb_hotkey_pending
+ stx rb_hotkey_suppress
+ txa
+ cmp #KEY_CTRL_B
+ beq @launcher
+ cmp #KEY_F2
+ beq @next
+ cmp #KEY_F4
+ beq @prev
+@done:
+ rts
+@launcher:
+ jsr rb_wait_hotkey_release
+ jmp rb_hotkey_return_ready
+@next:
+ jsr call_hidden_select_next_app
+ lda rb_found_kind
+ bne rb_hotkey_switch
+ jmp rb_hotkey_no_switch
+@prev:
+ jsr call_hidden_select_prev_app
+ lda rb_found_kind
+ bne rb_hotkey_switch
+rb_hotkey_no_switch:
+ jsr rb_wait_hotkey_release
+ lda rb_hotkey_chrin_dispatch
+ beq @no_switch_return
+ lda #0
+ sta rb_hotkey_chrin_dispatch
+ ldx #$F8
+ txs
+ cli
+ jmp BASIC_READY
+@no_switch_return:
+ rts
+rb_hotkey_switch:
+ lda rb_tmp_lo
+ sta rb_hotkey_target_bank
+ jsr rb_wait_hotkey_release
+ jsr rb_prepare_ready_resume
+ jsr prepare_shim_yield
+ lda rb_hotkey_target_bank
+ sta SHIM_TARGET_BANK
+ jmp SHIM_SWITCH
+
+ .segment "RESIDENT"
+
.segment "PADLOW"
.res $0000, 0
@@ -458,6 +877,7 @@ rb_cold_start:
jsr install_basic_chrget
jsr init_basic_workspace
jsr install_vectors
+ jsr rb_clear_hotkey_input_state
lda #1
sta rb_seed_cold
jsr call_hidden_seed_plugin_reu
@@ -476,6 +896,7 @@ rb_cold_start:
rb_resume_ready:
jsr install_vectors
+ jsr rb_clear_hotkey_input_state
lda #0
sta rb_seed_cold
jsr call_hidden_seed_plugin_reu
@@ -488,6 +909,7 @@ rb_resume_ready:
rb_resume_running:
jsr install_vectors
+ jsr rb_clear_hotkey_input_state
lda #0
sta rb_seed_cold
jsr call_hidden_seed_plugin_reu
@@ -498,62 +920,18 @@ rb_resume_running:
cli
jmp restore_basic_runtime_state
-install_vectors:
- lda rb_vectors_saved
- bne @install
- lda $0304
- sta rb_orig_crunch_lo
- lda $0305
- sta rb_orig_crunch_hi
- lda $0306
- sta rb_orig_list_lo
- lda $0307
- sta rb_orig_list_hi
- lda $0308
- sta rb_orig_execute_lo
- lda $0309
- sta rb_orig_execute_hi
- lda #1
- sta rb_vectors_saved
-@install:
- lda #rb_crunch
- sta $0305
- lda #rb_execute
- sta $0309
- lda #rb_eval
- sta $030B
- rts
-
-restore_vectors:
- lda rb_vectors_saved
- beq @done
- lda rb_orig_crunch_lo
- sta $0304
- lda rb_orig_crunch_hi
- sta $0305
- lda rb_orig_list_lo
- sta $0306
- lda rb_orig_list_hi
- sta $0307
- lda rb_orig_execute_lo
- sta $0308
- lda rb_orig_execute_hi
- sta $0309
- lda #BASIC_EVAL
- sta $030B
-@done:
- rts
-
rb_execute:
+ lda #0
+ sta rb_prompt_active
+ lda rb_hotkey_pending
+ beq @peek
+ jmp rb_dispatch_pending_hotkey
+@peek:
jsr rb_peek_next_nonspace
+ tax
+@normal_tx:
+ txa
+@normal:
jsr rb_fold_a
cmp #'J'
beq @maybe_jump
@@ -581,8 +959,17 @@ rb_execute:
bcc rb_maybe_bare_command
jmp rb_label_statement
@maybe_proc:
+ lda rb_peek_lo
+ sta rb_ptr_lo
+ lda rb_peek_hi
+ sta rb_ptr_hi
+ ldy #1
+ lda (rb_ptr_lo),y
+ jsr rb_fold_a
+ cmp #'R'
+ bne rb_maybe_bare_command
jsr rb_match_proc
- bcc rb_call_orig_execute
+ bcc rb_maybe_bare_command
jmp BASIC_SYNERR
@maybe_func:
jsr rb_match_func
@@ -846,63 +1233,84 @@ rb_is_name_char:
cmd_exit:
lda TXTPTR+1
cmp #>BASIC_START
- bcs @running
+ bcs rb_exit_running
+rb_hotkey_return_ready:
lda #RB_RESUME_READY
sta RUNTIME_MODE
lda #RB_MAGIC_READY
- bne @store
-@running:
+ bne rb_exit_store_magic
+rb_exit_running:
lda #RB_RESUME_RUN
sta RUNTIME_MODE
lda #RB_MAGIC_RUN
-@store:
+rb_exit_store_magic:
sta rb_magic
sta rb_entry_magic
lda #RB_MAGIC2
sta rb_magic2
sta rb_entry_magic2
- jsr call_hidden_save_state
- jsr restore_vectors
- lda CPU_DDR
- ora #$07
- sta CPU_DDR
- lda CPU_PORT
- and #RAM_UNDER_BASIC_KEEP_KERNAL
- sta CPU_PORT
+ sei
+ jsr rb_clear_hotkey_input_state
+ lda SHIM_LAUNCHER_FLAGS
+ ora #SHIM_LAUNCHER_FLAG_SUPPRESS_STARTUP
+ sta SHIM_LAUNCHER_FLAGS
+ jsr prepare_shim_yield
jmp SHIM_RETURN
-call_hidden_save_state:
- php
- sei
- lda CPU_DDR
- ora #$07
- sta CPU_DDR
+ .segment "RESIDENT"
+
+prepare_shim_yield:
+ jsr call_hidden_save_state
+ lda rb_hotkey_chrin_dispatch
+ beq @stack_done
+ lda #0
+ sta rb_hotkey_chrin_dispatch
+ lda RUNTIME_MODE
+ cmp #RB_RESUME_READY
+ bne @stack_done
+ lda #$F8
+ sta RUNTIME_SP
+@stack_done:
+ jsr K_CLRCHN
lda CPU_PORT
- sta rb_saved_cpu
and #RAM_UNDER_BASIC_KEEP_KERNAL
sta CPU_PORT
- jsr save_basic_runtime_state
- lda rb_saved_cpu
- sta CPU_PORT
- plp
+ jsr hidden_restore_vectors
rts
+call_hidden_save_state:
+ lda #save_basic_runtime_state
+ sta rb_lookup_slots
+ bne call_hidden_common
+
call_hidden_seed_plugin_reu:
+ lda #rb_seed_plugin_reu_hidden
+ sta rb_lookup_slots
+ bne call_hidden_common
+
+call_hidden_common:
php
sei
lda CPU_DDR
ora #$07
sta CPU_DDR
lda CPU_PORT
- sta rb_saved_cpu
+ sta rb_common_saved_cpu
and #RAM_UNDER_BASIC_KEEP_KERNAL
sta CPU_PORT
- jsr rb_seed_plugin_reu_hidden
- lda rb_saved_cpu
+ jsr call_hidden_jmp
+ lda rb_common_saved_cpu
sta CPU_PORT
plp
rts
+call_hidden_jmp:
+ jmp (rb_lookup_index)
+
restore_basic_runtime_state:
sei
lda CPU_DDR
@@ -1865,127 +2273,61 @@ rb_start_numeric_actual:
rts
rb_lookup_command:
- lda #RB_REU_DESC_OFF
- sta rb_reu_off_hi
- lda #0
+ lda #RB_PAGEBUF
- sta rb_reu_c64_hi
- lda rb_reu_core_bank
- sta rb_reu_bank
- lda #0
- sta rb_reu_len_lo
- lda #1
- sta rb_reu_len_hi
- jsr rb_reu_fetch
- lda #RB_PAGEBUF
- sta rb_ptr_hi
- lda #RB_CMD_DESC_PER_PAGE
+ lda #>hidden_lookup_command
sta rb_lookup_slots
-@slot:
- lda rb_lookup_index
- cmp #RB_CMD_DESC_COUNT
- bcc :+
- jmp @miss
-: ldy #15
- lda (rb_ptr_lo),y
- cmp rb_cmd_len
- bne @next
- ldy #0
-@cmp:
- cpy rb_cmd_len
- beq @match
- tya
- pha
- clc
- adc #16
- tay
- lda (rb_ptr_lo),y
- sta rb_lookup_char
- pla
- tay
- lda rb_lookup_char
- cmp RB_CMDBUF,y
- bne @next
- iny
- jmp @cmp
-@match:
- ldy #0
-@copy:
- lda (rb_ptr_lo),y
- sta RB_DESC_BUF,y
- iny
- cpy #RB_CMD_DESC_SIZE
- bcc @copy
+ jsr call_hidden_common
+ lda rb_found_kind
+ beq @miss
sec
rts
-@next:
- clc
- lda rb_ptr_lo
- adc #RB_CMD_DESC_SIZE
- sta rb_ptr_lo
- bcc :+
- inc rb_ptr_hi
-: inc rb_lookup_index
- dec rb_lookup_slots
- bne @slot
- inc rb_reu_off_hi
- jmp @page
@miss:
clc
rts
rb_parse_by_signature:
lda RB_DESC_BUF+14
- cmp #SIG_ZECHO1
- beq parse_sig_zecho1
- cmp #SIG_ZADD16
- beq parse_sig_zadd16
- cmp #SIG_UPPER
- beq parse_sig_string_out
- cmp #SIG_LOWER
- beq parse_sig_string_out
- cmp #SIG_ZHIDDENRAM
- beq parse_sig_zhiddenram
- cmp #SIG_ZSUMNUMARRAY
- beq parse_sig_zsumnumarray
- cmp #SIG_ZRANGENUMARRAY
- beq parse_sig_zrangenumarray
- cmp #SIG_BUFNEW
- beq parse_sig_bufnew
- cmp #SIG_BUFFILL
- beq parse_sig_buffill
- cmp #SIG_BUFFREE
- beq parse_sig_buffree
- cmp #SIG_ZTEMPSCRATCH
- beq parse_sig_ztempscratch
- cmp #SIG_ZFAIL
- beq parse_sig_zfail
- cmp #SIG_FREEMEM
- beq parse_sig_freemem
- cmp #SIG_SCRCAP
- beq parse_sig_scrcap
- cmp #SIG_SCRPUT
- beq parse_sig_scrput
- cmp #SIG_FADD
- beq parse_sig_fadd
- cmp #SIG_ERRCODE
- beq parse_sig_errcode
- cmp #SIG_ERRLINE
- beq parse_sig_errline
+ beq @bad
+ cmp #SIG_POLY + 1
+ bcs @bad
+ asl
+ tax
+ lda rb_parse_sig_table-2,x
+ sta rb_ptr_lo
+ lda rb_parse_sig_table-1,x
+ sta rb_ptr_hi
+ jmp (rb_ptr_lo)
+@bad:
jmp BASIC_SYNERR
+rb_parse_sig_table:
+ .word parse_sig_zecho1
+ .word parse_sig_zadd16
+ .word parse_sig_string_out
+ .word parse_sig_string_out
+ .word parse_sig_zhiddenram
+ .word parse_sig_zsumnumarray
+ .word parse_sig_zrangenumarray
+ .word parse_sig_bufnew
+ .word parse_sig_buffill
+ .word rb_parse_num0
+ .word parse_sig_bufnew
+ .word parse_sig_zfail
+ .word parse_sig_no_args
+ .word rb_parse_out_int_current
+ .word rb_parse_num0
+ .word parse_sig_fadd
+ .word parse_sig_errcode
+ .word parse_sig_errline
+ .word parse_sig_gfxmode
+ .word parse_sig_gfxsurf
+ .word parse_sig_num3
+ .word parse_sig_num5
+ .word parse_sig_sprset
+ .word parse_sig_no_args
+ .word parse_sig_poly
+
parse_sig_zecho1:
jsr rb_parse_out_int_current
jmp rb_precompute_zecho1
@@ -2025,26 +2367,10 @@ parse_sig_buffill:
jsr rb_parse_num0
jmp rb_parse_num1
-parse_sig_buffree:
- jmp rb_parse_num0
-
-parse_sig_ztempscratch:
- jsr rb_parse_num0
- jmp rb_parse_out_int
-
parse_sig_zfail:
jsr rb_parse_num0
jmp rb_parse_out_int
-parse_sig_freemem:
- jmp rb_parse_no_args
-
-parse_sig_scrcap:
- jmp rb_parse_out_int_current
-
-parse_sig_scrput:
- jmp rb_parse_num0
-
parse_sig_fadd:
jsr rb_parse_float0
jsr rb_parse_float1
@@ -2059,6 +2385,50 @@ parse_sig_errline:
jsr rb_parse_out_int_current
jmp rb_precompute_errline
+parse_sig_no_args:
+ jmp rb_parse_no_args
+
+parse_sig_num3:
+ jsr rb_parse_num0
+ jsr rb_parse_num1
+ jmp rb_parse_num2
+
+parse_sig_num5:
+ jsr rb_parse_num0
+ jsr rb_parse_num1
+ jsr rb_parse_num2
+ jsr rb_parse_num3
+ jmp rb_parse_num4
+
+parse_sig_sprset:
+ jsr rb_parse_num0
+ jsr rb_parse_num1
+ jsr rb_parse_num2
+ jmp rb_parse_num3
+
+parse_sig_gfxmode:
+ jsr rb_skip_spaces
+ cmp #')'
+ beq :+
+ jsr rb_parse_string_value_current
+: rts
+
+parse_sig_gfxsurf:
+ jsr rb_parse_string_value_current
+ jsr rb_skip_spaces
+ cmp #')'
+ beq :+
+ jsr rb_parse_out_int
+: rts
+
+parse_sig_poly:
+ lda #0
+ sta CF_COUNT0_HI
+ jsr rb_parse_int_array_arg
+ jsr rb_resolve_int_array_input_ptr
+ jsr rb_parse_num1
+ jmp rb_parse_num2
+
rb_parse_no_args:
jsr rb_skip_spaces
cmp #0
@@ -2071,6 +2441,94 @@ rb_parse_no_args:
@ok:
rts
+ .segment "HIDDEN"
+
+hidden_lookup_command:
+ lda #RB_REU_DESC_OFF
+ sta rb_reu_off_hi
+ lda #0
+ sta rb_lookup_index
+@page:
+ lda rb_lookup_index
+ cmp #RB_CMD_DESC_COUNT
+ bcc :+
+ jmp @miss
+: lda #RB_PAGEBUF
+ sta rb_reu_c64_hi
+ lda rb_reu_core_bank
+ sta rb_reu_bank
+ lda #0
+ sta rb_reu_len_lo
+ lda #1
+ sta rb_reu_len_hi
+ jsr rb_reu_fetch
+ lda #RB_PAGEBUF
+ sta rb_ptr_hi
+ lda #RB_CMD_DESC_PER_PAGE
+ sta rb_lookup_slots
+@slot:
+ lda rb_lookup_index
+ cmp #RB_CMD_DESC_COUNT
+ bcc :+
+ jmp @miss
+: ldy #15
+ lda (rb_ptr_lo),y
+ cmp rb_cmd_len
+ bne @next
+ ldy #0
+@cmp:
+ cpy rb_cmd_len
+ beq @match
+ tya
+ pha
+ clc
+ adc #16
+ tay
+ lda (rb_ptr_lo),y
+ sta rb_lookup_char
+ pla
+ tay
+ lda rb_lookup_char
+ cmp RB_CMDBUF,y
+ bne @next
+ iny
+ jmp @cmp
+@match:
+ ldy #0
+@copy:
+ lda (rb_ptr_lo),y
+ sta RB_DESC_BUF,y
+ iny
+ cpy #RB_CMD_DESC_SIZE
+ bcc @copy
+ lda #1
+ sta rb_found_kind
+ rts
+@next:
+ clc
+ lda rb_ptr_lo
+ adc #RB_CMD_DESC_SIZE
+ sta rb_ptr_lo
+ bcc :+
+ inc rb_ptr_hi
+: inc rb_lookup_index
+ dec rb_lookup_slots
+ bne @slot
+ inc rb_reu_off_hi
+ jmp @page
+@miss:
+ lda #0
+ sta rb_found_kind
+ rts
+
+ .segment "RESIDENT"
+
rb_precompute_zecho1:
lda #0
sta RF_STATUS
@@ -2117,6 +2575,15 @@ rb_parse_num1:
bne rb_parse_num_to_slot
rb_parse_num2:
lda #CF_NUM2_LO-RB_CF
+ bne rb_parse_num_to_slot
+rb_parse_num3:
+ lda #CF_NUM3_LO-RB_CF
+ bne rb_parse_num_to_slot
+rb_parse_num4:
+ lda #CF_NUM4_LO-RB_CF
+ bne rb_parse_num_to_slot
+rb_parse_num5:
+ lda #CF_NUM5_LO-RB_CF
rb_parse_num_to_slot:
sta rb_target_off
jsr rb_parse_arg_sep
@@ -2309,7 +2776,7 @@ rb_parse_out_int_array:
inc CF_PARAM_COUNT
rts
-rb_parse_int_array_input:
+rb_parse_int_array_arg:
jsr rb_parse_arg_sep
lda #0
sta SUBFLG
@@ -2330,6 +2797,10 @@ rb_parse_int_array_input:
sbc ARYTAB+1
sta CF_PTR0_HI
inc CF_PARAM_COUNT
+ rts
+
+rb_parse_int_array_input:
+ jsr rb_parse_int_array_arg
jsr rb_parse_num2
lda CF_NUM2_LO
sta CF_COUNT0_LO
@@ -3142,6 +3613,10 @@ rb_parse_expr_signature:
beq parse_expr_int_string
cmp #SIG_BUFNEW
beq parse_expr_num0
+ cmp #SIG_BUFFILL
+ beq parse_expr_num2
+ cmp #SIG_BUFFREE
+ beq parse_expr_num0
cmp #SIG_ZTEMPSCRATCH
beq parse_expr_num0
cmp #SIG_SCRCAP
@@ -3154,6 +3629,12 @@ rb_parse_expr_signature:
beq parse_expr_errcode
cmp #SIG_ERRLINE
beq parse_expr_errline
+ cmp #SIG_GFXMODE
+ beq parse_expr_gfxmode
+ cmp #SIG_GFXSURF
+ beq parse_expr_gfxsurf
+ cmp #SIG_KEYNONE
+ beq parse_expr_no_args
jmp BASIC_SYNERR
parse_expr_no_args:
@@ -3182,6 +3663,20 @@ parse_expr_errline:
parse_expr_num0:
jmp rb_parse_num0
+parse_expr_num2:
+ jsr rb_parse_num0
+ jmp rb_parse_num1
+
+parse_expr_gfxmode:
+ jsr rb_skip_spaces
+ cmp #')'
+ beq :+
+ jsr rb_parse_string_value_current
+: rts
+
+parse_expr_gfxsurf:
+ jmp rb_parse_string_value_current
+
parse_expr_int_string:
jmp rb_parse_string_value
@@ -3377,7 +3872,7 @@ rb_call_underrom_payload:
sta CPU_DDR
lda CPU_PORT
sta rb_saved_cpu
- and #RAM_UNDER_BASIC_KEEP_KERNAL
+ lda #$36
sta CPU_PORT
jsr rb_hidden_overlay_jmp
lda rb_saved_cpu
@@ -3761,7 +4256,7 @@ rb_reu_header_end:
.macro CMD_OVL1 id, sig, label, name
.byte id, 2
- .word __OVL1PACK_LOAD__ - __LOWPACK_LOAD__
+ .word RB_CODE_GFXSPR_OFF
.word __OVL1PACK_SIZE__
.byte RB_SUBMOD_PROOF_OVERLAY
.byte 1
@@ -3776,7 +4271,7 @@ rb_reu_header_end:
.macro CMD_OVL2 id, sig, label, name
.byte id, 2
- .word __OVL2PACK_LOAD__ - __LOWPACK_LOAD__
+ .word RB_CODE_INPUTEV_OFF
.word __OVL2PACK_SIZE__
.byte RB_SUBMOD_PROOF_OVERLAY
.byte 2
@@ -3789,86 +4284,583 @@ rb_reu_header_end:
.res 16 - .strlen(name), 0
.endmacro
-rb_command_descriptors:
- CMD_LOW_ALL CMD_ZECHO1, SIG_ZECHO1, cmd_zecho1_low, "ZECHO1"
- CMD_LOW CMD_ZADD16, SIG_ZADD16, cmd_zadd16_low, cmd_zadd16_low_end, "ZADD16"
- CMD_LOW CMD_UPPER, SIG_UPPER, cmd_upper_low, cmd_upper_low_end, "UPPER"
- CMD_LOW CMD_LOWER, SIG_LOWER, cmd_lower_low, cmd_lower_low_end, "LOWER"
- CMD_HIDDEN CMD_ZHIDDENRAM, SIG_ZHIDDENRAM, cmd_zhiddenram_hidden, cmd_zhiddenram_hidden_end, "ZHIDDENRAM"
- CMD_LOW CMD_ZSUMNUMARRAY, SIG_ZSUMNUMARRAY, cmd_zsumnumarray_low, cmd_zsumnumarray_low_end, "ZSUMNUMARRAY"
- CMD_LOW CMD_ZRANGENUMARRAY, SIG_ZRANGENUMARRAY, cmd_zrangenumarray_low, cmd_zrangenumarray_low_end, "ZRANGENUMARRAY"
- CMD_LOW_ALL CMD_BUFNEW, SIG_BUFNEW, cmd_bufnew_low, "BUFNEW"
- CMD_LOW_ALL CMD_BUFFILL, SIG_BUFFILL, cmd_buffill_low, "BUFFILL"
- CMD_LOW_ALL CMD_BUFFREE, SIG_BUFFREE, cmd_buffree_low, "BUFFREE"
- CMD_LOW_ALL CMD_ZTEMPSCRATCH, SIG_ZTEMPSCRATCH, cmd_ztempscratch_low, "ZTEMPSCRATCH"
- CMD_LOW CMD_ZFAIL, SIG_ZFAIL, cmd_zfail_low, cmd_zfail_low_end, "ZFAIL"
- CMD_LOW CMD_FREEMEM, SIG_FREEMEM, cmd_freemem_low, cmd_freemem_low_end, "FREEMEM"
- CMD_LOW_ALL CMD_SCRCAP, SIG_SCRCAP, cmd_scrcap_low, "SCRCAP"
- CMD_LOW CMD_FADD, SIG_FADD, cmd_fadd_low, cmd_fadd_low_end, "FADD"
- CMD_LOW CMD_ZPAUSE, SIG_ZPAUSE, cmd_zpause_low, cmd_zpause_low_end, "ZPAUSE"
- CMD_LOW CMD_ERRCODE, SIG_ERRCODE, cmd_zecho1_low, cmd_zecho1_low_end, "ERRCODE"
- CMD_LOW CMD_ERRLINE, SIG_ERRLINE, cmd_zecho1_low, cmd_zecho1_low_end, "ERRLINE"
- CMD_LOW CMD_ZSLOT0, SIG_SCRCAP, cmd_zslot0_low, cmd_zslot0_low_end, "ZSLOT0"
- CMD_SLOT1 CMD_ZSLOT1, SIG_SCRCAP, cmd_zslot1, "ZSLOT1"
- CMD_SLOT2 CMD_ZSLOT2, SIG_SCRCAP, cmd_zslot2, "ZSLOT2"
- CMD_SPAN CMD_ZSPAN, SIG_SCRCAP, cmd_zspan, "ZSPAN"
- CMD_OVL1 CMD_ZOVL1, SIG_SCRCAP, cmd_zovl1, "ZOVL1"
- CMD_OVL2 CMD_ZOVL2, SIG_SCRCAP, cmd_zovl2, "ZOVL2"
- CMD_LOW CMD_ZCPYRST, SIG_SCRCAP, cmd_zcpyrst_low, cmd_zcpyrst_low_end, "ZCPYRST"
- CMD_LOW CMD_ZCOPY, SIG_SCRCAP, cmd_zcopy_low, cmd_zcopy_low_end, "ZCOPY"
- CMD_SLOT1 CMD_ZMODLOAD, SIG_ZHIDDENRAM, cmd_zmodload, "ZMODLD"
- .res (RB_CMD_DESC_COUNT - 28) * RB_CMD_DESC_SIZE, 0
- CMD_LOW_ALL CMD_SCRPUT, SIG_SCRPUT, cmd_scrput_low, "SCRPUT"
+.macro CMD_GFXCORE id, sig, label, name
+ .byte id, RB_MODULE_GFX
+ .word __SLOTPACK1_LOAD__ - __LOWPACK_LOAD__
+ .word __SLOTPACK1_SIZE__
+ .byte RB_SUBMOD_GFXCORE
+ .byte 0
+ .byte RB_SLOT_PROOF_1
+ .byte 1
+ .word 0
+ .word label - __SLOTPACK1_RUN__
+ .byte sig, .strlen(name)
+ .byte name
+ .res 16 - .strlen(name), 0
+.endmacro
-; ---------------------------------------------------------------------------
-; Hidden helper code, called by visible resident code with BASIC ROM hidden.
-; ---------------------------------------------------------------------------
+.macro CMD_GFXPRIM id, sig, label, name
+ .byte id, RB_MODULE_GFX
+ .word __SLOTPACK2_LOAD__ - __LOWPACK_LOAD__
+ .word __SLOTPACK2_SIZE__
+ .byte RB_SUBMOD_GFXPRIM
+ .byte 0
+ .byte RB_SLOT_PROOF_2
+ .byte 1
+ .word 0
+ .word label - __SLOTPACK2_RUN__
+ .byte sig, .strlen(name)
+ .byte name
+ .res 16 - .strlen(name), 0
+.endmacro
- .segment "HIDDEN"
+.macro CMD_GFXSPR id, sig, label, name
+ .byte id, RB_MODULE_GFX
+ .word RB_CODE_GFXSPR_OFF
+ .word __OVL1PACK_SIZE__
+ .byte RB_SUBMOD_GFXSPR
+ .byte 1
+ .byte RB_SLOT_PROOF_2
+ .byte 1
+ .word 0
+ .word label - __OVL1PACK_RUN__
+ .byte sig, .strlen(name)
+ .byte name
+ .res 16 - .strlen(name), 0
+.endmacro
-hidden_restore_basic_runtime_state:
- lda RUNTIME_MAGIC1
- cmp #RB_STATE_MAGIC1
- beq :+
- jmp @fallback
-:
- lda RUNTIME_MAGIC2
- cmp #RB_STATE_MAGIC2
- beq :+
- jmp @fallback
-:
- lda RUNTIME_LINE_OK
+.macro CMD_INPUTEV id, sig, label, name
+ .byte id, RB_MODULE_GFX
+ .word RB_CODE_INPUTEV_OFF
+ .word __OVL2PACK_SIZE__
+ .byte RB_SUBMOD_INPUTEV
+ .byte 2
+ .byte RB_SLOT_PROOF_2
+ .byte 1
+ .word 0
+ .word label - __OVL2PACK_RUN__
+ .byte sig, .strlen(name)
+ .byte name
+ .res 16 - .strlen(name), 0
+.endmacro
+
+.macro CMD_GFXPOLY id, sig, label, name
+ .byte id, RB_MODULE_GFX
+ .word RB_CODE_GFXPOLY_OFF
+ .word __OVL3PACK_SIZE__
+ .byte RB_SUBMOD_GFXPOLY
+ .byte 3
+ .byte RB_SLOT_PROOF_2
+ .byte 1
+ .word 0
+ .word label - __OVL3PACK_RUN__
+ .byte sig, .strlen(name)
+ .byte name
+ .res 16 - .strlen(name), 0
+.endmacro
+
+.macro CMD_GFXDL id, sig, label, name
+ .byte id, RB_MODULE_GFX
+ .word RB_CODE_GFXDL_OFF
+ .word __OVL4PACK_SIZE__
+ .byte RB_SUBMOD_GFXDL
+ .byte 4
+ .byte RB_SLOT_PROOF_2
+ .byte 1
+ .word 0
+ .word label - __OVL4PACK_RUN__
+ .byte sig, .strlen(name)
+ .byte name
+ .res 16 - .strlen(name), 0
+.endmacro
+
+.macro CMD_GFXTILE id, sig, label, name
+ .byte id, RB_MODULE_GFX
+ .word RB_CODE_GFXTILE_OFF
+ .word __OVL5PACK_SIZE__
+ .byte RB_SUBMOD_GFXTILE
+ .byte 5
+ .byte RB_SLOT_PROOF_2
+ .byte 1
+ .word 0
+ .word label - __OVL5PACK_RUN__
+ .byte sig, .strlen(name)
+ .byte name
+ .res 16 - .strlen(name), 0
+.endmacro
+
+.macro CMD_SIDCORE id, sig, label, name
+ .byte id, RB_MODULE_SID
+ .word RB_CODE_SIDCORE_OFF
+ .word __OVL6PACK_SIZE__
+ .byte RB_SUBMOD_SIDCORE
+ .byte 6
+ .byte RB_SLOT_PROOF_2
+ .byte 1
+ .word 0
+ .word label - __OVL6PACK_RUN__
+ .byte sig, .strlen(name)
+ .byte name
+ .res 16 - .strlen(name), 0
+.endmacro
+
+rb_command_descriptors:
+ CMD_LOW_ALL CMD_ZECHO1, SIG_ZECHO1, cmd_zecho1_low, "ZECHO1"
+ CMD_LOW CMD_ZADD16, SIG_ZADD16, cmd_zadd16_low, cmd_zadd16_low_end, "ZADD16"
+ CMD_LOW CMD_UPPER, SIG_UPPER, cmd_upper_low, cmd_upper_low_end, "UPPER"
+ CMD_LOW CMD_LOWER, SIG_LOWER, cmd_lower_low, cmd_lower_low_end, "LOWER"
+ CMD_HIDDEN CMD_ZHIDDENRAM, SIG_ZHIDDENRAM, cmd_zhiddenram_hidden, cmd_zhiddenram_hidden_end, "ZHIDDENRAM"
+ CMD_LOW CMD_ZSUMNUMARRAY, SIG_ZSUMNUMARRAY, cmd_zsumnumarray_low, cmd_zsumnumarray_low_end, "ZSUMNUMARRAY"
+ CMD_LOW CMD_ZRANGENUMARRAY, SIG_ZRANGENUMARRAY, cmd_zrangenumarray_low, cmd_zrangenumarray_low_end, "ZRANGENUMARRAY"
+ CMD_LOW_ALL CMD_BUFNEW, SIG_BUFNEW, cmd_bufnew_low, "BUFMAKE"
+ CMD_LOW_ALL CMD_BUFFILL, SIG_BUFFILL, cmd_buffill_low, "BUFFILL"
+ CMD_LOW_ALL CMD_BUFFREE, SIG_BUFFREE, cmd_buffree_low, "BUFDROP"
+ CMD_LOW_ALL CMD_ZTEMPSCRATCH, SIG_ZTEMPSCRATCH, cmd_ztempscratch_low, "ZTEMPSCRATCH"
+ CMD_LOW CMD_ZFAIL, SIG_ZFAIL, cmd_zfail_low, cmd_zfail_low_end, "ZFAIL"
+ CMD_LOW CMD_FREEMEM, SIG_FREEMEM, cmd_freemem_low, cmd_freemem_low_end, "MEMAVL"
+ CMD_LOW_ALL CMD_SCRCAP, SIG_SCRCAP, cmd_scrcap_low, "SCRCAP"
+ CMD_LOW CMD_FADD, SIG_FADD, cmd_fadd_low, cmd_fadd_low_end, "FADD"
+ CMD_LOW CMD_ZPAUSE, SIG_ZPAUSE, cmd_zpause_low, cmd_zpause_low_end, "ZPAUSE"
+ CMD_LOW CMD_ERRCODE, SIG_ERRCODE, cmd_zecho1_low, cmd_zecho1_low_end, "ERRCODE"
+ CMD_LOW CMD_ERRLINE, SIG_ERRLINE, cmd_zecho1_low, cmd_zecho1_low_end, "ERRLINE"
+ CMD_LOW CMD_ZSLOT0, SIG_SCRCAP, cmd_zslot0_low, cmd_zslot0_low_end, "ZSLOT0"
+ CMD_SLOT1 CMD_ZSLOT1, SIG_SCRCAP, cmd_zslot1, "ZSLOT1"
+ CMD_SLOT2 CMD_ZSLOT2, SIG_SCRCAP, cmd_zslot2, "ZSLOT2"
+ CMD_SPAN CMD_ZSPAN, SIG_SCRCAP, cmd_zspan, "ZSPAN"
+ CMD_OVL1 CMD_ZOVL1, SIG_SCRCAP, cmd_zovl1, "ZOVL1"
+ CMD_OVL2 CMD_ZOVL2, SIG_SCRCAP, cmd_zovl2, "ZOVL2"
+ CMD_LOW CMD_ZCPYRST, SIG_SCRCAP, cmd_zcpyrst_low, cmd_zcpyrst_low_end, "ZCPYRST"
+ CMD_LOW CMD_ZCOPY, SIG_SCRCAP, cmd_zcopy_low, cmd_zcopy_low_end, "ZCOPY"
+ CMD_SLOT1 CMD_ZMODLOAD, SIG_ZHIDDENRAM, cmd_zmodload, "ZMODLD"
+ CMD_GFXCORE CMD_GFXMODE, SIG_GFXMODE, cmd_gfxmode, "GFXMODE"
+ CMD_GFXCORE CMD_GFXTEXT, SIG_FREEMEM, cmd_gfxtext, "GFXTEXT"
+ CMD_GFXCORE CMD_GFXCLEAR, SIG_BUFFREE, cmd_gfxclear, "GFXCLEAR"
+ CMD_LOW_ALL CMD_GFXSURF, SIG_GFXSURF, cmd_gfxsurf_low, "GFXSURF"
+ CMD_LOW_ALL CMD_GFXTARGET, SIG_BUFFREE, cmd_gfxtarget_low, "GFXTGT"
+ CMD_LOW_ALL CMD_GFXBLIT, SIG_BUFFREE, cmd_gfxblit_low, "GFXBLIT"
+ CMD_GFXCORE CMD_GFXSYNC, SIG_FREEMEM, cmd_gfxsync, "GFXSYNC"
+ CMD_GFXPRIM CMD_PLOT, SIG_PLOT, cmd_plot, "PLOT"
+ CMD_GFXPRIM CMD_PNT, SIG_ZADD16, cmd_point, "PNT"
+ CMD_GFXPRIM CMD_LINE, SIG_LINE, cmd_line, "LINE"
+ CMD_GFXPRIM CMD_RECT, SIG_LINE, cmd_rect, "RECT"
+ CMD_GFXPRIM CMD_FRECT, SIG_LINE, cmd_frect, "FBOX"
+ CMD_GFXPRIM CMD_CIRCLE, SIG_SPRSET, cmd_circle, "CIRCLE"
+ CMD_GFXPRIM CMD_FCIRCLE, SIG_SPRSET, cmd_fcircle, "FCIRCLE"
+ CMD_GFXPRIM CMD_TILE, SIG_SPRSET, cmd_tile, "TILE"
+ CMD_GFXPRIM CMD_CHARAT, SIG_SPRSET, cmd_tile, "CHARAT"
+ CMD_GFXSPR CMD_SPRSET, SIG_SPRSET, cmd_sprset, "SPRSET"
+ CMD_GFXSPR CMD_SPRMOVE, SIG_PLOT, cmd_sprmove, "SPRMOVE"
+ CMD_GFXSPR CMD_SPRROW, SIG_LINE, cmd_sprrow, "SPRROW"
+ CMD_GFXSPR CMD_SPRSIZE, SIG_PLOT, cmd_sprexpand, "SPRSIZE"
+ CMD_GFXSPR CMD_SPRPRI, SIG_BUFFILL, cmd_sprpri, "SPRPRI"
+ CMD_GFXSPR CMD_SPRMUL, SIG_BUFFILL, cmd_sprmulti, "SPRMUL"
+ CMD_GFXSPR CMD_SPRCOL, SIG_BUFFILL, cmd_sprcolor, "SPRCOL"
+ CMD_GFXSPR CMD_SPRMCO, SIG_BUFFILL, cmd_sprmcolor, "SPRMCO"
+ CMD_GFXSPR CMD_SPRSCAN, SIG_FREEMEM, cmd_sprscan, "SPRSCAN"
+ CMD_GFXSPR CMD_SPRCOLL, SIG_ZFAIL, cmd_sprcoll, "SPRCOLL"
+ CMD_INPUTEV CMD_JOY, SIG_ZFAIL, cmd_joy, "JOY"
+ CMD_INPUTEV CMD_KEYP, SIG_SCRCAP, cmd_keyp, "KEYP"
+ CMD_INPUTEV CMD_KEYSCAN, SIG_KEYNONE, cmd_keyscan, "KEYSCAN"
+ CMD_INPUTEV CMD_KEYLAST, SIG_SCRCAP, cmd_keylast, "KEYLAST"
+ CMD_GFXPOLY CMD_POLY, SIG_POLY, cmd_poly, "POLY"
+ CMD_GFXPOLY CMD_FPOLY, SIG_POLY, cmd_fpoly, "FPOLY"
+ CMD_GFXPOLY CMD_PBUFNEW, SIG_BUFNEW, cmd_pbufnew, "PBMAKE"
+ CMD_GFXPOLY CMD_PBUFSET, SIG_SPRSET, cmd_pbufset, "PBUFSET"
+ CMD_GFXPOLY CMD_PBUFFREE, SIG_BUFFREE, cmd_pbuffree, "PBDROP"
+ CMD_GFXPOLY CMD_POLYH, SIG_PLOT, cmd_poly, "POLYH"
+ CMD_GFXPOLY CMD_FPOLYH, SIG_PLOT, cmd_fpoly, "FPOLYH"
+ CMD_GFXDL CMD_DLNEW, SIG_BUFNEW, cmd_dlnew, "DLMAKE"
+ CMD_GFXDL CMD_DLCLR, SIG_BUFFREE, cmd_dlclr, "DLRST"
+ CMD_GFXDL CMD_DLPLOT, SIG_SPRSET, cmd_dlplot, "DLPLOT"
+ CMD_GFXDL CMD_DLLINE, SIG_LINE, cmd_dlline, "DLLINE"
+ CMD_GFXDL CMD_DLRECT, SIG_LINE, cmd_dlrect, "DLRECT"
+ CMD_GFXDL CMD_DLFRECT, SIG_LINE, cmd_dlfrect, "DLFBOX"
+ CMD_GFXDL CMD_DLDRAW, SIG_BUFFREE, cmd_dldraw, "DLDRAW"
+ CMD_GFXTILE CMD_CHRNEW, SIG_BUFNEW, cmd_chrnew, "CHRMAKE"
+ CMD_GFXTILE CMD_CHRROW, SIG_SPRSET, cmd_chrrow, "CHRROW"
+ CMD_GFXTILE CMD_CHRUSE, SIG_BUFFREE, cmd_chruse, "CHRUSE"
+ CMD_GFXTILE CMD_TSNEW, SIG_BUFNEW, cmd_tsnew, "TSMAKE"
+ CMD_GFXTILE CMD_TSSET, SIG_SPRSET, cmd_tsset, "TSSET"
+ CMD_GFXTILE CMD_TMNEW, SIG_BUFNEW, cmd_tmnew, "TMMAKE"
+ CMD_GFXTILE CMD_TMSET, SIG_SPRSET, cmd_tmset, "TMSET"
+ CMD_GFXTILE CMD_TMDRAW, SIG_BUFFILL, cmd_tmdraw, "TMDRAW"
+ CMD_GFXTILE CMD_MCELL, SIG_LINE, cmd_mcell, "MCELL"
+ CMD_GFXTILE CMD_MCBG, SIG_BUFFREE, cmd_mcbg, "MCBG"
+ CMD_SIDCORE CMD_SIDCLR, SIG_KEYNONE, cmd_sidclr, "SIDRST"
+ CMD_SIDCORE CMD_SILENCE, SIG_KEYNONE, cmd_sidclr, "SIDOFF"
+ CMD_SIDCORE CMD_VOL, SIG_BUFFREE, cmd_vol, "VOL"
+ CMD_SIDCORE CMD_FREQ, SIG_BUFFILL, cmd_freq, "FRQ"
+ CMD_SIDCORE CMD_NOTE, SIG_PLOT, cmd_note, "PITCH"
+ CMD_SIDCORE CMD_PULSE, SIG_BUFFILL, cmd_pulse, "PULSE"
+ CMD_SIDCORE CMD_ADSR, SIG_LINE, cmd_adsr, "ADSR"
+ CMD_SIDCORE CMD_WAVE, SIG_BUFFILL, cmd_wave, "WAVE"
+ CMD_SIDCORE CMD_GATE, SIG_BUFFILL, cmd_gate, "GATE"
+ CMD_SIDCORE CMD_VOICE, SIG_LINE, cmd_voice, "VOICE"
+ CMD_SIDCORE CMD_FILTER, SIG_SPRSET, cmd_filter, "FILTER"
+ CMD_SIDCORE CMD_SOUND, SIG_SPRSET, cmd_sound, "SOUND"
+ .res (RB_CMD_DESC_COUNT - 94) * RB_CMD_DESC_SIZE, 0
+ CMD_LOW_ALL CMD_SCRPUT, SIG_SCRPUT, cmd_scrput_low, "SCRPUT"
+
+; ---------------------------------------------------------------------------
+; Hidden helper code, called by visible resident code with BASIC ROM hidden.
+; ---------------------------------------------------------------------------
+
+ .segment "HIDDEN"
+
+hidden_calc_basic_free:
+ sec
+ lda FRETOP
+ sbc STREND
+ sta rb_free_lo
+ lda FRETOP+1
+ sbc STREND+1
+ sta rb_free_hi
+ rts
+
+hidden_print_live_free:
+ jsr hidden_calc_basic_free
+ lda #0
+ sta rb_digit_seen
+ ldx #0
+@place:
+ lda #0
+ sta rb_digit_count
+@sub:
+ sec
+ lda rb_free_lo
+ sbc hidden_decimal_lo,x
+ sta rb_tmp_lo
+ lda rb_free_hi
+ sbc hidden_decimal_hi,x
+ bcc @emit
+ sta rb_free_hi
+ lda rb_tmp_lo
+ sta rb_free_lo
+ inc rb_digit_count
+ jmp @sub
+@emit:
+ lda rb_digit_count
+ bne @print
+ lda rb_digit_seen
+ bne @print
+ cpx #4
+ bne @next
+ lda #0
+@print:
+ ora #'0'
+ jsr K_CHROUT
+ lda #1
+ sta rb_digit_seen
+@next:
+ inx
+ cpx #5
+ bcc @place
+ rts
+
+hidden_decimal_lo:
+ .byte <10000,<1000,<100,<10,<1
+hidden_decimal_hi:
+ .byte >10000,>1000,>100,>10,>1
+
+hidden_prepare_ready_resume:
+ lda #RB_RESUME_READY
+ sta RUNTIME_MODE
+ lda #RB_MAGIC_READY
+ sta rb_magic
+ sta rb_entry_magic
+ lda #RB_MAGIC2
+ sta rb_magic2
+ sta rb_entry_magic2
+ rts
+
+hidden_install_vectors:
+ lda rb_vectors_saved
+ bne @install
+ lda IMAIN_VEC
+ sta rb_orig_imain_lo
+ lda IMAIN_VEC+1
+ sta rb_orig_imain_hi
+ lda $0304
+ sta rb_orig_crunch_lo
+ lda $0305
+ sta rb_orig_crunch_hi
+ lda $0306
+ sta rb_orig_list_lo
+ lda $0307
+ sta rb_orig_list_hi
+ lda KEYLOG_VEC
+ sta rb_orig_keylog_lo
+ lda KEYLOG_VEC+1
+ sta rb_orig_keylog_hi
+ lda $0308
+ sta rb_orig_execute_lo
+ lda $0309
+ sta rb_orig_execute_hi
+ lda KERNAL_CHRIN_VEC
+ sta rb_orig_chrin_lo
+ lda KERNAL_CHRIN_VEC+1
+ sta rb_orig_chrin_hi
+ lda #1
+ sta rb_vectors_saved
+@install:
+ lda #rb_imain
+ sta IMAIN_VEC+1
+ lda #rb_crunch
+ sta $0305
+ lda #rb_execute
+ sta $0309
+ lda #rb_eval
+ sta $030B
+ lda #rb_keylog
+ sta KEYLOG_VEC+1
+ lda #rb_chrin
+ sta KERNAL_CHRIN_VEC+1
+ rts
+
+hidden_select_next_app:
+ jsr hidden_normalize_current_bank
+ sta rb_saved_count_lo
+ sta rb_tmp_lo
+ lda #0
+ sta rb_digit_count
+@loop:
+ inc rb_tmp_lo
+ lda rb_tmp_lo
+ cmp #APP_BANK_MAX_PLUS_ONE
+ bcc :+
+ lda #APP_BANK_MIN
+ sta rb_tmp_lo
+: jsr hidden_bank_loaded
+ bcs @found
+ inc rb_digit_count
+ lda rb_digit_count
+ cmp #(APP_BANK_MAX_PLUS_ONE - APP_BANK_MIN)
+ bcc @loop
+ clc
+ rts
+@found:
+ sec
+ rts
+
+hidden_select_prev_app:
+ jsr hidden_normalize_current_bank
+ sta rb_saved_count_lo
+ sta rb_tmp_lo
+ lda #0
+ sta rb_digit_count
+@loop:
+ lda rb_tmp_lo
+ cmp #APP_BANK_MIN
bne :+
- jmp @fallback
-:
+ lda #APP_BANK_MAX_PLUS_ONE
+ sta rb_tmp_lo
+: dec rb_tmp_lo
+ jsr hidden_bank_loaded
+ bcs @found
+ inc rb_digit_count
+ lda rb_digit_count
+ cmp #(APP_BANK_MAX_PLUS_ONE - APP_BANK_MIN)
+ bcc @loop
+ clc
+ rts
+@found:
+ sec
+ rts
- lda #RUNTIME_STACK_BUF
- sta rb_reu_c64_hi
- lda #RB_REU_RUNTIME_STACK_OFF
+ lda #>RB_REUCB_TOKEN_STATUS_OFF
+ adc #0
sta rb_reu_off_hi
- lda rb_reu_core_bank
+ lda #rb_lookup_char
+ sta rb_reu_c64_hi
+ lda SHIM_READYOS_BANK
sta rb_reu_bank
- lda #0
- sta rb_reu_len_lo
lda #1
+ sta rb_reu_len_lo
+ lda #0
sta rb_reu_len_hi
jsr rb_reu_fetch
+ lda rb_lookup_char
+ and #$02 ; schema-v5 TOKEN_LOADED
+ beq @clear
+ lda rb_tmp_lo
+ cmp rb_saved_count_lo
+ beq @clear
+ sec
+ rts
+@clear:
+ clc
+ rts
- lda #RUNTIME_ZP_BUF
+ lda #>rb_lookup_char
sta rb_reu_c64_hi
- lda #RB_REU_RUNTIME_ZP_OFF
+ lda #>RB_REUCB_APP_REG_OFF
+ adc #0
sta rb_reu_off_hi
- lda rb_reu_core_bank
+ lda SHIM_READYOS_BANK
sta rb_reu_bank
- lda #0
+ lda #1
+ sta rb_reu_len_lo
+ lda #0
+ sta rb_reu_len_hi
+ jsr rb_reu_fetch
+ lda rb_lookup_char
+ cmp rb_hidden_next_lo
+ beq @found
+ inc rb_hidden_next_hi
+ lda rb_hidden_next_hi
+ cmp #RB_REUCB_APP_REG_COUNT
+ bcc @scan
+ clc
+ rts
+@found:
+ sec
+ rts
+.endif
+
+hidden_restore_vectors:
+ lda rb_vectors_saved
+ beq @done
+ lda rb_orig_imain_lo
+ sta IMAIN_VEC
+ lda rb_orig_imain_hi
+ sta IMAIN_VEC+1
+ lda rb_orig_crunch_lo
+ sta $0304
+ lda rb_orig_crunch_hi
+ sta $0305
+ lda rb_orig_list_lo
+ sta $0306
+ lda rb_orig_list_hi
+ sta $0307
+ lda rb_orig_keylog_lo
+ sta KEYLOG_VEC
+ lda rb_orig_keylog_hi
+ sta KEYLOG_VEC+1
+ lda rb_orig_execute_lo
+ sta $0308
+ lda rb_orig_execute_hi
+ sta $0309
+ lda #BASIC_EVAL
+ sta $030B
+ lda rb_orig_chrin_lo
+ sta KERNAL_CHRIN_VEC
+ lda rb_orig_chrin_hi
+ sta KERNAL_CHRIN_VEC+1
+@done:
+ rts
+
+hidden_restore_basic_runtime_state:
+ lda RUNTIME_MAGIC1
+ cmp #RB_STATE_MAGIC1
+ beq :+
+ jmp @fallback
+:
+ lda RUNTIME_MAGIC2
+ cmp #RB_STATE_MAGIC2
+ beq :+
+ jmp @fallback
+:
+ lda RUNTIME_LINE_OK
+ bne :+
+ jmp @fallback
+:
+
+ lda #RUNTIME_STACK_BUF
+ sta rb_reu_c64_hi
+ lda #RB_REU_RUNTIME_STACK_OFF
+ sta rb_reu_off_hi
+ lda rb_reu_core_bank
+ sta rb_reu_bank
+ lda #0
+ sta rb_reu_len_lo
+ lda #1
+ sta rb_reu_len_hi
+ jsr rb_reu_fetch
+
+ lda #RUNTIME_ZP_BUF
+ sta rb_reu_c64_hi
+ lda #RB_REU_RUNTIME_ZP_OFF
+ sta rb_reu_off_hi
+ lda rb_reu_core_bank
+ sta rb_reu_bank
+ lda #0
sta rb_reu_len_lo
lda #1
sta rb_reu_len_hi
@@ -4112,15 +5104,49 @@ rb_seed_plugin_reu_hidden:
sta rb_reu_off_hi
lda rb_reu_code_bank
sta rb_reu_bank
- lda #<((__OVL2PACK_LOAD__ - __LOWPACK_LOAD__) + __OVL2PACK_SIZE__)
+ lda #<((__SPANPACK_LOAD__ - __LOWPACK_LOAD__) + __SPANPACK_SIZE__)
+ sta rb_reu_len_lo
+ lda #>((__SPANPACK_LOAD__ - __LOWPACK_LOAD__) + __SPANPACK_SIZE__)
+ sta rb_reu_len_hi
+ jsr rb_reu_stash
+
+ ldx #0
+@stash_ovl:
+ lda rb_builtin_ovl_stash,x
+ sta rb_reu_c64_lo
+ lda rb_builtin_ovl_stash+1,x
+ sta rb_reu_c64_hi
+ lda rb_builtin_ovl_stash+2,x
+ sta rb_reu_off_lo
+ lda rb_builtin_ovl_stash+3,x
+ sta rb_reu_off_hi
+ lda rb_builtin_ovl_stash+4,x
sta rb_reu_len_lo
- lda #>((__OVL2PACK_LOAD__ - __LOWPACK_LOAD__) + __OVL2PACK_SIZE__)
+ lda rb_builtin_ovl_stash+5,x
sta rb_reu_len_hi
+ txa
+ pha
+ lda rb_reu_code_bank
+ sta rb_reu_bank
jsr rb_reu_stash
+ pla
+ clc
+ adc #6
+ tax
+ cpx #36
+ bcc @stash_ovl
jsr rb_clear_slot_residency
jmp rb_clear_handle_heap
+rb_builtin_ovl_stash:
+ .byte <__OVL1PACK_LOAD__, >__OVL1PACK_LOAD__, RB_CODE_GFXSPR_OFF, <__OVL1PACK_SIZE__, >__OVL1PACK_SIZE__
+ .byte <__OVL2PACK_LOAD__, >__OVL2PACK_LOAD__, RB_CODE_INPUTEV_OFF, <__OVL2PACK_SIZE__, >__OVL2PACK_SIZE__
+ .byte <__OVL3PACK_LOAD__, >__OVL3PACK_LOAD__, RB_CODE_GFXPOLY_OFF, <__OVL3PACK_SIZE__, >__OVL3PACK_SIZE__
+ .byte <__OVL4PACK_LOAD__, >__OVL4PACK_LOAD__, RB_CODE_GFXDL_OFF, <__OVL4PACK_SIZE__, >__OVL4PACK_SIZE__
+ .byte <__OVL5PACK_LOAD__, >__OVL5PACK_LOAD__, RB_CODE_GFXTILE_OFF, <__OVL5PACK_SIZE__, >__OVL5PACK_SIZE__
+ .byte <__OVL6PACK_LOAD__, >__OVL6PACK_LOAD__, RB_CODE_SIDCORE_OFF, <__OVL6PACK_SIZE__, >__OVL6PACK_SIZE__
+
rb_clear_slot_residency:
lda #0
sta rb_slot0_cmd
@@ -4132,43 +5158,34 @@ rb_mark_reu_banks_hidden:
ldx rb_reu_core_bank
beq :+
lda #RB_REU_TYPE_CORE
- sta RB_REU_ALLOC_TABLE,x
+ sta RB_PAGEBUF,x
:
ldx rb_reu_code_bank
beq :+
lda #RB_REU_TYPE_CODE
- sta RB_REU_ALLOC_TABLE,x
+ sta RB_PAGEBUF,x
:
+ lda #RB_PAGEBUF
+ sta rb_reu_c64_hi
+ lda #RB_REUCB_BANK_TYPE_OFF
+ sta rb_reu_off_hi
+ lda SHIM_READYOS_BANK
+ sta rb_reu_bank
+ lda #0
+ sta rb_reu_len_lo
+ lda #1
+ sta rb_reu_len_hi
+ jsr rb_reu_stash
rts
rb_resolve_reu_banks_hidden:
lda #0
sta rb_reu_core_bank
sta rb_reu_code_bank
- tax
-@scan:
- lda RB_REU_ALLOC_TABLE,x
- cmp #RB_REU_TYPE_CORE
- bne @check_code
- lda rb_reu_core_bank
- bne @next
- stx rb_reu_core_bank
- jmp @next
-@check_code:
- cmp #RB_REU_TYPE_CODE
- bne @next
- lda rb_reu_code_bank
- bne @next
- stx rb_reu_code_bank
-@next:
- inx
- bne @scan
- lda rb_reu_core_bank
- beq @fetch_mirror
- lda rb_reu_code_bank
- beq @fetch_mirror
- rts
-@fetch_mirror:
lda #RB_PAGEBUF
@@ -4177,7 +5194,7 @@ rb_resolve_reu_banks_hidden:
sta rb_reu_off_lo
lda #>RB_REUCB_BANK_TYPE_OFF
sta rb_reu_off_hi
- lda SHIM_REU_BANK_SKIP
+ lda SHIM_READYOS_BANK
sta rb_reu_bank
lda #0
sta rb_reu_len_lo
@@ -4185,23 +5202,23 @@ rb_resolve_reu_banks_hidden:
sta rb_reu_len_hi
jsr rb_reu_fetch
ldx #0
-@mirror_scan:
+@scan:
lda RB_PAGEBUF,x
cmp #RB_REU_TYPE_CORE
- bne @mirror_check_code
+ bne @check_code
lda rb_reu_core_bank
- bne @mirror_next
+ bne @next
stx rb_reu_core_bank
- jmp @mirror_next
-@mirror_check_code:
+ jmp @next
+@check_code:
cmp #RB_REU_TYPE_CODE
- bne @mirror_next
+ bne @next
lda rb_reu_code_bank
- bne @mirror_next
+ bne @next
stx rb_reu_code_bank
-@mirror_next:
+@next:
inx
- bne @mirror_scan
+ bne @scan
rts
rb_clear_handle_heap:
@@ -4370,60 +5387,12 @@ rb_draw_header:
sta COLOR_CODE
rts
-rb_calc_basic_free:
- sec
- lda FRETOP
- sbc STREND
- sta rb_free_lo
- lda FRETOP+1
- sbc STREND+1
- sta rb_free_hi
- rts
-
rb_print_live_free:
- jsr rb_calc_basic_free
- lda #0
- sta rb_digit_seen
- ldx #0
-@place:
- lda #0
- sta rb_digit_count
-@sub:
- sec
- lda rb_free_lo
- sbc rb_decimal_lo,x
- sta rb_tmp_lo
- lda rb_free_hi
- sbc rb_decimal_hi,x
- bcc @emit
- sta rb_free_hi
- lda rb_tmp_lo
- sta rb_free_lo
- inc rb_digit_count
- jmp @sub
-@emit:
- lda rb_digit_count
- bne @print
- lda rb_digit_seen
- bne @print
- cpx #4
- bne @next
- lda #0
-@print:
- ora #'0'
- jsr K_CHROUT
- lda #1
- sta rb_digit_seen
-@next:
- inx
- cpx #5
- bcc @place
- rts
-
-rb_decimal_lo:
- .byte <10000,<1000,<100,<10,<1
-rb_decimal_hi:
- .byte >10000,>1000,>100,>10,>1
+ lda #hidden_print_live_free
+ sta rb_lookup_slots
+ jmp call_hidden_common
rb_update_header_free:
sec
@@ -4437,16 +5406,12 @@ rb_update_header_free:
jsr K_PLOT
lda #13
sta COLOR_CODE
+ ldx #5
+@blank:
lda #' '
jsr K_CHROUT
- lda #' '
- jsr K_CHROUT
- lda #' '
- jsr K_CHROUT
- lda #' '
- jsr K_CHROUT
- lda #' '
- jsr K_CHROUT
+ dex
+ bne @blank
clc
ldx #1
@@ -4463,20 +5428,11 @@ rb_update_header_free:
rts
call_hidden_draw_default_header:
- php
- sei
- lda CPU_DDR
- ora #$07
- sta CPU_DDR
- lda CPU_PORT
- sta rb_saved_cpu
- and #RAM_UNDER_BASIC_KEEP_KERNAL
- sta CPU_PORT
- jsr draw_default_header
- lda rb_saved_cpu
- sta CPU_PORT
- plp
- rts
+ lda #draw_default_header
+ sta rb_lookup_slots
+ jmp call_hidden_common
rb_crunch:
jsr rb_call_orig_crunch
@@ -4538,13 +5494,20 @@ rb_magic2: .byte 0
rb_seed_cold: .byte 0
rb_error: .byte 0
rb_saved_cpu: .byte 0
+rb_common_saved_cpu:.byte 0
rb_vectors_saved:.byte 0
+rb_orig_imain_lo:.byte 0
+rb_orig_imain_hi:.byte 0
rb_orig_crunch_lo:.byte 0
rb_orig_crunch_hi:.byte 0
rb_orig_list_lo:.byte 0
rb_orig_list_hi:.byte 0
+rb_orig_keylog_lo:.byte 0
+rb_orig_keylog_hi:.byte 0
rb_orig_execute_lo:.byte 0
rb_orig_execute_hi:.byte 0
+rb_orig_chrin_lo:.byte 0
+rb_orig_chrin_hi:.byte 0
rb_peek_lo: .byte 0
rb_peek_hi: .byte 0
rb_crunch_len: .byte 0
@@ -4571,15 +5534,17 @@ rb_save_num0_hi:.res 4
rb_float_save_depth:.byte 0
rb_save_float0_buf:.res 20
- .segment "BRIDGE"
+ .segment "ENTRY"
rb_free_lo: .byte 0
rb_free_hi: .byte 0
rb_tmp_lo: .byte 0
+rb_hotkey_target_bank:.byte 0
rb_digit_count: .byte 0
rb_digit_seen: .byte 0
rb_saved_plot_x:.byte 0
rb_saved_plot_y:.byte 0
+ .segment "BRIDGE"
rb_kw_proc: .byte "PROC",0
rb_kw_func: .byte "FUNC",0
rb_kw_exec: .byte "EXEC",0
@@ -4589,11 +5554,12 @@ rb_kw_repeat: .byte "REPEAT",0
rb_kw_until: .byte "UNTIL",0
rb_kw_label: .byte "LABEL",0
rb_kw_jump: .byte "JUMP",0
- .segment "BRIDGE"
+ .segment "ENTRY"
rb_kw_endp: .byte "ENDP",0
rb_kw_char: .byte 0
-
rb_found_kind: .byte 0
+
+ .segment "BRIDGE"
rb_found_line_lo:.byte 0
rb_found_line_hi:.byte 0
rb_scan_line_lo:.byte 0
@@ -4633,6 +5599,12 @@ rb_loop_cur_hi:.res RB_LOOP_DEPTH
rb_last_error: .byte 0
rb_last_line_lo:.byte 0
rb_last_line_hi:.byte 0
+rb_hotkey_pending:.byte 0
+rb_hotkey_suppress:.byte 0
+rb_prompt_active:.byte 0
+rb_hotkey_chrin_dispatch:.byte 0
+rb_hotkey_release_key:.byte 0
+rb_hotkey_release_start:.byte 0
rb_func_depth:.byte 0
rb_form_save_count:.res RB_PROC_DEPTH
@@ -4669,6 +5641,7 @@ rb_out_ptr_hi: .byte 0
rb_out_count_lo:.byte 0
rb_out_count_hi:.byte 0
+ .segment "ENTRY"
rb_overlay_vec_lo:.byte 0
rb_overlay_vec_hi:.byte 0
rb_slot0_cmd: .byte 0
@@ -4679,462 +5652,4464 @@ rb_reu_c64_lo: .byte 0
rb_reu_c64_hi: .byte 0
rb_reu_off_lo: .byte 0
rb_reu_off_hi: .byte 0
+
+ .segment "BRIDGE"
rb_reu_bank: .byte 0
rb_reu_len_lo: .byte 0
rb_reu_len_hi: .byte 0
rb_reu_core_bank:.byte 0
rb_reu_code_bank:.byte 0
-rb_handle_bank: .byte 0
-rb_handle_page: .byte 0
-rb_handle_pages:.byte 0
-rb_handle_type: .byte 0
-rb_handle_index:.byte 0
-rb_needed_pages:.byte 0
-rb_handle_new_type:.byte 0
-rb_found_page: .byte 0
-rb_handle_desc_off:.byte 0
-rb_handle_scan_base:.byte 0
-rb_fill_page: .byte 0
-rb_copy_page: .byte 0
-rb_copy_chunks: .byte 0
-rb_copy_len_lo: .byte 0
-rb_copy_len_hi: .byte 0
+rb_handle_bank: .byte 0
+rb_handle_page: .byte 0
+rb_handle_pages:.byte 0
+rb_handle_type: .byte 0
+rb_handle_index:.byte 0
+rb_needed_pages:.byte 0
+rb_handle_new_type:.byte 0
+rb_found_page: .byte 0
+rb_handle_desc_off:.byte 0
+rb_handle_scan_base:.byte 0
+rb_fill_page: .byte 0
+rb_copy_page: .byte 0
+rb_copy_chunks: .byte 0
+rb_copy_len_lo: .byte 0
+rb_copy_len_hi: .byte 0
+
+install_vectors:
+ lda #hidden_install_vectors
+ sta rb_lookup_slots
+ jmp call_hidden_common
+
+rb_keylog:
+ lda DFLTN
+ bne @orig
+ lda rb_prompt_active
+ bne @prompt
+ lda TXTPTR+1
+ cmp #>BASIC_START
+ bcc @prompt
+ bne @orig
+ lda TXTPTR
+ cmp #hidden_select_next_app_store = >hidden_select_prev_app_store, error, "ReadyBASIC selector stubs crossed a hidden page"
+ sta rb_lookup_index
+ lda #>hidden_select_next_app_store
+ sta rb_lookup_slots
+ jmp call_hidden_common
+
+rb_prepare_ready_resume:
+ lda #hidden_prepare_ready_resume
+ sta rb_lookup_slots
+ jmp call_hidden_common
+
+; ---------------------------------------------------------------------------
+; Packed command submodule 0. This 2KB slot image is copied from the
+; loader-assigned ReadyBASIC code bank
+; into $A800-$AFFF on demand, then reused while residency metadata matches.
+; ---------------------------------------------------------------------------
+
+ .segment "LOWPACK"
+
+cmd_zecho1_low:
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_INT
+ sta RF_TAG
+ lda #1
+ sta RF_VAL_LO
+ lda #0
+ sta RF_VAL_HI
+ rts
+cmd_zecho1_low_end:
+
+cmd_zadd16_low:
+ clc
+ lda CF_NUM0_LO
+ adc CF_NUM1_LO
+ sta RF_VAL_LO
+ lda CF_NUM0_HI
+ adc CF_NUM1_HI
+ sta RF_VAL_HI
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_INT
+ sta RF_TAG
+ rts
+cmd_zadd16_low_end:
+
+cmd_zslot0_low:
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_INT
+ sta RF_TAG
+ lda #30
+ sta RF_VAL_LO
+ lda #0
+ sta RF_VAL_HI
+ rts
+cmd_zslot0_low_end:
+
+cmd_zcpyrst_low:
+ lda #0
+ sta rb_copy_count
+ sta RF_STATUS
+ sta RF_VAL_LO
+ sta RF_VAL_HI
+ lda #RB_VAL_INT
+ sta RF_TAG
+ rts
+cmd_zcpyrst_low_end:
+
+cmd_zcopy_low:
+ lda #0
+ sta RF_STATUS
+ sta RF_VAL_HI
+ lda rb_copy_count
+ sta RF_VAL_LO
+ lda #RB_VAL_INT
+ sta RF_TAG
+ rts
+cmd_zcopy_low_end:
+
+cmd_fadd_low:
+ rts
+cmd_fadd_low_end:
+
+cmd_zpause_low:
+ lda CF_NUM0_LO
+ beq @done
+ sta RF_COUNT_LO
+@outer:
+ ldx #$20
+@middle:
+ ldy #$ff
+@inner:
+ dey
+ bne @inner
+ dex
+ bne @middle
+ dec RF_COUNT_LO
+ bne @outer
+@done:
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_NONE
+ sta RF_TAG
+ rts
+cmd_zpause_low_end:
+
+cmd_upper_low:
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_STRING
+ sta RF_TAG
+ lda CF_STR_LEN
+ sta RF_STR_LEN
+ ldy #0
+@loop:
+ cpy CF_STR_LEN
+ beq @done
+ lda CF_STR_BUF,y
+ cmp #$C1
+ bcc @ascii_case
+ cmp #$DB
+ bcs @ascii_case
+ sec
+ sbc #$80
+ jmp @store
+@ascii_case:
+ cmp #'a'
+ bcc :+
+ cmp #'z' + 1
+ bcs :+
+ sec
+ sbc #$20
+@store:
+: sta RF_STR_BUF,y
+ iny
+ jmp @loop
+@done:
+ rts
+cmd_upper_low_end:
+
+cmd_lower_low:
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_STRING
+ sta RF_TAG
+ lda CF_STR_LEN
+ sta RF_STR_LEN
+ ldy #0
+@loop:
+ cpy CF_STR_LEN
+ beq @done
+ lda CF_STR_BUF,y
+ cmp #$C1
+ bcc @ascii_case
+ cmp #$DB
+ bcs @ascii_case
+ sec
+ sbc #$60
+ jmp @store
+@ascii_case:
+ cmp #'A'
+ bcc :+
+ cmp #'Z' + 1
+ bcs :+
+ clc
+ adc #$20
+@store:
+: sta RF_STR_BUF,y
+ iny
+ jmp @loop
+@done:
+ rts
+cmd_lower_low_end:
+
+cmd_zsumnumarray_low:
+ lda CF_PTR0_LO
+ sta rb_ptr_lo
+ lda CF_PTR0_HI
+ sta rb_ptr_hi
+ lda #0
+ sta RF_VAL_LO
+ sta RF_VAL_HI
+ ldx CF_COUNT0_LO
+ beq @done
+@loop:
+ ldy #1
+ clc
+ lda RF_VAL_LO
+ adc (rb_ptr_lo),y
+ sta RF_VAL_LO
+ dey
+ lda RF_VAL_HI
+ adc (rb_ptr_lo),y
+ sta RF_VAL_HI
+ clc
+ lda rb_ptr_lo
+ adc #2
+ sta rb_ptr_lo
+ bcc :+
+ inc rb_ptr_hi
+: dex
+ bne @loop
+@done:
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_INT
+ sta RF_TAG
+ rts
+cmd_zsumnumarray_low_end:
+
+cmd_zrangenumarray_low:
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_ARRAYI
+ sta RF_TAG
+ lda CF_NUM1_LO
+ sta RF_COUNT_LO
+ lda CF_NUM1_HI
+ sta RF_COUNT_HI
+ lda CF_NUM0_LO
+ sta rb_ptr_lo
+ lda CF_NUM0_HI
+ sta rb_ptr_hi
+ ldx CF_NUM1_LO
+ beq @done
+ ldy #0
+@loop:
+ lda rb_ptr_hi
+ sta RF_ARRAY_BUF,y
+ iny
+ lda rb_ptr_lo
+ sta RF_ARRAY_BUF,y
+ iny
+ inc rb_ptr_lo
+ bne :+
+ inc rb_ptr_hi
+: dex
+ bne @loop
+@done:
+ rts
+cmd_zrangenumarray_low_end:
+
+cmd_bufnew_low:
+ jsr rb_handle_alloc
+ rts
+cmd_bufnew_low_end:
+
+cmd_buffill_low:
+ jsr rb_handle_fill
+ rts
+cmd_buffill_low_end:
+
+cmd_buffree_low:
+ jsr rb_handle_free
+ rts
+cmd_buffree_low_end:
+
+cmd_ztempscratch_low:
+ jsr rb_temp_alloc
+ rts
+cmd_ztempscratch_low_end:
+
+cmd_zfail_low:
+ lda CF_NUM0_LO
+ bne :+
+ lda #$7F
+: sta RF_STATUS
+ sta RF_ERROR
+ lda #RB_VAL_INT
+ sta RF_TAG
+ lda #0
+ sta RF_VAL_LO
+ sta RF_VAL_HI
+ rts
+cmd_zfail_low_end:
+
+cmd_freemem_low:
+ jsr rb_print_live_free
+ lda #13
+ jsr K_CHROUT
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_NONE
+ sta RF_TAG
+ rts
+cmd_freemem_low_end:
+
+cmd_scrcap_low:
+ jsr rb_screen_handle_alloc
+ lda RF_STATUS
+ beq :+
+ rts
+: jsr rb_screen_save_text
+ jsr rb_screen_save_color
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_INT
+ sta RF_TAG
+ ldx rb_handle_index
+ txa
+ clc
+ adc #1
+ sta RF_VAL_LO
+ lda #0
+ sta RF_VAL_HI
+ rts
+cmd_scrcap_low_end:
+
+cmd_scrput_low:
+ jsr rb_screen_handle_validate
+ lda RF_STATUS
+ beq :+
+ rts
+: jsr rb_screen_load_text
+ jsr rb_screen_load_color
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_NONE
+ sta RF_TAG
+ rts
+cmd_scrput_low_end:
+
+cmd_gfxsurf_low:
+ lda #RB_GFX_SURF_PAGES
+ sta rb_needed_pages
+ lda #RB_HANDLE_TYPE_GFXSURF
+ sta rb_handle_new_type
+ jsr rb_handle_alloc_with_pages
+ rts
+cmd_gfxsurf_low_end:
+
+cmd_gfxtarget_low:
+ lda CF_NUM0_LO
+ ora CF_NUM0_HI
+ bne @handle
+ sta RB_GFX_TARGET_HANDLE
+ sta RB_GFX_TARGET_BANK
+ sta RB_GFX_TARGET_PAGE
+ sta RB_GFX_TARGET_PAGES
+ jmp rb_gfx_ok_none
+@handle:
+ jsr rb_handle_load_arg
+ bcs @bad
+ lda rb_handle_type
+ cmp #RB_HANDLE_TYPE_GFXSURF
+ bne @wrong
+ lda rb_handle_index
+ clc
+ adc #1
+ sta RB_GFX_TARGET_HANDLE
+ lda rb_handle_bank
+ sta RB_GFX_TARGET_BANK
+ lda rb_handle_page
+ sta RB_GFX_TARGET_PAGE
+ lda rb_handle_pages
+ sta RB_GFX_TARGET_PAGES
+ jmp rb_gfx_ok_none
+@bad:
+ lda #$24
+ jmp rb_overlay_fail
+@wrong:
+ lda #$28
+ jmp rb_overlay_fail
+cmd_gfxtarget_low_end:
+
+cmd_gfxblit_low:
+ jsr rb_handle_load_arg
+ bcs @bad
+ lda rb_handle_type
+ cmp #RB_HANDLE_TYPE_GFXSURF
+ bne @wrong
+ lda CPU_PORT
+ pha
+ lda #$35
+ sta CPU_PORT
+ jsr rb_gfx_blit_bitmap
+ jsr rb_gfx_blit_screen
+ jsr rb_gfx_blit_color
+ pla
+ sta CPU_PORT
+ jmp rb_gfx_ok_none
+@bad:
+ lda #$24
+ jmp rb_overlay_fail
+@wrong:
+ lda #$28
+ jmp rb_overlay_fail
+cmd_gfxblit_low_end:
+
+rb_gfx_ok_none:
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_NONE
+ sta RF_TAG
+ rts
+
+rb_gfx_blit_bitmap:
+ lda #RB_GFX_BITMAP
+ sta rb_reu_c64_hi
+ lda #0
+ sta rb_reu_off_lo
+ lda rb_handle_page
+ sta rb_reu_off_hi
+ lda rb_handle_bank
+ sta rb_reu_bank
+ lda #0
+ sta rb_reu_len_lo
+ lda #$20
+ sta rb_reu_len_hi
+ jmp rb_reu_fetch
+
+rb_gfx_blit_screen:
+ lda #RB_GFX_SCREEN
+ sta rb_reu_c64_hi
+ lda #0
+ sta rb_reu_off_lo
+ lda rb_handle_page
+ clc
+ adc #$20
+ sta rb_reu_off_hi
+ lda rb_handle_bank
+ sta rb_reu_bank
+ lda #0
+ sta rb_reu_len_lo
+ lda #4
+ sta rb_reu_len_hi
+ jmp rb_reu_fetch
+
+rb_gfx_blit_color:
+ lda #RB_GFX_COLOR
+ sta rb_reu_c64_hi
+ lda #0
+ sta rb_reu_off_lo
+ lda rb_handle_page
+ clc
+ adc #$24
+ sta rb_reu_off_hi
+ lda rb_handle_bank
+ sta rb_reu_bank
+ lda #0
+ sta rb_reu_len_lo
+ lda #4
+ sta rb_reu_len_hi
+ jmp rb_reu_fetch
+
+rb_handle_alloc:
+ jsr rb_len_to_pages
+ bcc :+
+ jmp rb_overlay_bad_length
+: lda #RB_HANDLE_TYPE_BUFFER
+ sta rb_handle_new_type
+ jmp rb_handle_alloc_with_pages
+
+rb_screen_handle_alloc:
+ lda #RB_SCREEN_HANDLE_PAGES
+ sta rb_needed_pages
+ lda #RB_HANDLE_TYPE_SCREEN_TC
+ sta rb_handle_new_type
+
+rb_handle_alloc_with_pages:
+ jsr rb_find_free_handle
+ bcc @got_handle
+ lda #$21
+ jmp rb_overlay_fail
+@got_handle:
+ jsr rb_find_pages
+ bcs @no_pages
+ lda rb_reu_core_bank
+ sta rb_handle_bank
+ lda rb_found_page
+ clc
+ adc #RB_HEAP_PAGE_BASE
+ sta rb_handle_page
+ lda rb_needed_pages
+ sta rb_handle_pages
+ lda rb_handle_new_type
+ sta rb_handle_type
+ jsr rb_mark_pages_used
+ jsr rb_store_heap_bitmap
+ jsr rb_handle_store
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_INT
+ sta RF_TAG
+ lda rb_handle_index
+ clc
+ adc #1
+ sta RF_VAL_LO
+ lda #0
+ sta RF_VAL_HI
+ rts
+@no_pages:
+ lda #$22
+ jmp rb_overlay_fail
+
+rb_screen_handle_validate:
+ jsr rb_handle_load_arg
+ bcs @bad
+ lda rb_handle_type
+ cmp #RB_HANDLE_TYPE_SCREEN_TC
+ bne @wrong_type
+ clc
+ rts
+@wrong_type:
+ lda #$28
+ jmp rb_overlay_fail
+@bad:
+ lda #$24
+ jmp rb_overlay_fail
+
+rb_overlay_bad_length:
+ lda #$23
+rb_overlay_fail:
+ sta RF_STATUS
+ sta RF_ERROR
+ rts
+
+rb_len_to_pages:
+ lda CF_NUM0_LO
+ ora CF_NUM0_HI
+ beq @bad
+ lda CF_NUM0_HI
+ sta rb_needed_pages
+ lda CF_NUM0_LO
+ beq @check
+ inc rb_needed_pages
+@check:
+ lda rb_needed_pages
+ beq @bad
+ cmp #RB_HEAP_PAGES + 1
+ bcs @bad
+ clc
+ rts
+@bad:
+ sec
+ rts
+
+rb_handle_desc_fetch_page:
+ lda rb_handle_index
+ and #$3F
+ asl
+ asl
+ sta rb_handle_desc_off
+ lda #0
+ sta rb_reu_off_lo
+ lda #>RB_REU_HANDLE_OFF
+ ldx rb_handle_index
+ cpx #RB_HANDLE_PAGE_SLOTS
+ bcc :+
+ clc
+ adc #1
+: sta rb_reu_off_hi
+ lda #RB_PAGEBUF
+ sta rb_reu_c64_hi
+ lda rb_reu_core_bank
+ sta rb_reu_bank
+ lda #0
+ sta rb_reu_len_lo
+ lda #1
+ sta rb_reu_len_hi
+ jsr rb_reu_fetch
+ rts
+
+rb_handle_fetch:
+ jsr rb_handle_desc_fetch_page
+ ldy rb_handle_desc_off
+ lda RB_PAGEBUF,y
+ sta rb_handle_bank
+ iny
+ lda RB_PAGEBUF,y
+ sta rb_handle_page
+ iny
+ lda RB_PAGEBUF,y
+ sta rb_handle_pages
+ iny
+ lda RB_PAGEBUF,y
+ sta rb_handle_type
+ rts
+
+rb_handle_store:
+ jsr rb_handle_desc_fetch_page
+ ldy rb_handle_desc_off
+ lda rb_handle_bank
+ sta RB_PAGEBUF,y
+ iny
+ lda rb_handle_page
+ sta RB_PAGEBUF,y
+ iny
+ lda rb_handle_pages
+ sta RB_PAGEBUF,y
+ iny
+ lda rb_handle_type
+ sta RB_PAGEBUF,y
+ lda #RB_PAGEBUF
+ sta rb_reu_c64_hi
+ lda rb_reu_core_bank
+ sta rb_reu_bank
+ lda #0
+ sta rb_reu_len_lo
+ lda #1
+ sta rb_reu_len_hi
+ jsr rb_reu_stash
+ rts
+
+rb_find_free_handle:
+ lda #0
+ sta rb_handle_scan_base
+@page:
+ lda rb_handle_scan_base
+ sta rb_handle_index
+ jsr rb_handle_desc_fetch_page
+ ldy #0
+ ldx #0
+@slot:
+ lda RB_PAGEBUF,y
+ beq @found
+ tya
+ clc
+ adc #RB_HANDLE_DESC_SIZE
+ tay
+ inx
+ cpx #RB_HANDLE_PAGE_SLOTS
+ bcc @slot
+ lda rb_handle_scan_base
+ bne @full
+ lda #RB_HANDLE_PAGE_SLOTS
+ sta rb_handle_scan_base
+ jmp @page
+@found:
+ txa
+ clc
+ adc rb_handle_scan_base
+ sta rb_handle_index
+ clc
+ rts
+@full:
+ sec
+ rts
+
+rb_handle_load_arg:
+ lda CF_NUM0_HI
+ bne @bad
+ lda CF_NUM0_LO
+ beq @bad
+ cmp #RB_HANDLE_COUNT + 1
+ bcs @bad
+ sec
+ sbc #1
+ sta rb_handle_index
+ jsr rb_handle_fetch
+ lda rb_handle_bank
+ beq @bad
+ clc
+ rts
+@bad:
+ sec
+ rts
+
+rb_fetch_heap_bitmap:
+ lda #RB_PAGEBUF
+ sta rb_reu_c64_hi
+ lda #RB_REU_HEAP_OFF
+ sta rb_reu_off_hi
+ lda rb_reu_core_bank
+ sta rb_reu_bank
+ lda #0
+ sta rb_reu_len_lo
+ lda #1
+ sta rb_reu_len_hi
+ jsr rb_reu_fetch
+ rts
+
+rb_store_heap_bitmap:
+ lda #RB_PAGEBUF
+ sta rb_reu_c64_hi
+ lda #RB_REU_HEAP_OFF
+ sta rb_reu_off_hi
+ lda rb_reu_core_bank
+ sta rb_reu_bank
+ lda #0
+ sta rb_reu_len_lo
+ lda #1
+ sta rb_reu_len_hi
+ jsr rb_reu_stash
+ rts
+
+rb_find_pages:
+ jsr rb_fetch_heap_bitmap
+ lda #0
+ sta rb_found_page
+@outer:
+ lda rb_found_page
+ clc
+ adc rb_needed_pages
+ cmp #RB_HEAP_PAGES + 1
+ bcc :+
+ sec
+ rts
+: ldx #0
+@inner:
+ txa
+ clc
+ adc rb_found_page
+ tay
+ lda RB_PAGEBUF,y
+ bne @next_start
+ inx
+ cpx rb_needed_pages
+ bcc @inner
+ clc
+ rts
+@next_start:
+ inc rb_found_page
+ jmp @outer
+
+rb_mark_pages_used:
+ ldx #0
+@loop:
+ txa
+ clc
+ adc rb_found_page
+ tay
+ lda #1
+ sta RB_PAGEBUF,y
+ inx
+ cpx rb_needed_pages
+ bcc @loop
+ rts
+
+rb_handle_free:
+ jsr rb_handle_load_arg
+ bcs @bad
+ lda rb_handle_page
+ sec
+ sbc #RB_HEAP_PAGE_BASE
+ sta rb_found_page
+ lda rb_handle_pages
+ sta rb_needed_pages
+ jsr rb_fetch_heap_bitmap
+ jsr rb_mark_pages_free
+ lda #0
+ sta rb_handle_bank
+ sta rb_handle_page
+ sta rb_handle_pages
+ sta rb_handle_type
+ jsr rb_store_heap_bitmap
+ jsr rb_handle_store
+ lda #0
+ sta RF_STATUS
+ sta RF_TAG
+ rts
+@bad:
+ lda #$24
+ jmp rb_overlay_fail
+
+rb_mark_pages_free:
+ ldx #0
+@loop:
+ txa
+ clc
+ adc rb_found_page
+ tay
+ lda #0
+ sta RB_PAGEBUF,y
+ inx
+ cpx rb_needed_pages
+ bcc @loop
+ rts
+
+rb_handle_fill:
+ jsr rb_handle_load_arg
+ bcs @bad
+ lda rb_handle_type
+ cmp #RB_HANDLE_TYPE_BUFFER
+ bne @wrong_type
+ lda CF_NUM1_LO
+ ldx #0
+@fillbuf:
+ sta RB_PAGEBUF,x
+ inx
+ bne @fillbuf
+ lda rb_handle_page
+ sta rb_fill_page
+ lda rb_handle_pages
+ sta rb_needed_pages
+@page:
+ lda #RB_PAGEBUF
+ sta rb_reu_c64_hi
+ lda #0
+ sta rb_reu_off_lo
+ lda rb_fill_page
+ sta rb_reu_off_hi
+ lda rb_reu_core_bank
+ sta rb_reu_bank
+ lda #0
+ sta rb_reu_len_lo
+ lda #1
+ sta rb_reu_len_hi
+ jsr rb_reu_stash
+ inc rb_fill_page
+ dec rb_needed_pages
+ bne @page
+ lda #0
+ sta RF_STATUS
+ sta RF_TAG
+ rts
+@bad:
+ lda #$25
+ jmp rb_overlay_fail
+@wrong_type:
+ lda #$28
+ jmp rb_overlay_fail
+
+rb_temp_alloc:
+ jsr rb_len_to_pages
+ bcs @bad
+ jsr rb_find_pages
+ bcs @bad
+ jsr rb_mark_pages_used
+ jsr rb_mark_pages_free
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_INT
+ sta RF_TAG
+ lda rb_needed_pages
+ sta RF_VAL_LO
+ lda #0
+ sta RF_VAL_HI
+ rts
+@bad:
+ lda #$26
+ jmp rb_overlay_fail
+
+rb_screen_save_text:
+ lda #SCREEN
+ sta rb_reu_c64_hi
+ lda #0
+ sta rb_reu_off_lo
+ lda rb_handle_page
+ sta rb_reu_off_hi
+ lda rb_reu_core_bank
+ sta rb_reu_bank
+ lda #RB_SCREEN_BYTES
+ sta rb_reu_len_hi
+ jsr rb_reu_stash
+ rts
+
+rb_screen_load_text:
+ lda #SCREEN
+ sta rb_reu_c64_hi
+ lda #0
+ sta rb_reu_off_lo
+ lda rb_handle_page
+ sta rb_reu_off_hi
+ lda rb_reu_core_bank
+ sta rb_reu_bank
+ lda #RB_SCREEN_BYTES
+ sta rb_reu_len_hi
+ jsr rb_reu_fetch
+ rts
+
+rb_screen_save_color:
+ lda #COLOR_RAM
+ sta rb_ptr_hi
+ lda rb_handle_page
+ clc
+ adc #4
+ sta rb_copy_page
+ lda #4
+ sta rb_copy_chunks
+@chunk:
+ jsr rb_screen_set_copy_len
+ jsr rb_copy_ptr_to_pagebuf
+ jsr rb_stash_pagebuf_to_copy_page
+ inc rb_ptr_hi
+ inc rb_copy_page
+ dec rb_copy_chunks
+ bne @chunk
+ rts
+
+rb_screen_load_color:
+ lda #COLOR_RAM
+ sta rb_ptr_hi
+ lda rb_handle_page
+ clc
+ adc #4
+ sta rb_copy_page
+ lda #4
+ sta rb_copy_chunks
+@chunk:
+ jsr rb_screen_set_copy_len
+ jsr rb_fetch_pagebuf_from_copy_page
+ jsr rb_copy_pagebuf_to_ptr
+ inc rb_ptr_hi
+ inc rb_copy_page
+ dec rb_copy_chunks
+ bne @chunk
+ rts
+
+rb_screen_set_copy_len:
+ lda rb_copy_chunks
+ cmp #1
+ beq @tail
+ lda #0
+ sta rb_copy_len_lo
+ lda #1
+ sta rb_copy_len_hi
+ rts
+@tail:
+ lda #RB_PAGEBUF
+ sta rb_reu_c64_hi
+ lda #0
+ sta rb_reu_off_lo
+ lda rb_copy_page
+ sta rb_reu_off_hi
+ lda rb_reu_core_bank
+ sta rb_reu_bank
+ lda rb_copy_len_lo
+ sta rb_reu_len_lo
+ lda rb_copy_len_hi
+ sta rb_reu_len_hi
+ jsr rb_reu_stash
+ rts
+
+rb_fetch_pagebuf_from_copy_page:
+ lda #RB_PAGEBUF
+ sta rb_reu_c64_hi
+ lda #0
+ sta rb_reu_off_lo
+ lda rb_copy_page
+ sta rb_reu_off_hi
+ lda rb_reu_core_bank
+ sta rb_reu_bank
+ lda rb_copy_len_lo
+ sta rb_reu_len_lo
+ lda rb_copy_len_hi
+ sta rb_reu_len_hi
+ jsr rb_reu_fetch
+ rts
+
+; ---------------------------------------------------------------------------
+; Former hidden worker command implementation. It now lives in the same
+; default command submodule as the other command workers.
+; ---------------------------------------------------------------------------
+
+cmd_zhiddenram_hidden:
+ lda #0
+ sta RF_VAL_LO
+ sta RF_VAL_HI
+ ldy #0
+@loop:
+ cpy CF_STR_LEN
+ beq @done
+ lda RF_VAL_LO
+ sta rb_ptr_lo
+ lda CF_STR_BUF,y
+ cmp #$C1
+ bcc @ascii_case
+ cmp #$DB
+ bcs @ascii_case
+ sec
+ sbc #$80
+ jmp @sum
+@ascii_case:
+ cmp #'a'
+ bcc @sum
+ cmp #'z' + 1
+ bcs @sum
+ sec
+ sbc #$20
+@sum:
+ clc
+ adc rb_ptr_lo
+ sta RF_VAL_LO
+ lda RF_VAL_HI
+ adc #0
+ sta RF_VAL_HI
+ iny
+ jmp @loop
+@done:
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_INT
+ sta RF_TAG
+ rts
+cmd_zhiddenram_hidden_end:
+
+ .segment "SLOTPACK1"
+
+cmd_zslot1:
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_INT
+ sta RF_TAG
+ lda #31
+ sta RF_VAL_LO
+ lda #0
+ sta RF_VAL_HI
+ rts
+cmd_zslot1_end:
+
+cmd_gfxmode:
+ lda CF_STR_LEN
+ beq @return_current
+ jsr gfx_mode_from_string
+ bcc @bad
+ jsr gfx_apply_mode
+@return_current:
+ jsr gfx_get_mode
+ pha
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_INT
+ sta RF_TAG
+ pla
+ sta RF_VAL_LO
+ lda #0
+ sta RF_VAL_HI
+ rts
+@bad:
+ lda #$41
+ jmp gfx_fail
+
+cmd_gfxtext:
+ jsr gfx_apply_text
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_NONE
+ sta RF_TAG
+ rts
+
+cmd_gfxclear:
+ jsr gfx_get_mode
+ bne @gfx
+ lda #147
+ jsr K_CHROUT
+ jmp gfx_ok_none
+@gfx:
+ sta rb_saved_plot_y
+ jsr gfx_clear_bankd_screen
+ lda rb_saved_plot_y
+ cmp #RB_GFX_MODE_TILE
+ beq @tile
+ cmp #RB_GFX_MODE_MTILE
+ beq @tile
+ jsr gfx_clear_bitmap
+@done:
+ jmp gfx_ok_none
+@tile:
+ jsr gfx_init_tile_glyphs
+ jmp @done
+
+cmd_gfxtarget:
+ jmp gfx_ok_none
+
+cmd_gfxsync:
+ lda RB_GFX_TARGET_HANDLE
+ bne :+
+ jmp gfx_ok_none
+:
+ lda CPU_PORT
+ pha
+ lda #$35
+ sta CPU_PORT
+ jsr gfx_sync_bitmap
+ jsr gfx_sync_screen
+ jsr gfx_sync_color
+ pla
+ sta CPU_PORT
+ jmp gfx_ok_none
+
+gfx_ok_none:
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_NONE
+ sta RF_TAG
+ rts
+
+gfx_fail:
+ sta RF_STATUS
+ sta RF_ERROR
+ rts
+
+gfx_sync_bitmap:
+ lda #RB_GFX_BITMAP
+ sta rb_reu_c64_hi
+ lda #0
+ sta rb_reu_off_lo
+ lda RB_GFX_TARGET_PAGE
+ sta rb_reu_off_hi
+ lda RB_GFX_TARGET_BANK
+ sta rb_reu_bank
+ lda #0
+ sta rb_reu_len_lo
+ lda #$20
+ sta rb_reu_len_hi
+ jmp rb_reu_stash
+
+gfx_sync_screen:
+ lda #RB_GFX_SCREEN
+ sta rb_reu_c64_hi
+ lda #0
+ sta rb_reu_off_lo
+ lda RB_GFX_TARGET_PAGE
+ clc
+ adc #$20
+ sta rb_reu_off_hi
+ lda RB_GFX_TARGET_BANK
+ sta rb_reu_bank
+ lda #0
+ sta rb_reu_len_lo
+ lda #4
+ sta rb_reu_len_hi
+ jmp rb_reu_stash
+
+gfx_sync_color:
+ lda #RB_GFX_COLOR
+ sta rb_reu_c64_hi
+ lda #0
+ sta rb_reu_off_lo
+ lda RB_GFX_TARGET_PAGE
+ clc
+ adc #$24
+ sta rb_reu_off_hi
+ lda RB_GFX_TARGET_BANK
+ sta rb_reu_bank
+ lda #0
+ sta rb_reu_len_lo
+ lda #4
+ sta rb_reu_len_hi
+ jmp rb_reu_stash
+
+gfx_mode_from_string:
+ lda CF_STR_LEN
+ cmp #5
+ beq @len5
+ cmp #7
+ beq @len7
+ cmp #4
+ bne :+
+ jmp @len4
+:
+ clc
+ rts
+@len5:
+ lda CF_STR_BUF
+ jsr gfx_fold
+ cmp #'H'
+ beq @hires
+ cmp #'T'
+ beq @tile
+ cmp #'M'
+ beq @mtile5
+ clc
+ rts
+@hires:
+ lda CF_STR_BUF+1
+ jsr gfx_fold
+ cmp #'I'
+ bne @bad_len5
+ lda CF_STR_BUF+2
+ jsr gfx_fold
+ cmp #'R'
+ bne @bad_len5
+ lda CF_STR_BUF+3
+ jsr gfx_fold
+ cmp #'E'
+ bne @bad_len5
+ lda CF_STR_BUF+4
+ jsr gfx_fold
+ cmp #'S'
+ bne @bad_len5
+ lda #RB_GFX_MODE_HIRES
+ sec
+ rts
+@tile:
+ lda CF_STR_BUF+1
+ jsr gfx_fold
+ cmp #'I'
+ bne @bad_len5
+ lda CF_STR_BUF+2
+ jsr gfx_fold
+ cmp #'L'
+ bne @bad_len5
+ lda CF_STR_BUF+3
+ jsr gfx_fold
+ cmp #'E'
+ bne @bad_len5
+ lda #RB_GFX_MODE_TILE
+ sec
+ rts
+@bad_len5:
+ clc
+ rts
+@mtile5:
+ lda #RB_GFX_MODE_MTILE
+ sec
+ rts
+@len7:
+ lda CF_STR_BUF
+ jsr gfx_fold
+ cmp #'M'
+ bne @no
+ lda CF_STR_BUF+1
+ jsr gfx_fold
+ cmp #'B'
+ beq @mbitmap
+ cmp #'T'
+ beq @mtile
+ bne @no
+@mbitmap:
+ lda #RB_GFX_MODE_MBITMAP
+ sec
+ rts
+@mtile:
+ lda #RB_GFX_MODE_MTILE
+ sec
+ rts
+@len4:
+ lda CF_STR_BUF
+ jsr gfx_fold
+ cmp #'T'
+ bne @no
+ lda CF_STR_BUF+1
+ jsr gfx_fold
+ cmp #'I'
+ beq @tile4
+ cmp #'E'
+ bne @no
+ lda #RB_GFX_MODE_TEXT
+ sec
+ rts
+@tile4:
+ lda #RB_GFX_MODE_TILE
+ sec
+ rts
+@no:
+ clc
+ rts
+
+gfx_fold:
+ cmp #'a'
+ bcc :+
+ cmp #'z' + 1
+ bcs :+
+ sec
+ sbc #$20
+: rts
+
+gfx_apply_mode:
+ cmp #RB_GFX_MODE_TEXT
+ bne :+
+ jmp gfx_apply_text
+:
+ pha
+ lda CIA2_DDRA
+ ora #$03
+ sta CIA2_DDRA
+ lda CIA2_PRA
+ and #$FC
+ sta CIA2_PRA
+ lda #RB_GFX_VICMEM
+ sta VIC_MEM
+ lda VIC_CTRL1
+ ora #$20
+ sta rb_saved_plot_x
+ pla
+ pha
+ tax
+ lda rb_saved_plot_x
+ cpx #RB_GFX_MODE_TILE
+ beq @textlike
+ cpx #RB_GFX_MODE_MTILE
+ bne @store_d011
+@textlike:
+ and #$DF
+@store_d011:
+ sta VIC_CTRL1
+ lda VIC_CTRL2
+ sta rb_saved_plot_x
+ pla
+ tax
+ lda rb_saved_plot_x
+ cpx #RB_GFX_MODE_MBITMAP
+ beq @multi
+ cpx #RB_GFX_MODE_MTILE
+ beq @multi
+ and #$EF
+ jmp @store_d016
+@multi:
+ ora #$10
+@store_d016:
+ sta VIC_CTRL2
+ txa
+ sta RB_GFX_MODE_STATE
+ rts
+
+gfx_get_mode:
+ lda RB_GFX_MODE_STATE
+ cmp #RB_GFX_MODE_MTILE + 1
+ bcc :+
+ lda #RB_GFX_MODE_TEXT
+: rts
+
+gfx_apply_text:
+ lda CIA2_DDRA
+ ora #$03
+ sta CIA2_DDRA
+ lda CIA2_PRA
+ ora #$03
+ sta CIA2_PRA
+ lda #VIC_MEM_LOWERCASE
+ sta VIC_MEM
+ lda VIC_CTRL1
+ and #$DF
+ sta VIC_CTRL1
+ lda VIC_CTRL2
+ and #$EF
+ sta VIC_CTRL2
+ lda #RB_GFX_MODE_TEXT
+ sta RB_GFX_MODE_STATE
+ rts
+
+gfx_clear_bankd_screen:
+ lda #RB_GFX_SCREEN
+ sta rb_ptr_hi
+ lda CF_NUM0_LO
+ and #$0F
+ sta rb_saved_plot_x
+ lda rb_saved_plot_y
+ cmp #RB_GFX_MODE_TILE
+ beq @dup_color
+ cmp #RB_GFX_MODE_MTILE
+ beq @dup_color
+ lda rb_saved_plot_x
+ ora #$10
+ jmp @fill_screen
+@dup_color:
+ lda rb_saved_plot_x
+ asl
+ asl
+ asl
+ asl
+ ora rb_saved_plot_x
+@fill_screen:
+ ldx #4
+@page:
+ ldy #0
+@loop:
+ sta (rb_ptr_lo),y
+ iny
+ bne @loop
+ inc rb_ptr_hi
+ dex
+ bne @page
+ lda #RB_GFX_COLOR
+ sta rb_ptr_hi
+ lda CF_NUM0_LO
+ and #$0F
+ ldx #4
+@cpage:
+ ldy #0
+@cloop:
+ sta (rb_ptr_lo),y
+ iny
+ bne @cloop
+ inc rb_ptr_hi
+ dex
+ bne @cpage
+ rts
+
+gfx_clear_bitmap:
+ lda CPU_PORT
+ pha
+ and #RAM_UNDER_BASIC
+ sta CPU_PORT
+ lda #RB_GFX_BITMAP
+ sta rb_ptr_hi
+ lda #0
+ ldx #32
+@page:
+ ldy #0
+@loop:
+ sta (rb_ptr_lo),y
+ iny
+ bne @loop
+ inc rb_ptr_hi
+ dex
+ bne @page
+ pla
+ sta CPU_PORT
+ rts
+
+gfx_init_tile_glyphs:
+ lda CPU_PORT
+ pha
+ and #RAM_UNDER_BASIC
+ sta CPU_PORT
+ lda #<($E000 + (64 * 8))
+ sta rb_ptr_lo
+ lda #>($E000 + (64 * 8))
+ sta rb_ptr_hi
+ lda #$FF
+ ldy #0
+@loop:
+ sta (rb_ptr_lo),y
+ iny
+ cpy #$80
+ bne @loop
+ pla
+ sta CPU_PORT
+ rts
+
+cmd_zmodload:
+ lda CF_STR_LEN
+ bne :+
+ lda #240
+ jmp @return_int
+:
+ ldx #CF_STR_BUF
+ jsr K_SETNAM
+ lda #1
+ ldx #8
+ ldy #2
+ jsr K_SETLFS
+ lda MSGFLG
+ sta rb_saved_msgflg
+ lda #0
+ sta MSGFLG
+ sta rb_zmod_eof
+ jsr K_OPEN
+ bcs @fail_io_finish
+ ldx #1
+ jsr K_CHKIN
+ bcs @fail_io_finish
+ lda #16
+ jsr rb_zmodload_read_pagebuf_bytes
+ bcc @loaded
+@fail_io_finish:
+ lda #241
+ jmp @finish
+@loaded:
+ lda RB_PAGEBUF
+ cmp #'R'
+ bne @fail_magic
+ lda RB_PAGEBUF+1
+ cmp #'B'
+ bne @fail_magic
+ lda RB_PAGEBUF+2
+ cmp #'M'
+ bne @fail_magic
+ lda RB_PAGEBUF+3
+ cmp #'!'
+ bne @fail_magic
+ lda RB_PAGEBUF+4
+ cmp #1
+ bne @fail_version
+ lda RB_PAGEBUF+6
+ beq @fail_count
+ cmp #33
+ bcs @fail_count
+ sta rb_saved_count_lo
+ lda RB_PAGEBUF+7
+ cmp #33
+ bcs @fail_count
+ sta rb_saved_count_hi
+ jsr rb_zmodload_stash_descriptors
+ bcs @fail_bounds
+ jsr rb_zmodload_stash_payloads
+ bcs @fail_bounds
+ jsr rb_clear_slot_residency
+ lda rb_saved_count_lo
+ jmp @finish
+@fail_magic:
+ lda #242
+ jmp @finish
+@fail_version:
+ lda #243
+ jmp @finish
+@fail_count:
+ lda #244
+ jmp @finish
+@fail_bounds:
+ lda #245
+@finish:
+ pha
+ jsr rb_zmodload_close
+ pla
+ jmp @return_int
+@return_int:
+ sta RF_VAL_LO
+ lda #0
+ sta RF_STATUS
+ sta RF_VAL_HI
+ lda #RB_VAL_INT
+ sta RF_TAG
+ rts
+
+rb_zmodload_stash_descriptors:
+ lda rb_saved_count_lo
+ sta rb_copy_len_lo
+ lda #0
+ sta rb_copy_len_hi
+.repeat 5
+ asl rb_copy_len_lo
+ rol rb_copy_len_hi
+.endrepeat
+ lda RB_PAGEBUF+8
+ sta rb_reu_off_lo
+ lda RB_PAGEBUF+9
+ sta rb_reu_off_hi
+ cmp #>RB_REU_DESC_OFF
+ bcc @bad
+ cmp #>RB_REU_SLOT_STATE_OFF
+ bcs @bad
+ clc
+ lda rb_reu_off_lo
+ adc rb_copy_len_lo
+ tax
+ lda rb_reu_off_hi
+ adc rb_copy_len_hi
+ cmp #>RB_REU_SLOT_STATE_OFF
+ bcc @stream
+ bne @bad
+ txa
+ bne @bad
+@stream:
+ lda rb_reu_core_bank
+ sta rb_reu_bank
+ jmp rb_zmodload_stream_to_reu
+@bad:
+ sec
+ rts
+
+rb_zmodload_stash_payloads:
+ lda rb_saved_count_hi
+ sta rb_saved_count_hi
+ beq @done
+@loop:
+ lda #6
+ jsr rb_zmodload_read_pagebuf_bytes
+ bcs @bad
+ lda RB_PAGEBUF+2
+ ora RB_PAGEBUF+3
+ beq @bad
+ lda RB_PAGEBUF
+ sta rb_reu_off_lo
+ lda RB_PAGEBUF+1
+ sta rb_reu_off_hi
+ lda RB_PAGEBUF+2
+ sta rb_copy_len_lo
+ lda RB_PAGEBUF+3
+ sta rb_copy_len_hi
+ clc
+ lda rb_reu_off_lo
+ adc rb_copy_len_lo
+ lda rb_reu_off_hi
+ adc rb_copy_len_hi
+ bcs @bad
+ lda rb_reu_code_bank
+ sta rb_reu_bank
+ jsr rb_zmodload_stream_to_reu
+ bcs @bad
+ dec rb_saved_count_hi
+ bne @loop
+@done:
+ clc
+ rts
+@bad:
+ sec
+ rts
+
+rb_zmodload_read_pagebuf_bytes:
+ sta rb_copy_chunks
+ lda #0
+ sta rb_target_off
+@loop:
+ jsr rb_zmodload_read_byte
+ bcs @bad
+ ldy rb_target_off
+ sta RB_PAGEBUF,y
+ inc rb_target_off
+ dec rb_copy_chunks
+ bne @loop
+ clc
+ rts
+@bad:
+ sec
+ rts
+
+rb_zmodload_stream_to_reu:
+@more:
+ lda rb_copy_len_lo
+ ora rb_copy_len_hi
+ beq @done
+ lda rb_copy_len_hi
+ beq @last
+ lda #0
+ sta rb_reu_len_lo
+ lda #1
+ sta rb_reu_len_hi
+ jsr rb_zmodload_read_reu_chunk
+ bcs @bad
+ jsr rb_reu_stash
+ inc rb_reu_off_hi
+ dec rb_copy_len_hi
+ jmp @more
+@last:
+ lda rb_copy_len_lo
+ sta rb_reu_len_lo
+ lda #0
+ sta rb_reu_len_hi
+ jsr rb_zmodload_read_reu_chunk
+ bcs @bad
+ jsr rb_reu_stash
+ lda #0
+ sta rb_copy_len_lo
+@done:
+ clc
+ rts
+@bad:
+ sec
+ rts
+
+rb_zmodload_read_reu_chunk:
+ lda #RB_PAGEBUF
+ sta rb_reu_c64_hi
+ lda #0
+ sta rb_target_off
+@loop:
+ jsr rb_zmodload_read_byte
+ bcs @bad
+ ldy rb_target_off
+ sta RB_PAGEBUF,y
+ inc rb_target_off
+ lda rb_target_off
+ cmp rb_reu_len_lo
+ bne @loop
+ clc
+ rts
+@bad:
+ sec
+ rts
+
+rb_zmodload_read_byte:
+ lda rb_zmod_eof
+ bne @bad
+ jsr K_CHRIN
+ sta rb_lookup_char
+ jsr K_READST
+ beq @ok
+ cmp #$40
+ beq @eof
+ sec
+ lda rb_lookup_char
+ rts
+@eof:
+ lda #1
+ sta rb_zmod_eof
+@ok:
+ lda rb_lookup_char
+ clc
+ rts
+@bad:
+ sec
+ rts
+
+rb_zmodload_close:
+ lda rb_saved_msgflg
+ pha
+ jsr K_CLRCHN
+ lda #1
+ jsr K_CLOSE
+ pla
+ sta MSGFLG
+ rts
+cmd_zmodload_end:
+
+ .segment "SLOTPACK2"
+
+cmd_zslot2:
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_INT
+ sta RF_TAG
+ lda #32
+ sta RF_VAL_LO
+ lda #0
+ sta RF_VAL_HI
+ rts
+cmd_zslot2_end:
+
+cmd_plot:
+ jsr gfx_plot_current
+ jmp gfxprim_ok_none
+
+cmd_point:
+ jsr gfx_point_current
+ rts
+
+cmd_line:
+ lda CF_NUM2_LO
+ sta RF_ARRAY_BUF
+ lda CF_NUM2_HI
+ sta RF_ARRAY_BUF+1
+ lda CF_NUM3_LO
+ sta RF_ARRAY_BUF+2
+ lda CF_NUM3_HI
+ sta RF_ARRAY_BUF+3
+ lda CF_NUM4_LO
+ sta RF_ARRAY_BUF+4
+ lda CF_NUM4_HI
+ sta RF_ARRAY_BUF+5
+@loop:
+ lda RF_ARRAY_BUF+4
+ sta CF_NUM2_LO
+ lda RF_ARRAY_BUF+5
+ sta CF_NUM2_HI
+ jsr gfx_plot_current
+ lda CF_NUM0_LO
+ cmp RF_ARRAY_BUF
+ bne @step
+ lda CF_NUM0_HI
+ cmp RF_ARRAY_BUF+1
+ bne @step
+ lda CF_NUM1_LO
+ cmp RF_ARRAY_BUF+2
+ beq @done
+@step:
+ jsr gfx_step_x_toward_saved
+ jsr gfx_step_y_toward_saved
+ jmp @loop
+@done:
+ jmp gfxprim_ok_none
+
+cmd_rect:
+ jsr gfx_save_rect_args
+ jsr gfx_rect_top
+ jsr gfx_rect_bottom
+ jsr gfx_rect_left
+ jsr gfx_rect_right
+ jmp gfxprim_ok_none
+
+cmd_frect:
+ jsr gfx_save_rect_args
+ lda RF_RECT_BUF+2
+ sta CF_NUM1_LO
+@row:
+ jsr gfx_rect_row
+ lda CF_NUM1_LO
+ cmp RF_RECT_BUF+6
+ beq @done
+ inc CF_NUM1_LO
+ jmp @row
+@done:
+ jmp gfxprim_ok_none
+
+cmd_circle:
+ jsr gfx_save_circle_args
+ lda #0
+ sta RF_RECT_BUF+10
+ lda RF_RECT_BUF+4
+ sta RF_RECT_BUF+11
+ lda #3
+ sta RF_RECT_BUF+12
+ lda #0
+ sta RF_RECT_BUF+13
+ lda RF_RECT_BUF+4
+ asl
+ sta rb_digit_seen
+ lda #0
+ rol
+ sta rb_digit_count
+ lda RF_RECT_BUF+12
+ sec
+ sbc rb_digit_seen
+ sta RF_RECT_BUF+12
+ lda RF_RECT_BUF+13
+ sbc rb_digit_count
+ sta RF_RECT_BUF+13
+@loop:
+ lda RF_RECT_BUF+11
+ cmp RF_RECT_BUF+10
+ bcc @done
+ jsr gfx_circle_plot8
+ lda RF_RECT_BUF+13
+ bmi @dneg
+ lda RF_RECT_BUF+10
+ asl
+ asl
+ clc
+ adc #10
+ sta RF_RECT_BUF+14
+ lda #0
+ adc #0
+ sta RF_RECT_BUF+15
+ lda RF_RECT_BUF+11
+ asl
+ asl
+ sta rb_digit_seen
+ lda #0
+ rol
+ sta rb_digit_count
+ lda RF_RECT_BUF+14
+ sec
+ sbc rb_digit_seen
+ sta RF_RECT_BUF+14
+ lda RF_RECT_BUF+15
+ sbc rb_digit_count
+ sta RF_RECT_BUF+15
+ jsr gfx_circle_add_delta
+ dec RF_RECT_BUF+11
+ jmp @incx
+@dneg:
+ lda RF_RECT_BUF+10
+ asl
+ asl
+ clc
+ adc #6
+ sta RF_RECT_BUF+14
+ lda #0
+ adc #0
+ sta RF_RECT_BUF+15
+ jsr gfx_circle_add_delta
+@incx:
+ inc RF_RECT_BUF+10
+ jmp @loop
+@done:
+ jmp gfxprim_ok_none
+
+cmd_fcircle:
+ jsr gfx_save_circle_args
+ jsr gfx_circle_bbox_to_rect_args
+ jmp cmd_frect
+
+gfx_circle_add_delta:
+ lda RF_RECT_BUF+12
+ clc
+ adc RF_RECT_BUF+14
+ sta RF_RECT_BUF+12
+ lda RF_RECT_BUF+13
+ adc RF_RECT_BUF+15
+ sta RF_RECT_BUF+13
+ rts
+
+gfx_circle_plot_point:
+ lda #0
+ sta CF_NUM0_HI
+ sta CF_NUM1_HI
+ sta CF_NUM2_HI
+ lda RF_RECT_BUF+8
+ sta CF_NUM2_LO
+ jmp gfx_plot_current
+
+gfx_circle_plot8:
+ lda RF_RECT_BUF
+ clc
+ adc RF_RECT_BUF+10
+ sta CF_NUM0_LO
+ lda RF_RECT_BUF+2
+ clc
+ adc RF_RECT_BUF+11
+ sta CF_NUM1_LO
+ jsr gfx_circle_plot_point
+ lda RF_RECT_BUF
+ sec
+ sbc RF_RECT_BUF+10
+ sta CF_NUM0_LO
+ lda RF_RECT_BUF+2
+ clc
+ adc RF_RECT_BUF+11
+ sta CF_NUM1_LO
+ jsr gfx_circle_plot_point
+ lda RF_RECT_BUF
+ clc
+ adc RF_RECT_BUF+10
+ sta CF_NUM0_LO
+ lda RF_RECT_BUF+2
+ sec
+ sbc RF_RECT_BUF+11
+ sta CF_NUM1_LO
+ jsr gfx_circle_plot_point
+ lda RF_RECT_BUF
+ sec
+ sbc RF_RECT_BUF+10
+ sta CF_NUM0_LO
+ lda RF_RECT_BUF+2
+ sec
+ sbc RF_RECT_BUF+11
+ sta CF_NUM1_LO
+ jsr gfx_circle_plot_point
+ lda RF_RECT_BUF
+ clc
+ adc RF_RECT_BUF+11
+ sta CF_NUM0_LO
+ lda RF_RECT_BUF+2
+ clc
+ adc RF_RECT_BUF+10
+ sta CF_NUM1_LO
+ jsr gfx_circle_plot_point
+ lda RF_RECT_BUF
+ sec
+ sbc RF_RECT_BUF+11
+ sta CF_NUM0_LO
+ lda RF_RECT_BUF+2
+ clc
+ adc RF_RECT_BUF+10
+ sta CF_NUM1_LO
+ jsr gfx_circle_plot_point
+ lda RF_RECT_BUF
+ clc
+ adc RF_RECT_BUF+11
+ sta CF_NUM0_LO
+ lda RF_RECT_BUF+2
+ sec
+ sbc RF_RECT_BUF+10
+ sta CF_NUM1_LO
+ jsr gfx_circle_plot_point
+ lda RF_RECT_BUF
+ sec
+ sbc RF_RECT_BUF+11
+ sta CF_NUM0_LO
+ lda RF_RECT_BUF+2
+ sec
+ sbc RF_RECT_BUF+10
+ sta CF_NUM1_LO
+ jmp gfx_circle_plot_point
+
+gfx_circle_bbox_to_rect_args:
+ lda RF_RECT_BUF
+ sec
+ sbc RF_RECT_BUF+4
+ sta CF_NUM0_LO
+ lda #0
+ sta CF_NUM0_HI
+ lda RF_RECT_BUF+2
+ sec
+ sbc RF_RECT_BUF+4
+ sta CF_NUM1_LO
+ lda RF_RECT_BUF
+ clc
+ adc RF_RECT_BUF+4
+ sta CF_NUM2_LO
+ lda #0
+ sta CF_NUM2_HI
+ lda RF_RECT_BUF+2
+ clc
+ adc RF_RECT_BUF+4
+ sta CF_NUM3_LO
+ lda RF_RECT_BUF+8
+ sta CF_NUM4_LO
+ lda #0
+ sta CF_NUM1_HI
+ sta CF_NUM3_HI
+ sta CF_NUM4_HI
+ rts
+
+cmd_tile:
+ jsr gfx_get_mode_prim
+ cmp #RB_GFX_MODE_TEXT
+ beq @text
+ jsr gfx_calc_tile_addr
+ ldy #0
+ lda CF_NUM2_LO
+ sta (rb_ptr_lo),y
+ jsr gfx_screen_ptr_to_color
+ lda CF_NUM3_LO
+ and #$0F
+ sta (rb_ptr_lo),y
+ jmp gfxprim_ok_none
+@text:
+ jsr gfx_calc_tile_addr
+ lda rb_ptr_hi
+ sec
+ sbc #>RB_GFX_SCREEN
+ clc
+ adc #>SCREEN
+ sta rb_ptr_hi
+ ldy #0
+ lda CF_NUM2_LO
+ sta (rb_ptr_lo),y
+ jsr gfx_text_ptr_to_color
+ lda CF_NUM3_LO
+ and #$0F
+ sta (rb_ptr_lo),y
+ jmp gfxprim_ok_none
+
+gfx_save_circle_args:
+ lda CF_NUM0_LO
+ sta RF_RECT_BUF
+ lda CF_NUM1_LO
+ sta RF_RECT_BUF+2
+ lda CF_NUM2_LO
+ sta RF_RECT_BUF+4
+ lda CF_NUM3_LO
+ sta RF_RECT_BUF+8
+ rts
+
+gfxprim_ok_none:
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_NONE
+ sta RF_TAG
+ rts
+
+gfxprim_ok_int:
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_INT
+ sta RF_TAG
+ rts
+
+gfx_save_rect_args:
+ lda CF_NUM0_LO
+ sta RF_RECT_BUF
+ lda CF_NUM0_HI
+ sta RF_RECT_BUF+1
+ lda CF_NUM1_LO
+ sta RF_RECT_BUF+2
+ lda CF_NUM1_HI
+ sta RF_RECT_BUF+3
+ lda CF_NUM2_LO
+ sta RF_RECT_BUF+4
+ lda CF_NUM2_HI
+ sta RF_RECT_BUF+5
+ lda CF_NUM3_LO
+ sta RF_RECT_BUF+6
+ lda CF_NUM3_HI
+ sta RF_RECT_BUF+7
+ lda CF_NUM4_LO
+ sta RF_RECT_BUF+8
+ lda CF_NUM4_HI
+ sta RF_RECT_BUF+9
+ rts
+
+gfx_restore_color_to_num4:
+ lda RF_RECT_BUF+8
+ sta CF_NUM4_LO
+ lda RF_RECT_BUF+9
+ sta CF_NUM4_HI
+ rts
+
+gfx_rect_top:
+ lda RF_RECT_BUF
+ sta CF_NUM0_LO
+ lda RF_RECT_BUF+1
+ sta CF_NUM0_HI
+ lda RF_RECT_BUF+2
+ sta CF_NUM1_LO
+ lda RF_RECT_BUF+4
+ sta CF_NUM2_LO
+ lda RF_RECT_BUF+5
+ sta CF_NUM2_HI
+ lda RF_RECT_BUF+2
+ sta CF_NUM3_LO
+ jsr gfx_restore_color_to_num4
+ jmp cmd_line
+
+gfx_rect_bottom:
+ lda RF_RECT_BUF
+ sta CF_NUM0_LO
+ lda RF_RECT_BUF+1
+ sta CF_NUM0_HI
+ lda RF_RECT_BUF+6
+ sta CF_NUM1_LO
+ lda RF_RECT_BUF+4
+ sta CF_NUM2_LO
+ lda RF_RECT_BUF+5
+ sta CF_NUM2_HI
+ lda RF_RECT_BUF+6
+ sta CF_NUM3_LO
+ jsr gfx_restore_color_to_num4
+ jmp cmd_line
+
+gfx_rect_left:
+ lda RF_RECT_BUF
+ sta CF_NUM0_LO
+ lda RF_RECT_BUF+1
+ sta CF_NUM0_HI
+ lda RF_RECT_BUF+2
+ sta CF_NUM1_LO
+ lda RF_RECT_BUF
+ sta CF_NUM2_LO
+ lda RF_RECT_BUF+1
+ sta CF_NUM2_HI
+ lda RF_RECT_BUF+6
+ sta CF_NUM3_LO
+ jsr gfx_restore_color_to_num4
+ jmp cmd_line
+
+gfx_rect_right:
+ lda RF_RECT_BUF+4
+ sta CF_NUM0_LO
+ lda RF_RECT_BUF+5
+ sta CF_NUM0_HI
+ lda RF_RECT_BUF+2
+ sta CF_NUM1_LO
+ lda RF_RECT_BUF+4
+ sta CF_NUM2_LO
+ lda RF_RECT_BUF+5
+ sta CF_NUM2_HI
+ lda RF_RECT_BUF+6
+ sta CF_NUM3_LO
+ jsr gfx_restore_color_to_num4
+ jmp cmd_line
+
+gfx_rect_row:
+ lda RF_RECT_BUF
+ sta CF_NUM0_LO
+ lda RF_RECT_BUF+1
+ sta CF_NUM0_HI
+ lda RF_RECT_BUF+4
+ sta CF_NUM2_LO
+ lda RF_RECT_BUF+5
+ sta CF_NUM2_HI
+ lda CF_NUM1_LO
+ sta CF_NUM3_LO
+ jsr gfx_restore_color_to_num4
+ jmp cmd_line
+
+gfx_step_x_toward_saved:
+ lda CF_NUM0_HI
+ cmp RF_ARRAY_BUF+1
+ bcc @inc
+ bne @dec
+ lda CF_NUM0_LO
+ cmp RF_ARRAY_BUF
+ bcc @inc
+ beq @done
+@dec:
+ lda CF_NUM0_LO
+ bne :+
+ dec CF_NUM0_HI
+: dec CF_NUM0_LO
+ rts
+@inc:
+ inc CF_NUM0_LO
+ bne @done
+ inc CF_NUM0_HI
+@done:
+ rts
+
+gfx_step_y_toward_saved:
+ lda CF_NUM1_LO
+ cmp RF_ARRAY_BUF+2
+ bcc @inc
+ beq @done
+ dec CF_NUM1_LO
+ rts
+@inc:
+ inc CF_NUM1_LO
+@done:
+ rts
+
+gfx_plot_current:
+ jsr gfx_get_mode_prim
+ cmp #RB_GFX_MODE_TILE
+ beq @tile
+ cmp #RB_GFX_MODE_MTILE
+ beq @tile
+ cmp #RB_GFX_MODE_MBITMAP
+ beq @mbitmap
+ jsr gfx_calc_bitmap_addr
+ lda CPU_PORT
+ pha
+ and #RAM_UNDER_BASIC
+ sta CPU_PORT
+ ldy #0
+ lda (rb_ptr_lo),y
+ ldx CF_NUM2_LO
+ beq @clear
+ ldx rb_saved_plot_y
+ ora gfx_bit_masks,x
+ sta (rb_ptr_lo),y
+ pla
+ sta CPU_PORT
+ rts
+@clear:
+ ldx rb_saved_plot_y
+ and gfx_bit_unmasks,x
+ sta (rb_ptr_lo),y
+ pla
+ sta CPU_PORT
+ rts
+@tile:
+ jmp gfx_plot_tile
+@mbitmap:
+ jmp gfx_plot_mbitmap
+
+gfx_point_current:
+ jsr gfx_get_mode_prim
+ cmp #RB_GFX_MODE_TILE
+ beq @tile
+ cmp #RB_GFX_MODE_MTILE
+ beq @tile
+ cmp #RB_GFX_MODE_MBITMAP
+ beq @mbitmap
+ jsr gfx_calc_bitmap_addr
+ lda CPU_PORT
+ pha
+ and #RAM_UNDER_BASIC
+ sta CPU_PORT
+ ldy #0
+ lda (rb_ptr_lo),y
+ ldx rb_saved_plot_y
+ and gfx_bit_masks,x
+ beq @zero
+ lda #1
+ bne @ret
+@zero:
+ lda #0
+@ret:
+ sta RF_VAL_LO
+ lda #0
+ sta RF_VAL_HI
+ pla
+ sta CPU_PORT
+ jmp gfxprim_ok_int
+@mbitmap:
+ jmp gfx_point_mbitmap
+@tile:
+ jsr gfx_calc_tile_addr
+ ldy #0
+ lda (rb_ptr_lo),y
+ sta RF_VAL_LO
+ lda #0
+ sta RF_VAL_HI
+ jmp gfxprim_ok_int
+
+gfx_plot_mbitmap:
+ lda CF_NUM2_LO
+ beq @clear
+ jsr gfx_mbitmap_apply_attr
+ jsr gfx_calc_mbitmap_addr
+ lda CPU_PORT
+ pha
+ and #RAM_UNDER_BASIC
+ sta CPU_PORT
+ ldy #0
+ lda (rb_ptr_lo),y
+ ldx rb_saved_plot_y
+ and gfx_mbit_unmasks,x
+ sta rb_digit_seen
+ lda rb_digit_count
+ sec
+ sbc #1
+ asl
+ asl
+ clc
+ adc rb_saved_plot_y
+ tax
+ lda gfx_mbit_pair_masks,x
+ ora rb_digit_seen
+ sta (rb_ptr_lo),y
+ pla
+ sta CPU_PORT
+ rts
+@clear:
+ jsr gfx_calc_mbitmap_addr
+ lda CPU_PORT
+ pha
+ and #RAM_UNDER_BASIC
+ sta CPU_PORT
+ ldy #0
+ lda (rb_ptr_lo),y
+ ldx rb_saved_plot_y
+ and gfx_mbit_unmasks,x
+ sta (rb_ptr_lo),y
+ pla
+ sta CPU_PORT
+ rts
+
+gfx_point_mbitmap:
+ jsr gfx_calc_mbitmap_addr
+ lda CPU_PORT
+ pha
+ and #RAM_UNDER_BASIC
+ sta CPU_PORT
+ ldy #0
+ lda (rb_ptr_lo),y
+ sta rb_digit_seen
+ pla
+ sta CPU_PORT
+ lda rb_saved_plot_y
+ clc
+ adc #8
+ tax
+ lda rb_digit_seen
+ and gfx_mbit_pair_masks,x
+ cmp gfx_mbit_pair_masks,x
+ beq @three
+ lda rb_saved_plot_y
+ clc
+ adc #4
+ tax
+ lda rb_digit_seen
+ and gfx_mbit_pair_masks,x
+ bne @two
+ ldx rb_saved_plot_y
+ lda rb_digit_seen
+ and gfx_mbit_pair_masks,x
+ bne @one
+ lda #0
+ beq @store
+@one:
+ lda #1
+ bne @store
+@two:
+ lda #2
+ bne @store
+@three:
+ lda #3
+@store:
+ sta RF_VAL_LO
+ lda #0
+ sta RF_VAL_HI
+ jmp gfxprim_ok_int
+
+gfx_plot_tile:
+ jsr gfx_calc_tile_addr
+ ldy #0
+ lda CF_NUM2_LO
+ and #$3F
+ ora #$40
+ sta (rb_ptr_lo),y
+ jsr gfx_screen_ptr_to_color
+ lda CF_NUM2_LO
+ and #$0F
+ sta (rb_ptr_lo),y
+ rts
+
+gfx_screen_ptr_to_color:
+ lda rb_ptr_hi
+ sec
+ sbc #>RB_GFX_SCREEN
+ clc
+ adc #>RB_GFX_COLOR
+ sta rb_ptr_hi
+ rts
+
+gfx_text_ptr_to_color:
+ lda rb_ptr_hi
+ sec
+ sbc #>SCREEN
+ clc
+ adc #>COLOR_RAM
+ sta rb_ptr_hi
+ rts
+
+gfx_calc_tile_addr:
+ lda #RB_GFX_SCREEN
+ sta rb_ptr_hi
+ lda CF_NUM1_LO
+ asl
+ asl
+ asl
+ sta rb_saved_plot_x
+ lda CF_NUM1_LO
+ asl
+ asl
+ asl
+ asl
+ asl
+ clc
+ adc rb_saved_plot_x
+ clc
+ adc CF_NUM0_LO
+ sta rb_ptr_lo
+ lda #>RB_GFX_SCREEN
+ adc #0
+ sta rb_ptr_hi
+ rts
+
+gfx_get_mode_prim:
+ lda RB_GFX_MODE_STATE
+ cmp #RB_GFX_MODE_MTILE + 1
+ bcc :+
+ lda #RB_GFX_MODE_TEXT
+: rts
+
+gfx_calc_bitmap_addr:
+ lda CF_NUM1_LO
+ and #7
+ sta rb_saved_plot_x
+ lda CF_NUM0_LO
+ and #7
+ sta rb_saved_plot_y
+ lda CF_NUM1_LO
+ lsr
+ lsr
+ lsr
+ sta rb_digit_seen
+ lda rb_digit_seen
+ and #3
+ asl
+ asl
+ asl
+ asl
+ asl
+ asl
+ sta rb_ptr_lo
+ lda #>RB_GFX_BITMAP
+ clc
+ adc rb_digit_seen
+ sta rb_ptr_hi
+ lda rb_digit_seen
+ lsr
+ lsr
+ clc
+ adc rb_ptr_hi
+ sta rb_ptr_hi
+ lda CF_NUM0_LO
+ and #$F8
+ clc
+ adc rb_ptr_lo
+ sta rb_ptr_lo
+ bcc :+
+ inc rb_ptr_hi
+: lda CF_NUM0_HI
+ clc
+ adc rb_ptr_hi
+ sta rb_ptr_hi
+ lda rb_saved_plot_x
+ clc
+ adc rb_ptr_lo
+ sta rb_ptr_lo
+ bcc :+
+ inc rb_ptr_hi
+: rts
+
+gfx_calc_mbitmap_addr:
+ lda CF_NUM1_LO
+ and #7
+ sta rb_saved_plot_x
+ lda CF_NUM0_LO
+ and #3
+ sta rb_saved_plot_y
+ lda CF_NUM1_LO
+ lsr
+ lsr
+ lsr
+ sta rb_digit_seen
+ lda rb_digit_seen
+ and #3
+ asl
+ asl
+ asl
+ asl
+ asl
+ asl
+ sta rb_ptr_lo
+ lda #>RB_GFX_BITMAP
+ clc
+ adc rb_digit_seen
+ sta rb_ptr_hi
+ lda rb_digit_seen
+ lsr
+ lsr
+ clc
+ adc rb_ptr_hi
+ sta rb_ptr_hi
+ lda CF_NUM0_LO
+ and #$FC
+ asl
+ clc
+ adc rb_ptr_lo
+ sta rb_ptr_lo
+ bcc :+
+ inc rb_ptr_hi
+: lda rb_saved_plot_x
+ clc
+ adc rb_ptr_lo
+ sta rb_ptr_lo
+ bcc :+
+ inc rb_ptr_hi
+: rts
+
+gfx_calc_mbitmap_cell_addr:
+ lda #RB_GFX_SCREEN
+ sta rb_ptr_hi
+ lda CF_NUM1_LO
+ lsr
+ lsr
+ lsr
+ sta rb_digit_seen
+ asl
+ asl
+ asl
+ sta rb_saved_plot_x
+ lda rb_digit_seen
+ asl
+ asl
+ asl
+ asl
+ asl
+ clc
+ adc rb_saved_plot_x
+ sta rb_ptr_lo
+ lda #>RB_GFX_SCREEN
+ adc #0
+ sta rb_ptr_hi
+ lda CF_NUM0_LO
+ lsr
+ lsr
+ clc
+ adc rb_ptr_lo
+ sta rb_ptr_lo
+ bcc :+
+ inc rb_ptr_hi
+: rts
+
+gfx_mbitmap_apply_attr:
+ lda CF_NUM2_LO
+ cmp #16
+ bcc @slot3
+ cmp #32
+ bcc @slot1
+ cmp #48
+ bcc @slot2
+@slot3:
+ lda #3
+ sta rb_digit_count
+ jsr gfx_calc_mbitmap_cell_addr
+ jsr gfx_screen_ptr_to_color
+ ldy #0
+ lda CF_NUM2_LO
+ and #$0F
+ sta (rb_ptr_lo),y
+ rts
+@slot1:
+ lda #1
+ sta rb_digit_count
+ jsr gfx_calc_mbitmap_cell_addr
+ ldy #0
+ lda (rb_ptr_lo),y
+ and #$0F
+ sta rb_digit_seen
+ lda CF_NUM2_LO
+ and #$0F
+ asl
+ asl
+ asl
+ asl
+ ora rb_digit_seen
+ sta (rb_ptr_lo),y
+ rts
+@slot2:
+ lda #2
+ sta rb_digit_count
+ jsr gfx_calc_mbitmap_cell_addr
+ ldy #0
+ lda (rb_ptr_lo),y
+ and #$F0
+ sta rb_digit_seen
+ lda CF_NUM2_LO
+ and #$0F
+ ora rb_digit_seen
+ sta (rb_ptr_lo),y
+ rts
+
+gfx_bit_masks:
+ .byte $80,$40,$20,$10,$08,$04,$02,$01
+gfx_bit_unmasks:
+ .byte $7F,$BF,$DF,$EF,$F7,$FB,$FD,$FE
+gfx_mbit_pair_masks:
+ .byte $40,$10,$04,$01,$80,$20,$08,$02,$C0,$30,$0C,$03
+gfx_mbit_unmasks:
+ .byte $3F,$CF,$F3,$FC
+
+ .segment "SPANPACK"
+
+cmd_zspan:
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_INT
+ sta RF_TAG
+ lda #40
+ sta RF_VAL_LO
+ lda #0
+ sta RF_VAL_HI
+ rts
+cmd_zspan_end:
+
+ .segment "OVL1PACK"
+
+cmd_zovl1:
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_INT
+ sta RF_TAG
+ lda #51
+ sta RF_VAL_LO
+ lda #0
+ sta RF_VAL_HI
+ rts
+cmd_zovl1_end:
+
+cmd_sprset:
+ lda CF_NUM0_LO
+ and #7
+ sta CF_NUM0_LO
+ jsr gfx_sprite_pattern
+ ldx CF_NUM0_LO
+ lda gfx_sprite_bits,x
+ ldy CF_NUM1_LO
+ beq @off
+ ora VIC_SPR_ENABLE
+ sta VIC_SPR_ENABLE
+ jmp @color
+@off:
+ eor #$FF
+ and VIC_SPR_ENABLE
+ sta VIC_SPR_ENABLE
+@color:
+ lda CF_NUM2_LO
+ and #$0F
+ ldx CF_NUM0_LO
+ sta VIC_SPR_COLOR0,x
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_NONE
+ sta RF_TAG
+ rts
+
+cmd_sprmove:
+ lda CF_NUM0_LO
+ and #7
+ sta CF_NUM0_LO
+ ldx CF_NUM0_LO
+ txa
+ asl
+ tax
+ lda CF_NUM1_LO
+ sta $D000,x
+ lda CF_NUM2_LO
+ sta $D001,x
+ ldx CF_NUM0_LO
+ lda gfx_sprite_bits,x
+ ldy CF_NUM1_HI
+ beq @clear_msb
+ ora VIC_SPR_X_MSB
+ sta VIC_SPR_X_MSB
+ jmp @done
+@clear_msb:
+ eor #$FF
+ and VIC_SPR_X_MSB
+ sta VIC_SPR_X_MSB
+@done:
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_NONE
+ sta RF_TAG
+ rts
+
+cmd_sprcolor:
+ lda CF_NUM0_LO
+ and #7
+ sta CF_NUM0_LO
+ ldx CF_NUM0_LO
+ lda CF_NUM1_LO
+ and #$0F
+ sta VIC_SPR_COLOR0,x
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_NONE
+ sta RF_TAG
+ rts
+
+cmd_sprexpand:
+ lda CF_NUM0_LO
+ and #7
+ tax
+ lda gfx_sprite_bits,x
+ sta rb_saved_plot_x
+ lda CF_NUM1_LO
+ beq @xoff
+ lda rb_saved_plot_x
+ ora VIC_SPR_EXP_X
+ sta VIC_SPR_EXP_X
+ jmp @y
+@xoff:
+ lda rb_saved_plot_x
+ eor #$FF
+ and VIC_SPR_EXP_X
+ sta VIC_SPR_EXP_X
+@y:
+ lda CF_NUM2_LO
+ beq @yoff
+ lda rb_saved_plot_x
+ ora VIC_SPR_EXP_Y
+ sta VIC_SPR_EXP_Y
+ jmp gfx_ok_none_ovl1
+@yoff:
+ lda rb_saved_plot_x
+ eor #$FF
+ and VIC_SPR_EXP_Y
+ sta VIC_SPR_EXP_Y
+ jmp gfx_ok_none_ovl1
+
+cmd_sprpri:
+ lda CF_NUM0_LO
+ and #7
+ tax
+ lda gfx_sprite_bits,x
+ sta rb_saved_plot_x
+ lda CF_NUM1_LO
+ beq @front
+ lda rb_saved_plot_x
+ ora VIC_SPR_PRIORITY
+ sta VIC_SPR_PRIORITY
+ jmp gfx_ok_none_ovl1
+@front:
+ lda rb_saved_plot_x
+ eor #$FF
+ and VIC_SPR_PRIORITY
+ sta VIC_SPR_PRIORITY
+ jmp gfx_ok_none_ovl1
+
+cmd_sprmulti:
+ lda CF_NUM0_LO
+ and #7
+ tax
+ lda gfx_sprite_bits,x
+ sta rb_saved_plot_x
+ lda CF_NUM1_LO
+ beq @single
+ lda rb_saved_plot_x
+ ora VIC_SPR_MCOLOR
+ sta VIC_SPR_MCOLOR
+ jmp gfx_ok_none_ovl1
+@single:
+ lda rb_saved_plot_x
+ eor #$FF
+ and VIC_SPR_MCOLOR
+ sta VIC_SPR_MCOLOR
+ jmp gfx_ok_none_ovl1
+
+cmd_sprmcolor:
+ lda CF_NUM0_LO
+ and #$0F
+ sta VIC_SPR_MCOLOR0
+ lda CF_NUM1_LO
+ and #$0F
+ sta VIC_SPR_MCOLOR1
+ jmp gfx_ok_none_ovl1
+
+cmd_sprrow:
+ lda CF_NUM1_LO
+ cmp #21
+ bcc :+
+ jmp gfx_ok_none_ovl1
+: lda CPU_PORT
+ pha
+ and #RAM_UNDER_BASIC
+ sta CPU_PORT
+ lda CF_NUM0_LO
+ and #7
+ sta CF_NUM0_LO
+ ldx CF_NUM0_LO
+ lda #RB_GFX_SPRITES
+ sta rb_ptr_hi
+ cpx #0
+ beq @row_offset
+@sprite_advance:
+ clc
+ lda rb_ptr_lo
+ adc #64
+ sta rb_ptr_lo
+ bcc :+
+ inc rb_ptr_hi
+: dex
+ bne @sprite_advance
+@row_offset:
+ lda CF_NUM1_LO
+ asl
+ clc
+ adc CF_NUM1_LO
+ tay
+ lda CF_NUM2_LO
+ sta (rb_ptr_lo),y
+ iny
+ lda CF_NUM3_LO
+ sta (rb_ptr_lo),y
+ iny
+ lda CF_NUM4_LO
+ sta (rb_ptr_lo),y
+ pla
+ sta CPU_PORT
+ lda CF_NUM0_LO
+ clc
+ adc #<(RB_GFX_SPRITES / 64)
+ ldx CF_NUM0_LO
+ sta RB_GFX_SPR_PTRS,x
+gfx_ok_none_ovl1:
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_NONE
+ sta RF_TAG
+ rts
+
+cmd_sprscan:
+ lda VIC_SPR_COLL
+ lda VIC_BG_COLL
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_NONE
+ sta RF_TAG
+ rts
+
+cmd_sprcoll:
+ lda CF_NUM0_LO
+ and #7
+ sta CF_NUM0_LO
+ ldx CF_NUM0_LO
+ lda gfx_sprite_bits,x
+ and VIC_SPR_COLL
+ beq @zero
+ lda #1
+ bne @ret
+@zero:
+ lda #0
+@ret:
+ sta RF_VAL_LO
+ lda #0
+ sta RF_STATUS
+ sta RF_VAL_HI
+ lda #RB_VAL_INT
+ sta RF_TAG
+ rts
+
+gfx_sprite_pattern:
+ lda CPU_PORT
+ pha
+ and #RAM_UNDER_BASIC
+ sta CPU_PORT
+ ldx CF_NUM0_LO
+ lda #RB_GFX_SPRITES
+ sta rb_ptr_hi
+ cpx #0
+ beq @fill
+@advance:
+ clc
+ lda rb_ptr_lo
+ adc #64
+ sta rb_ptr_lo
+ bcc :+
+ inc rb_ptr_hi
+: dex
+ bne @advance
+@fill:
+ lda CF_NUM3_LO
+ asl
+ tax
+ lda gfx_sprite_patterns,x
+ sta rb_saved_plot_x
+ lda gfx_sprite_patterns+1,x
+ sta rb_saved_plot_y
+ ldy #0
+@loop:
+ lda rb_saved_plot_x
+ sta (rb_ptr_lo),y
+ iny
+ lda rb_saved_plot_y
+ sta (rb_ptr_lo),y
+ iny
+ lda #0
+ sta (rb_ptr_lo),y
+ iny
+ cpy #63
+ bcc @loop
+ pla
+ sta CPU_PORT
+ lda CF_NUM0_LO
+ clc
+ adc #<(RB_GFX_SPRITES / 64)
+ ldx CF_NUM0_LO
+ sta RB_GFX_SPR_PTRS,x
+ rts
+
+gfx_sprite_bits:
+ .byte $01,$02,$04,$08,$10,$20,$40,$80
+gfx_sprite_patterns:
+ .byte $FF,$FF
+ .byte $81,$81
+ .byte $18,$18
+ .byte $3C,$3C
+
+ .segment "OVL2PACK"
+
+cmd_zovl2:
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_INT
+ sta RF_TAG
+ lda #52
+ sta RF_VAL_LO
+ lda #0
+ sta RF_VAL_HI
+ rts
+cmd_zovl2_end:
+
+cmd_joy:
+ lda CF_NUM0_LO
+ cmp #2
+ beq @port2
+ lda CIA1_PRA
+ jmp @finish
+@port2:
+ lda CIA1_PRB
+@finish:
+ eor #$FF
+ and #$1F
+ sta RF_VAL_LO
+ lda #0
+ sta RF_STATUS
+ sta RF_VAL_HI
+ lda #RB_VAL_INT
+ sta RF_TAG
+ rts
+
+cmd_keyp:
+ lda KEYD_COUNT
+ beq @none
+ lda KEYD_BUFFER
+ bne @store
+@none:
+ lda #0
+@store:
+ sta RF_VAL_LO
+ lda #0
+ sta RF_STATUS
+ sta RF_VAL_HI
+ lda #RB_VAL_INT
+ sta RF_TAG
+ rts
+
+cmd_keyscan:
+ jmp cmd_keyp
+
+cmd_keylast:
+ lda KEYD_BUFFER
+ sta RF_VAL_LO
+ lda #0
+ sta RF_STATUS
+ sta RF_VAL_HI
+ lda #RB_VAL_INT
+ sta RF_TAG
+ rts
+
+ .segment "OVL4PACK"
+
+cmd_dlnew:
+ lda CF_NUM0_HI
+ bne @bad
+ lda CF_NUM0_LO
+ beq @bad
+ cmp #RB_DL_MAX_RECORDS + 1
+ bcs @bad
+ lda #1
+ sta rb_needed_pages
+ lda #RB_HANDLE_TYPE_DLIST
+ sta rb_handle_new_type
+ jsr dl_handle_alloc_with_pages
+ lda RF_STATUS
+ bne @done
+ jsr dl_handle_load_result
+ jsr dl_clear_loaded_page
+@done:
+ rts
+@bad:
+ lda #$61
+ jmp dl_fail
+
+cmd_dlclr:
+ jsr dl_load_dlist_handle
+ bcs @bad
+ jsr dl_clear_loaded_page
+ jmp dl_ok
+@bad:
+ lda #$24
+ jmp dl_fail
+
+cmd_dlplot:
+ jsr dl_load_dlist_handle
+ bcs @bad
+ lda #1
+ jsr dl_append_begin
+ bcs @full
+ lda CF_NUM1_LO
+ sta RB_PAGEBUF+1,y
+ lda CF_NUM2_LO
+ sta RB_PAGEBUF+2,y
+ lda CF_NUM1_LO
+ sta RB_PAGEBUF+3,y
+ lda CF_NUM2_LO
+ sta RB_PAGEBUF+4,y
+ lda CF_NUM3_LO
+ sta RB_PAGEBUF+5,y
+ jsr dl_stash_handle_page
+ jmp dl_ok
+@bad:
+ lda #$24
+ jmp dl_fail
+@full:
+ lda #$62
+ jmp dl_fail
+
+cmd_dlline:
+ lda #2
+ bne dl_append_six
+cmd_dlrect:
+ lda #3
+ bne dl_append_six
+cmd_dlfrect:
+ lda #4
+dl_append_six:
+ pha
+ jsr dl_load_dlist_handle
+ bcs @bad
+ pla
+ jsr dl_append_begin
+ bcs @full
+ lda CF_NUM1_LO
+ sta RB_PAGEBUF+1,y
+ lda CF_NUM2_LO
+ sta RB_PAGEBUF+2,y
+ lda CF_NUM3_LO
+ sta RB_PAGEBUF+3,y
+ lda CF_NUM4_LO
+ sta RB_PAGEBUF+4,y
+ lda #1
+ sta RB_PAGEBUF+5,y
+ jsr dl_stash_handle_page
+ jmp dl_ok
+@bad:
+ pla
+ lda #$24
+ jmp dl_fail
+@full:
+ lda #$62
+ jmp dl_fail
+
+cmd_dldraw:
+ jsr dl_load_dlist_handle
+ bcs @bad
+ jsr dl_fetch_handle_page
+ lda RB_PAGEBUF
+ sta rb_copy_count
+ lda #0
+ sta rb_copy_chunks
+@loop:
+ lda rb_copy_chunks
+ cmp rb_copy_count
+ bcs @done
+ jsr dl_record_y
+ lda RB_PAGEBUF,y
+ cmp #1
+ beq @plot
+ cmp #2
+ beq @line
+ cmp #3
+ beq @rect
+ cmp #4
+ beq @frect
+@next:
+ inc rb_copy_chunks
+ jmp @loop
+@plot:
+ jsr dl_load_record_nums
+ lda CF_NUM4_LO
+ sta CF_NUM2_LO
+ lda #0
+ sta CF_NUM2_HI
+ jsr dl_plot_current
+ jmp @next
+@line:
+ jsr dl_load_record_nums
+ jsr dl_line
+ jmp @next
+@rect:
+ jsr dl_load_record_nums
+ jsr dl_rect
+ jmp @next
+@frect:
+ jsr dl_load_record_nums
+ jsr dl_frect
+ jmp @next
+@done:
+ jmp dl_ok
+@bad:
+ lda #$24
+ jmp dl_fail
+
+dl_handle_load_result:
+ lda RF_VAL_LO
+ sta CF_NUM0_LO
+ lda RF_VAL_HI
+ sta CF_NUM0_HI
+ jmp dl_load_dlist_handle
+
+dl_load_dlist_handle:
+ jsr dl_handle_load_arg
+ bcs @bad
+ lda rb_handle_type
+ cmp #RB_HANDLE_TYPE_DLIST
+ bne @bad
+ clc
+ rts
+@bad:
+ sec
+ rts
+
+dl_clear_loaded_page:
+ lda #0
+ tay
+@loop:
+ sta RB_PAGEBUF,y
+ iny
+ bne @loop
+ jmp dl_stash_handle_page
+
+dl_append_begin:
+ pha
+ jsr dl_fetch_handle_page
+ lda RB_PAGEBUF
+ cmp #RB_DL_MAX_RECORDS
+ bcs @full
+ sta rb_copy_chunks
+ inc RB_PAGEBUF
+ jsr dl_record_y
+ pla
+ sta RB_PAGEBUF,y
+ clc
+ rts
+@full:
+ pla
+ sec
+ rts
+
+dl_record_y:
+ lda rb_copy_chunks
+ asl
+ asl
+ asl
+ clc
+ adc #1
+ tay
+ rts
+
+dl_load_record_nums:
+ iny
+ lda RB_PAGEBUF,y
+ sta CF_NUM0_LO
+ lda #0
+ sta CF_NUM0_HI
+ iny
+ lda RB_PAGEBUF,y
+ sta CF_NUM1_LO
+ lda #0
+ sta CF_NUM1_HI
+ iny
+ lda RB_PAGEBUF,y
+ sta CF_NUM2_LO
+ lda #0
+ sta CF_NUM2_HI
+ iny
+ lda RB_PAGEBUF,y
+ sta CF_NUM3_LO
+ lda #0
+ sta CF_NUM3_HI
+ iny
+ lda RB_PAGEBUF,y
+ sta CF_NUM4_LO
+ lda #0
+ sta CF_NUM4_HI
+ rts
+
+dl_line:
+ lda CF_NUM2_LO
+ sta RF_ARRAY_BUF
+ lda CF_NUM3_LO
+ sta RF_ARRAY_BUF+2
+ lda CF_NUM4_LO
+ sta RF_ARRAY_BUF+4
+@loop:
+ lda RF_ARRAY_BUF+4
+ sta CF_NUM2_LO
+ jsr dl_plot_current
+ lda CF_NUM0_LO
+ cmp RF_ARRAY_BUF
+ bne @step
+ lda CF_NUM1_LO
+ cmp RF_ARRAY_BUF+2
+ beq @done
+@step:
+ jsr dl_step_x
+ jsr dl_step_y
+ jmp @loop
+@done:
+ rts
+
+dl_rect:
+ jsr dl_save_rect
+ jsr dl_rect_top
+ jsr dl_rect_bottom
+ jsr dl_rect_left
+ jmp dl_rect_right
+
+dl_frect:
+ jsr dl_save_rect
+ lda RF_RECT_BUF+2
+ sta CF_NUM1_LO
+@row:
+ jsr dl_rect_row
+ lda CF_NUM1_LO
+ cmp RF_RECT_BUF+6
+ beq @done
+ inc CF_NUM1_LO
+ jmp @row
+@done:
+ rts
+
+dl_save_rect:
+ lda CF_NUM0_LO
+ sta RF_RECT_BUF
+ lda CF_NUM1_LO
+ sta RF_RECT_BUF+2
+ lda CF_NUM2_LO
+ sta RF_RECT_BUF+4
+ lda CF_NUM3_LO
+ sta RF_RECT_BUF+6
+ lda CF_NUM4_LO
+ sta RF_RECT_BUF+8
+ rts
+
+dl_rect_top:
+ lda RF_RECT_BUF
+ sta CF_NUM0_LO
+ lda RF_RECT_BUF+2
+ sta CF_NUM1_LO
+ lda RF_RECT_BUF+4
+ sta CF_NUM2_LO
+ lda RF_RECT_BUF+2
+ sta CF_NUM3_LO
+ lda RF_RECT_BUF+8
+ sta CF_NUM4_LO
+ jmp dl_line
+dl_rect_bottom:
+ lda RF_RECT_BUF
+ sta CF_NUM0_LO
+ lda RF_RECT_BUF+6
+ sta CF_NUM1_LO
+ lda RF_RECT_BUF+4
+ sta CF_NUM2_LO
+ lda RF_RECT_BUF+6
+ sta CF_NUM3_LO
+ lda RF_RECT_BUF+8
+ sta CF_NUM4_LO
+ jmp dl_line
+dl_rect_left:
+ lda RF_RECT_BUF
+ sta CF_NUM0_LO
+ lda RF_RECT_BUF+2
+ sta CF_NUM1_LO
+ lda RF_RECT_BUF
+ sta CF_NUM2_LO
+ lda RF_RECT_BUF+6
+ sta CF_NUM3_LO
+ lda RF_RECT_BUF+8
+ sta CF_NUM4_LO
+ jmp dl_line
+dl_rect_right:
+ lda RF_RECT_BUF+4
+ sta CF_NUM0_LO
+ lda RF_RECT_BUF+2
+ sta CF_NUM1_LO
+ lda RF_RECT_BUF+4
+ sta CF_NUM2_LO
+ lda RF_RECT_BUF+6
+ sta CF_NUM3_LO
+ lda RF_RECT_BUF+8
+ sta CF_NUM4_LO
+ jmp dl_line
+dl_rect_row:
+ lda RF_RECT_BUF
+ sta CF_NUM0_LO
+ lda RF_RECT_BUF+4
+ sta CF_NUM2_LO
+ lda CF_NUM1_LO
+ sta CF_NUM3_LO
+ lda RF_RECT_BUF+8
+ sta CF_NUM4_LO
+ jmp dl_line
+
+dl_step_x:
+ lda CF_NUM0_LO
+ cmp RF_ARRAY_BUF
+ bcc @inc
+ beq @done
+ dec CF_NUM0_LO
+ rts
+@inc:
+ inc CF_NUM0_LO
+@done:
+ rts
+
+dl_step_y:
+ lda CF_NUM1_LO
+ cmp RF_ARRAY_BUF+2
+ bcc @inc
+ beq @done
+ dec CF_NUM1_LO
+ rts
+@inc:
+ inc CF_NUM1_LO
+@done:
+ rts
+
+dl_plot_current:
+ jsr dl_get_mode
+ cmp #RB_GFX_MODE_TILE
+ beq dl_plot_tile
+ cmp #RB_GFX_MODE_MTILE
+ beq dl_plot_tile
+ cmp #RB_GFX_MODE_MBITMAP
+ beq dl_plot_mbitmap
+ jsr dl_calc_bitmap_addr
+ lda CPU_PORT
+ pha
+ and #RAM_UNDER_BASIC
+ sta CPU_PORT
+ ldy #0
+ lda (rb_ptr_lo),y
+ ldx CF_NUM2_LO
+ beq @clear
+ ldx rb_saved_plot_y
+ ora dl_bit_masks,x
+ sta (rb_ptr_lo),y
+ pla
+ sta CPU_PORT
+ rts
+@clear:
+ ldx rb_saved_plot_y
+ and dl_bit_unmasks,x
+ sta (rb_ptr_lo),y
+ pla
+ sta CPU_PORT
+ rts
+
+dl_plot_tile:
+ jsr dl_calc_tile_addr
+ ldy #0
+ lda CF_NUM2_LO
+ and #$3F
+ ora #$40
+ sta (rb_ptr_lo),y
+ lda rb_ptr_hi
+ sec
+ sbc #>RB_GFX_SCREEN
+ clc
+ adc #>RB_GFX_COLOR
+ sta rb_ptr_hi
+ lda CF_NUM2_LO
+ and #$0F
+ sta (rb_ptr_lo),y
+ rts
+
+dl_plot_mbitmap:
+ lda CF_NUM2_LO
+ beq @clear
+ jsr dl_mbitmap_apply_attr
+ jsr dl_calc_mbitmap_addr
+ lda CPU_PORT
+ pha
+ and #RAM_UNDER_BASIC
+ sta CPU_PORT
+ ldy #0
+ lda (rb_ptr_lo),y
+ ldx rb_saved_plot_y
+ and dl_mbit_unmasks,x
+ sta rb_digit_seen
+ lda rb_digit_count
+ sec
+ sbc #1
+ asl
+ asl
+ clc
+ adc rb_saved_plot_y
+ tax
+ lda dl_mbit_pair_masks,x
+ ora rb_digit_seen
+ sta (rb_ptr_lo),y
+ pla
+ sta CPU_PORT
+ rts
+@clear:
+ jsr dl_calc_mbitmap_addr
+ lda CPU_PORT
+ pha
+ and #RAM_UNDER_BASIC
+ sta CPU_PORT
+ ldy #0
+ lda (rb_ptr_lo),y
+ ldx rb_saved_plot_y
+ and dl_mbit_unmasks,x
+ sta (rb_ptr_lo),y
+ pla
+ sta CPU_PORT
+ rts
+
+dl_get_mode:
+ lda RB_GFX_MODE_STATE
+ cmp #RB_GFX_MODE_MTILE + 1
+ bcc :+
+ lda #RB_GFX_MODE_TEXT
+: rts
+
+dl_calc_tile_addr:
+ lda #RB_GFX_SCREEN
+ sta rb_ptr_hi
+ lda CF_NUM1_LO
+ asl
+ asl
+ asl
+ sta rb_saved_plot_x
+ lda CF_NUM1_LO
+ asl
+ asl
+ asl
+ asl
+ asl
+ clc
+ adc rb_saved_plot_x
+ clc
+ adc CF_NUM0_LO
+ sta rb_ptr_lo
+ lda #>RB_GFX_SCREEN
+ adc #0
+ sta rb_ptr_hi
+ rts
+
+dl_calc_bitmap_addr:
+ lda CF_NUM1_LO
+ and #7
+ sta rb_saved_plot_x
+ lda CF_NUM0_LO
+ and #7
+ sta rb_saved_plot_y
+ lda CF_NUM1_LO
+ lsr
+ lsr
+ lsr
+ sta rb_digit_seen
+ lda rb_digit_seen
+ and #3
+ asl
+ asl
+ asl
+ asl
+ asl
+ asl
+ sta rb_ptr_lo
+ lda #>RB_GFX_BITMAP
+ clc
+ adc rb_digit_seen
+ sta rb_ptr_hi
+ lda rb_digit_seen
+ lsr
+ lsr
+ clc
+ adc rb_ptr_hi
+ sta rb_ptr_hi
+ lda CF_NUM0_LO
+ and #$F8
+ clc
+ adc rb_ptr_lo
+ sta rb_ptr_lo
+ bcc :+
+ inc rb_ptr_hi
+: lda CF_NUM0_HI
+ clc
+ adc rb_ptr_hi
+ sta rb_ptr_hi
+ lda rb_saved_plot_x
+ clc
+ adc rb_ptr_lo
+ sta rb_ptr_lo
+ bcc :+
+ inc rb_ptr_hi
+: rts
+
+dl_calc_mbitmap_addr:
+ lda CF_NUM1_LO
+ and #7
+ sta rb_saved_plot_x
+ lda CF_NUM0_LO
+ and #3
+ sta rb_saved_plot_y
+ lda CF_NUM1_LO
+ lsr
+ lsr
+ lsr
+ sta rb_digit_seen
+ lda rb_digit_seen
+ and #3
+ asl
+ asl
+ asl
+ asl
+ asl
+ asl
+ sta rb_ptr_lo
+ lda #>RB_GFX_BITMAP
+ clc
+ adc rb_digit_seen
+ sta rb_ptr_hi
+ lda rb_digit_seen
+ lsr
+ lsr
+ clc
+ adc rb_ptr_hi
+ sta rb_ptr_hi
+ lda CF_NUM0_LO
+ and #$FC
+ asl
+ clc
+ adc rb_ptr_lo
+ sta rb_ptr_lo
+ bcc :+
+ inc rb_ptr_hi
+: lda rb_saved_plot_x
+ clc
+ adc rb_ptr_lo
+ sta rb_ptr_lo
+ bcc :+
+ inc rb_ptr_hi
+: rts
+
+dl_calc_mbitmap_cell_addr:
+ lda #RB_GFX_SCREEN
+ sta rb_ptr_hi
+ lda CF_NUM1_LO
+ lsr
+ lsr
+ lsr
+ sta rb_digit_seen
+ asl
+ asl
+ asl
+ sta rb_saved_plot_x
+ lda rb_digit_seen
+ asl
+ asl
+ asl
+ asl
+ asl
+ clc
+ adc rb_saved_plot_x
+ sta rb_ptr_lo
+ lda #>RB_GFX_SCREEN
+ adc #0
+ sta rb_ptr_hi
+ lda CF_NUM0_LO
+ lsr
+ lsr
+ clc
+ adc rb_ptr_lo
+ sta rb_ptr_lo
+ bcc :+
+ inc rb_ptr_hi
+: rts
+
+dl_mbitmap_apply_attr:
+ lda CF_NUM2_LO
+ cmp #16
+ bcc @slot3
+ cmp #32
+ bcc @slot1
+ cmp #48
+ bcc @slot2
+@slot3:
+ lda #3
+ sta rb_digit_count
+ jsr dl_calc_mbitmap_cell_addr
+ lda rb_ptr_hi
+ sec
+ sbc #>RB_GFX_SCREEN
+ clc
+ adc #>RB_GFX_COLOR
+ sta rb_ptr_hi
+ ldy #0
+ lda CF_NUM2_LO
+ and #$0F
+ sta (rb_ptr_lo),y
+ rts
+@slot1:
+ lda #1
+ sta rb_digit_count
+ jsr dl_calc_mbitmap_cell_addr
+ ldy #0
+ lda (rb_ptr_lo),y
+ and #$0F
+ sta rb_digit_seen
+ lda CF_NUM2_LO
+ and #$0F
+ asl
+ asl
+ asl
+ asl
+ ora rb_digit_seen
+ sta (rb_ptr_lo),y
+ rts
+@slot2:
+ lda #2
+ sta rb_digit_count
+ jsr dl_calc_mbitmap_cell_addr
+ ldy #0
+ lda (rb_ptr_lo),y
+ and #$F0
+ sta rb_digit_seen
+ lda CF_NUM2_LO
+ and #$0F
+ ora rb_digit_seen
+ sta (rb_ptr_lo),y
+ rts
+
+dl_fetch_handle_page:
+ lda #RB_PAGEBUF
+ sta rb_reu_c64_hi
+ lda #0
+ sta rb_reu_off_lo
+ lda rb_handle_page
+ sta rb_reu_off_hi
+ lda rb_handle_bank
+ sta rb_reu_bank
+ lda #0
+ sta rb_reu_len_lo
+ lda #1
+ sta rb_reu_len_hi
+ jmp rb_reu_fetch
+
+dl_stash_handle_page:
+ lda #RB_PAGEBUF
+ sta rb_reu_c64_hi
+ lda #0
+ sta rb_reu_off_lo
+ lda rb_handle_page
+ sta rb_reu_off_hi
+ lda rb_handle_bank
+ sta rb_reu_bank
+ lda #0
+ sta rb_reu_len_lo
+ lda #1
+ sta rb_reu_len_hi
+ jmp rb_reu_stash
-; ---------------------------------------------------------------------------
-; Packed command submodule 0. This 2KB slot image is copied from REU bank $45
-; into $A800-$AFFF on demand, then reused while residency metadata matches.
-; ---------------------------------------------------------------------------
+dl_handle_load_arg:
+ lda CF_NUM0_HI
+ bne @bad
+ lda CF_NUM0_LO
+ beq @bad
+ cmp #RB_HANDLE_COUNT + 1
+ bcs @bad
+ sec
+ sbc #1
+ sta rb_handle_index
+ jsr dl_handle_fetch
+ lda rb_handle_bank
+ beq @bad
+ clc
+ rts
+@bad:
+ sec
+ rts
- .segment "LOWPACK"
+dl_handle_fetch:
+ jsr dl_handle_desc_fetch_page
+ ldy rb_handle_desc_off
+ lda RB_PAGEBUF,y
+ sta rb_handle_bank
+ iny
+ lda RB_PAGEBUF,y
+ sta rb_handle_page
+ iny
+ lda RB_PAGEBUF,y
+ sta rb_handle_pages
+ iny
+ lda RB_PAGEBUF,y
+ sta rb_handle_type
+ rts
-cmd_zecho1_low:
+dl_handle_store:
+ jsr dl_handle_desc_fetch_page
+ ldy rb_handle_desc_off
+ lda rb_handle_bank
+ sta RB_PAGEBUF,y
+ iny
+ lda rb_handle_page
+ sta RB_PAGEBUF,y
+ iny
+ lda rb_handle_pages
+ sta RB_PAGEBUF,y
+ iny
+ lda rb_handle_type
+ sta RB_PAGEBUF,y
+ lda #RB_PAGEBUF
+ sta rb_reu_c64_hi
+ lda rb_reu_core_bank
+ sta rb_reu_bank
lda #0
- sta RF_STATUS
- lda #RB_VAL_INT
- sta RF_TAG
+ sta rb_reu_len_lo
lda #1
- sta RF_VAL_LO
- lda #0
- sta RF_VAL_HI
- rts
-cmd_zecho1_low_end:
+ sta rb_reu_len_hi
+ jmp rb_reu_stash
-cmd_zadd16_low:
+dl_handle_desc_fetch_page:
+ lda rb_handle_index
+ and #$3F
+ asl
+ asl
+ sta rb_handle_desc_off
+ lda #0
+ sta rb_reu_off_lo
+ lda #>RB_REU_HANDLE_OFF
+ ldx rb_handle_index
+ cpx #RB_HANDLE_PAGE_SLOTS
+ bcc :+
clc
- lda CF_NUM0_LO
- adc CF_NUM1_LO
- sta RF_VAL_LO
- lda CF_NUM0_HI
- adc CF_NUM1_HI
- sta RF_VAL_HI
+ adc #1
+: sta rb_reu_off_hi
+ lda #RB_PAGEBUF
+ sta rb_reu_c64_hi
+ lda rb_reu_core_bank
+ sta rb_reu_bank
lda #0
- sta RF_STATUS
- lda #RB_VAL_INT
- sta RF_TAG
- rts
-cmd_zadd16_low_end:
+ sta rb_reu_len_lo
+ lda #1
+ sta rb_reu_len_hi
+ jmp rb_reu_fetch
-cmd_zslot0_low:
+dl_handle_alloc_with_pages:
+ jsr dl_find_free_handle
+ bcc @got
+ lda #$21
+ jmp dl_fail
+@got:
+ jsr dl_find_pages
+ bcc :+
+ lda #$22
+ jmp dl_fail
+: lda rb_reu_core_bank
+ sta rb_handle_bank
+ lda rb_found_page
+ clc
+ adc #RB_HEAP_PAGE_BASE
+ sta rb_handle_page
+ lda rb_needed_pages
+ sta rb_handle_pages
+ lda rb_handle_new_type
+ sta rb_handle_type
+ jsr dl_mark_pages_used
+ jsr dl_store_heap_bitmap
+ jsr dl_handle_store
lda #0
sta RF_STATUS
lda #RB_VAL_INT
sta RF_TAG
- lda #30
+ lda rb_handle_index
+ clc
+ adc #1
sta RF_VAL_LO
lda #0
sta RF_VAL_HI
rts
-cmd_zslot0_low_end:
-cmd_zcpyrst_low:
+dl_find_free_handle:
lda #0
- sta rb_copy_count
- sta RF_STATUS
- sta RF_VAL_LO
- sta RF_VAL_HI
- lda #RB_VAL_INT
- sta RF_TAG
+ sta rb_handle_scan_base
+@page:
+ lda rb_handle_scan_base
+ sta rb_handle_index
+ jsr dl_handle_desc_fetch_page
+ ldy #0
+ ldx #0
+@slot:
+ lda RB_PAGEBUF,y
+ beq @found
+ tya
+ clc
+ adc #RB_HANDLE_DESC_SIZE
+ tay
+ inx
+ cpx #RB_HANDLE_PAGE_SLOTS
+ bcc @slot
+ lda rb_handle_scan_base
+ bne @full
+ lda #RB_HANDLE_PAGE_SLOTS
+ sta rb_handle_scan_base
+ jmp @page
+@found:
+ txa
+ clc
+ adc rb_handle_scan_base
+ sta rb_handle_index
+ clc
+ rts
+@full:
+ sec
rts
-cmd_zcpyrst_low_end:
-cmd_zcopy_low:
+dl_fetch_heap_bitmap:
+ lda #RB_PAGEBUF
+ sta rb_reu_c64_hi
+ lda #RB_REU_HEAP_OFF
+ sta rb_reu_off_hi
+ lda rb_reu_core_bank
+ sta rb_reu_bank
lda #0
- sta RF_STATUS
- sta RF_VAL_HI
- lda rb_copy_count
- sta RF_VAL_LO
- lda #RB_VAL_INT
- sta RF_TAG
+ sta rb_reu_len_lo
+ lda #1
+ sta rb_reu_len_hi
+ jmp rb_reu_fetch
+
+dl_store_heap_bitmap:
+ lda #RB_PAGEBUF
+ sta rb_reu_c64_hi
+ lda #RB_REU_HEAP_OFF
+ sta rb_reu_off_hi
+ lda rb_reu_core_bank
+ sta rb_reu_bank
+ lda #0
+ sta rb_reu_len_lo
+ lda #1
+ sta rb_reu_len_hi
+ jmp rb_reu_stash
+
+dl_find_pages:
+ jsr dl_fetch_heap_bitmap
+ lda #0
+ sta rb_found_page
+@outer:
+ lda rb_found_page
+ clc
+ adc rb_needed_pages
+ cmp #RB_HEAP_PAGES + 1
+ bcc :+
+ sec
rts
-cmd_zcopy_low_end:
+: ldx #0
+@inner:
+ txa
+ clc
+ adc rb_found_page
+ tay
+ lda RB_PAGEBUF,y
+ bne @next
+ inx
+ cpx rb_needed_pages
+ bcc @inner
+ clc
+ rts
+@next:
+ inc rb_found_page
+ jmp @outer
-cmd_fadd_low:
+dl_mark_pages_used:
+ ldx #0
+@loop:
+ txa
+ clc
+ adc rb_found_page
+ tay
+ lda #1
+ sta RB_PAGEBUF,y
+ inx
+ cpx rb_needed_pages
+ bcc @loop
rts
-cmd_fadd_low_end:
-cmd_zpause_low:
- lda CF_NUM0_LO
- beq @done
- sta RF_COUNT_LO
-@outer:
- ldx #$20
-@middle:
- ldy #$ff
-@inner:
- dey
- bne @inner
- dex
- bne @middle
- dec RF_COUNT_LO
- bne @outer
-@done:
+dl_ok:
lda #0
sta RF_STATUS
lda #RB_VAL_NONE
sta RF_TAG
rts
-cmd_zpause_low_end:
-cmd_upper_low:
- lda #0
+dl_fail:
sta RF_STATUS
- lda #RB_VAL_STRING
- sta RF_TAG
- lda CF_STR_LEN
- sta RF_STR_LEN
- ldy #0
-@loop:
- cpy CF_STR_LEN
- beq @done
- lda CF_STR_BUF,y
- cmp #$C1
- bcc @ascii_case
- cmp #$DB
- bcs @ascii_case
- sec
- sbc #$80
- jmp @store
-@ascii_case:
- cmp #'a'
- bcc :+
- cmp #'z' + 1
- bcs :+
- sec
- sbc #$20
-@store:
-: sta RF_STR_BUF,y
- iny
- jmp @loop
-@done:
+ sta RF_ERROR
rts
-cmd_upper_low_end:
-cmd_lower_low:
- lda #0
- sta RF_STATUS
- lda #RB_VAL_STRING
- sta RF_TAG
- lda CF_STR_LEN
- sta RF_STR_LEN
- ldy #0
-@loop:
- cpy CF_STR_LEN
- beq @done
- lda CF_STR_BUF,y
- cmp #$C1
- bcc @ascii_case
- cmp #$DB
- bcs @ascii_case
- sec
- sbc #$60
- jmp @store
-@ascii_case:
- cmp #'A'
- bcc :+
- cmp #'Z' + 1
- bcs :+
- clc
- adc #$20
-@store:
-: sta RF_STR_BUF,y
- iny
- jmp @loop
-@done:
- rts
-cmd_lower_low_end:
+dl_bit_masks:
+ .byte $80,$40,$20,$10,$08,$04,$02,$01
+dl_bit_unmasks:
+ .byte $7F,$BF,$DF,$EF,$F7,$FB,$FD,$FE
+dl_mbit_pair_masks:
+ .byte $40,$10,$04,$01,$80,$20,$08,$02,$C0,$30,$0C,$03
+dl_mbit_unmasks:
+ .byte $3F,$CF,$F3,$FC
-cmd_zsumnumarray_low:
- lda CF_PTR0_LO
- sta rb_ptr_lo
- lda CF_PTR0_HI
- sta rb_ptr_hi
- lda #0
- sta RF_VAL_LO
- sta RF_VAL_HI
- ldx CF_COUNT0_LO
- beq @done
-@loop:
- ldy #1
+ .segment "OVL5PACK"
+
+cmd_chrnew:
+ lda #8
+ sta rb_needed_pages
+ lda #RB_HANDLE_TYPE_CHARSET
+ jmp tile_alloc_resource
+
+cmd_chrrow:
+ jsr tile_load_handle_arg
+ bcc :+
+ jmp tile_bad_handle
+:
+ lda rb_handle_type
+ cmp #RB_HANDLE_TYPE_CHARSET
+ beq :+
+ jmp tile_wrong_type
+:
+ lda CF_NUM2_LO
+ cmp #8
+ bcc :+
+ jmp tile_bad_range
+:
+ lda CF_NUM1_LO
+ lsr
+ lsr
+ lsr
+ lsr
+ lsr
clc
- lda RF_VAL_LO
- adc (rb_ptr_lo),y
- sta RF_VAL_LO
- dey
- lda RF_VAL_HI
- adc (rb_ptr_lo),y
- sta RF_VAL_HI
+ adc rb_handle_page
+ sta rb_fill_page
+ jsr tile_fetch_fill_page
+ lda CF_NUM1_LO
+ and #$1F
+ asl
+ asl
+ asl
clc
- lda rb_ptr_lo
- adc #2
- sta rb_ptr_lo
+ adc CF_NUM2_LO
+ tay
+ lda CF_NUM3_LO
+ sta RB_PAGEBUF,y
+ jsr tile_stash_fill_page
+ jmp tile_ok
+
+cmd_chruse:
+ jsr tile_load_handle_arg
bcc :+
- inc rb_ptr_hi
-: dex
- bne @loop
-@done:
+ jmp tile_bad_handle
+:
+ lda rb_handle_type
+ cmp #RB_HANDLE_TYPE_CHARSET
+ beq :+
+ jmp tile_wrong_type
+:
+ lda CPU_PORT
+ pha
+ and #RAM_UNDER_BASIC
+ sta CPU_PORT
+ lda #RB_GFX_BITMAP
+ sta rb_reu_c64_hi
lda #0
- sta RF_STATUS
- lda #RB_VAL_INT
- sta RF_TAG
- rts
-cmd_zsumnumarray_low_end:
-
-cmd_zrangenumarray_low:
+ sta rb_reu_off_lo
+ lda rb_handle_page
+ sta rb_reu_off_hi
+ lda rb_handle_bank
+ sta rb_reu_bank
lda #0
- sta RF_STATUS
- lda #RB_VAL_ARRAYI
- sta RF_TAG
+ sta rb_reu_len_lo
+ lda #8
+ sta rb_reu_len_hi
+ jsr rb_reu_fetch
+ pla
+ sta CPU_PORT
+ jmp tile_ok
+
+cmd_tsnew:
+ lda #1
+ sta rb_needed_pages
+ lda #RB_HANDLE_TYPE_TILESET
+ jmp tile_alloc_resource
+
+cmd_tsset:
+ jsr tile_load_handle_arg
+ bcc :+
+ jmp tile_bad_handle
+:
+ lda rb_handle_type
+ cmp #RB_HANDLE_TYPE_TILESET
+ beq :+
+ jmp tile_wrong_type
+:
+ jsr tile_fetch_handle_page
lda CF_NUM1_LO
- sta RF_COUNT_LO
+ asl
+ tay
+ lda CF_NUM2_LO
+ sta RB_PAGEBUF,y
+ iny
+ lda CF_NUM3_LO
+ and #$0F
+ sta RB_PAGEBUF,y
+ jsr tile_stash_handle_page
+ jmp tile_ok
+
+cmd_tmnew:
+ lda #4
+ sta rb_needed_pages
+ lda #RB_HANDLE_TYPE_TILEMAP
+ jmp tile_alloc_resource
+
+cmd_tmset:
+ jsr tile_load_handle_arg
+ bcc :+
+ jmp tile_bad_handle
+:
+ lda rb_handle_type
+ cmp #RB_HANDLE_TYPE_TILEMAP
+ beq :+
+ jmp tile_wrong_type
+:
lda CF_NUM1_HI
- sta RF_COUNT_HI
- lda CF_NUM0_LO
+ cmp #4
+ bcc :+
+ jmp tile_bad_range
+:
+ clc
+ adc rb_handle_page
+ sta rb_fill_page
+ jsr tile_fetch_fill_page
+ ldy CF_NUM1_LO
+ lda CF_NUM2_LO
+ sta RB_PAGEBUF,y
+ jsr tile_stash_fill_page
+ jmp tile_ok
+
+cmd_tmdraw:
+ jsr tile_load_handle_arg
+ bcc :+
+ jmp tile_bad_handle
+:
+ lda rb_handle_type
+ cmp #RB_HANDLE_TYPE_TILEMAP
+ beq :+
+ jmp tile_wrong_type
+:
+ lda rb_handle_bank
+ sta rb_saved_plot_x
+ lda rb_handle_page
+ sta rb_saved_plot_y
+ lda CF_NUM1_LO
+ sta CF_NUM0_LO
+ lda CF_NUM1_HI
+ sta CF_NUM0_HI
+ jsr tile_load_handle_arg
+ bcc :+
+ jmp tile_bad_handle
+:
+ lda rb_handle_type
+ cmp #RB_HANDLE_TYPE_TILESET
+ beq :+
+ jmp tile_wrong_type
+:
+ lda #RF_ARRAY_BUF
+ sta rb_reu_c64_hi
+ lda #0
+ sta rb_reu_off_lo
+ lda rb_handle_page
+ sta rb_reu_off_hi
+ lda rb_handle_bank
+ sta rb_reu_bank
+ lda #$80
+ sta rb_reu_len_lo
+ lda #0
+ sta rb_reu_len_hi
+ jsr rb_reu_fetch
+ lda #RB_GFX_SCREEN
sta rb_ptr_hi
- ldx CF_NUM1_LO
+ lda #RB_GFX_COLOR
+ sta rb_ptr2_hi
+ lda #$E8
+ sta rb_copy_len_lo
+ lda #3
+ sta rb_copy_len_hi
+ lda #0
+ sta rb_copy_chunks
+@page:
+ lda rb_copy_chunks
+ clc
+ adc rb_saved_plot_y
+ sta rb_fill_page
+ lda rb_saved_plot_x
+ sta rb_handle_bank
+ jsr tile_fetch_fill_page
+ lda #0
+ sta rb_copy_count
+@cell:
+ lda rb_copy_len_lo
+ ora rb_copy_len_hi
beq @done
+ ldx rb_copy_count
+ lda RB_PAGEBUF,x
+ and #$3F
+ asl
+ tax
ldy #0
-@loop:
- lda rb_ptr_hi
- sta RF_ARRAY_BUF,y
- iny
- lda rb_ptr_lo
- sta RF_ARRAY_BUF,y
- iny
+ lda RF_ARRAY_BUF,x
+ sta (rb_ptr_lo),y
+ inx
+ lda RF_ARRAY_BUF,x
+ sta (rb_ptr2_lo),y
inc rb_ptr_lo
bne :+
inc rb_ptr_hi
-: dex
- bne @loop
+: inc rb_ptr2_lo
+ bne :+
+ inc rb_ptr2_hi
+: inc rb_copy_count
+ bne :+
+ inc rb_copy_chunks
+ jmp @page
+: lda rb_copy_len_lo
+ bne :+
+ dec rb_copy_len_hi
+: dec rb_copy_len_lo
+ jmp @cell
@done:
- rts
-cmd_zrangenumarray_low_end:
-
-cmd_bufnew_low:
- jsr rb_handle_alloc
- rts
-cmd_bufnew_low_end:
-
-cmd_buffill_low:
- jsr rb_handle_fill
- rts
-cmd_buffill_low_end:
-
-cmd_buffree_low:
- jsr rb_handle_free
- rts
-cmd_buffree_low_end:
+ jmp tile_ok
-cmd_ztempscratch_low:
- jsr rb_temp_alloc
- rts
-cmd_ztempscratch_low_end:
+cmd_mcell:
+ jsr tile_calc_cell_addr
+ ldy #0
+ lda CF_NUM2_LO
+ and #$0F
+ asl
+ asl
+ asl
+ asl
+ sta rb_digit_seen
+ lda CF_NUM3_LO
+ and #$0F
+ ora rb_digit_seen
+ sta (rb_ptr_lo),y
+ jsr tile_screen_ptr_to_color
+ lda CF_NUM4_LO
+ and #$0F
+ sta (rb_ptr_lo),y
+ jmp tile_ok
-cmd_zfail_low:
+cmd_mcbg:
lda CF_NUM0_LO
- bne :+
- lda #$7F
-: sta RF_STATUS
- sta RF_ERROR
- lda #RB_VAL_INT
- sta RF_TAG
- lda #0
- sta RF_VAL_LO
- sta RF_VAL_HI
- rts
-cmd_zfail_low_end:
-
-cmd_freemem_low:
- jsr rb_print_live_free
- lda #13
- jsr K_CHROUT
- jsr rb_update_header_free
- lda #0
- sta RF_STATUS
- lda #RB_VAL_NONE
- sta RF_TAG
- rts
-cmd_freemem_low_end:
-
-cmd_scrcap_low:
- jsr rb_screen_handle_alloc
- lda RF_STATUS
- beq :+
- rts
-: jsr rb_screen_save_text
- jsr rb_screen_save_color
- lda #0
- sta RF_STATUS
- lda #RB_VAL_INT
- sta RF_TAG
- ldx rb_handle_index
- txa
- clc
- adc #1
- sta RF_VAL_LO
- lda #0
- sta RF_VAL_HI
- rts
-cmd_scrcap_low_end:
-
-cmd_scrput_low:
- jsr rb_screen_handle_validate
- lda RF_STATUS
- beq :+
- rts
-: jsr rb_screen_load_text
- jsr rb_screen_load_color
- lda #0
- sta RF_STATUS
- lda #RB_VAL_NONE
- sta RF_TAG
- rts
-cmd_scrput_low_end:
+ and #$0F
+ sta VIC_BG
+ jmp tile_ok
-rb_handle_alloc:
- jsr rb_len_to_pages
- bcc :+
- jmp rb_overlay_bad_length
-: lda #RB_HANDLE_TYPE_BUFFER
+tile_alloc_resource:
sta rb_handle_new_type
- jmp rb_handle_alloc_with_pages
+ jsr tile_handle_alloc_with_pages
+ rts
-rb_screen_handle_alloc:
- lda #RB_SCREEN_HANDLE_PAGES
- sta rb_needed_pages
- lda #RB_HANDLE_TYPE_SCREEN_TC
- sta rb_handle_new_type
+tile_bad_handle:
+ lda #$24
+ jmp tile_fail
+tile_wrong_type:
+ lda #$28
+ jmp tile_fail
+tile_bad_range:
+ lda #$64
+ jmp tile_fail
-rb_handle_alloc_with_pages:
- jsr rb_find_free_handle
- bcc @got_handle
- lda #$21
- jmp rb_overlay_fail
-@got_handle:
- jsr rb_find_pages
- bcs @no_pages
- lda rb_reu_core_bank
- sta rb_handle_bank
- lda rb_found_page
+tile_calc_cell_addr:
+ lda #RB_GFX_SCREEN
+ sta rb_ptr_hi
+ lda CF_NUM1_LO
+ asl
+ asl
+ asl
+ sta rb_saved_plot_x
+ lda CF_NUM1_LO
+ asl
+ asl
+ asl
+ asl
+ asl
clc
- adc #RB_HEAP_PAGE_BASE
- sta rb_handle_page
- lda rb_needed_pages
- sta rb_handle_pages
- lda rb_handle_new_type
- sta rb_handle_type
- jsr rb_mark_pages_used
- jsr rb_store_heap_bitmap
- jsr rb_handle_store
- lda #0
- sta RF_STATUS
- lda #RB_VAL_INT
- sta RF_TAG
- lda rb_handle_index
+ adc rb_saved_plot_x
clc
- adc #1
- sta RF_VAL_LO
- lda #0
- sta RF_VAL_HI
+ adc CF_NUM0_LO
+ sta rb_ptr_lo
+ lda #>RB_GFX_SCREEN
+ adc #0
+ sta rb_ptr_hi
rts
-@no_pages:
- lda #$22
- jmp rb_overlay_fail
-rb_screen_handle_validate:
- jsr rb_handle_load_arg
- bcs @bad
- lda rb_handle_type
- cmp #RB_HANDLE_TYPE_SCREEN_TC
- bne @wrong_type
+tile_screen_ptr_to_color:
+ lda rb_ptr_hi
+ sec
+ sbc #>RB_GFX_SCREEN
clc
- rts
-@wrong_type:
- lda #$28
- jmp rb_overlay_fail
-@bad:
- lda #$24
- jmp rb_overlay_fail
-
-rb_overlay_bad_length:
- lda #$23
-rb_overlay_fail:
- sta RF_STATUS
- sta RF_ERROR
+ adc #>RB_GFX_COLOR
+ sta rb_ptr_hi
rts
-rb_len_to_pages:
- lda CF_NUM0_LO
- ora CF_NUM0_HI
- beq @bad
+tile_load_handle_arg:
lda CF_NUM0_HI
- sta rb_needed_pages
+ bne @bad
lda CF_NUM0_LO
- beq @check
- inc rb_needed_pages
-@check:
- lda rb_needed_pages
beq @bad
- cmp #RB_HEAP_PAGES + 1
+ cmp #RB_HANDLE_COUNT + 1
bcs @bad
+ sec
+ sbc #1
+ sta rb_handle_index
+ jsr tile_handle_fetch
+ lda rb_handle_bank
+ beq @bad
clc
rts
@bad:
sec
rts
-rb_handle_desc_fetch_page:
- lda rb_handle_index
- and #$3F
- asl
- asl
- sta rb_handle_desc_off
- lda #0
- sta rb_reu_off_lo
- lda #>RB_REU_HANDLE_OFF
- ldx rb_handle_index
- cpx #RB_HANDLE_PAGE_SLOTS
- bcc :+
- clc
- adc #1
-: sta rb_reu_off_hi
- lda #RB_PAGEBUF
- sta rb_reu_c64_hi
- lda rb_reu_core_bank
- sta rb_reu_bank
- lda #0
- sta rb_reu_len_lo
- lda #1
- sta rb_reu_len_hi
- jsr rb_reu_fetch
- rts
-
-rb_handle_fetch:
- jsr rb_handle_desc_fetch_page
+tile_handle_fetch:
+ jsr tile_handle_desc_fetch_page
ldy rb_handle_desc_off
lda RB_PAGEBUF,y
sta rb_handle_bank
@@ -5149,8 +10124,8 @@ rb_handle_fetch:
sta rb_handle_type
rts
-rb_handle_store:
- jsr rb_handle_desc_fetch_page
+tile_handle_store:
+ jsr tile_handle_desc_fetch_page
ldy rb_handle_desc_off
lda rb_handle_bank
sta RB_PAGEBUF,y
@@ -5173,16 +10148,96 @@ rb_handle_store:
sta rb_reu_len_lo
lda #1
sta rb_reu_len_hi
- jsr rb_reu_stash
+ jmp rb_reu_stash
+
+tile_handle_desc_fetch_page:
+ lda rb_handle_index
+ and #$3F
+ asl
+ asl
+ sta rb_handle_desc_off
+ lda #0
+ sta rb_reu_off_lo
+ lda #>RB_REU_HANDLE_OFF
+ ldx rb_handle_index
+ cpx #RB_HANDLE_PAGE_SLOTS
+ bcc :+
+ clc
+ adc #1
+: sta rb_reu_off_hi
+ lda #RB_PAGEBUF
+ sta rb_reu_c64_hi
+ lda rb_reu_core_bank
+ sta rb_reu_bank
+ lda #0
+ sta rb_reu_len_lo
+ lda #1
+ sta rb_reu_len_hi
+ jmp rb_reu_fetch
+
+tile_handle_alloc_with_pages:
+ jsr tile_find_free_handle
+ bcc @got
+ lda #$21
+ jmp tile_fail
+@got:
+ jsr tile_find_pages
+ bcc :+
+ lda #$22
+ jmp tile_fail
+: lda rb_reu_core_bank
+ sta rb_handle_bank
+ lda rb_found_page
+ clc
+ adc #RB_HEAP_PAGE_BASE
+ sta rb_handle_page
+ lda rb_needed_pages
+ sta rb_handle_pages
+ lda rb_handle_new_type
+ sta rb_handle_type
+ jsr tile_mark_pages_used
+ jsr tile_store_heap_bitmap
+ jsr tile_handle_store
+ jsr tile_clear_alloc_pages
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_INT
+ sta RF_TAG
+ lda rb_handle_index
+ clc
+ adc #1
+ sta RF_VAL_LO
+ lda #0
+ sta RF_VAL_HI
rts
-rb_find_free_handle:
+tile_clear_alloc_pages:
+ lda #0
+ tay
+@clearbuf:
+ sta RB_PAGEBUF,y
+ iny
+ bne @clearbuf
+ lda rb_handle_page
+ sta rb_fill_page
+ lda rb_handle_pages
+ sta rb_copy_count
+@page:
+ jsr tile_stash_fill_page
+ inc rb_fill_page
+ dec rb_copy_count
+ bne @page
+ rts
+
+tile_find_free_handle:
lda #0
sta rb_handle_scan_base
@page:
lda rb_handle_scan_base
sta rb_handle_index
- jsr rb_handle_desc_fetch_page
+ jsr tile_handle_desc_fetch_page
ldy #0
ldx #0
@slot:
@@ -5211,26 +10266,7 @@ rb_find_free_handle:
sec
rts
-rb_handle_load_arg:
- lda CF_NUM0_HI
- bne @bad
- lda CF_NUM0_LO
- beq @bad
- cmp #RB_HANDLE_COUNT + 1
- bcs @bad
- sec
- sbc #1
- sta rb_handle_index
- jsr rb_handle_fetch
- lda rb_handle_bank
- beq @bad
- clc
- rts
-@bad:
- sec
- rts
-
-rb_fetch_heap_bitmap:
+tile_fetch_heap_bitmap:
lda #RB_PAGEBUF
@@ -5245,10 +10281,9 @@ rb_fetch_heap_bitmap:
sta rb_reu_len_lo
lda #1
sta rb_reu_len_hi
- jsr rb_reu_fetch
- rts
+ jmp rb_reu_fetch
-rb_store_heap_bitmap:
+tile_store_heap_bitmap:
lda #RB_PAGEBUF
@@ -5263,713 +10298,1289 @@ rb_store_heap_bitmap:
sta rb_reu_len_lo
lda #1
sta rb_reu_len_hi
- jsr rb_reu_stash
+ jmp rb_reu_stash
+
+tile_find_pages:
+ jsr tile_fetch_heap_bitmap
+ lda #0
+ sta rb_found_page
+@outer:
+ lda rb_found_page
+ clc
+ adc rb_needed_pages
+ cmp #RB_HEAP_PAGES + 1
+ bcc :+
+ sec
+ rts
+: ldx #0
+@inner:
+ txa
+ clc
+ adc rb_found_page
+ tay
+ lda RB_PAGEBUF,y
+ bne @next
+ inx
+ cpx rb_needed_pages
+ bcc @inner
+ clc
+ rts
+@next:
+ inc rb_found_page
+ jmp @outer
+
+tile_mark_pages_used:
+ ldx #0
+@loop:
+ txa
+ clc
+ adc rb_found_page
+ tay
+ lda #1
+ sta RB_PAGEBUF,y
+ inx
+ cpx rb_needed_pages
+ bcc @loop
+ rts
+
+tile_fetch_handle_page:
+ lda rb_handle_page
+ sta rb_fill_page
+tile_fetch_fill_page:
+ lda #RB_PAGEBUF
+ sta rb_reu_c64_hi
+ lda #0
+ sta rb_reu_off_lo
+ lda rb_fill_page
+ sta rb_reu_off_hi
+ lda rb_handle_bank
+ sta rb_reu_bank
+ lda #0
+ sta rb_reu_len_lo
+ lda #1
+ sta rb_reu_len_hi
+ jmp rb_reu_fetch
+
+tile_stash_handle_page:
+ lda rb_handle_page
+ sta rb_fill_page
+tile_stash_fill_page:
+ lda #RB_PAGEBUF
+ sta rb_reu_c64_hi
+ lda #0
+ sta rb_reu_off_lo
+ lda rb_fill_page
+ sta rb_reu_off_hi
+ lda rb_handle_bank
+ sta rb_reu_bank
+ lda #0
+ sta rb_reu_len_lo
+ lda #1
+ sta rb_reu_len_hi
+ jmp rb_reu_stash
+
+tile_ok:
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_NONE
+ sta RF_TAG
+ rts
+
+tile_fail:
+ sta RF_STATUS
+ sta RF_ERROR
+ rts
+
+ .segment "OVL3PACK"
+
+cmd_poly:
+ jsr poly_apply_command_kind
+ jsr poly_prepare
+ bcc :+
+ rts
+: jsr poly_init_first_prev
+ bcc :+
+ rts
+: lda #1
+ sta rb_copy_chunks
+@loop:
+ lda rb_copy_chunks
+ cmp rb_copy_count
+ bcs @close
+ jsr poly_read_point_temp
+ bcc :+
+ rts
+: jsr poly_line_prev_to_temp
+ jsr poly_temp_to_prev
+ inc rb_copy_chunks
+ jmp @loop
+@close:
+ jsr poly_first_to_temp
+ jsr poly_line_prev_to_temp
+ jmp poly_ok
+
+cmd_fpoly:
+ jsr poly_apply_command_kind
+ jsr poly_prepare
+ bcc :+
+ rts
+: jsr poly_init_first_prev
+ bcc :+
+ rts
+: lda #1
+ sta rb_copy_chunks
+@loop:
+ lda rb_copy_chunks
+ cmp rb_copy_count
+ bcs @done
+ jsr poly_read_point_temp
+ bcc :+
+ rts
+: jsr poly_fill_edge_from_prev_to_temp
+ jsr poly_temp_to_prev
+ inc rb_copy_chunks
+ jmp @loop
+@done:
+ jsr poly_first_to_temp
+ jsr poly_fill_edge_from_prev_to_temp
+ jmp poly_ok
+
+cmd_pbufnew:
+ lda CF_NUM0_HI
+ bne @bad
+ lda CF_NUM0_LO
+ beq @bad
+ cmp #65
+ bcs @bad
+ lda #1
+ sta rb_needed_pages
+ lda #RB_HANDLE_TYPE_POINTBUF
+ sta rb_handle_new_type
+ jsr poly_handle_alloc_with_pages
+ rts
+@bad:
+ lda #$51
+ jmp poly_fail
+
+cmd_pbuffree:
+ jsr poly_handle_load_arg
+ bcs @bad
+ lda rb_handle_type
+ cmp #RB_HANDLE_TYPE_POINTBUF
+ bne @wrong
+ jsr poly_handle_free_loaded
+ jmp poly_ok
+@bad:
+ lda #$24
+ jmp poly_fail
+@wrong:
+ lda #$28
+ jmp poly_fail
+
+cmd_pbufset:
+ jsr poly_handle_load_arg
+ bcs @bad
+ lda rb_handle_type
+ cmp #RB_HANDLE_TYPE_POINTBUF
+ bne @wrong
+ lda CF_NUM1_HI
+ bne @range
+ lda CF_NUM1_LO
+ cmp #64
+ bcs @range
+ jsr poly_fetch_handle_page
+ lda CF_NUM1_LO
+ asl
+ asl
+ tay
+ lda CF_NUM2_LO
+ sta RB_PAGEBUF,y
+ iny
+ lda CF_NUM2_HI
+ sta RB_PAGEBUF,y
+ iny
+ lda CF_NUM3_LO
+ sta RB_PAGEBUF,y
+ iny
+ lda CF_NUM3_HI
+ sta RB_PAGEBUF,y
+ jsr poly_stash_handle_page
+ jmp poly_ok
+@bad:
+ lda #$24
+ jmp poly_fail
+@wrong:
+ lda #$28
+ jmp poly_fail
+@range:
+ lda #$52
+ jmp poly_fail
+
+poly_prepare:
+ lda CF_NUM1_HI
+ bne @bad
+ lda CF_NUM1_LO
+ cmp #3
+ bcc @bad
+ cmp #33
+ bcs @bad
+ lda CF_NUM2_LO
+ sta RF_RECT_BUF+8
+ lda CF_NUM2_HI
+ sta RF_RECT_BUF+9
+ lda CF_NUM1_LO
+ sta rb_copy_count
+ lda CF_COUNT0_HI
+ beq @array
+ jsr poly_handle_load_arg
+ bcs @bad_handle
+ lda rb_handle_type
+ cmp #RB_HANDLE_TYPE_POINTBUF
+ bne @wrong
+@array:
+ clc
+ rts
+@bad_handle:
+ lda #$24
+ jmp poly_fail_sec
+@wrong:
+ lda #$28
+ jmp poly_fail_sec
+@bad:
+ lda #$51
+poly_fail_sec:
+ jsr poly_fail
+ sec
+ rts
+
+poly_apply_command_kind:
+ lda CF_CMD_ID
+ cmp #CMD_POLYH
+ beq @handle
+ cmp #CMD_FPOLYH
+ beq @handle
+ lda #0
+ beq @store
+@handle:
+ lda #1
+@store:
+ sta CF_COUNT0_HI
+ rts
+
+poly_init_first_prev:
+ lda #0
+ sta rb_copy_chunks
+ jsr poly_read_point_temp
+ bcc :+
+ rts
+: lda RF_RECT_BUF+10
+ sta RF_RECT_BUF
+ sta RF_RECT_BUF+4
+ lda RF_RECT_BUF+11
+ sta RF_RECT_BUF+1
+ sta RF_RECT_BUF+5
+ lda RF_RECT_BUF+12
+ sta RF_RECT_BUF+2
+ sta RF_RECT_BUF+6
+ lda RF_RECT_BUF+13
+ sta RF_RECT_BUF+3
+ sta RF_RECT_BUF+7
+ clc
+ rts
+
+poly_read_point_temp:
+ lda CF_COUNT0_HI
+ beq poly_read_array_point_temp
+ jmp poly_read_handle_point_temp
+
+poly_read_array_point_temp:
+ lda rb_copy_chunks
+ asl
+ asl
+ tay
+ lda CF_PTR0_LO
+ sta rb_ptr_lo
+ lda CF_PTR0_HI
+ sta rb_ptr_hi
+ tya
+ clc
+ adc rb_ptr_lo
+ sta rb_ptr_lo
+ bcc :+
+ inc rb_ptr_hi
+: ldy #0
+ lda (rb_ptr_lo),y
+ sta RF_RECT_BUF+11
+ iny
+ lda (rb_ptr_lo),y
+ sta RF_RECT_BUF+10
+ iny
+ lda (rb_ptr_lo),y
+ sta RF_RECT_BUF+13
+ iny
+ lda (rb_ptr_lo),y
+ sta RF_RECT_BUF+12
+ clc
rts
-rb_find_pages:
- jsr rb_fetch_heap_bitmap
- lda #0
- sta rb_found_page
-@outer:
- lda rb_found_page
- clc
- adc rb_needed_pages
- cmp #RB_HEAP_PAGES + 1
+poly_read_handle_point_temp:
+ lda rb_copy_chunks
+ cmp #64
bcc :+
+ lda #$52
+ jsr poly_fail
sec
rts
-: ldx #0
-@inner:
- txa
- clc
- adc rb_found_page
+: jsr poly_fetch_handle_page
+ lda rb_copy_chunks
+ asl
+ asl
tay
lda RB_PAGEBUF,y
- bne @next_start
- inx
- cpx rb_needed_pages
- bcc @inner
+ sta RF_RECT_BUF+10
+ iny
+ lda RB_PAGEBUF,y
+ sta RF_RECT_BUF+11
+ iny
+ lda RB_PAGEBUF,y
+ sta RF_RECT_BUF+12
+ iny
+ lda RB_PAGEBUF,y
+ sta RF_RECT_BUF+13
clc
rts
-@next_start:
- inc rb_found_page
- jmp @outer
-rb_mark_pages_used:
- ldx #0
+poly_line_prev_to_temp:
+ lda RF_RECT_BUF+4
+ sta CF_NUM0_LO
+ lda RF_RECT_BUF+5
+ sta CF_NUM0_HI
+ lda RF_RECT_BUF+6
+ sta CF_NUM1_LO
+ lda RF_RECT_BUF+7
+ sta CF_NUM1_HI
+ lda RF_RECT_BUF+10
+ sta CF_NUM2_LO
+ lda RF_RECT_BUF+11
+ sta CF_NUM2_HI
+ lda RF_RECT_BUF+12
+ sta CF_NUM3_LO
+ lda RF_RECT_BUF+13
+ sta CF_NUM3_HI
+ lda RF_RECT_BUF+8
+ sta CF_NUM4_LO
+ lda RF_RECT_BUF+9
+ sta CF_NUM4_HI
+ jmp poly_line
+
+poly_temp_to_prev:
+ lda RF_RECT_BUF+10
+ sta RF_RECT_BUF+4
+ lda RF_RECT_BUF+11
+ sta RF_RECT_BUF+5
+ lda RF_RECT_BUF+12
+ sta RF_RECT_BUF+6
+ lda RF_RECT_BUF+13
+ sta RF_RECT_BUF+7
+ rts
+
+poly_first_to_temp:
+ lda RF_RECT_BUF
+ sta RF_RECT_BUF+10
+ lda RF_RECT_BUF+1
+ sta RF_RECT_BUF+11
+ lda RF_RECT_BUF+2
+ sta RF_RECT_BUF+12
+ lda RF_RECT_BUF+3
+ sta RF_RECT_BUF+13
+ rts
+
+poly_fill_edge_from_prev_to_temp:
+ lda RF_RECT_BUF+10
+ sta RF_RECT_BUF+14
+ lda RF_RECT_BUF+11
+ sta RF_RECT_BUF+15
+ lda RF_RECT_BUF+12
+ sta RF_STR_BUF
+ lda RF_RECT_BUF+13
+ sta RF_STR_BUF+1
+ lda RF_RECT_BUF+4
+ sta CF_NUM0_LO
+ lda RF_RECT_BUF+5
+ sta CF_NUM0_HI
+ lda RF_RECT_BUF+6
+ sta CF_NUM1_LO
+ lda RF_RECT_BUF+7
+ sta CF_NUM1_HI
+ lda #0
+ sta rb_copy_len_hi
@loop:
- txa
- clc
- adc rb_found_page
- tay
- lda #1
- sta RB_PAGEBUF,y
- inx
- cpx rb_needed_pages
- bcc @loop
+ dec rb_copy_len_hi
+ bne :+
+ jmp @done
+:
+ lda CF_NUM0_LO
+ sta RF_STR_BUF+2
+ lda CF_NUM0_HI
+ sta RF_STR_BUF+3
+ lda CF_NUM1_LO
+ sta RF_STR_BUF+4
+ lda CF_NUM1_HI
+ sta RF_STR_BUF+5
+ lda RF_RECT_BUF
+ sta CF_NUM0_LO
+ lda RF_RECT_BUF+1
+ sta CF_NUM0_HI
+ lda RF_RECT_BUF+2
+ sta CF_NUM1_LO
+ lda RF_RECT_BUF+3
+ sta CF_NUM1_HI
+ lda RF_STR_BUF+2
+ sta CF_NUM2_LO
+ lda RF_STR_BUF+3
+ sta CF_NUM2_HI
+ lda RF_STR_BUF+4
+ sta CF_NUM3_LO
+ lda RF_STR_BUF+5
+ sta CF_NUM3_HI
+ lda RF_RECT_BUF+8
+ sta CF_NUM4_LO
+ lda RF_RECT_BUF+9
+ sta CF_NUM4_HI
+ jsr poly_line
+ lda RF_STR_BUF+2
+ sta CF_NUM0_LO
+ lda RF_STR_BUF+3
+ sta CF_NUM0_HI
+ lda RF_STR_BUF+4
+ sta CF_NUM1_LO
+ lda RF_STR_BUF+5
+ sta CF_NUM1_HI
+ lda CF_NUM0_LO
+ cmp RF_RECT_BUF+14
+ bne @step
+ lda CF_NUM0_HI
+ cmp RF_RECT_BUF+15
+ bne @step
+ lda CF_NUM1_LO
+ cmp RF_STR_BUF
+ beq @done
+@step:
+ jsr poly_step_x_toward_temp
+ jsr poly_step_y_toward_temp
+ jmp @loop
+@done:
rts
-rb_handle_free:
- jsr rb_handle_load_arg
- bcs @bad
- lda rb_handle_page
- sec
- sbc #RB_HEAP_PAGE_BASE
- sta rb_found_page
- lda rb_handle_pages
- sta rb_needed_pages
- jsr rb_fetch_heap_bitmap
- jsr rb_mark_pages_free
- lda #0
- sta rb_handle_bank
- sta rb_handle_page
- sta rb_handle_pages
- sta rb_handle_type
- jsr rb_store_heap_bitmap
- jsr rb_handle_store
+poly_line:
+ lda CF_NUM2_LO
+ sta RF_ARRAY_BUF
+ lda CF_NUM2_HI
+ sta RF_ARRAY_BUF+1
+ lda CF_NUM3_LO
+ sta RF_ARRAY_BUF+2
+ lda CF_NUM3_HI
+ sta RF_ARRAY_BUF+3
+ lda CF_NUM4_LO
+ sta RF_ARRAY_BUF+4
+ lda CF_NUM4_HI
+ sta RF_ARRAY_BUF+5
lda #0
- sta RF_STATUS
- sta RF_TAG
+ sta rb_copy_len_lo
+@loop:
+ dec rb_copy_len_lo
+ beq @done
+ lda RF_ARRAY_BUF+4
+ sta CF_NUM2_LO
+ lda RF_ARRAY_BUF+5
+ sta CF_NUM2_HI
+ jsr poly_plot_current
+ lda CF_NUM0_LO
+ cmp RF_ARRAY_BUF
+ bne @step
+ lda CF_NUM0_HI
+ cmp RF_ARRAY_BUF+1
+ bne @step
+ lda CF_NUM1_LO
+ cmp RF_ARRAY_BUF+2
+ beq @done
+@step:
+ jsr poly_step_x_toward_array
+ jsr poly_step_y_toward_array
+ jmp @loop
+@done:
rts
-@bad:
- lda #$24
- jmp rb_overlay_fail
-rb_mark_pages_free:
- ldx #0
-@loop:
- txa
- clc
- adc rb_found_page
- tay
- lda #0
- sta RB_PAGEBUF,y
- inx
- cpx rb_needed_pages
- bcc @loop
+poly_step_x_toward_array:
+ lda CF_NUM0_HI
+ cmp RF_ARRAY_BUF+1
+ bcc @inc
+ bne @dec
+ lda CF_NUM0_LO
+ cmp RF_ARRAY_BUF
+ bcc @inc
+ beq @done
+@dec:
+ lda CF_NUM0_LO
+ bne :+
+ dec CF_NUM0_HI
+: dec CF_NUM0_LO
+ rts
+@inc:
+ inc CF_NUM0_LO
+ bne @done
+ inc CF_NUM0_HI
+@done:
rts
-rb_handle_fill:
- jsr rb_handle_load_arg
- bcs @bad
- lda rb_handle_type
- cmp #RB_HANDLE_TYPE_BUFFER
- bne @wrong_type
+poly_step_y_toward_array:
lda CF_NUM1_LO
- ldx #0
-@fillbuf:
- sta RB_PAGEBUF,x
- inx
- bne @fillbuf
- lda rb_handle_page
- sta rb_fill_page
- lda rb_handle_pages
- sta rb_needed_pages
-@page:
- lda #RB_PAGEBUF
- sta rb_reu_c64_hi
- lda #0
- sta rb_reu_off_lo
- lda rb_fill_page
- sta rb_reu_off_hi
- lda rb_reu_core_bank
- sta rb_reu_bank
- lda #0
- sta rb_reu_len_lo
- lda #1
- sta rb_reu_len_hi
- jsr rb_reu_stash
- inc rb_fill_page
- dec rb_needed_pages
- bne @page
- lda #0
- sta RF_STATUS
- sta RF_TAG
+ cmp RF_ARRAY_BUF+2
+ bcc @inc
+ beq @done
+ dec CF_NUM1_LO
+ rts
+@inc:
+ inc CF_NUM1_LO
+@done:
rts
-@bad:
- lda #$25
- jmp rb_overlay_fail
-@wrong_type:
- lda #$28
- jmp rb_overlay_fail
-rb_temp_alloc:
- jsr rb_len_to_pages
- bcs @bad
- jsr rb_find_pages
- bcs @bad
- jsr rb_mark_pages_used
- jsr rb_mark_pages_free
- lda #0
- sta RF_STATUS
- lda #RB_VAL_INT
- sta RF_TAG
- lda rb_needed_pages
- sta RF_VAL_LO
- lda #0
- sta RF_VAL_HI
+poly_step_x_toward_temp:
+ lda CF_NUM0_HI
+ cmp RF_RECT_BUF+15
+ bcc @inc
+ bne @dec
+ lda CF_NUM0_LO
+ cmp RF_RECT_BUF+14
+ bcc @inc
+ beq @done
+@dec:
+ lda CF_NUM0_LO
+ bne :+
+ dec CF_NUM0_HI
+: dec CF_NUM0_LO
+ rts
+@inc:
+ inc CF_NUM0_LO
+ bne @done
+ inc CF_NUM0_HI
+@done:
rts
-@bad:
- lda #$26
- jmp rb_overlay_fail
-rb_screen_save_text:
- lda #SCREEN
- sta rb_reu_c64_hi
- lda #0
- sta rb_reu_off_lo
- lda rb_handle_page
- sta rb_reu_off_hi
- lda rb_reu_core_bank
- sta rb_reu_bank
- lda #RB_SCREEN_BYTES
- sta rb_reu_len_hi
- jsr rb_reu_stash
+poly_step_y_toward_temp:
+ lda CF_NUM1_LO
+ cmp RF_STR_BUF
+ bcc @inc
+ beq @done
+ dec CF_NUM1_LO
+ rts
+@inc:
+ inc CF_NUM1_LO
+@done:
rts
-rb_screen_load_text:
- lda #SCREEN
- sta rb_reu_c64_hi
- lda #0
- sta rb_reu_off_lo
- lda rb_handle_page
- sta rb_reu_off_hi
- lda rb_reu_core_bank
- sta rb_reu_bank
- lda #RB_SCREEN_BYTES
- sta rb_reu_len_hi
- jsr rb_reu_fetch
+poly_plot_current:
+ jsr poly_get_mode
+ cmp #RB_GFX_MODE_TILE
+ beq poly_plot_tile
+ cmp #RB_GFX_MODE_MTILE
+ beq poly_plot_tile
+ jsr poly_calc_bitmap_addr
+ lda CPU_PORT
+ pha
+ and #RAM_UNDER_BASIC
+ sta CPU_PORT
+ ldy #0
+ lda (rb_ptr_lo),y
+ ldx CF_NUM2_LO
+ beq @clear
+ ldx rb_saved_plot_y
+ ora poly_bit_masks,x
+ sta (rb_ptr_lo),y
+ pla
+ sta CPU_PORT
+ rts
+@clear:
+ ldx rb_saved_plot_y
+ and poly_bit_unmasks,x
+ sta (rb_ptr_lo),y
+ pla
+ sta CPU_PORT
+ rts
+
+poly_plot_tile:
+ jsr poly_calc_tile_addr
+ ldy #0
+ lda CF_NUM2_LO
+ and #$3F
+ ora #$40
+ sta (rb_ptr_lo),y
+ lda rb_ptr_hi
+ sec
+ sbc #>RB_GFX_SCREEN
+ clc
+ adc #>RB_GFX_COLOR
+ sta rb_ptr_hi
+ lda CF_NUM2_LO
+ and #$0F
+ sta (rb_ptr_lo),y
rts
-rb_screen_save_color:
- lda #COLOR_RAM
+ lda #>RB_GFX_SCREEN
sta rb_ptr_hi
- lda rb_handle_page
+ lda CF_NUM1_LO
+ asl
+ asl
+ asl
+ sta rb_saved_plot_x
+ lda CF_NUM1_LO
+ asl
+ asl
+ asl
+ asl
+ asl
clc
- adc #4
- sta rb_copy_page
- lda #4
- sta rb_copy_chunks
-@chunk:
- jsr rb_screen_set_copy_len
- jsr rb_copy_ptr_to_pagebuf
- jsr rb_stash_pagebuf_to_copy_page
- inc rb_ptr_hi
- inc rb_copy_page
- dec rb_copy_chunks
- bne @chunk
+ adc rb_saved_plot_x
+ clc
+ adc CF_NUM0_LO
+ sta rb_ptr_lo
+ lda #>RB_GFX_SCREEN
+ adc #0
+ sta rb_ptr_hi
rts
-rb_screen_load_color:
- lda #COLOR_RAM
+ lda #>RB_GFX_BITMAP
+ clc
+ adc rb_digit_seen
sta rb_ptr_hi
- lda rb_handle_page
+ lda rb_digit_seen
+ lsr
+ lsr
clc
- adc #4
- sta rb_copy_page
- lda #4
- sta rb_copy_chunks
-@chunk:
- jsr rb_screen_set_copy_len
- jsr rb_fetch_pagebuf_from_copy_page
- jsr rb_copy_pagebuf_to_ptr
+ adc rb_ptr_hi
+ sta rb_ptr_hi
+ lda CF_NUM0_LO
+ and #$F8
+ clc
+ adc rb_ptr_lo
+ sta rb_ptr_lo
+ bcc :+
inc rb_ptr_hi
- inc rb_copy_page
- dec rb_copy_chunks
- bne @chunk
- rts
+: lda CF_NUM0_HI
+ clc
+ adc rb_ptr_hi
+ sta rb_ptr_hi
+ lda rb_saved_plot_x
+ clc
+ adc rb_ptr_lo
+ sta rb_ptr_lo
+ bcc :+
+ inc rb_ptr_hi
+: rts
-rb_screen_set_copy_len:
- lda rb_copy_chunks
- cmp #1
- beq @tail
- lda #0
- sta rb_copy_len_lo
- lda #1
- sta rb_copy_len_hi
+poly_handle_load_arg:
+ lda CF_NUM0_HI
+ bne @bad
+ lda CF_NUM0_LO
+ beq @bad
+ cmp #RB_HANDLE_COUNT + 1
+ bcs @bad
+ sec
+ sbc #1
+ sta rb_handle_index
+ jsr poly_handle_fetch
+ lda rb_handle_bank
+ beq @bad
+ clc
rts
-@tail:
- lda #RB_PAGEBUF
sta rb_reu_c64_hi
- lda #0
- sta rb_reu_off_lo
- lda rb_copy_page
- sta rb_reu_off_hi
lda rb_reu_core_bank
sta rb_reu_bank
- lda rb_copy_len_lo
+ lda #0
sta rb_reu_len_lo
- lda rb_copy_len_hi
+ lda #1
sta rb_reu_len_hi
- jsr rb_reu_stash
- rts
+ jmp rb_reu_stash
-rb_fetch_pagebuf_from_copy_page:
+poly_handle_desc_fetch_page:
+ lda rb_handle_index
+ and #$3F
+ asl
+ asl
+ sta rb_handle_desc_off
+ lda #0
+ sta rb_reu_off_lo
+ lda #>RB_REU_HANDLE_OFF
+ ldx rb_handle_index
+ cpx #RB_HANDLE_PAGE_SLOTS
+ bcc :+
+ clc
+ adc #1
+: sta rb_reu_off_hi
lda #RB_PAGEBUF
sta rb_reu_c64_hi
- lda #0
- sta rb_reu_off_lo
- lda rb_copy_page
- sta rb_reu_off_hi
lda rb_reu_core_bank
sta rb_reu_bank
- lda rb_copy_len_lo
+ lda #0
sta rb_reu_len_lo
- lda rb_copy_len_hi
+ lda #1
sta rb_reu_len_hi
- jsr rb_reu_fetch
- rts
-
-; ---------------------------------------------------------------------------
-; Former hidden worker command implementation. It now lives in the same
-; default command submodule as the other command workers.
-; ---------------------------------------------------------------------------
-
-cmd_zhiddenram_hidden:
- lda #0
- sta RF_VAL_LO
- sta RF_VAL_HI
- ldy #0
-@loop:
- cpy CF_STR_LEN
- beq @done
- lda RF_VAL_LO
- sta rb_ptr_lo
- lda CF_STR_BUF,y
- cmp #$C1
- bcc @ascii_case
- cmp #$DB
- bcs @ascii_case
- sec
- sbc #$80
- jmp @sum
-@ascii_case:
- cmp #'a'
- bcc @sum
- cmp #'z' + 1
- bcs @sum
- sec
- sbc #$20
-@sum:
- clc
- adc rb_ptr_lo
- sta RF_VAL_LO
- lda RF_VAL_HI
- adc #0
- sta RF_VAL_HI
- iny
- jmp @loop
-@done:
- lda #0
- sta RF_STATUS
- lda #RB_VAL_INT
- sta RF_TAG
- rts
-cmd_zhiddenram_hidden_end:
-
- .segment "SLOTPACK1"
+ jmp rb_reu_fetch
-cmd_zslot1:
+poly_handle_alloc_with_pages:
+ jsr poly_find_free_handle
+ bcc @got_handle
+ lda #$21
+ jmp poly_fail
+@got_handle:
+ jsr poly_find_pages
+ bcc :+
+ lda #$22
+ jmp poly_fail
+: lda rb_reu_core_bank
+ sta rb_handle_bank
+ lda rb_found_page
+ clc
+ adc #RB_HEAP_PAGE_BASE
+ sta rb_handle_page
+ lda rb_needed_pages
+ sta rb_handle_pages
+ lda rb_handle_new_type
+ sta rb_handle_type
+ jsr poly_mark_pages_used
+ jsr poly_store_heap_bitmap
+ jsr poly_handle_store
lda #0
sta RF_STATUS
lda #RB_VAL_INT
sta RF_TAG
- lda #31
+ lda rb_handle_index
+ clc
+ adc #1
sta RF_VAL_LO
lda #0
sta RF_VAL_HI
rts
-cmd_zslot1_end:
-cmd_zmodload:
- lda CF_STR_LEN
- bne :+
- lda #240
- jmp @return_int
-:
- ldx #CF_STR_BUF
- jsr K_SETNAM
- lda #1
- ldx #8
- ldy #2
- jsr K_SETLFS
- lda MSGFLG
- sta rb_saved_msgflg
- lda #0
- sta MSGFLG
- sta rb_zmod_eof
- jsr K_OPEN
- bcs @fail_io_finish
- ldx #1
- jsr K_CHKIN
- bcs @fail_io_finish
- lda #16
- jsr rb_zmodload_read_pagebuf_bytes
- bcc @loaded
-@fail_io_finish:
- lda #241
- jmp @finish
-@loaded:
- lda RB_PAGEBUF
- cmp #'R'
- bne @fail_magic
- lda RB_PAGEBUF+1
- cmp #'B'
- bne @fail_magic
- lda RB_PAGEBUF+2
- cmp #'M'
- bne @fail_magic
- lda RB_PAGEBUF+3
- cmp #'!'
- bne @fail_magic
- lda RB_PAGEBUF+4
- cmp #1
- bne @fail_version
- lda RB_PAGEBUF+6
- beq @fail_count
- cmp #33
- bcs @fail_count
- sta rb_saved_count_lo
- lda RB_PAGEBUF+7
- cmp #33
- bcs @fail_count
- sta rb_saved_count_hi
- jsr rb_zmodload_stash_descriptors
- bcs @fail_bounds
- jsr rb_zmodload_stash_payloads
- bcs @fail_bounds
- jsr rb_clear_slot_residency
- lda rb_saved_count_lo
- jmp @finish
-@fail_magic:
- lda #242
- jmp @finish
-@fail_version:
- lda #243
- jmp @finish
-@fail_count:
- lda #244
- jmp @finish
-@fail_bounds:
- lda #245
-@finish:
- pha
- jsr rb_zmodload_close
- pla
- jmp @return_int
-@return_int:
- sta RF_VAL_LO
+poly_find_free_handle:
lda #0
- sta RF_STATUS
- sta RF_VAL_HI
- lda #RB_VAL_INT
- sta RF_TAG
+ sta rb_handle_scan_base
+@page:
+ lda rb_handle_scan_base
+ sta rb_handle_index
+ jsr poly_handle_desc_fetch_page
+ ldy #0
+ ldx #0
+@slot:
+ lda RB_PAGEBUF,y
+ beq @found
+ tya
+ clc
+ adc #RB_HANDLE_DESC_SIZE
+ tay
+ inx
+ cpx #RB_HANDLE_PAGE_SLOTS
+ bcc @slot
+ lda rb_handle_scan_base
+ bne @full
+ lda #RB_HANDLE_PAGE_SLOTS
+ sta rb_handle_scan_base
+ jmp @page
+@found:
+ txa
+ clc
+ adc rb_handle_scan_base
+ sta rb_handle_index
+ clc
+ rts
+@full:
+ sec
rts
-rb_zmodload_stash_descriptors:
- lda rb_saved_count_lo
- sta rb_copy_len_lo
- lda #0
- sta rb_copy_len_hi
-.repeat 5
- asl rb_copy_len_lo
- rol rb_copy_len_hi
-.endrepeat
- lda RB_PAGEBUF+8
+poly_fetch_heap_bitmap:
+ lda #RB_PAGEBUF
+ sta rb_reu_c64_hi
+ lda #RB_REU_HEAP_OFF
sta rb_reu_off_hi
- cmp #>RB_REU_DESC_OFF
- bcc @bad
- cmp #>RB_REU_SLOT_STATE_OFF
- bcs @bad
- clc
- lda rb_reu_off_lo
- adc rb_copy_len_lo
- tax
- lda rb_reu_off_hi
- adc rb_copy_len_hi
- cmp #>RB_REU_SLOT_STATE_OFF
- bcc @stream
- bne @bad
- txa
- bne @bad
-@stream:
lda rb_reu_core_bank
sta rb_reu_bank
- jmp rb_zmodload_stream_to_reu
-@bad:
- sec
- rts
+ lda #0
+ sta rb_reu_len_lo
+ lda #1
+ sta rb_reu_len_hi
+ jmp rb_reu_fetch
-rb_zmodload_stash_payloads:
- lda rb_saved_count_hi
- sta rb_saved_count_hi
- beq @done
-@loop:
- lda #6
- jsr rb_zmodload_read_pagebuf_bytes
- bcs @bad
- lda RB_PAGEBUF+2
- ora RB_PAGEBUF+3
- beq @bad
- lda RB_PAGEBUF
+poly_store_heap_bitmap:
+ lda #RB_PAGEBUF
+ sta rb_reu_c64_hi
+ lda #RB_REU_HEAP_OFF
sta rb_reu_off_hi
- lda RB_PAGEBUF+2
- sta rb_copy_len_lo
- lda RB_PAGEBUF+3
- sta rb_copy_len_hi
- clc
- lda rb_reu_off_lo
- adc rb_copy_len_lo
- lda rb_reu_off_hi
- adc rb_copy_len_hi
- bcs @bad
- lda rb_reu_code_bank
+ lda rb_reu_core_bank
sta rb_reu_bank
- jsr rb_zmodload_stream_to_reu
- bcs @bad
- dec rb_saved_count_hi
- bne @loop
-@done:
+ lda #0
+ sta rb_reu_len_lo
+ lda #1
+ sta rb_reu_len_hi
+ jmp rb_reu_stash
+
+poly_find_pages:
+ jsr poly_fetch_heap_bitmap
+ lda #0
+ sta rb_found_page
+@outer:
+ lda rb_found_page
clc
- rts
-@bad:
+ adc rb_needed_pages
+ cmp #RB_HEAP_PAGES + 1
+ bcc :+
sec
rts
+: ldx #0
+@inner:
+ txa
+ clc
+ adc rb_found_page
+ tay
+ lda RB_PAGEBUF,y
+ bne @next_start
+ inx
+ cpx rb_needed_pages
+ bcc @inner
+ clc
+ rts
+@next_start:
+ inc rb_found_page
+ jmp @outer
-rb_zmodload_read_pagebuf_bytes:
- sta rb_copy_chunks
- lda #0
- sta rb_target_off
+poly_mark_pages_used:
+ ldx #0
+@loop:
+ txa
+ clc
+ adc rb_found_page
+ tay
+ lda #1
+ sta RB_PAGEBUF,y
+ inx
+ cpx rb_needed_pages
+ bcc @loop
+ rts
+
+poly_mark_pages_free:
+ ldx #0
@loop:
- jsr rb_zmodload_read_byte
- bcs @bad
- ldy rb_target_off
- sta RB_PAGEBUF,y
- inc rb_target_off
- dec rb_copy_chunks
- bne @loop
+ txa
clc
+ adc rb_found_page
+ tay
+ lda #0
+ sta RB_PAGEBUF,y
+ inx
+ cpx rb_needed_pages
+ bcc @loop
rts
-@bad:
+
+poly_handle_free_loaded:
+ lda rb_handle_page
sec
- rts
+ sbc #RB_HEAP_PAGE_BASE
+ sta rb_found_page
+ lda rb_handle_pages
+ sta rb_needed_pages
+ jsr poly_fetch_heap_bitmap
+ jsr poly_mark_pages_free
+ lda #0
+ sta rb_handle_bank
+ sta rb_handle_page
+ sta rb_handle_pages
+ sta rb_handle_type
+ jsr poly_store_heap_bitmap
+ jmp poly_handle_store
-rb_zmodload_stream_to_reu:
-@more:
- lda rb_copy_len_lo
- ora rb_copy_len_hi
- beq @done
- lda rb_copy_len_hi
- beq @last
+poly_fetch_handle_page:
+ lda #RB_PAGEBUF
+ sta rb_reu_c64_hi
+ lda #0
+ sta rb_reu_off_lo
+ lda rb_handle_page
+ sta rb_reu_off_hi
+ lda rb_reu_core_bank
+ sta rb_reu_bank
lda #0
sta rb_reu_len_lo
lda #1
sta rb_reu_len_hi
- jsr rb_zmodload_read_reu_chunk
- bcs @bad
- jsr rb_reu_stash
- inc rb_reu_off_hi
- dec rb_copy_len_hi
- jmp @more
-@last:
- lda rb_copy_len_lo
- sta rb_reu_len_lo
- lda #0
- sta rb_reu_len_hi
- jsr rb_zmodload_read_reu_chunk
- bcs @bad
- jsr rb_reu_stash
- lda #0
- sta rb_copy_len_lo
-@done:
- clc
- rts
-@bad:
- sec
- rts
+ jmp rb_reu_fetch
-rb_zmodload_read_reu_chunk:
+poly_stash_handle_page:
lda #RB_PAGEBUF
sta rb_reu_c64_hi
lda #0
- sta rb_target_off
-@loop:
- jsr rb_zmodload_read_byte
- bcs @bad
- ldy rb_target_off
- sta RB_PAGEBUF,y
- inc rb_target_off
- lda rb_target_off
- cmp rb_reu_len_lo
- bne @loop
- clc
+ sta rb_reu_off_lo
+ lda rb_handle_page
+ sta rb_reu_off_hi
+ lda rb_reu_core_bank
+ sta rb_reu_bank
+ lda #0
+ sta rb_reu_len_lo
+ lda #1
+ sta rb_reu_len_hi
+ jmp rb_reu_stash
+
+poly_ok:
+ lda #0
+ sta RF_STATUS
+ lda #RB_VAL_NONE
+ sta RF_TAG
rts
-@bad:
- sec
+
+poly_fail:
+ sta RF_STATUS
+ sta RF_ERROR
rts
-rb_zmodload_read_byte:
- lda rb_zmod_eof
- bne @bad
- jsr K_CHRIN
- sta rb_lookup_char
- jsr K_READST
- beq @ok
- cmp #$40
- beq @eof
- sec
- lda rb_lookup_char
+poly_bit_masks:
+ .byte $80,$40,$20,$10,$08,$04,$02,$01
+poly_bit_unmasks:
+ .byte $7F,$BF,$DF,$EF,$F7,$FB,$FD,$FE
+
+ .segment "OVL6PACK"
+
+cmd_sidclr:
+ ldx #24
+ lda #0
+@loop:
+ sta SID_BASE,x
+ dex
+ bpl @loop
+ jmp sid_ok
+
+cmd_vol:
+ lda CF_NUM0_LO
+ and #$0F
+ sta rb_saved_plot_x
+ lda SID_MODE_VOL
+ and #$F0
+ ora rb_saved_plot_x
+ sta SID_MODE_VOL
+ jmp sid_ok
+
+cmd_freq:
+ jsr sid_voice_offset
+ bcc :+
rts
-@eof:
- lda #1
- sta rb_zmod_eof
-@ok:
- lda rb_lookup_char
- clc
+: lda CF_NUM1_LO
+ sta SID_V1_FREQ_LO,x
+ lda CF_NUM1_HI
+ sta SID_V1_FREQ_HI,x
+ jmp sid_ok
+
+cmd_note:
+ jsr sid_voice_offset
+ bcc :+
rts
-@bad:
- sec
+: stx rb_target_off
+ lda CF_NUM1_LO
+ cmp #12
+ bcc :+
+ lda #$64
+ jmp sid_fail
+: tax
+ lda sid_note_c0_lo,x
+ sta rb_saved_plot_x
+ lda sid_note_c0_hi,x
+ sta rb_saved_plot_y
+ lda CF_NUM2_LO
+ and #7
+ sta RF_COUNT_LO
+ beq @store
+@shift:
+ asl rb_saved_plot_x
+ rol rb_saved_plot_y
+ dec RF_COUNT_LO
+ bne @shift
+@store:
+ ldx rb_target_off
+ lda rb_saved_plot_x
+ sta SID_V1_FREQ_LO,x
+ lda rb_saved_plot_y
+ sta SID_V1_FREQ_HI,x
+ jmp sid_ok
+
+cmd_pulse:
+ jsr sid_voice_offset
+ bcc :+
rts
+: lda CF_NUM1_LO
+ sta SID_V1_PW_LO,x
+ lda CF_NUM1_HI
+ and #$0F
+ sta SID_V1_PW_HI,x
+ jmp sid_ok
-rb_zmodload_close:
- lda rb_saved_msgflg
- pha
- jsr K_CLRCHN
- lda #1
- jsr K_CLOSE
- pla
- sta MSGFLG
+cmd_adsr:
+ jsr sid_voice_offset
+ bcc :+
rts
-cmd_zmodload_end:
+: lda CF_NUM2_LO
+ and #$0F
+ sta rb_saved_plot_x
+ lda CF_NUM1_LO
+ and #$0F
+ asl
+ asl
+ asl
+ asl
+ ora rb_saved_plot_x
+ sta SID_V1_AD,x
+ lda CF_NUM4_LO
+ and #$0F
+ sta rb_saved_plot_x
+ lda CF_NUM3_LO
+ and #$0F
+ asl
+ asl
+ asl
+ asl
+ ora rb_saved_plot_x
+ sta SID_V1_SR,x
+ jmp sid_ok
- .segment "SLOTPACK2"
+cmd_wave:
+ jsr sid_voice_offset
+ bcc :+
+ rts
+: lda CF_NUM1_LO
+ sta SID_V1_CTRL,x
+ jmp sid_ok
-cmd_zslot2:
- lda #0
- sta RF_STATUS
- lda #RB_VAL_INT
- sta RF_TAG
- lda #32
- sta RF_VAL_LO
- lda #0
- sta RF_VAL_HI
+cmd_gate:
+ jsr sid_voice_offset
+ bcc :+
rts
-cmd_zslot2_end:
+: lda CF_NUM1_LO
+ beq @off
+ lda SID_V1_CTRL,x
+ ora #$01
+ sta SID_V1_CTRL,x
+ jmp sid_ok
+@off:
+ lda SID_V1_CTRL,x
+ and #$FE
+ sta SID_V1_CTRL,x
+ jmp sid_ok
+
+cmd_voice:
+ jsr sid_voice_offset
+ bcc :+
+ rts
+: lda CF_NUM1_LO
+ sta SID_V1_FREQ_LO,x
+ lda CF_NUM1_HI
+ sta SID_V1_FREQ_HI,x
+ lda CF_NUM3_LO
+ sta SID_V1_AD,x
+ lda CF_NUM4_LO
+ sta SID_V1_SR,x
+ lda CF_NUM2_LO
+ sta SID_V1_CTRL,x
+ jmp sid_ok
- .segment "SPANPACK"
+cmd_filter:
+ lda CF_NUM0_LO
+ and #$07
+ sta SID_FILTER_LO
+ lda CF_NUM0_LO
+ sta rb_saved_plot_x
+ lda CF_NUM0_HI
+ sta rb_saved_plot_y
+ lsr rb_saved_plot_y
+ ror rb_saved_plot_x
+ lsr rb_saved_plot_y
+ ror rb_saved_plot_x
+ lsr rb_saved_plot_y
+ ror rb_saved_plot_x
+ lda rb_saved_plot_x
+ sta SID_FILTER_HI
+ lda CF_NUM1_LO
+ and #$0F
+ asl
+ asl
+ asl
+ asl
+ sta rb_saved_plot_x
+ lda CF_NUM2_LO
+ and #$0F
+ ora rb_saved_plot_x
+ sta SID_FILTER_RES
+ lda CF_NUM3_LO
+ and #$0F
+ asl
+ asl
+ asl
+ asl
+ sta rb_saved_plot_x
+ lda SID_MODE_VOL
+ and #$0F
+ ora rb_saved_plot_x
+ sta SID_MODE_VOL
+ jmp sid_ok
+
+cmd_sound:
+ jsr sid_voice_offset
+ bcc :+
+ rts
+: stx rb_target_off
+ lda CF_NUM1_LO
+ sta SID_V1_FREQ_LO,x
+ lda CF_NUM1_HI
+ sta SID_V1_FREQ_HI,x
+ lda CF_NUM3_LO
+ ora #$01
+ sta SID_V1_CTRL,x
+ lda CF_NUM2_LO
+ beq @release
+ sta RF_COUNT_LO
+@outer:
+ ldx #$20
+@middle:
+ ldy #$FF
+@inner:
+ dey
+ bne @inner
+ dex
+ bne @middle
+ dec RF_COUNT_LO
+ bne @outer
+@release:
+ ldx rb_target_off
+ lda SID_V1_CTRL,x
+ and #$FE
+ sta SID_V1_CTRL,x
+ jmp sid_ok
+
+sid_voice_offset:
+ lda CF_NUM0_LO
+ cmp #1
+ bcc @bad
+ cmp #4
+ bcs @bad
+ sec
+ sbc #1
+ tax
+ lda sid_voice_offsets,x
+ tax
+ clc
+ rts
+@bad:
+ lda #$64
+ jsr sid_fail
+ sec
+ rts
-cmd_zspan:
+sid_ok:
lda #0
sta RF_STATUS
- lda #RB_VAL_INT
+ lda #RB_VAL_NONE
sta RF_TAG
- lda #40
- sta RF_VAL_LO
- lda #0
- sta RF_VAL_HI
rts
-cmd_zspan_end:
- .segment "OVL1PACK"
-
-cmd_zovl1:
- lda #0
+sid_fail:
sta RF_STATUS
- lda #RB_VAL_INT
- sta RF_TAG
- lda #51
- sta RF_VAL_LO
- lda #0
- sta RF_VAL_HI
+ sta RF_ERROR
rts
-cmd_zovl1_end:
- .segment "OVL2PACK"
+sid_voice_offsets:
+ .byte 0,7,14
-cmd_zovl2:
- lda #0
- sta RF_STATUS
- lda #RB_VAL_INT
- sta RF_TAG
- lda #52
- sta RF_VAL_LO
- lda #0
- sta RF_VAL_HI
- rts
-cmd_zovl2_end:
+; PAL C0-B0 SID frequency words. PITCH shifts these by octave.
+sid_note_c0_lo:
+ .byte $16,$2B,$41,$58,$70,$8A,$A4,$C0,$DD,$FC,$1D,$3F
+sid_note_c0_hi:
+ .byte $01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$02,$02
diff --git a/src/apps/readybasic/readybasic_current_design.html b/src/apps/readybasic/readybasic_current_design.html
index a7165fd..e4f9498 100644
--- a/src/apps/readybasic/readybasic_current_design.html
+++ b/src/apps/readybasic/readybasic_current_design.html
@@ -1,1281 +1,2966 @@
-
-
+
+
-
-
- ReadyBASIC Current Design
+
+
+
+ READYBASIC_CURRENT_DESIGN
-
-
-
ReadyBASIC current design
-
Bare BASIC Commands, REU Plugin Spine, ReadyOS Suspend/Resume
-
- A factual visual guide to the current ReadyBASIC implementation:
- visible BASIC syntax, native routines, command categories, C64 RAM ownership, REU bank
- layout, command frames, cold boot, manual EXIT, and warm resume.
-
-
-
COMMAND(...) Bare statements and selected expression returns.
-
$1200-$2ABB Visible resident core, $18BC (6332 bytes). Parser, hooks, ROM calls, REU DMA, commit, PROC/FUNC, flow control, modules.
-
Assigned REU Core/runtime registry bank and command/module payload bank.
-
128 slots Command registry pages in REU, with screen-handle commands proving slot-128 lookup.
-
-
-
-
-
-
-
-
-
-
- Current Module/Submodule Memory Update
- This page is the current ReadyBASIC module/submodule design. After cold initialization, BASIC owns $2AC1-$9FFF, while registries and module payloads are authoritative in loader-assigned ReadyBASIC core/code banks.
-
-
$2AC1 BASIC start; formula empty free bytes remain 30013.
-
$A000-$A7FF Common under-ROM helper area, current helper through $A364.
-
$A800/$B000/$B800 Three 2KB submodule slots behind BASIC ROM.
-
$C000-$C1F6 Bridge stays below the shared frame region at $C200.
-
-
-
Slot 0: module 1 system/default payload at $A800-$AEC6, copied from assigned code-bank offset $0000.
-
Slot 1: module 2 proof and streaming ZMODLD loader payload at $B000-$B238, copied from assigned code-bank offset $06C7.
-
Slot 2: proof and overlay target at $B800-$B83E; disk overlay samples use assigned code-bank offsets $3300 and $3400.
-
- Terms: a module is the logical command family; a module package is the SEQ disk container named rbm.<name>; a submodule is the runtime payload family that claims one or more slots; an overlay is a swappable image for that submodule. RBM2 repeats submodule 5 because ZDOV1 and ZDOV2 are different overlays of that same family.
- Descriptors remain 32 bytes but now carry module id, submodule id, overlay id, slot mask, generation/check byte, payload offset/size in the assigned code bank, runtime destination, entry offset, signature id, and name. Older implementation names such as LOWPACK remain where they are still used by the linker and source.
- Generated visual companion: ReadyBASIC Memory Diagrams is the proportional special report for the current RAM, REU, cold-load, and module/submodule pictures. Regenerate it with
make readybasic-memory-report after layout changes.
-
-
-
- Current Syntax And Statement Behavior
-
-
-
ReadyBASIC commands use raw visible text. Stored lines remain readable, and LIST shows the command text.
-
COMMAND(arg,arg,out%)
-
PRINT COMMAND(arg,arg)
-
- Statement commands use output variables as final actuals where the
- command has a statement-output form. Expression-safe commands return
- scalar, string, or float values directly. Older non-parenthesized
- command syntax is no longer part of the current design.
-
-
- IF normalization: IF 1 THEN EXEC SHOWI(7) and
- IF I%>0 THEN JUMP LOOP store/list with a colon after
- THEN. Descriptor-backed command statements should write that
- colon explicitly, for example IF 1 THEN :ZECHO1(P%).
-
-
-
- Yes Immediate mode, for example ZECHO1(P%).
- Yes Stored program line start.
- Yes After :, for example PRINT "A":ZECHO1(P%).
- Yes Inside a FOR/NEXT body as a normal statement.
- Some After IF ... THEN: EXEC and JUMP are normalized; bare command statements use an explicit colon.
- Text Inside strings, REM, and DATA; not rewritten or dispatched.
- Some Inside expressions for scalar/string-safe commands and FUNC returns.
- No ELSE is not native BASIC V2 and is not added by ReadyBASIC.
-
-
-
-
-
- Native PROC/FUNC Routines
-
-
-
Reusable BASIC routines are ordinary BASIC program text, not command overlays or descriptors.
-
1000 PROC SHOW(P%,M$)
+
+CURRENT DOCUMENT Current ReadyBASIC implementation and custom assembler/linker-shape contract generated from READYBASIC_CURRENT_DESIGN.md.
+
+ReadyBASIC Current Design
+This is the current ReadyBASIC design as implemented by
+src/apps/readybasic/readybasic.s, linked by
+cfg/ready_app_readybasic.cfg, and verified against the
+current obj/readybasic.map.
+ReadyBASIC is a ReadyOS app that hosts a relocated C64 BASIC V2
+workspace and adds a lean command spine for bare
+COMMAND(...) statements and selected
+COMMAND(...) expressions, plus native bare
+PROC/FUNC reusable BASIC routines. It is not a
+private BASIC token system. Stored program lines remain readable,
+LIST shows visible PROC, FUNC,
+EXEC, ENDP, and command text, and the
+execute/eval hooks recognize extensions when BASIC dispatches a
+statement or expression.
+For the most visual current memory explanation, regenerate and open
+docs/readybasic_memory_diagrams.html with:
+make readybasic-memory-report
+That special report is generated from the current ReadyBASIC
+map/linker/source facts and shows the proportional C64 RAM, cold-load
+seed, steady-state BASIC workspace, under-ROM slot, and assigned
+ReadyBASIC core/code bank pictures.
+The current example inventory is build-owned rather than handwritten
+into disk images. READYBASIC_GFX_DEMO_NAMES in the Makefile
+contains 32 programs from rbgfx01_modes through
+rbgfx32_convex_poly;
+READYBASIC_SOUND_DEMO_NAMES contains 6 programs from
+rbsnd01_sid_basics through
+rbsnd06_three_voice. Regular and EasyFlash demo/probe
+wrappers are generated from the same sources, so documentation should
+refer to those lists instead of copying an older partial set.
+Current Module/Submodule
+Snapshot
+This section is the current source of truth for ReadyBASIC’s
+module/submodule layout. Older implementation names such as
+LOWPACK remain in a few labels and tables because they are
+still used by the linker and source, but the current runtime model is
+the module-aware layout described here.
+Measured from the current obj/readybasic.map:
+
+
+
+
+
+
+
+Item
+Current value
+
+
+
+
+BASIC_START
+$2AC1
+
+
+Empty BASIC free bytes
+30013
+
+
+ENTRY
+$1000-$11FF,
+$0200 / 512B
+
+
+RESIDENT
+$1200-$2ABF,
+$18C0 / 6336B
+
+
+BASIC sentinel
+$2AC0
+
+
+Common under-ROM helper
+$A000-$A78A,
+$078B / 1931B
+
+
+Slot 0 / module 1
+$A800-$AFDB,
+$07DC / 2012B
+
+
+Slot 1 / module 2/GFXCORE
+$B000-$B540,
+$0541 / 1345B
+
+
+Slot 2 / GFXPRIM
+$B800-$BF37,
+$0738 / 1848B
+
+
+Slot 2 overlay 1 / GFXSPR
+$B800-$BA71 replacement
+overlay, $0272 / 626B
+
+
+Slot 2 overlay 2 / INPUTEV
+$B800-$B86C replacement
+overlay, $006D / 109B
+
+
+Slot 2 overlay 3 / GFXPOLY
+$B800-$BF78 replacement
+overlay, $0779 / 1913B
+
+
+Slot 2 overlay 4 / GFXDL
+$B800-$BF82 replacement
+overlay, $0783 / 1923B
+
+
+Slot 2 overlay 5 / GFXTILE
+$B800-$BCD9 replacement
+overlay, $04DA / 1242B
+
+
+Slot 2 overlay 6 / SIDCORE
+$B800-$BA0D replacement
+overlay, $020E / 526B
+
+
+BRIDGE
+$C000-$C1FE,
+$01FF / 511B
+
+
+Shared frames/buffers
+$C200-$C5FF
+
+
+REGSEED load-only registry
+$5000-$600F,
+$1010 / 4112B
+
+
+
+After cold initialization, BASIC owns $2AC1-$9FFF. The
+bytes loaded there as module payload seed or registry seed are not
+persistent C64 RAM; they have been copied into the loader-assigned
+ReadyBASIC core and code banks.
+ReadyBASIC now treats $A000-$BFFF as a common under-ROM
+helper area plus three 2KB command submodule slots:
+
+
+
+
+
+
+
+
+Area
+Range
+Current role
+
+
+
+
+Common under-ROM
+$A000-$A7FF
+Helper code and future resident-code relief.
+
+
+Slot 0
+$A800-$AFFF
+Default/system module; existing core commands run here.
+
+
+Slot 1
+$B000-$B7FF
+Built-in proof module and ZMODLD disk-module
+loader.
+
+
+Slot 2
+$B800-$BFFF
+Proof submodule and overlay target.
+
+
+
+Command descriptors are still 32 bytes, but they are module-aware
+records now: command id, module id, payload offset/size in the assigned
+code bank, submodule id, overlay id, slot mask, generation/check byte,
+runtime destination, entry offset, signature id, and command name. The
+special hidden-command dispatch category is gone; all descriptor-backed
+machine-code commands execute from RAM hidden behind BASIC ROM.
+The current proof commands added by the module work are
+ZSLOT0, ZSLOT1, ZSLOT2,
+ZSPAN, ZOVL1, ZOVL2,
+ZCPYRST, and ZCOPY. The disk-module loader
+proof is ZMODLD(name$) in module 2/slot 1. It opens
+ReadyBasicModule SEQ packages named rbm.<name> and
+streams them through the $C500 page buffer into REU, rather
+than loading them as PRG files. Current sample packages are
+rbm.sample1, rbm.sample2, and
+rbm.sample3.
+Phase 1 through Phase 5 graphics commands are also built in and
+prestashed to the assigned code bank; they do not require
+ZMODLD. They use module id 3:
+GFXCORE submodule 16 in slot 1,
+GFXPRIM submodule 17 in slot 2,
+GFXSPR submodule 18 as slot-2 overlay 1, and
+INPUTEV submodule 19 as slot-2 overlay 2,
+GFXPOLY submodule 20 as slot-2 overlay 3,
+GFXDL submodule 21 as slot-2 overlay 4, and
+GFXTILE submodule 22 as slot-2 overlay 5. The
+surface handle entry points GFXSURF and
+GFXBLIT use the existing system slot allocator path so
+typed REU graphics handles can share the same handle directory as
+BUFMAKE and SCRCAP.
+Sound Phase 1 is also built in and does not require
+ZMODLD. It uses module id 4:
+SIDCORE submodule 23 as slot-2 overlay 6,
+prestashed to the assigned code bank at $7800.
+GFXSPR, INPUTEV, GFXPOLY,
+GFXDL, GFXTILE, and SIDCORE are
+true slot-2 replacement overlays. They are loaded from the second
+cold-only command seed window (CMDPACK2) into fixed
+assigned code-bank offsets $5000, $5800,
+$6000, $6800, $7000, and
+$7800, then fetched into $B800 only when their
+commands run. This removes the old slot-2 packing mismatch where
+GFXPRIM, GFXSPR, INPUTEV, and
+polygon work would otherwise consume one runtime strip.
+The graphics Bank D layout intentionally avoids ReadyBASIC/ReadyOS
+state: screen RAM is $CC00-$CFFF, sprite data is
+$CA00-$CBFF, bitmap/charset RAM is
+$E000-$FFFF, and color RAM is $D800-$DBE7.
+ReadyBASIC owns bridge/shared frames through $C5FF; the
+resident 1 KB shim owns $C600-$C9FF, with its expansion
+reserve below the stable ABI at $C800.
+The naming nuance matters. A module is the logical command family
+identified by module id. A module package/container is the disk SEQ file
+that carries descriptors and payload records. A submodule is the runtime
+payload family that claims one or more 2K command slots. An overlay is
+one swappable image of that submodule. That is why the RBM2 sample can
+mention submodule 5 twice: both entries are the same
+submodule family, but they are different overlays.
+The assigned core bank is the authoritative registry/runtime bank:
+header, call/result scratch, handle directory, zero-page/stack
+snapshots, command descriptors, and the typed heap. The assigned code
+bank is the payload bank: built-in module bytes start at
+$0000, and the current disk samples use $3000,
+$3200, $3300, and $3400. Future
+richer per-slot residency metadata is reserved for assigned core-bank
+offsets $2000-$3FFF; the current proof keeps only a tiny
+last-command/copy-count record in bridge RAM.
+Current Syntax And
+Statement Behavior
+ReadyBASIC commands now prefer ordinary-looking parenthesized BASIC
+syntax:
+COMMAND(arg,arg,out%)
+PRINT COMMAND(arg,arg)
+Statement commands keep the existing output-variable convention.
+Expression commands return the scalar, string, or float result directly.
+Older non-parenthesized command syntax is no longer part of the current
+design; current examples and tests use bare
+COMMAND(...).
+Bare commands are recognized only where BASIC is about to dispatch a
+statement or evaluate an expression:
+
+
+
+
+
+
+
+
+Context
+Supported
+Notes
+
+
+
+
+Immediate mode statement
+Yes
+Example: ZECHO1(P%).
+
+
+Stored program line start
+Yes
+Raw command text survives LIST and runs through
+$0308.
+
+
+After :
+Yes
+Example: PRINT "A":ZECHO1(P%).
+
+
+Inside FOR/NEXT body
+Yes
+Use it as a statement in the loop body.
+
+
+After IF ... THEN
+Limited
+EXEC and JUMP are normalized by the crunch
+hook to THEN :EXEC and THEN :JUMP. Bare
+command statements should use an explicit colon, such as
+IF 1 THEN :ZECHO1(P%). Ordinary BASIC assignments like
+IF 1 THEN A%=ZADD16(1,2) work through BASIC’s normal
+assignment path.
+
+
+Inside PRINT, assignments, or larger expressions
+Selected commands only
+ZADD16(2,3)+7, ABS(ADDI(1,6)-10),
+ABS(FADD(1.2,2.3)-3),
+LEFT$(GREET("READY")+"!",3), UPPER(S$), and
+numeric/string/float FUNC expression returns are
+supported.
+
+
+Inside strings, REM, or DATA
+Ordinary text
+These are not rewritten or dispatched.
+
+
+After ELSE
+No native support
+BASIC V2 has no ELSE; ReadyBASIC does not add it.
+
+
+
+IF 1 THEN EXEC SHOW(7) and
+IF I%>0 THEN JUMP LOOP work when typed interactively,
+but their stored/listed forms include the inserted colon after
+THEN. For descriptor-backed command statements, write the
+colon explicitly: IF 1 THEN :ZECHO1(P%). This keeps BASIC’s
+existing statement dispatcher in charge without adding a larger custom
+IF parser.
+Native routines use ordinary BASIC program text:
+1000 PROC SHOW(P%,M$)
1010 PRINT P%;M$
1020 ENDP
1100 FUNC ADDI(X%,Y%)
-1110 R%=X%+Y%
-1120 RET R%
-1130 ENDP
+1110 RET X%+Y%
+1120 ENDP
-10 EXEC SHOW(3,"READY")
+10 EXEC SHOW(3,"READY")
20 A%=ADDI(4,5)
30 PRINT ADDI(6,7)
-
-
-
- PROC Input formals only; called through EXEC.
- FUNC Input formals only; called as an expression and returns through RET.
- ENDP Ends both PROC and FUNC definitions.
- V1 % integer, $ string, and plain float formals; no locals, arrays, by-ref, or multiple outputs.
- Depth 4 A fifth active EXEC reports ?RB ERROR 33.
-
-
Place definitions after END. Fall-through into PROC or FUNC is invalid in V1. Formals are ordinary BASIC globals, so avoid unintended name collisions with caller variables.
-
-
-
+EXEC calls a PROC. PROC has
+input formals only. FUNC also declares input formals only,
+but is called as a BASIC expression and returns with a RET
+statement. EXEC FUNC(...) is rejected; write
+A%=ADDI(4,5) or PRINT ADDI(6,7) instead.
+ENDP returns from PROC without a value.
+Version 1 supports scalar % integer, $ string,
+and plain C64 BASIC floating formals/variables. Arrays, locals,
+by-reference parameters, and multiple outputs remain out of scope.
+String inputs and returns use the same 64-byte ReadyBASIC string cap as
+command results. Nested EXEC has a four-entry return stack;
+a fifth active call reports ?RB ERROR 33.
+RET expr returns from a FUNC.
+RET% expr and RET$ expr force integer or
+string return handling. Untyped RET expr evaluates through
+BASIC ROM and returns the expression’s natural type: string for string
+expressions and plain C64 BASIC float for numeric expressions. Assigning
+that float result to a % target still works through BASIC’s
+normal integer coercion. A FUNC expression scans and runs
+simple scalar assignment statements before RET, so later
+assignment then return works:
+2000 FUNC ADDLATE(X%,Y%)
+2010 R%=X%+Y%
+2020 RET R%
+2030 ENDP
-
- Native Flow Control And Error Introspection
-
-
-
10 I%=0
+10 A%=ADDLATE(4,5)
+
This is still intentionally smaller than a general BASIC
+subinterpreter: V1 FUNC bodies support scalar
+%/$/plain numeric assignments before
+RET, including nested command/FUNC calls in
+the tested assignment forms. Other statements inside a FUNC
+body remain invalid. The current implementation preserves enough BASIC
+ROM expression/string-descriptor state for nested ROM consumers and
+ReadyBASIC actuals such as ABS(ADDI(1,6)-10),
+ABS(FADD(1.2,2.3)-3),
+LEFT$(GREET("READY")+"!",3),
+ADDI(1,ADDI(2,3)), and
+FADD(1.5,FADD(2.25,3.25)).
+
Routine definitions are normal BASIC lines and are not command
+overlays, descriptors, or LOWPACK entries. Put definitions
+after END in V1. Reaching a PROC or
+FUNC definition by ordinary fall-through is invalid and
+produces a BASIC syntax error; this keeps the resident implementation
+small. Like C64 BASIC variables generally, formal variables are global
+by name. Avoid reusing a function’s input formal name as an important
+caller variable unless you intend the call to overwrite that global
+BASIC variable.
+
IF 1 THEN A%=ADDI(1,2) works through BASIC’s normal
+assignment path. IF 1 THEN EXEC SHOW(7) works when typed
+into ReadyBASIC and is normalized by the crunch hook to
+IF 1 THEN :EXEC SHOW(7). petcat-built stored
+examples should use the already-normalized THEN :EXEC form
+because they bypass the interactive crunch hook.
+
ReadyBASIC recognizes manual prompt EXIT plus
+prompt-level CTRL+B, F2, and F4
+as ReadyOS navigation. Prompt hotkeys are detected by the KEYLOG
+preprocessing vector at $028F/$0290 only after ReadyBASIC’s
+IMAIN hook at $0302/$0303 has marked the direct prompt
+active, input is coming from the keyboard, and BASIC is not executing a
+program statement. The execute hook clears that prompt-active flag
+before direct commands and stored program lines run. A legacy
+TXTPTR < BASIC_START check remains as a fallback for
+partially typed prompt lines, but it is not the sole proof of prompt
+state because CURLIN and TXTPTR can still
+point into the just-run program after RUN returns to
+READY.. KEYLOG records the requested ReadyOS action,
+consumes the decoded key state, and queues only Return. The CHRIN hook
+at $0324/$0325 then discards the editor-returned character
+and dispatches the pending action before BASIC can store or execute any
+partial line. This keeps ordinary key repeat, cursor blink, line
+editing, and space handling owned by the ROM editor; ReadyBASIC no
+longer installs a CINV/IRQ scanner for prompt hotkeys and no longer
+injects visible REM text. ReadyBASIC also quarantines any
+still-held ReadyOS hotkey on cold/warm entry and waits, with a
+jiffy-bounded timeout, for the selected physical chord to be released
+before yielding through CTRL+B, F2, or
+F4. That release wait is what prevents one held function
+key from being seen by both the outgoing and incoming app. Program-line
+EXIT resume and running-program hotkeys remain future work;
+the proven paths are direct prompt EXIT and prompt-level
+navigation keys.
+
Phase 1, 2, And 3 Graphics
+Commands
+
The current command catalog includes the command-only Phase 1
+graphics surface plus the Phase 2 visible primitive/sprite-control
+additions and Phase 3 polygon overlay:
+
+
+
+
+
+
+
+
+Command
+Form
+Notes
+
+
+
+
+GFXMODE
+GFXMODE("HIRES"), M%=GFXMODE()
+Supports TEXT, HIRES,
+MBITMAP, TILE, and MTILE.
+
+
+GFXTEXT
+GFXTEXT()
+Restores ordinary text mode.
+
+
+GFXCLEAR
+GFXCLEAR(C)
+Clears Bank D screen/color RAM and bitmap RAM for bitmap modes.
+
+
+GFXSURF
+H%=GFXSURF("HIRES")
+Allocates typed graphics-surface handle 3 in the REU
+heap.
+
+
+GFXTGT
+GFXTGT(0), GFXTGT(H%)
+Selects visible target 0 or records a typed
+graphics-surface handle. Immediate primitives still draw visible Bank
+D.
+
+
+GFXBLIT
+GFXBLIT(H%)
+Copies a typed graphics-surface handle’s bitmap/screen/color layout
+from REU to Bank D.
+
+
+GFXSYNC
+GFXSYNC()
+Snapshots the current visible Bank D bitmap/screen/color layout into
+the selected GFXTGT(H%) surface. No dirty-rect queue
+yet.
+
+
+PLOT / PNT
+PLOT(X,Y,C), PNT(X,Y,P%)
+Hires bitmap bit plot/read, multicolor bitmap pair plot/read, or
+tile cell write/read depending on mode.
+
+
+LINE / RECT / FBOX
+five numeric args
+Immediate primitive workers in GFXPRIM.
+
+
+CIRCLE / FCIRCLE
+CIRCLE(X,Y,R,C), FCIRCLE(X,Y,R,C)
+Phase 2 immediate primitive additions. CIRCLE uses a
+compact midpoint outline worker; FCIRCLE currently proves
+the fill path with a bounding filled rectangle.
+
+
+POLY / FPOLY
+POLY(A%(0),COUNT,C),
+FPOLY(A%(0),COUNT,C)
+Phase 3 array-backed polygons from BASIC integer array pairs.
+FPOLY is a conservative convex fan fill, not full
+scanline/concave fill yet.
+
+
+PBMAKE / PBUFSET /
+PBDROP
+point-buffer handle lifecycle
+Allocates typed REU point-buffer handle 4, writes
+zero-based little-endian x,y point pairs, and releases the
+handle.
+
+
+POLYH / FPOLYH
+POLYH(H%,COUNT,C), FPOLYH(H%,COUNT,C)
+Phase 3 REU point-buffer polygon handle forms. The originally
+proposed same-name POLY(H%,...) overload was not added so
+BASIC_START and bytes free stay fixed.
+
+
+TILE / CHARAT
+TILE(X,Y,CH,C), CHARAT(X,Y,CH,C)
+Phase 2 cell write commands for Bank D tile modes and ordinary text
+mode demo output.
+
+
+DLMAKE / DLRST / DLPLOT /
+DLLINE / DLRECT / DLFBOX /
+DLDRAW
+retained display-list handle commands
+Phase 4 GFXDL overlay. DLMAKE allocates a
+one-page typed REU display list; DLDRAW replays
+plot/line/rectangle records.
+
+
+CHRMAKE / CHRROW /
+CHRUSE
+charset handle commands
+Phase 4 GFXTILE overlay. Creates an 8-page charset
+handle, writes individual character rows, and copies the charset to Bank
+D. Phase 5 screenshots prove visible Bank D tile rendering.
+
+
+TSMAKE / TSSET / TMMAKE /
+TMSET / TMDRAW
+tileset/tilemap handle commands
+Phase 4 GFXTILE overlay. Fixed 1-page tilesets and
+4-page 40x25 tilemaps; no external resource loader yet.
+
+
+MCELL / MCBG
+MCELL(CX,CY,S1,S2,S3), MCBG(C)
+Phase 4 explicit multicolor bitmap cell attributes and background
+color.
+
+
+SIDRST / SIDOFF
+SIDRST()
+Phase 1 sound SIDCORE overlay. Clears SID registers
+$D400-$D418.
+
+
+VOL
+VOL(VOL)
+Sets SID master volume 0..15, preserving filter mode
+bits.
+
+
+FRQ / PITCH
+FRQ(V,F), PITCH(V,N,O)
+Raw SID frequency or PAL note table frequency for voice
+1..3. PITCH sets frequency only; use
+GATE, WAVE, or VOICE to start
+sound.
+
+
+PULSE / ADSR
+pulse width and envelope setup
+PULSE(V,W) writes 12-bit pulse width.
+ADSR(V,A,D,S,R) writes SID nibble envelope values.
+
+
+WAVE / GATE
+control register helpers
+WAVE(V,M) writes the SID control byte;
+GATE(V,ON) sets or clears bit 0 without disturbing the
+other waveform/control bits.
+
+
+VOICE
+VOICE(V,F,W,AD,SR)
+Fast packed voice setup: frequency, control/wave byte, packed
+attack/decay byte, and packed sustain/release byte. This intentionally
+reuses an existing five-number parser signature to avoid resident
+growth.
+
+
+FILTER
+FILTER(CUTOFF,RES,ROUTE,MODE)
+Writes SID cutoff, resonance, route, and filter mode. Mode uses
+logical bits 1 low-pass, 2 band-pass,
+4 high-pass, 8 voice-3-off.
+
+
+SOUND
+SOUND(V,F,D,W)
+Blocking tone helper: gates wave W on for
+D spin-delay units and gates it off. No IRQ music engine
+yet.
+
+
+SPRSET / SPRMOVE / SPRCOL /
+SPRROW
+sprite config/move/color/pixels
+Uses eight 64-byte Bank D sprite definitions at $CA00;
+SPRROW writes explicit 24-bit sprite rows.
+
+
+SPRSIZE
+SPRSIZE(N,XON,YON)
+Phase 2 VIC sprite X/Y expansion.
+
+
+SPRPRI
+SPRPRI(N,BEHIND)
+Phase 2 VIC sprite priority bit control.
+
+
+SPRMUL
+SPRMUL(N,ON)
+Phase 2 VIC sprite multicolor enable.
+
+
+SPRMCO
+SPRMCO(C1,C2)
+Phase 2 shared sprite multicolor registers.
+
+
+
+
This alpha build intentionally keeps one public spelling per command
+behavior. ReadyBASIC can create aliases by adding extra 32-byte
+descriptors that share a command id, parser signature, payload, and
+entrypoint, but duplicate spellings consume registry slots and preserve
+tokenizer hazards. New demos and stored programs use only the canonical
+names because C64 BASIC V2 can tokenize embedded words such as
+FN, FRE, INT, CLR,
+LEN, and NOT.
+
In GFXMODE("MBITMAP"), immediate primitives use 160x200
+logical coordinates. C=0 clears a pixel pair,
+C=1..15 draws pair code 3 and writes color
+RAM, C=16..31 draws pair code 1 and writes the
+screen high nibble, C=32..47 draws pair code 2
+and writes the screen low nibble, and C=48..63 draws pair
+code 3 with an explicit color-RAM write. PNT
+returns pair code 0..3; it does not resolve the final VIC
+color through the per-cell attributes. The demos
+rbgfx21_mbitmap_prims.bas and
+rbgfx22_mbitmap_point.bas exercise this path. |
+SPRSCAN / SPRCOLL | SPRSCAN(),
+SPRCOLL(N,C%) | Polls VIC collision latches; no IRQ
+sampler. | | JOY / KEYP / KEYSCAN
+/ KEYLAST | output/polling forms | Polling only, no
+resident input event queue. |
+
See READYBASIC_GRAPHICS_COMMAND_DESIGN.md for mode
+tradeoffs, memory layout, implemented phases, REU surface/display-list
+behavior, and remaining limits.
+
Native Flow Control
+And Error Introspection
+
ReadyBASIC now also adds a small visible-text flow-control layer.
+These are language features in the resident parser, not
+descriptor-backed command overlays:
+
10 I%=0
20 REPEAT
30 I%=I%+1
40 UNTIL I%=3
-50 PRINT "DONE";I%
+50 PRINT "DONE";I%
100 LABEL LOOP
110 PRINT I%
120 I%=I%-1
130 IF I%>0 THEN JUMP LOOP
-
-
-
- REPEAT Stores the current text pointer and line; loops can nest four deep.
- UNTIL Evaluates a BASIC numeric expression; false loops, true continues.
- LABEL Marks a stored BASIC line without changing execution by itself.
- JUMP Scans for the named label; missing labels report ?RB ERROR 39.
- ERR ERRCODE() and ERRLINE() return the last ReadyBASIC runtime error.
-
-
10 ZFAIL(6,X%)
+REPEAT records the current BASIC text pointer and line
+number. UNTIL expr evaluates the expression through BASIC
+ROM; false loops back and true continues after the UNTIL.
+Loops can be nested four deep. A fifth active REPEAT
+reports ?RB ERROR 35; UNTIL without a matching
+active REPEAT reports ?RB ERROR 36.
+LABEL name is a no-op marker in stored BASIC text.
+JUMP name scans the stored program for the matching label,
+sets the current execution line, and continues there. It works forward,
+backward, after colons, and after normalized IF ... THEN.
+Missing labels report ?RB ERROR 39. Numeric
+GOTO remains the ordinary BASIC ROM statement.
+The last ReadyBASIC runtime error can be read back with
+ERRCODE and ERRLINE, either as expression
+functions or statement output commands:
+10 ZFAIL(6,X%)
20 PRINT ERRCODE();ERRLINE()
30 ERRCODE(E%):ERRLINE(L%):PRINT E%;L%
-
-
-
-
-
- Command Families
-
- These are implementation examples of command shapes the spine supports,
- not the final product command catalog.
-
-
-
-
Scalar Outputs slot 0
-
ZECHO1 ZADD16
-
Prove integer output variables, numeric expression parsing, output clearing, and scalar commit.
-
-
-
String Transfer/Transform slot 0
-
UPPER LOWER
-
Captures string variables or quoted literals, stages transformed bytes, and lets resident code allocate the BASIC string result.
-
-
-
Under-ROM Worker slot 0
-
ZHIDDENRAM
-
Runs worker code behind BASIC ROM in the module 1 slot-0 payload and returns an integer result.
-
-
-
Integer Array Transfer slot 0
-
ZSUMNUMARRAY ZRANGENUMARRAY
-
Uses explicit base element plus count, for example A%(0),N, to read or write integer arrays.
-
-
-
Persistent REU Handles REU data
-
BUFNEW BUFFILL BUFFREE SCRCAP SCRPUT
-
Returns small BASIC integer handles for persistent REU-backed buffers and typed screen text+color resources.
-
-
-
Temporary REU Workspace temp pages
-
ZTEMPSCRATCH
-
Allocates and immediately frees pages, proving temporary workspace without persistent state leaks.
-
-
-
Error/Failure Contract error path
-
ZFAIL
-
Clears output first, then reports ?RB ERROR n without committing stale results.
-
-
-
Runtime Introspection header
-
FREEMEM ERRCODE ERRLINE
-
Prints live BASIC free bytes, refreshes the header, and exposes the last ReadyBASIC runtime error.
-
-
-
Native Flow resident
-
REPEAT UNTIL LABEL JUMP
-
Readable BASIC text for post-test loops and named stored-program transfer; numeric GOTO remains BASIC ROM.
-
-
-
ReadyOS Yield system
-
EXIT
-
Manual prompt command that saves BASIC runtime state, restores vectors, and returns through the ReadyOS shim.
-
-
-
- Command Placement Parameters Result
-
- ZECHO1(OUT%) / ZECHO1()Resident-precomputed result; legacy low stub remains in LOWPACK output integer or expression integer Returns 1 without fetching an overlay in the current runtime.
- ZADD16(A,B,OUT%) / ZADD16(A,B)Module 1 slot 0 at $A800+, descriptor-backed slice two numeric expressions, output integer Returns 16-bit sum.
- FADD(A,B,OUT) / FADD(A,B)Resident-computed float demo; one-byte low stub two plain numeric expressions, output float Uses BASIC ROM floating addition.
- ZPAUSE(TICKS)Module 1 slot 0 at $A800+, descriptor-backed slice tick count Waits for the requested jiffy count.
- UPPER(S$,OUT$) / UPPER(S$)Module 1 slot 0 at $A800+, descriptor-backed slice string variable or quoted literal, output string Uppercases staged bytes.
- LOWER(S$,OUT$) / LOWER(S$)Module 1 slot 0 at $A800+, descriptor-backed slice string variable or quoted literal, output string Lowercases staged byte values; tests use ASC() because display case is charset-dependent.
- ZHIDDENRAM(S$,OUT%) / ZHIDDENRAM(S$)Module 1 slot 0 under-ROM worker at $A800+ string variable or quoted literal, output integer Returns uppercase-byte checksum.
- ZSUMNUMARRAY(A%(0),COUNT,OUT%) / ZSUMNUMARRAY(A%(0),COUNT)Module 1 slot 0 at $A800+, descriptor-backed slice array base, count, output integer Sums integer array elements.
- ZRANGENUMARRAY(START,COUNT,A%(0))Module 1 slot 0 at $A800+, descriptor-backed slice start, count, output array base Stages consecutive integers for resident commit.
- BUFNEW(LEN,H%) / BUFNEW(LEN)Module 1 slot 0, full $06C7 payload byte length, output handle Allocates buffer pages and returns one-based handle.
- BUFFILL(H%,BYTE)Module 1 slot 0, full $06C7 payload buffer handle, fill byte Fills buffer handles and rejects non-buffer handles.
- BUFFREE(H%)Module 1 slot 0, full $06C7 payload handle Frees any valid handle type.
- ZTEMPSCRATCH(LEN,OUT%) / ZTEMPSCRATCH(LEN)Module 1 slot 0, full $06C7 payload byte length, output integer Returns pages required after temporary allocation/free.
- ZFAIL(CODE,OUT%)Module 1 slot 0 at $A800+, descriptor-backed slice error code, output integer Clears output, then reports ?RB ERROR code.
- FREEMEM()Module 1 slot 0 at $A800+, descriptor-backed slice none Prints live BASIC free bytes and refreshes the header.
- SCRCAP(H%) / SCRCAP()Slot 14; module 1 slot 0, full $06C7 payload output screen handle Captures screen text and color RAM into a type-2 handle.
- ERRCODE(OUT%) / ERRCODE()Resident-precomputed result; legacy low stub remains in LOWPACK output integer or expression integer Returns the last ReadyBASIC runtime error code.
- ERRLINE(OUT%) / ERRLINE()Resident-precomputed result; legacy low stub remains in LOWPACK output integer or expression integer Returns the last ReadyBASIC runtime error line, or 0 in direct mode.
- SCRPUT(H%)Slot 128; module 1 slot 0, full $06C7 payload screen handle Restores screen text and color RAM after type validation.
- ZSLOT0 / ZSLOT1 / ZSLOT2 / ZSPANBuilt-in module proof payloads in slots 0, 1, and 2 none Prove slot dispatch and multi-slot span loading.
- ZOVL1 / ZOVL2 / ZCPYRST / ZCOPYBuilt-in overlay and no-recopy proof payloads none Prove overlay replacement and residency behavior.
- ZMODLD(NAME$)Built-in module 2 slot-1 disk-module loader module package filename string Streams generated SEQ packages such as RBM.SAMPLE1, RBM.SAMPLE2, and RBM.SAMPLE3 into REU.
- ZDM1() / ZDM2S() / ZDOV1() / ZDOV2()Disk-loaded sample module payloads in the assigned code bank none Prove disk module, span, and overlay registration after ZMODLD.
- ZSAA()-ZUEB()rbm.sample3 disk-loaded proof payloads in the assigned code banknone Return stateful integer sentinels. The name encodes submodule, overlay, and entrypoint: ZSAA is submodule 6, overlay 1, entry A. Each overlay image has one local counter byte, so reuse increments while reload resets.
-
-
-
- Historical proof names such as PING, ADD16, STRUP,
- HCRC, SUMAI, RANGEAI, TEMPSCRATCH,
- and FAIL are no longer runtime aliases. The current proof/demo
- commands use the Z... namespace, and array demo names use
- NUM rather than INT to avoid the BASIC tokenizer.
-
-
-
-
- Command Overlay Loading And Files Involved
-
- There is one ReadyBASIC app executable: bin/readybasic.prg.
- There is not one PRG or executable file per command. The command
- overlays are linker segments inside that one PRG load image.
-
-
-
-
Files And Artifacts
-
- File or artifact Role
-
- readybasic.sAll current ReadyBASIC code, command descriptors, module/submodule payloads, overlay proof payloads, and hidden helpers.
- ready_app_readybasic.cfgDefines resident code, CMDPACK, REGSEED, hidden helper load image, bridge load image, and runtime overlay slots.
- MakefileAssembles, links, and writes bin/readybasic.prg plus obj/readybasic.map.
- obj/readybasic.mapCurrent source of truth for segment ranges and sizes.
- rbtest1.basLegacy sample BASIC program only; not part of the command overlay mechanism.
- rbproc1.basPositive native routine sample covering PROC, FUNC, EXEC, ENDP, colon chains, normalized IF, nesting, return assignments, command return inside top-level ABS(...), flat numeric expression actuals, and string command return inside a FUNC body.
- rbprocerr.basNegative native routine sample; run sections by line number to exercise expected errors.
- READYBASIC_MAKING_COMMAND_GUIDE.md / readybasic_making_command_guide.htmlAnnotated walkthrough for adding commands using current demo, string, array, hidden, and REU-handle examples.
-
-
-
-
-
Load Image To Runtime
-
-
1 Link Built-in slot payloads, overlay proof slices, and REGSEED are embedded in one PRG.
-
2 Cold Seed Hidden helper copies registry/header to the assigned core bank and command code to the assigned code bank.
-
3 Release BASIC may later own former load-image ranges such as $5000+.
-
4 Fetch Each command descriptor tells the loader which assigned code-bank bytes to copy.
-
5 Call Module payloads run behind BASIC ROM in fixed 2K slots at $A800, $B000, and $B800.
-
-
-
-
- Segment Size Load/source role Runtime role
-
- LOWPACK$06C7 (1.7K, 1735 exact bytes)Historical segment name for the current built-in module 1 slot-0 payload, prestashed to assigned code-bank offset $0000. Fetched on demand into $A800-$AEC6.
- SLOTPACK1$0239 (569B)Built-in module 2 proof and streaming ZMODLD loader payload, prestashed to assigned code-bank offset $06C7. Fetched on demand into $B000-$B238.
- SLOTPACK2 / SPANPACK / overlays$0015 each (21B)Proof slot-2, span, and overlay payloads stored after SLOTPACK1. Fetched into $B800, $B000-$B014, or slot-2 overlay addresses.
- HIDLOAD$0365 (0.8K, 869 exact bytes)Load-only hidden helper seed starting at $4000. Copied on cold boot into $A000-$A364 and the visible $C280 warm-resume shadow.
- BRLOAD$01F7 (503B)Load-only bridge seed starting at $4800. Copied on cold boot into $C000-$C1F6.
- REGSEED$1010 (4.0K, 4112 exact bytes)Load-only registry header and 128 command descriptors at $5000-$600F. Copied on cold boot into assigned core-bank offsets $0000 and $1000.
-
-
-
- Cold boot is the only time the load-image command pack and
- REGSEED are trusted. Warm resume reuses the REU copies and
- does not reseed from $2B00+, $4000+,
- $4800+, or $5000+.
-
-
-
-
- C64 RAM Layout
-
- ReadyBASIC runs inside the ReadyOS app working region $1000-$C5FF.
- Shared ReadyOS metadata and shim space above that are not general scratch.
-
-
-
$1000-$1102
ENTRY Cold/warm discriminator and early copy code.
$0103259B
-
$1200-$2ABB
RESIDENT Parser, hooks, BASIC ROM calls, REU DMA, result commit, PROC/FUNC, flow control, proper float terms.
$18BC6.2K
-
$2AC0
BASIC Sentinel Must stay zero before stored-program RUN.
1 byte
-
$2AC1-$9FFF
BASIC Workspace Program text, variables, arrays, string heap.
$753F30013 formula free / 29.3K
-
$2B00-$3FFF
Command Pack Load Image Built-in module/submodule payload seed bytes before cold prestash.
$15005.25K
-
$4000+
HIDLOAD Image Hidden helper seed copied to $A000 and $C280.
$03770.9K
-
$4800+
BRLOAD Image Bridge seed copied to $C000.
$01F4500B
-
$5000-$600F
REGSEED Load-Only Image Cold 128-slot descriptor seed copied to REU, then this range may be BASIC-owned.
$10104.0K
-
Core bank $0A00-$0BFF
Runtime Snapshot Zero page, stack, SP, mode, line-chain guards.
$02000.5K
-
$A000-$A364
COMMON HELPER Helper code under BASIC ROM RAM.
$0365869B
-
$A800-$AEC6
SLOT 0 PAYLOAD Module 1 system/default payload.
$06C71.7K
-
$B000-$B238
SLOT 1 PAYLOAD Module 2 proof and streaming ZMODLD loader payload.
$0239569B
-
$B800-$B83E
SLOT 2 / OVERLAYS Proof and overlay slices at the front of slot 2.
$003F63B
-
$C000-$C1F6
BRIDGE Magic, saved vectors, overlay vars, current handle scratch, PROC/FUNC stack.
$01F7503B
-
$C200-$C5FF
Shared Frames Call/result frames, descriptor/name/page buffers; hidden shadow is refreshed at $C280 on EXIT.
$04001.0K
-
$C600-$C7FF
ReadyOS REU Metadata ReadyBASIC only marks REU bank ownership here.
$02000.5K
-
$C800-$C9FF
ReadyOS Shim ABI Jump table/data, not ReadyBASIC RAM.
$02000.5K
-
-
- Load image versus runtime: cold entry copies hidden, bridge,
- registry, and command seeds out of the PRG load image. After that,
- BASIC owns $2AC1-$9FFF, so warm resume must not reread cold-only seed
- tables at $5000+.
-
-
-
-
-
Cold Load View: Temporary Seed Bytes Inside The Future BASIC Span
-
-
-
$2AC1-$2AFF gap
-
$2B00-$3FFF CMDPACK reserved 5.25K
-
$4000+ HIDLOAD seed
-
$4800+ BRLOAD seed
-
$5000-$600F REGSEED 4.0K
-
$6010-$9FFF future BASIC bytes
-
-
- These seed bytes are real during loading, but no user BASIC program
- exists yet. Cold setup copies them to REU or runtime homes before
- the Ready prompt.
-
-
-
-
-
-
Ready Prompt View: BASIC Owns The Whole Workspace
-
-
-
$2AC1-$9FFF BASIC program, variables, arrays, and strings; 30013 formula empty free bytes
-
-
-
- CMDPACK capacity: 2.1K used now inside today's 5.25K cold-load seed window; this is not the long-term command-code ceiling
-
-
- Growing packed command code toward the current 5.25K CMDPACK
- reservation increases cold-load content and PRG payload, not
- steady-state BASIC free bytes.
-
-
-
-
5.25K current seed
-
CMDPACK is the current C64 cold-load window at $2B00-$3FFF.
-
-
-
64.0K current code bank
-
The assigned code bank is addressed by 16-bit descriptor offsets and sizes; native PROC/FUNC bodies are BASIC text and do not use this bank.
-
-
-
More later
-
More than one 64K code bank needs a descriptor/loader extension for additional command-code banks.
-
-
-
-
-
-
-
-
- BASIC Free RAM And Growth Strategy
-
- Stock C64 BASIC V2 starts at $0801 with top at
- $A000, giving about 38911 bytes free.
- ReadyBASIC relocates BASIC to $2AC1 with top at
- $A000. On an empty ReadyBASIC workspace, variables begin at
- $2AC3, so the practical empty BASIC free space is
- $A000 - $2AC3 = 30013 formula bytes.
-
-
-
38911 bytes 38.0K stock empty C64 BASIC V2 free space.
-
30013 bytes 29.3K current formula empty ReadyBASIC free space.
-
-8898 bytes -8.7K current ReadyBASIC tradeoff for ReadyOS integration, native dispatch, expression syntax, flow control, and proper float terms.
-
-
- Environment BASIC text start BASIC top Empty free bytes
-
- Stock C64 BASIC V2 $0801$A00038911 (38.0K)
- ReadyBASIC current layout $2AC1$A00030013 (29.3K)
- Difference - - -8898 (-8.7K)
-
-
-
-
-
How To Add Many More Commands
-
- Keep the resident core below the current BASIC page boundary; every resident byte is permanent C64 RAM pressure.
- Put implementation code in packed REU code banks and copy it into existing overlay slots only when invoked.
- Reuse existing signatures and commit paths where possible.
- Keep descriptors in the REU registry, not in resident RAM.
- Expose large or persistent state as BASIC integer handles backed by dynamic REU banks.
- If the assigned code bank becomes crowded, extend the registry for more packed code banks instead of lowering BASIC top.
-
-
-
-
Current Per-Command Overhead
-
- New command kind Permanent C64 RAM REU/load image
-
- Existing signature and overlay slot Usually 0 bytes of BASIC workspace and 0 bytes resident. 32-byte descriptor plus command code bytes.
- New parameter/result signature No BASIC workspace cost; resident parser/commit support grows. 32-byte descriptor plus command code bytes.
- Persistent data No BASIC workspace cost if represented as a handle. Descriptor/code bytes plus REU data allocation and handle metadata.
- Larger fixed C64 buffer Costs C64 RAM only if it expands frames, slots, resident code, or bridge state. Prefer REU if possible.
-
-
-
-
-
-
-
- Page-3 Vector Ownership
-
- Vector Address ReadyBASIC role
-
- Crunch $0304/$0305Calls ROM crunch first, then normalizes tokenized THEN EXEC ... and THEN JUMP ... into colon-prefixed statements.
- List $0306/$0307Saved/restored; V1 leaves normal ROM listing behavior.
- Execute $0308/$0309Peeks for EXIT, PROC, FUNC, EXEC, ENDP, or a bare descriptor command; otherwise tail-calls the original execute vector without advancing TXTPTR.
- Eval $030A/$030BRecognizes selected COMMAND(...) and FUNC(...) expression returns, then falls back to ROM expression evaluation.
-
-
-
- Restore-before-yield is mandatory. Page-3 vectors are
- global machine state. EXIT restores the originals before the ReadyOS
- shim return so other apps cannot dispatch through stale ReadyBASIC code.
-
-
-
-
- Command Dispatch Pipeline
-
-
MatchExecute hook peeks without mutating TXTPTR. Non-ReadyBASIC statements tail-call ROM.
-
ParseCommand name normalizes into $C4A0; descriptors are scanned from the assigned core bank.
-
ExecuteCode is fetched from the assigned code bank into the $A800, $B000, and/or $B800 slots, then writes result frame $C300.
-
CommitResident prints ?RB ERROR n on failure or commits integer, string, or array results.
-
-
- Surface Address or offset Role
-
- Call frame $C200Command id, parameter count, numeric slots, pointer/count slots, string input buffer.
- Result frame $C300Status, error, value tag, scalar value, string output buffer, array output buffer.
- Descriptor buffer $C480One descriptor fetched from the assigned core bank.
- Command buffer $C4A0Uppercase normalized command name.
- Page buffer $C500256-byte staging page for REU handle operations and warm-resume stack buffer.
- REU call snapshot Core bank $0400 Copy of the current call frame.
- REU result snapshot Core bank $0400 Copy of the current result frame.
- Runtime ZP snapshot Core bank $0A00 Restored through temporary buffer $C400.
- Runtime stack snapshot Core bank $0B00 Restored through temporary buffer $C500.
-
-
-
-
-
Descriptor ABI
-
-
- 0Command id.
- 1Module id.
- 2-5Payload offset and size in the assigned code bank.
- 6-9Submodule id, overlay id, slot mask, and generation/check byte.
- 10-13Runtime destination offset from $A000 and entry offset inside the loaded payload.
- 14-15Signature id and command-name length.
- 16-31Uppercase command-name bytes, zero padded.
-
-
-
-
-
Result Tags
-
-
- 0No result.
- 1Integer result.
- 2String result.
- 3Integer array result.
-
-
-
String heap writes happen only in visible resident code after successful worker execution.
-
-
-
-
-
- REU Layout
-
- ReadyBASIC uses loader-assigned core/system and code banks for
- packed command code, then marks ReadyOS ownership in $C600-$C6FF.
-
-
-
-
Assigned Core Bank: Core/System Storage, type 14
-
$0000 Header: RBPL, version, descriptor count, descriptor size, frame offsets.
-
$0400 Current call-frame snapshot.
-
$0400 Current result-frame snapshot.
-
$0600 Reserved debug ring area.
-
$0800-$09FF REU-backed handle directory: 128 descriptors, 4 bytes each.
-
$0A00 Saved zero page for ReadyOS suspend/resume.
-
$0B00 Saved stack page for ReadyOS suspend/resume.
-
$0C00 192-page heap bitmap plus reserved bytes.
-
$1000-$1FFF 128 command descriptor slots, 32 bytes each; slot 128 proves full-table lookup.
-
$2000-$3FFF Reserved common/system expansion space.
-
$4000-$FFFF Typed handle heap: 192 pages / 48KB.
-
-
-
Assigned Code Bank: Packed Command Code, type 15
-
$0000-$06C6 Built-in module 1 slot-0 payload, copied into $A800-$AEC6.
-
$06C7-$08FF Built-in module 2 slot-1 proof and streaming ZMODLD loader payload, copied into $B000-$B238.
-
$0900-$0953 Slot-2, span, and overlay proof slices.
-
$1500-$1ABF SEQ package descriptor regions for rbm.sample1, rbm.sample2, and rbm.sample3.
-
$3000+ Disk-loaded proof payloads for ZDM1, ZDM2S, ZDOV1, ZDOV2, and ZSAA-ZUEB.
-
desc Descriptors point to payload offsets, sizes, slot masks, runtime destinations, and entry offsets.
-
handles Handle and screen commands fetch the full $06C7 slot-0 payload because shared helpers live there.
-
-
-
- BASIC sees persistent objects as small integer handles from 1 to 128.
- Canonical handle descriptors and the 48KB heap bitmap live in REU.
- Type 1 is a byte buffer; type 2 is screen text+color.
-
-
-
-
- Cold Boot, EXIT, And Warm Resume
- Cold Boot
-
-
1 Load ReadyOS loads readybasic.prg at $1000.
-
2 Copy Entry copies hidden helper seed to $A000 and a visible shadow to $C280, then bridge seed to $C000.
-
3 Relocate Resident installs hooks and relocates BASIC to $2AC1 with top at $A000.
-
4 Seed REU The assigned core bank gets header/descriptors; the assigned code bank gets packed command code.
-
5 READY ReadyBASIC clears/redraws the screen, prints its banner, and enters BASIC_READY.
-
- Manual EXIT And Warm Resume
-
-
1 EXIT Manual prompt EXIT stores READY-mode bridge and entry magic.
-
2 Snapshot Zero page and stack page are saved to the assigned core bank, while SP, mode, and guards remain in bridge metadata.
-
3 Yield Original vectors are restored and ReadyBASIC jumps to shim return $C80C.
-
4 Restore Warm entry restores $A000 from $C280, reinstalls vectors, and re-marks REU ownership.
-
5 Resume Runtime state is restored, live BASIC pointers are preserved, and the screen is redrawn.
-
-
- Warm resume does not cold-reset FRETOP, VARTAB, ARYTAB, or
- STREND. Those live BASIC pointers must survive with variables, arrays,
- and string heap state intact.
-
-
-
-
- Hard Invariants
-
- Boot ReadyBASIC through normal ReadyOS run/profile flows.
- BASIC_START remains $2AC1.
- $2AC0 remains zero before stored-program RUN.
- RESIDENT stays below $2AC0.
- BRIDGE stays below $C200.
- $C600-$C7FF is shared ReadyOS REU metadata.
- $C800-$C9FF is ReadyOS shim ABI.
- Warm resume restores $A000 from the refreshed visible shadow at $C280 before hidden helper calls.
- Warm resume does not cold-reset BASIC heap or variable pointers.
- ReadyBASIC-owned vectors are restored before yielding to ReadyOS.
- Non-ReadyBASIC statements tail-call ROM with unmutated TXTPTR.
- Output variables are cleared before command execution.
- String heap writes happen only in visible resident code.
- Acceptance re-entry uses launcher menu navigation, not direct app-bank hotkeys.
-
-
-
-
- Current Verification Evidence
- Static guardrails are checked with make readybasic-plugin-static-check.
-
- Measure Current value
-
- BASIC_START$2AC1
- Empty BASIC free bytes 30013
- bin/readybasic.prg20994 bytes
- RESIDENT$18BC / 6332B
- LOWPACK$06C7 / 1735B
- BRIDGE$01F7 / 503B
- REGSEED$1010 / 4112B
-
-
-
- Probe Coverage
-
- Full expression probe Direct bare command statements, command expressions, parenthesized EXEC, numeric FUNC expression return, numeric FUNC assignment, string FUNC expression return, and readable LIST.
- Plugin command probe Direct command statements, IF ... THEN assignment/expression coverage, UPPER/LOWER, old-name rejection, string/REM safety, leading-comma rejection, SCRCAP/SCRPUT, slot-128 lookup, 128-handle edge, 48KB heap edge, screen heap exhaustion, wrong-handle-type rejection, screen-handle free, resume.
- Program probe Stored line start, colon chains, true/false IF ... THEN assignment/expression coverage, FOR/NEXT, strings, REM, DATA, arrays, hidden worker, handles, failure clearing.
- rbproc1 probePositive stored PROC/FUNC coverage, including readable LIST, colon chain, normalized IF, nested depth 2, return assignments, command return inside top-level ABS(...), flat numeric expression actuals, and string command return inside a FUNC body.
- rbprocerr probeNegative routine coverage: unknown routine, wrong count/type, missing output, extra actual, bare ENDP, and stack overflow.
- Full visual verification Human-watchable command, program, screen-handle, handle/heap edge, resume, and error coverage.
- Lifecycle probe Cold entry, EXIT, launcher re-entry, READY-mode redraw.
- State probe BASIC variable/string survival and command availability after resume.
- rbtest1 probeSample program assembled at the relocated BASIC workspace.
- Large-vars probe BASIC workspace and variable behavior under heavier state.
- Cross-app resume stress ReadyBASIC survives repeated app switches.
- Second-entry/editor stress ReadyBASIC survives editor/launcher round trips and later re-entry.
-
-
-
- The broad external command/program/lifecycle/state wrappers have been
- refreshed for bare parenthesized syntax. The demo suite is
- intentionally viewer-paced; regression probes stay shorter and more
- assertion-heavy.
-
-
- Some harness wrappers can report process-level partial even when every
- step is ok and FailedStep is null; for ReadyBASIC these are treated
- as harness shutdown-status quirks, not command failures.
-
-
-
-
- Current Bare Commands And Expressions
-
- Parenthesized calls are the preferred syntax. A small eval-vector hook
- supports expression-safe calls: ZADD16(a,b) and
- ZHIDDENRAM(s$) return integers, while UPPER(s$)
- returns a string. Native routines accept parenthesized non-empty
- argument lists, such as PROC SHOWI(P%) and
- EXEC SHOWI(7). Zero-argument routines still use
- EXEC NAME.
-
-
- FUNC calls return through RET and can be assigned or
- printed directly. Numeric actuals can be flat expressions such as
- ADDI(1,2+4) and one-wrapper forms such as
- ADDI(1,(2+4)), ZADD16(1,(2+4)), and
- ADDI((1+2),(3+4)). Command and FUNC returns work
- in the tested ROM consumer forms ABS(ZADD16(1,6)-10),
- ABS(ADDI(1,6)-10), and
- LEFT$(GREET("READY"),2). Fully recursive ReadyBASIC terms
- inside other ReadyBASIC actual lists remain future work.
-
-
+After a ReadyBASIC runtime error, ERRCODE() returns the
+?RB ERROR code and ERRLINE() returns the BASIC
+line number. Direct-mode errors report line 0.
+Command Families
+The current commands are examples of command shapes that the spine
+needs to support, not the final product command catalog.
+
+
+
+
+
+
+
+
+Category
+Commands
+Purpose
+
+
+
+
+Scalar Outputs
+ZECHO1, ZADD16
+Prove integer output variables, numeric expression parsing, and
+scalar result commit.
+
+
+String Transfer/Transform
+UPPER, LOWER
+Prove string input capture and resident-owned BASIC string output
+allocation.
+
+
+Under-ROM Worker
+ZHIDDENRAM
+Prove worker code can run behind BASIC ROM in the shared slot-0
+module payload.
+
+
+Integer Array Transfer
+ZSUMNUMARRAY, ZRANGENUMARRAY
+Prove array input/output via explicit base element plus count.
+
+
+Persistent REU Handles
+BUFMAKE, BUFFILL, BUFDROP,
+SCRCAP, SCRPUT
+Prove stable BASIC-visible handles for persistent REU-backed data,
+including typed screen text+color resources.
+
+
+Temporary REU Workspace
+ZTEMPSCRATCH
+Prove temporary page allocation and cleanup.
+
+
+Error/Failure Contract
+ZFAIL
+Prove outputs are cleared before execution and stale results are not
+committed.
+
+
+Timing/Delay
+ZPAUSE
+Prove a small timing command can wait for a number of jiffies
+without command overlay growth elsewhere.
+
+
+Runtime Introspection
+MEMAVL, ERRCODE, ERRLINE
+Prints live BASIC free memory and exposes the last ReadyBASIC
+runtime error.
+
+
+Module/Submodule Proofs
+ZSLOT0, ZSLOT1, ZSLOT2,
+ZSPAN, ZOVL1, ZOVL2,
+ZCPYRST, ZCOPY, ZMODLD,
+ZDM1, ZDM2S, ZDOV1,
+ZDOV2, ZSAA-ZUEB
+Prove slot dispatch, multi-slot span loading, overlay replacement,
+no-recopy behavior, SEQ package streaming, and disk-loaded module
+registration.
+
+
+ReadyOS Yield
+EXIT
+Save BASIC runtime state, restore vectors, and return through the
+ReadyOS shim.
+
+
+
+Command Inventory
+
+
+
+
+
+
+
+
+
+Command
+Code placement
+Parameters
+Result behavior
+
+
+
+
+ZECHO1(OUT%) / ZECHO1()
+Resident-precomputed result; a legacy low stub remains in
+LOWPACK
+output integer, or expression integer
+Returns 1 without fetching an overlay in the current
+runtime.
+
+
+ZADD16(A,B,OUT%) / ZADD16(A,B)
+Module 1 slot 0 at $A800+, descriptor-backed slice
+two numeric expressions, output integer or expression integer
+Returns 16-bit sum.
+
+
+FADD(A,B,OUT) / FADD(A,B)
+Resident-computed float demo command; descriptor slot 16 has a tiny
+slot-0 stub
+two plain numeric expressions, output plain numeric variable or
+expression float
+Uses BASIC ROM floating addition. Statement output must be a plain
+numeric variable, not %.
+
+
+ZPAUSE(TICKS)
+Module 1 slot 0 at $A800+, descriptor-backed slice
+tick count
+Waits for the requested jiffy count.
+
+
+UPPER(S$,OUT$) / UPPER(S$)
+Module 1 slot 0 at $A800+, descriptor-backed slice
+string variable or quoted literal, output string or expression
+string
+Uppercases staged bytes.
+
+
+LOWER(S$,OUT$) / LOWER(S$)
+Module 1 slot 0 at $A800+, descriptor-backed slice
+string variable or quoted literal, output string or expression
+string
+Lowercases string byte values. On the default C64 screen this is
+verified by ASC() values, because display case is
+charset-dependent.
+
+
+ZHIDDENRAM(S$,OUT%) / ZHIDDENRAM(S$)
+Module 1 slot 0 at $A800+, unified under-ROM
+dispatch
+string variable or quoted literal, output integer or expression
+integer
+Returns a simple uppercase-byte checksum.
+
+
+ZSUMNUMARRAY(A%(0),COUNT,OUT%) /
+ZSUMNUMARRAY(A%(0),COUNT)
+Module 1 slot 0 at $A800+, descriptor-backed slice
+integer array base, count, output integer or expression integer
+Sums integer array elements.
+
+
+ZRANGENUMARRAY(START,COUNT,A%(0))
+Module 1 slot 0 at $A800+, descriptor-backed slice
+start value, count, output array base
+Stages consecutive integers, then resident code writes them to the
+array.
+
+
+BUFMAKE(LEN,H%) / BUFMAKE(LEN)
+Module 1 slot 0, copies full $07DC slot-0 payload
+byte length, output handle or expression handle
+Allocates buffer pages in the assigned core bank and returns a
+one-based handle.
+
+
+BUFFILL(H%,BYTE)
+Module 1 slot 0, copies full $07DC slot-0 payload
+buffer handle, fill byte
+Fills buffer handles through the $C500 page buffer and
+rejects non-buffer handles.
+
+
+BUFDROP(H%)
+Module 1 slot 0, copies full $07DC slot-0 payload
+handle
+Frees any valid handle type and clears metadata/page bitmap
+state.
+
+
+ZTEMPSCRATCH(LEN,OUT%) /
+ZTEMPSCRATCH(LEN)
+Module 1 slot 0, copies full $07DC slot-0 payload
+byte length, output integer or expression integer
+Allocates and frees temporary pages, returning page count.
+
+
+ZFAIL(CODE,OUT%)
+Module 1 slot 0 at $A800+, descriptor-backed slice
+error code, output integer
+Clears output first, then reports ?RB ERROR code.
+
+
+MEMAVL()
+Module 1 slot 0 at $A800+, descriptor-backed slice
+none
+Prints current live BASIC free bytes.
+
+
+SCRCAP(H%) / SCRCAP()
+Slot 14 descriptor; module 1 slot 0, copies full $07DC
+slot-0 payload
+output handle or expression handle
+Captures screen text $0400-$07E7 and color RAM
+$D800-$DBE7 into a typed screen handle.
+
+
+ERRCODE(OUT%) / ERRCODE()
+Resident-precomputed result; legacy low stub remains in
+LOWPACK
+output integer, or expression integer
+Returns the last ReadyBASIC runtime error code.
+
+
+ERRLINE(OUT%) / ERRLINE()
+Resident-precomputed result; legacy low stub remains in
+LOWPACK
+output integer, or expression integer
+Returns the line number of the last ReadyBASIC runtime error, or
+0 for direct mode.
+
+
+SCRPUT(H%)
+Slot 128 descriptor; module 1 slot 0, copies full $07DC
+slot-0 payload
+screen handle
+Validates the screen handle type and restores text plus color
+RAM.
+
+
+ZSLOT0() / ZSLOT1() /
+ZSLOT2()
+Built-in module proof payloads in slot 0, slot 1, and slot 2
+none
+Prove each 2K submodule slot can dispatch independently.
+
+
+ZSPAN()
+Built-in module 2 two-slot span payload for slots 1+2
+none
+Proves a payload can claim adjacent slots.
+
+
+ZOVL1() / ZOVL2()
+Built-in module 2 slot-2 overlay proof payloads
+none
+Prove overlay replacement in slot 2.
+
+
+ZCPYRST() / ZCOPY()
+Built-in module 1 slot-0 copy-count proof helpers
+none
+Reset and inspect the tiny no-recopy proof counter.
+
+
+ZMODLD(NAME$)
+Built-in module 2 slot-1 disk-module loader
+module package filename string
+Opens generated SEQ packages such as RBM.SAMPLE1,
+RBM.SAMPLE2, and RBM.SAMPLE3, registering
+their descriptors in the assigned core bank and payloads in the assigned
+code bank.
+
+
+ZDM1() / ZDM2S() / ZDOV1() /
+ZDOV2()
+Disk-loaded sample module payloads in the assigned code bank
+none
+Prove disk module, span, and overlay registration after
+ZMODLD.
+
+
+ZSAA()-ZUEB()
+rbm.sample3 disk-loaded proof payloads in the assigned
+code bank
+none
+Return stateful integer sentinels; the command name encodes
+submodule, overlay, and entrypoint while copy-count tests prove
+residency. ZS/ZT/ZU mean submodules 6/7/8,
+A-E mean overlays 1-5, and the final
+A/B is the entrypoint. Each overlay image has one local
+counter byte, so reuse increments while reload resets.
+
+
+
+The handle-oriented commands copy the full slot-0 payload because
+their wrappers share allocator helper routines that currently live in
+that module payload. That keeps the resident core lean at the cost of
+copying more under-ROM bytes for these sample commands.
+SCRCAP/SCRPUT were named to avoid C64 BASIC
+tokenizer conflicts with embedded SAVE/LOAD
+tokens. They are the implemented forms of the original screen save/load
+concept.
+Historical proof names such as PING, ADD16,
+STRUP, HCRC, SUMAI,
+RANGEAI, TEMPSCRATCH, and FAIL
+are no longer runtime command aliases. Their current demo/proof forms
+use the Z... namespace, and array demo names use
+NUM rather than INT to avoid the BASIC
+INT token.
+Command Overlay
+Loading And Files Involved
+There is one ReadyBASIC app executable:
+bin/readybasic.prg. There is not one PRG or executable file
+per command. The command overlays are linker segments inside that one
+PRG load image:
+
+
+
+
+
+
+
+File or artifact
+Role
+
+
+
+
+src/apps/readybasic/readybasic.s
+All current ReadyBASIC code, command descriptors, module/submodule
+payloads, overlay proof payloads, and hidden helpers.
+
+
+cfg/ready_app_readybasic.cfg
+Defines the load/run split: resident code, CMDPACK,
+REGSEED, hidden helper load image, bridge load image, and
+runtime overlay slots.
+
+
+Makefile
+Assembles readybasic.s, links it with
+ready_app_readybasic.cfg, and writes
+bin/readybasic.prg plus
+obj/readybasic.map.
+
+
+obj/readybasic.map
+Current source of truth for segment ranges and sizes.
+
+
+bin/readybasic.prg
+The single ReadyOS app executable that contains resident code plus
+cold-load seed images.
+
+
+src/apps/readybasic/rbtest1.bas /
+obj/rbtest1.prg
+Legacy sample BASIC program only; not part of the command overlay
+mechanism.
+
+
+src/apps/readybasic/rbproc1.bas /
+obj/rbproc1.prg
+Positive PROC/FUNC sample: no-param PROC,
+%, $, explicit
+RET%/RET$, colon chain, normalized
+IF THEN :EXEC, nested depth 2, int/string/float command and
+FUNC expression returns, nested ReadyBASIC actuals, statement
+FADD output, string concatenation through ROM functions,
+and readable LIST.
+
+
+src/apps/readybasic/rbprocerr.bas /
+obj/rbprocerr.prg
+Negative PROC/FUNC sample; run sections by
+line number to exercise unknown routine, wrong count/type, statement
+EXEC to FUNC, PROC extra actual, bare
+ENDP, return-stack overflow, malformed nested actuals, and
+float/string/numeric context errors.
+
+
+build_support/verify_readybasic_plugin.py
+Static guardrail checker for the ReadyBASIC layout and REU
+constants.
+
+
+READYBASIC_MAKING_COMMAND_GUIDE.md /
+readybasic_making_command_guide.html
+Walkthrough for adding commands using the current demo, string,
+array, hidden, and REU-handle examples.
+
+
+
+The linker puts packed command bytes in the PRG load image at
+CMDPACK $2B00-$3FFF and CMDPACK2
+$6200-$7FFF, but their runtime addresses are different:
+
+
+
+
+
+
+
+
+
+Segment
+Size
+Load/source role
+Runtime role
+
+
+
+
+LOWPACK
+$07DC (2.0K, 2012 exact
+bytes)
+Historical segment name for the built-in module 1 slot-0 payload
+loaded from CMDPACK and prestashed to assigned code-bank
+offset $0000.
+Fetched on demand into $A800-$AFDB.
+
+
+SLOTPACK1
+$0541 (1.3K, 1345 exact
+bytes)
+Built-in module 2 proof, streaming ZMODLD loader, and
+GFXCORE payload, prestashed to assigned code-bank offset
+$07DC.
+Fetched on demand into $B000-$B540.
+
+
+SLOTPACK2
+$0738 (1.8K, 1848 exact
+bytes)
+Built-in module 2 slot proof plus GFXPRIM, prestashed
+to assigned code-bank offset $0D1D.
+Fetched on demand into $B800-$BF37.
+
+
+SPANPACK
+$0015 (21B)
+Built-in two-slot span proof payload.
+Fetched into slots 1+2 at $B000-$B014.
+
+
+OVL1PACK
+$0272 (626B)
+Built-in slot-2 overlay proof plus GFXSPR, loaded from
+CMDPACK2 $6200 and prestashed to assigned
+code-bank offset $5000.
+Fetched as a replacement overlay into $B800-$BA71.
+
+
+OVL2PACK
+$006D (109B)
+Built-in slot-2 overlay proof plus INPUTEV, loaded from
+CMDPACK2 $6472 and prestashed to assigned
+code-bank offset $5800.
+Fetched as a replacement overlay into $B800-$B86C.
+
+
+OVL3PACK
+$0779 (1.9K, 1913 exact
+bytes)
+Built-in slot-2 overlay proof plus GFXPOLY, loaded from
+CMDPACK2 and prestashed to assigned code-bank offset
+$6000.
+Fetched as a replacement overlay into $B800-$BF78.
+
+
+OVL4PACK
+$0783 (1.9K, 1923 exact
+bytes)
+Built-in GFXDL display-list overlay, prestashed to
+assigned code-bank offset $6800.
+Fetched as a replacement overlay into $B800-$BF82.
+
+
+OVL5PACK
+$04DA (1.2K, 1242 exact
+bytes)
+Built-in GFXTILE charset/tilemap/multicolor-cell
+overlay, prestashed to assigned code-bank offset
+$7000.
+Fetched as a replacement overlay into $B800-$BCD9.
+
+
+OVL6PACK
+$020E (526B)
+Built-in SIDCORE immediate sound overlay, prestashed to
+assigned code-bank offset $7800.
+Fetched as a replacement overlay into $B800-$BA0D.
+
+
+HIDLOAD
+$078B (1.9K, 1931 exact
+bytes)
+Load-only hidden helper seed starting at $4000.
+Copied on cold boot into $A000-$A78A and stashed to the
+assigned core-bank hidden shadow at $3000.
+
+
+BRLOAD
+$01FF (511B)
+Load-only bridge seed starting at $4800.
+Copied on cold boot into $C000-$C1FE.
+
+
+REGSEED
+$1010 (4.0K, 4112 exact
+bytes)
+Load-only registry header and 128 command descriptors at
+$5000-$600F.
+Copied on cold boot into assigned core-bank offsets
+$0000 and $1000.
+
+
+
+Cold boot is the only time the load-image command pack and
+REGSEED are trusted. The hidden helper copies the
+registry/header to the assigned core bank and copies the built-in
+module/submodule payloads from CMDPACK and
+CMDPACK2 to the assigned code bank. After that, BASIC may
+own the former load-image addresses, so warm resume reuses the REU
+copies and does not reseed from $2B00+,
+$4000+, $4800+, or $5000+.
+At command execution time, the descriptor tells the resident loader
+which bytes to fetch:
+
+Descriptor bytes 2-5 name the payload offset and size
+in the assigned code bank.
+Descriptor bytes 6-9 name the submodule id, overlay id,
+slot mask, and generation/check byte.
+Descriptor bytes 10-13 name the runtime destination
+offset from $A000 and the entry offset inside the loaded
+payload.
+ReadyBASIC maps RAM under BASIC ROM, fetches the payload into
+$A800, $B000, $B800, or a
+multi-slot span, calls the entry, then returns to visible resident code
+for result commit.
+Commands can fetch a small slice or a full slot payload. The current
+handle and screen-handle commands fetch the whole $07DC
+slot-0 payload because their shared allocator and screen-copy helpers
+live there.
+
+C64 RAM Layout
+ReadyBASIC is captured by the ReadyOS $1000-$C5FF app
+snapshot. Its custom assembler/linker shape intentionally uses runtime
+bytes only through $C5FF; the full $C600-$C9FF
+region is resident shim space.
+
+
+
+
+
+
+
+
+
+Region
+Current range
+Size
+Owner and role
+
+
+
+
+ENTRY
+$1000-$11FF
+$0200 (512B)
+Tiny entry, cold/warm discriminator, early hidden/bridge copies, and
+prompt hotkey helpers.
+
+
+RESIDENT
+$1200-$2ABF
+$18C0 (6.2K, 6336 exact
+bytes)
+Visible parser, vector hooks, BASIC ROM calls, REU DMA wrappers,
+result commit, bare command dispatch, expression hook, native
+PROC/FUNC/RET,
+REPEAT/UNTIL,
+LABEL/JUMP, error introspection, proper nested
+term state, float helpers, and prompt hotkey dispatch.
+
+
+BASIC sentinel
+$2AC0
+1 byte
+Must stay zero before stored-program RUN.
+
+
+BASIC workspace
+$2AC1-$9FFF
+$753F region,
+30013 formula free bytes (29.3K)
+Program text, variables, arrays, string heap.
+
+
+Command pack load image
+$2B00-$3FFF
+$1500 (5.25K) file
+range
+Built-in module/submodule payload seed bytes before cold
+prestash.
+
+
+Hidden helper load image
+$4000+
+$078B (1.9K, 1931 exact
+bytes) load-only
+Hidden helper seed copied to $A000 and stashed to
+assigned core-bank offset $3000.
+
+
+Bridge load image
+$4800+
+$01FF (511B) load-only
+Bridge seed copied to $C000.
+
+
+Registry seed load image
+$5000-$600F
+$1010 (4.0K, 4112 exact
+bytes) load-only
+Header and 128 descriptors copied to the assigned core bank.
+
+
+Command pack 2 load image
+$6200-$7FFF
+$1E00 (7.5K) file range
+Built-in replacement overlay seed bytes before cold prestash.
+
+
+Runtime snapshot
+Assigned core bank offsets
+$0A00-$0BFF
+$0200 (0.5K) plus bridge
+metadata
+Saved zero page, stack page, SP, resume mode, line-chain
+guards.
+
+
+Common under-ROM helper
+$A000-$A78A
+$078B (1931B)
+Helper code run with RAM mapped under BASIC ROM.
+
+
+Slot 0 module payload
+$A800-$AFDB
+$07DC (2012B)
+Module 1 system/default payload fetched from the assigned code
+bank.
+
+
+Slot 1 module payload
+$B000-$B540
+$0541 (1345B)
+Module 2 proof, streaming ZMODLD loader, and
+GFXCORE payload.
+
+
+Slot 2 GFXPRIM image
+$B800-$BF37
+$0738 (1848B)
+Slot-2 base/proof plus GFXPRIM; replacement overlays
+load over this when called.
+
+
+Slot 2 GFXSPR overlay image
+$B800-$BA71
+$0272 (626B)
+Replacement overlay for sprite commands.
+
+
+Slot 2 INPUTEV overlay image
+$B800-$B86C
+$006D (109B)
+Replacement overlay for polling input commands.
+
+
+Slot 2 GFXPOLY overlay image
+$B800-$BF78
+$0779 (1913B)
+Replacement overlay for polygon and REU point-buffer commands.
+
+
+Slot 2 GFXDL overlay image
+$B800-$BF82
+$0783 (1923B)
+Replacement overlay for display-list commands.
+
+
+Slot 2 GFXTILE overlay image
+$B800-$BCD9
+$04DA (1242B)
+Replacement overlay for charset, tileset, tilemap, and
+multicolor-cell commands.
+
+
+Slot 2 SIDCORE overlay image
+$B800-$BA0D
+$020E (526B)
+Replacement overlay for immediate SID sound commands.
+
+
+BRIDGE
+$C000-$C1FE
+$01FF (511B)
+Persistent bridge state, saved vectors, overlay variables, current
+handle scratch, debug bytes, native routine return stack, and
+flow-control scratch.
+
+
+Shared frames
+$C200-$C5FF
+$0400 (1.0K)
+Call frame, result frame, descriptor buffer, command-name buffer,
+page/runtime buffers.
+
+
+Hidden helper shadow
+Assigned core bank
+$3000+
+$078B (1931B)
+REU source for restoring $A000 helper on warm resume;
+refreshed during EXIT and cold seed.
+
+
+ReadyOS shim expansion reserve
+$C600-$C7FF
+$0200 (0.5K) shared
+Resident capacity for future shim functionality; not ReadyBASIC
+RAM.
+
+
+ReadyOS shim ABI
+$C800-$C9FF
+$0200 (0.5K) shared
+Stable ReadyOS jump table and data; the full shim region is 1
+KB.
+
+
+
+The PRG load image is larger than the live resident core. On cold
+entry, ReadyBASIC copies the hidden helper seed from the load image to
+$A000, stashes the helper shadow in the assigned core bank
+at $3000, copies the bridge seed to $C000, and
+prestashes registry/code seed data into REU. After that, BASIC owns
+$2AC1-$9FFF. Warm resume must therefore not reread
+load-only seed tables at $4000+, because that address range
+may now be BASIC program or variable storage.
+Stage-Specific Memory Use
+Some map entries intentionally overlap the eventual BASIC workspace.
+That is not a contradiction; it is a time-of-use distinction.
+
+
+
+
+
+
+
+
+Stage
+C64 RAM ownership
+BASIC-visible effect
+
+
+
+
+PRG load / cold seed
+CMDPACK is loaded at $2B00-$3FFF,
+HIDLOAD at $4000+, BRLOAD at
+$4800+, REGSEED at $5000-$600F,
+and CMDPACK2 at $6200-$7FFF. These ranges are
+inside the future BASIC workspace but BASIC is not live there yet.
+No user BASIC program or variables exist yet, so the load image can
+safely occupy this space temporarily.
+
+
+End of cold seed
+Built-in module/submodule payloads have been copied from
+CMDPACK and CMDPACK2 to the assigned code
+bank; the registry has been copied to the assigned core bank; hidden and
+bridge live copies are in their runtime homes.
+$2AC1-$9FFF becomes the BASIC workspace. The former
+load-image bytes are now disposable.
+
+
+Ready prompt / running BASIC
+BASIC owns $2AC1-$9FFF, including the old
+$2B00-$7FFF load ranges. Command code is fetched from REU
+into $A800, $B000, and/or $B800
+under BASIC ROM only while a command runs.
+Empty BASIC free space is 30013 formula bytes. Warm
+resume never trusts the old load-image addresses.
+
+
+Future command growth
+CMDPACK carries $1455 / 5205B of base
+built-ins and has $00AB / 171B free. CMDPACK2
+carries $18C3 / 6339B of overlay built-ins and has
+$053D / 1341B free.
+Both cold-load windows are reclaimed before BASIC owns the
+workspace, so growing within them does not reduce steady-state BASIC
+free bytes. Runtime growth is still bounded by each 2K execution
+image.
+
+
+
+The visual way to read this: CMDPACK looks like it
+overlaps BASIC RAM in the link/load map because it really does during
+cold loading. It does not reduce the steady-state BASIC workspace
+because its live copy is in REU before the user can store a BASIC
+program.
+CMDPACK is only the current C64 cold-load seed window.
+It is not the total command-code capacity of the architecture. The
+current descriptor format points into the assigned code bank with 16-bit
+offsets and sizes, so the current single code bank can hold up to
+$10000 bytes (64.0K) of packed command bodies. The base
+built-in payloads currently use $1455 (5.1K, 5205 exact
+bytes) and the fixed built-in overlay reservations occupy through
+$77FF, leaving the contiguous tail $7800-$FFFF
+($8800, 34816 exact bytes) available in the assigned code
+bank. To actually seed beyond the current 5.25K CMDPACK
+linker window, the cold-load layout would need a larger or additional
+load-only seed range, copied to REU before BASIC owns
+$2AC1-$9FFF. Going beyond one 64K code bank would require a
+descriptor/loader extension for additional command-code banks.
+BASIC Free RAM
+Compared With Stock C64 BASIC
+Stock C64 BASIC V2 starts at $0801 and normally has
+memory top at $A000, which gives about 38911
+bytes free on an empty machine.
+ReadyBASIC relocates BASIC to $2AC1 and uses
+$A000 as the BASIC memory top. On an empty ReadyBASIC
+workspace, variables begin at $2AC3, so the practical empty
+BASIC free space is:
+$A000 - $2AC3 = 30013 bytes (29.3K)
+That is 8898 bytes (8.7K) less than stock C64 BASIC, or
+about 77.1% of the stock empty BASIC free space. The latest
+extra resident growth pays for REPEAT/UNTIL,
+LABEL/JUMP, and error introspection while
+keeping the resident segment below the measured $2ABF
+ceiling.
+
+
+
+Environment
+BASIC text start
+BASIC top
+Empty free bytes
+
+
+
+
+Stock C64 BASIC V2
+$0801
+$A000
+38911 (38.0K)
+
+
+ReadyBASIC current layout
+$2AC1
+$A000
+30013 (29.3K)
+
+
+Difference
+-
+-
+-8898 (-8.7K)
+
+
+
+Strategies to maximize BASIC RAM while adding many more commands:
+
+Keep the resident core below the current BASIC page boundary; every
+resident byte is permanent C64 RAM pressure.
+Put command implementation code in packed REU code banks and copy it
+into the existing overlay slots only when invoked.
+Reuse existing signatures and commit paths where possible. A new
+command with an existing parameter/result shape should not need new
+resident parser code.
+Keep descriptors in the REU registry, not in resident RAM.
+Move command-private persistent data to dynamic REU banks and expose
+small BASIC integer handles instead of storing large data in BASIC
+RAM.
+Split or group overlay helper routines only when it reduces total
+copied bytes without bloating resident RAM.
+If the current assigned code bank becomes crowded, extend the
+registry model to support additional packed code banks rather than
+lowering BASIC’s top or adding permanent C64-resident command code.
+Consider a compact REU-backed signature/parameter table if many
+future commands would otherwise require one resident parser case
+each.
+
+Current per-command overhead:
+
+
+
+
+
+
+
+
+New command kind
+Permanent C64 RAM overhead
+REU/load-image overhead
+
+
+
+
+New command reusing an existing signature and submodule slot
+Usually 0 bytes of BASIC
+workspace and 0 bytes of resident RAM.
+One 32-byte descriptor in the assigned core bank, command code bytes
+in the assigned code bank, and matching load-image bytes in the
+appropriate module/submodule payload.
+
+
+New command needing a new parameter/result signature
+No BASIC workspace cost, but resident
+parser/commit code grows by the new shared support.
+One 32-byte descriptor plus command code bytes.
+
+
+New command needing persistent data
+No BASIC workspace cost if represented as
+a handle.
+Descriptor/code bytes plus REU data-bank allocation and handle
+metadata.
+
+
+New command needing a larger fixed C64 buffer
+Permanent C64 RAM cost only if it expands
+$C200-$C5FF, the overlay slots, resident RAM, or bridge
+state.
+Depends on whether the data can be moved to REU instead.
+
+
+
+Page-3 Vector Ownership
+ReadyBASIC saves the original BASIC vectors, then installs:
+
+
+
+
+
+
+
+
+Vector
+Address
+ReadyBASIC role
+
+
+
+
+Crunch
+$0304/$0305
+Calls ROM crunch first, then normalizes tokenized
+THEN EXEC ... and THEN JUMP ... into
+colon-prefixed statements.
+
+
+Execute
+$0308/$0309
+Peeks for EXIT, PROC, FUNC,
+EXEC, ENDP, or a bare descriptor command;
+otherwise tail-calls the original execute vector without advancing
+TXTPTR.
+
+
+Eval
+$030A/$030B
+Recognizes selected COMMAND(...) and
+FUNC(...) expression returns, then falls back to ROM
+expression evaluation.
+
+
+IMAIN
+$0302/$0303
+Marks the BASIC direct prompt active when ROM BASIC returns to
+READY..
+
+
+KEYLOG
+$028F/$0290
+Catches KERNAL-decoded prompt hotkeys only while ReadyBASIC owns the
+direct prompt, records the pending ReadyOS action, clears the consumed
+key state, and queues Return.
+
+
+CHRIN
+$0324/$0325
+Wraps the original CHRIN, preserves normal return semantics for
+ordinary input, and abort-dispatches pending prompt hotkeys before BASIC
+stores or executes the partial line.
+
+
+List
+$0306/$0307
+Saved/restored, but V1 leaves normal ROM listing behavior.
+
+
+
+Page-3 vectors are global machine state. EXIT restores
+the original vectors before jumping back through the ReadyOS shim so the
+launcher or another app cannot accidentally dispatch through stale
+ReadyBASIC code.
+Command Dispatch Pipeline
+
+BASIC dispatches a statement through the execute vector.
+ReadyBASIC peeks at the next non-space byte without mutating
+TXTPTR.
+If the statement is neither EXIT, a native routine
+keyword, nor a known bare descriptor command followed by (,
+ReadyBASIC tail-calls the saved ROM execute vector.
+For a bare command, ReadyBASIC parses and normalizes the command
+name into $C4A0, requires (, and reuses the
+descriptor lookup and signature parser.
+Command lookup linearly scans up to 128 fixed 32-byte descriptors in
+the assigned core bank at $1000-$1FFF. It fetches one
+256-byte page into $C500, scans eight descriptors locally,
+and copies a match into $C480. Zero-filled filler
+descriptors are empty command slots.
+The resident parser dispatches by signature id and uses BASIC ROM
+helpers to parse parameters and capture output references.
+Output variables are cleared before command execution.
+The call frame at $C200 is mirrored to assigned
+core-bank offset $0400.
+Command code is fetched from the assigned code bank into one or more
+under-ROM submodule slots at $A800, $B000, and
+$B800.
+The worker writes a compact result frame at $C300.
+The result frame is mirrored to assigned core-bank offset
+$0400.
+Resident code checks status, prints ?RB ERROR n on
+failure, or commits integer, string, or array results to the captured
+BASIC output reference.
+
+The command-name parser accepts normal letters/digits, folds
+lowercase ASCII to uppercase, maps shifted uppercase/PETSCII-like
+$C1-$DA bytes back to A-Z, and handles a small
+number of tokenization edge cases that can appear inside names.
+Frames And ABI Surfaces
+
+
+
+
+
+
+
+
+Surface
+Address or offset
+Role
+
+
+
+
+Call frame
+$C200
+Command id, parameter count, numeric slots, pointer/count slots,
+string input buffer.
+
+
+Result frame
+$C300
+Status, error number, value tag, scalar value, string output buffer,
+array output buffer.
+
+
+Descriptor buffer
+$C480
+One descriptor fetched from the assigned core bank.
+
+
+Command buffer
+$C4A0
+Uppercase normalized command name.
+
+
+Page buffer
+$C500
+256-byte staging page for descriptor scans, REU handle operations,
+heap bitmap scans, and warm-resume stack buffer.
+
+
+REU call snapshot
+Assigned core bank
+$0400
+Copy of the current call frame.
+
+
+REU result snapshot
+Assigned core bank
+$0400
+Copy of the current result frame.
+
+
+Runtime zero-page snapshot
+Assigned core bank
+$0A00
+Saved zero page, restored through the temporary buffer at
+$C400.
+
+
+Runtime stack snapshot
+Assigned core bank
+$0B00
+Saved stack page, restored through the temporary buffer at
+$C500.
+
+
+
+The descriptor ABI is fixed-size and compact:
+
+
+
+Descriptor offset
+Field
+
+
+
+
+0
+Command id.
+
+
+1
+Module id.
+
+
+2-3
+Payload offset in the assigned code bank.
+
+
+4-5
+Payload size.
+
+
+6
+Submodule id.
+
+
+7
+Overlay id, or 0 for a base submodule.
+
+
+8
+Slot mask: bit 0 = $A800, bit 1 = $B000,
+bit 2 = $B800.
+
+
+9
+Generation/check byte.
+
+
+10-11
+Runtime destination offset from $A000.
+
+
+12-13
+Entry offset inside the loaded payload.
+
+
+14
+Signature id.
+
+
+15
+Uppercase command-name length.
+
+
+16-31
+Uppercase command-name bytes, zero padded.
+
+
+
+Supported result tags are:
+
+
+
+Tag
+Meaning
+
+
+
+
+0
+No result.
+
+
+1
+Integer result.
+
+
+2
+String result.
+
+
+3
+Integer array result.
+
+
+
+String output is committed only by visible resident code. Workers
+stage string bytes in the result frame; resident code allocates BASIC
+string heap space by lowering FRETOP and updates the output
+string descriptor. Hidden and low workers do not directly mutate the
+BASIC string heap.
+REU Layout
+ReadyBASIC uses two launcher-assigned REU resource banks:
+
+
+
+Resource
+ReadyOS type
+Purpose
+
+
+
+
+core bank
+14
+ReadyBASIC core/system storage.
+
+
+code bank
+15
+Packed ReadyBASIC command-code storage.
+
+
+
+The launcher marks the assigned physical banks in the ReadyOS REU
+allocation table at $C600-$C6FF. ReadyBASIC scans that
+table at startup and does not use $C600-$C7FF as private
+scratch.
+Assigned Core Bank:
+Core/System Storage
+
+
+
+
+
+
+
+Offset
+Region
+
+
+
+
+$0000
+Header: RBPL, version, descriptor count, descriptor
+size, and frame offsets.
+
+
+$0400
+Current call-frame snapshot.
+
+
+$0400
+Current result-frame snapshot.
+
+
+$0600
+Reserved debug ring area.
+
+
+$0800-$09FF
+REU-backed handle directory: 128 descriptors, 4 bytes each.
+
+
+$0A00
+Saved zero page for ReadyOS suspend/resume.
+
+
+$0B00
+Saved stack page for ReadyOS suspend/resume.
+
+
+$0C00-$0CFF
+192-byte heap page bitmap plus reserved bytes.
+
+
+$1000-$1FFF
+128 command descriptor slots, 32 bytes each. Current build has 94
+real descriptors, 34 zero-filled filler descriptors, and
+SCRPUT deliberately kept in slot 128.
+
+
+$2000-$3FFF
+Reserved common/system space for future ReadyBASIC metadata.
+
+
+$4000-$FFFF
+Typed handle heap: 192 pages / 48KB.
+
+
+
+The descriptor table keeps SCRPUT in the final slot to
+prove full-table lookup. Every duplicate public spelling would consume a
+real 32-byte descriptor in the assigned core bank, so the source filler
+count must track the actual descriptor count:
+
+
+
+
+
+
+
+
+
+
+Descriptor range
+REU offset
+Role
+Slots
+Size
+
+
+
+
+Slots 1-93
+$1000-$1B9F
+Current built-in descriptors from ZECHO1 through
+SOUND.
+93
+$0BA0 / 2976B
+
+
+Slots 94-127
+$1BA0-$1FDF
+Zero-filled filler descriptors available for future commands.
+34
+$0440 / 1088B
+
+
+Slot 128
+$1FE0-$1FFF
+SCRPUT, deliberately placed at the end to prove
+full-table lookup.
+1
+$0020 / 32B
+
+
+
+The persistent handle model supports 128 live handles. Each handle is
+represented to BASIC as a small integer from 1 to
+128, while canonical metadata lives in REU and bridge RAM
+keeps only the current descriptor scratch. Type 1 is a byte
+buffer, and type 2 is a screen text+color buffer.
+BUFFILL accepts only buffer handles; BUFDROP
+frees any valid handle; SCRPUT accepts only screen handles.
+The typed heap uses assigned core-bank pages $40-$FF;
+future large or long-lived objects should allocate additional REU banks
+and keep the same small handle model.
+Assigned Code Bank:
+Packed Command Code
+
+
+
+
+
+
+
+Offset
+Region
+
+
+
+
+$0000-$07DB
+Built-in module 1 slot-0 payload copied into
+$A800-$AFDB ($07DC, 2012B).
+
+
+$07DC-$0D1C
+Built-in module 2 slot-1 proof, streaming ZMODLD
+loader, and GFXCORE payload copied into
+$B000-$B540 ($0541, 1345B).
+
+
+$0D1D-$1454
+Built-in slot-2 proof plus GFXPRIM copied into
+$B800-$BF37 ($0738, 1848B).
+
+
+$13AA-$13BE
+Built-in two-slot span proof payload ($0015, 21B).
+
+
+$1455-$14FF
+Free gap before current disk-module descriptor proof offsets
+($00AB, 171B).
+
+
+$1500-$151F
+rbm.sample1 descriptor for ZDM1.
+
+
+$1600-$165F
+rbm.sample2 descriptors for ZDM2S,
+ZDOV1, and ZDOV2.
+
+
+$1700-$1ABF
+rbm.sample3 descriptors for
+ZSAA-ZUEB.
+
+
+$3000-$3014,
+$3200-$3214, $3300-$3314,
+$3400-$3414
+Small sample disk-loaded payload proofs.
+
+
+$3800-$463C
+rbm.sample3 payload records for
+ZSAA-ZUEB, stored on $100-byte
+strides.
+
+
+$463D-$4FFF
+Free gap before fixed built-in replacement overlay offsets
+($09C3, 2499B).
+
+
+$5000-$5271
+Built-in slot-2 replacement overlay plus GFXSPR
+($0272, 626B).
+
+
+$5272-$57FF
+Reserved GFXSPR overlay growth headroom
+($058E, 1422B).
+
+
+$5800-$586C
+Built-in slot-2 replacement overlay plus INPUTEV
+($006D, 109B).
+
+
+$586D-$5FFF
+Reserved INPUTEV overlay growth headroom
+($0793, 1939B).
+
+
+$6000-$6778
+Built-in slot-2 replacement overlay plus GFXPOLY
+($0779, 1913B).
+
+
+$6779-$67FF
+Reserved GFXPOLY overlay growth headroom
+($0087, 135B).
+
+
+$6800-$6F82
+Built-in GFXDL replacement overlay ($0783,
+1923B).
+
+
+$6F83-$6FFF
+Reserved GFXDL overlay growth headroom
+($007D, 125B).
+
+
+$7000-$74D9
+Built-in GFXTILE replacement overlay
+($04DA, 1242B).
+
+
+$74DA-$77FF
+Reserved GFXTILE overlay growth headroom
+($0326, 806B).
+
+
+$7800-$7A0D
+Built-in SIDCORE replacement overlay
+($020E, 526B).
+
+
+$7A0E-$7FFF
+Reserved SIDCORE overlay growth headroom
+($05F2, 1522B).
+
+
+$8000-$FFFF
+Free tail after fixed built-in replacement overlay reservations
+($8000, 32768B).
+
+
+
+Descriptors point into these packed bytes with payload offset,
+payload size, slot mask, runtime destination, and entry offset. Heap and
+screen-handle commands currently fetch the whole $07DC
+slot-0 payload because shared allocator and screen-copy helpers live
+there.
+Cold Boot Lifecycle
+
+ReadyOS loads readybasic.prg at
+$1000.
+Entry code checks its local warm/cold magic.
+On cold path, it maps RAM under BASIC ROM long enough to copy the
+hidden helper seed to $A000, then stashes the helper shadow
+to assigned core-bank offset $3000.
+It copies bridge seed bytes from the load image to
+$C000.
+The resident core resets KERNAL/BASIC vectors, saves originals, and
+installs ReadyBASIC crunch/execute/eval, KEYLOG, and CHRIN hooks.
+BASIC is relocated to TXTTAB=$2AC1 with top at
+$A000.
+$2AC0, $2AC1, and $2AC2 are
+cleared. $2AC0 is the sentinel byte required by BASIC
+RUN.
+The assigned core bank receives the header and descriptors from
+REGSEED.
+The assigned code bank receives the packed low and hidden command
+code.
+ReadyBASIC clears/redraws the screen, prints its banner, and enters
+BASIC_READY.
+
+EXIT, Suspend, And Warm
+Resume
+Manual prompt EXIT and prompt-level CTRL+B
+share the launcher-return path. Prompt-level
+F2/F4 use the same state-save/vector-restore
+setup, then write the selected loaded app bank to $C820 and
+jump through $C80F. The selected bank is first copied into
+bridge state before yield preparation, then replayed after the hidden
+save/vector/channel cleanup has run; scratch bytes used by the
+loaded-bank scan are not trusted across the yield path. The keyboard
+path records a pending action, queues only Return, then lets the CHRIN
+hook dispatch before BASIC stores or executes the editor line.
+READY-mode hotkey yields force the saved resume stack to a clean
+BASIC-ready value instead of preserving the transient CHRIN/editor call
+depth. Before a prompt hotkey yield, ReadyBASIC waits for the exact
+physical chord that selected the action to be released, then clears
+editor/KERNAL key state again. Cold and warm entry also scan the
+physical matrix and suppress the same still-held ReadyOS hotkey until it
+has been released. This keeps one F2/F4 press from double-switching
+through the next app and keeps the resumed BASIC editor
+keyboard-live.
+On EXIT, ReadyBASIC:
+
+Identifies direct-prompt return by checking that TXTPTR
+is below BASIC_START.
+Stores bridge and entry magic for READY-mode resume.
+Calls hidden save-state code.
+Saves zero page $0000-$00FF to assigned core-bank
+offset $0A00.
+Saves stack page $0100-$01FF to assigned core-bank
+offset $0B00.
+Saves SP, mode, runtime magic, and line-chain guards in bridge
+metadata.
+Refreshes the assigned-core-bank hidden-helper shadow at
+$3000.
+Clears pending ReadyBASIC/KERNAL keyboard state and calls
+CLRCHN.
+Restores the original page-3 BASIC/KERNAL vectors.
+Jumps to the ReadyOS shim return entry at $C80C.
+
+For F2/F4, ReadyBASIC scans the
+authoritative schema-v5 loaded flags at ReadyOS-bank offset
+$B840 + token, using the direct physical ReadyOS bank in
+$C83B, and starts from the current token in
+$C834. If a neighbor app is found, it performs the same
+READY-mode save/restore setup, persists the target bank in bridge state,
+clears editor hotkey state, restores channels/vectors, writes the saved
+target to $C820, and jumps to the shim switch entry
+$C80F. If no neighbor is loaded, the key is consumed and
+the BASIC editor continues waiting.
+On warm resume, ReadyOS restores the app window and jumps back to
+$1000. ReadyBASIC:
+
+Sees entry-local warm magic.
+Restores the hidden helper at $A000 from the preserved
+assigned-core-bank $3000 shadow.
+Reinstalls ReadyBASIC-owned vectors.
+Re-marks REU bank ownership for the assigned ReadyBASIC core/code
+banks.
+Does not reread cold-only REGSEED or command-pack load
+images.
+Restores zero page and stack from the assigned core bank through
+$C400/$C500, and restores SP/mode metadata from the
+bridge.
+Preserves live BASIC pointers such as FRETOP,
+VARTAB, ARYTAB, and STREND.
+In READY-mode resume, clears the launcher surface, redraws the
+ReadyBASIC banner, positions the prompt, and enters
+BASIC_READY.
+
+Hidden Code And Banking
+Contract
+ReadyBASIC uses hidden code in two places:
+
+
+
+
+
+
+
+
+Code
+Range
+Purpose
+
+
+
+
+Hidden helper
+$A000-$A6C7
+REU prestash, save/restore helpers, bank-sensitive work.
+
+
+Command slots
+$A800-$BFFF
+Module/submodule payload slots fetched from the assigned code
+bank.
+
+
+
+Before calling hidden code, ReadyBASIC saves flags, disables
+interrupts, forces the low CPU data-direction bits in $0000
+to outputs, saves $0001, maps RAM under BASIC ROM while
+keeping KERNAL visible, performs the copy or call, then restores
+$0001 and flags. This keeps BASIC ROM/RAM banking explicit
+and keeps KERNAL-visible calls safe where needed.
+Invariants
+
+ReadyBASIC is verified through normal ReadyOS run/profile flows, not
+by loading an individual app directly.
+BASIC_START is $2AC1.
+$2AC0 must remain zero before stored-program
+RUN.
+RESIDENT must stay below $2AC0.
+BRIDGE must stay below $C200, leaving
+$C200-$C5FF for relocated frames.
+$C600-$C7FF is resident ReadyOS shim expansion
+capacity, not app RAM.
+$C800-$C9FF is the stable ReadyOS shim ABI; together
+the shim owns 1 KB.
+Warm resume restores $A000 from the assigned-core-bank
+hidden-helper shadow before hidden helper calls.
+Warm resume must not cold-reset FRETOP,
+VARTAB, ARYTAB, or STREND.
+ReadyBASIC-owned vectors are restored before yielding to
+ReadyOS.
+Non-ReadyBASIC statements tail-call the original execute vector
+without mutating TXTPTR.
+Output variables are cleared before command execution.
+String heap writes happen only in visible resident code.
+Acceptance re-entry uses launcher menu navigation, not direct
+app-bank hotkeys.
+
+The assembler and linker config are a coupled ABI:
+readybasic.s is assembled with ca65 and linked only with
+cfg/ready_app_readybasic.cfg. Cold-load seed regions,
+under-ROM run slots, bridge/shared frames, and the exact
+$1000-$7FFF compact PRG span must move together.
+verify_readybasic_plugin.py enforces both sides of that
+dependency.
+Current Verification
+Evidence
+Static guardrails:
+make readybasic-plugin-static-check
+Current static layout:
+
+
+
+Segment
+Range
+Size
+
+
+
+
+ENTRY
+$1000-$11FF
+$0200 (512B)
+
+
+RESIDENT
+$1200-$2ABF
+$18C0 (6.2K, 6336 exact
+bytes)
+
+
+REGSEED
+$5000-$600F
+$1010 (4.0K, 4112 exact
+bytes)
+
+
+HIDDEN
+$A000-$A78A
+$078B (1931B)
+
+
+LOWPACK / slot 0 payload
+$A800-$AFDB
+$07DC (2012B)
+
+
+SLOTPACK1 / slot 1 payload
+$B000-$B540
+$0541 (1345B)
+
+
+SLOTPACK2 / GFXPRIM
+$B800-$BF37
+$0738 (1848B)
+
+
+OVL1PACK / GFXSPR
+$B800-$BA71
+$0272 (626B)
+
+
+OVL2PACK / INPUTEV
+$B800-$B86C
+$006D (109B)
+
+
+OVL3PACK / GFXPOLY
+$B800-$BF78
+$0779 (1913B)
+
+
+OVL4PACK / GFXDL
+$B800-$BF82
+$0783 (1923B)
+
+
+OVL5PACK / GFXTILE
+$B800-$BCD9
+$04DA (1242B)
+
+
+OVL6PACK / SIDCORE
+$B800-$BA0D
+$020E (526B)
+
+
+BRIDGE
+$C000-$C1FE
+$01FF (511B)
+
+
+
+Current measured guardrails:
+
+
+
+Measure
+Current value
+
+
+
+
+BASIC_START
+$2AC1
+
+
+Empty BASIC free bytes
+30013
+
+
+bin/readybasic.prg size
+28674
+
+
+RESIDENT
+$18C0 / 6336B
+
+
+LOWPACK
+$07DC / 2012B
+
+
+HIDDEN
+$078B / 1931B
+
+
+BRIDGE
+$01FF / 511B
+
+
+REGSEED
+$1010 / 4112B
+
+
+GFXPOLY overlay
+$0779 / 1913B
+
+
+GFXDL overlay
+$0783 / 1923B
+
+
+GFXTILE overlay
+$04DA / 1242B
+
+
+SIDCORE overlay
+$020E / 526B
+
+
+
+Recent VICE coverage includes:
+The broad external command/program/lifecycle/state wrappers have been
+refreshed for bare parenthesized syntax. The demo suite is intentionally
+viewer-paced; the regression probes stay shorter and more
+assertion-heavy.
+make readybasic-vice-suites is the complete 26-target
+regular acceptance aggregate. It includes the core
+lifecycle/program/state/hotkey/resume probes, the minimum-resume and
+screen/REU temporary-state probes, all current graphics phases and
+sprite-step examples, sound, ReadyOS loaded-app visibility, and the full
+visual verification. New official ReadyBASIC probes must be added to
+both READYBASIC_VICE_SCRIPTS and this aggregate so plan
+generation and execution cannot silently diverge.
+verify_readybasic_plugin.py enforces the exact 26-target
+aggregate and the plan-only script coverage for the formerly omitted
+resume/screen/graphics examples.
+
+
+
+
+
+
+
+Probe
+Coverage
+
+
+
+
+Full expression probe
+Direct bare command statements, command expressions, parenthesized
+EXEC PROC, FUNC with later assignment plus
+RET, numeric FUNC expression
+return/assignment, string FUNC expression return, and
+readable LIST.
+
+
+Plugin command probe
+Direct command statements, IF ... THEN
+assignment/expression coverage, UPPER/LOWER,
+old-name rejection, string/REM safety, leading-comma rejection,
+SCRCAP/SCRPUT, slot-128 lookup, descriptor
+filler-count guardrails, 128-handle edge, 48KB heap edge, screen heap
+exhaustion, wrong-handle-type rejection, screen-handle free,
+resume.
+
+
+Program probe
+Stored line start, colon chains, true/false IF ... THEN
+assignment/expression coverage, FOR/NEXT, strings, REM,
+DATA, arrays, hidden worker, handles, failure clearing.
+
+
+rbproc1 probe
+Stored positive PROC/FUNC: no-param PROC,
+%, $, explicit
+RET%/RET$, colon chain, normalized
+IF THEN :EXEC, nested depth 2, int/string/float command and
+FUNC returns, FADD expression and statement forms, nested
+ReadyBASIC actuals, string concatenation, and readable
+LIST.
+
+
+rbprocerr probe
+Stored negative PROC/FUNC: unknown
+routine, wrong count/type, statement EXEC to
+FUNC, PROC extra actual, ENDP without
+EXEC, return-stack overflow, malformed nested actuals, and
+return/context type errors.
+
+
+Full visual verification
+Human-watchable command, program, screen-handle, handle/heap edge,
+resume, and error coverage.
+
+
+Lifecycle probe
+Cold entry, EXIT, launcher re-entry, READY-mode
+redraw.
+
+
+State probe
+BASIC variable/string survival and command availability after
+resume.
+
+
+rbtest1 probe
+Sample program assembled at the relocated BASIC workspace.
+
+
+Large-vars probe
+BASIC workspace and variable behavior under heavier state.
+
+
+Cross-app resume stress
+ReadyBASIC survives repeated app switches.
+
+
+Second-entry/editor stress
+ReadyBASIC survives editor/launcher round trips and later
+re-entry.
+
+
+Demo automation suite
+Viewer-paced walkthrough covering MEMAVL, editor round
+trip, assembler commands, PROC/FUNC, parameter
+groups, expected errors, REU handles, and nested expression forms.
+
+
+
+Some harness wrappers can report a process-level partial
+status even when every step is ok and
+FailedStep is null; for ReadyBASIC these were
+treated as harness shutdown-status quirks, not command failures.
+Current Bare Commands And
+Expressions
+Parenthesized calls are the preferred syntax. Selected commands can
+return values as BASIC expressions while keeping the resident
+implementation tight.
+Supported command expressions:
+ZECHO1(P%)
+ZADD16(4,5,A%)
+PRINT ZADD16(5,10)
+A=ZADD16(8,9)
+T$=UPPER("ready")
+PRINT ZHIDDENRAM("A")
+Supported native routine forms:
+100 PROC SHOWI(P%)
+110 PRINT P%
+120 ENDP
-
- Current Float-Term Support
-
- Selected ReadyBASIC calls behave like real BASIC expression terms in the
- tested nested contexts. Plain C64 BASIC float values are supported on
- command and FUNC paths. Proven forms include
- ABS(FADD(1.2,2.3)-3),
- ADDI(1,ADDI(2,3)),
- FADD(1.5,FADD(2.25,3.25)), and
- LEFT$(GREET("READY")+"!",3).
-
-
- FADD(A,B) is resident-computed because the low overlay runs
- with BASIC ROM hidden and cannot safely call ROM float helpers. The
- descriptor still exists so registry lookup and syntax are exercised;
- the low code is only a one-byte RTS stub.
-
-
-
+200 FUNC GREET(N$)
+210 RET "HI "+N$
+220 ENDP
-
+10 EXEC SHOWI(7)
+20 T$=GREET("READY"):PRINT T$
+PROC/FUNC definitions and EXEC
+calls accept parentheses for non-empty argument lists. Zero-argument
+routines still use EXEC NAME; EXEC NAME() was
+cut to save resident bytes. FUNC uses
+RET expr, with optional RET% expr or
+RET$ expr type markers. EXEC runs
+PROC bodies only; FUNC returns the value as
+the expression result. FUNC calls scan the body, execute
+simple scalar assignments, and evaluate the RET expression;
+arbitrary earlier BASIC statements remain outside V1.
+Numeric actuals for command and FUNC calls can be
+ordinary numeric expressions in the flat forms tested by
+rbproc1, such as ADDI(1,2+4). ReadyBASIC also
+accepts a single wrapper pair around numeric actual expressions,
+including ADDI(1,(2+4)), ZADD16(1,(2+4)), and
+ADDI((1+2),(3+4)). String actuals remain string variables
+or quoted literals. Command and FUNC returns can be
+assigned or printed directly; command numeric returns work in
+ABS(ZADD16(1,6)-10), and FUNC returns now work
+in the tested ROM consumer forms ABS(ADDI(1,6)-10) and
+LEFT$(GREET("READY"),2). Fully recursive ReadyBASIC terms
+inside other ReadyBASIC actual lists remain future work.
+Current Float-Term Support
+Selected ReadyBASIC calls behave like real BASIC expression terms in
+the tested nested contexts. Plain C64 BASIC float values are supported
+on command and FUNC paths.
+Supported examples:
+A=ABS(FADD(1.2,2.3)-3)
+A%=ABS(ADDI(1,6)-10)
+A$=LEFT$(GREET("READY")+"!",3)
+PRINT ADDI(1,ADDI(2,3))
+PRINT FADD(1.5,FADD(2.25,3.25))
+PRINT LEFT$(UPPER(GREET("ready")),2)
+FUNC SCALE(X)
+RET X*1.5
+ENDP
+FADD(A,B) is the float demo command. It is
+resident-computed because the low overlay runs with BASIC ROM hidden and
+cannot safely call ROM float helpers. The descriptor still exists so
+registry lookup and syntax are exercised; the low code is only a
+one-byte RTS stub. FADD(A,B,Q) is the
+statement form and requires a plain numeric output variable.
+FADD(A,B,A%) is rejected.
+Current verification includes rbproc1 lines for
+FADD, nested FADD, float FUNC
+input/return, nested ADDI, ABS(FADD(...)-3),
+statement-form float output, string concatenation with a
+FUNC return, and LEFT$(UPPER(GREET(...)),2).
+rbprocerr adds negative sections for malformed nested
+actuals, float output to %, string return in numeric
+context, and numeric return in string context.
diff --git a/src/apps/readybasic/readybasic_lifecycle_visual_guide.html b/src/apps/readybasic/readybasic_lifecycle_visual_guide.html
index e0fa57c..797179c 100644
--- a/src/apps/readybasic/readybasic_lifecycle_visual_guide.html
+++ b/src/apps/readybasic/readybasic_lifecycle_visual_guide.html
@@ -671,6 +671,21 @@
+
+
+ Current ReadyOS contract (2026-08-02):
+ Physical Skip is the ReadyOS bank and Skip+1 is the first dynamic bank.
+ The launcher snapshot is ReadyOS $0000-$B5FF; schema v5 is $B600-$FFFF,
+ with token map $B740 and status $B840. C64 app RAM is
+ $1000-$C5FF ($B600), and the resident 1 KB shim owns
+ $C600-$C9FF with its public ABI at $C800.
+ The diagrams below apply this contract to the current ReadyBASIC lifecycle,
+ including its custom assembler/linker shape and assigned REU resource banks.
+
+
+
+CURRENT DOCUMENT Current ReadyBASIC lifecycle and REU architecture counterpart generated from READYBASIC_LIFECYCLE_AND_REU_ARCHITECTURE.md.
+
ReadyBASIC deep architecture guide
@@ -758,32 +773,34 @@
REU banks
Command Registry Slots: Real Commands, Filler, Slot-128 Proof
-
-
Slots 1-14
-
14 real commands, ending with SCRCAP. $01C0 / 448B.
+
+ Slots 1-93
+ 93 normal descriptors before filler; built-in graphics and sound commands live here. $0BA0 / 2976B.
-
-
Slots 15-127
-
113 zero-filled filler slots. This is future command descriptor room, kept empty to prove full-table scanning.
+
+ Slots 94-127
+ 34 zero-filled filler slots available for future command descriptors.
128
- SCRPUT
+ SCRPUT proof descriptor; 94 real descriptors total.
Descriptor range REU offset Role Slots Size
- Slots 1-14 $1000-$11BFCurrent real commands: ZECHO1 through SCRCAP. 14 $01C0 / 448B
- Slots 15-127 $11C0-$1FDFZero-filled filler descriptors; available for future command descriptors. 113 $0E20 / 3.5K / 3616 exact bytes
+ Slots 1-93 $1000-$1B9FCurrent built-in descriptors from ZECHO1 through SOUND. 93 $0BA0 / 2976B
+ Slots 94-127 $1BA0-$1FDFZero-filled filler descriptors; available for future command descriptors. 34 $0440 / 1088B
Slot 128 $1FE0-$1FFFSCRPUT, intentionally placed at the end to prove slot-128 lookup.1 $0020 / 32B
- `SCRCAP` sits directly after the existing front commands in slot 14.
- `SCRPUT` is separated from it by 113 filler descriptors, proving that
+ `SCRPUT` is separated from the current built-in descriptor run by 11
+ filler descriptors, proving that
ReadyBASIC pages through the whole 128-slot table instead of relying
- on a short resident index.
+ on a short resident index. Static verification now counts the real
+ descriptor macros so this filler span cannot drift as commands are
+ added or removed.
@@ -830,7 +847,7 @@
C64 RAM Ownership
$C200-$C5FF
SHARED FRAMES Call/result frames, descriptor/name/page buffers; hidden shadow at $C280. $0400 1.0K
$C600-$C7FF
-
READYOS REU METADATA Only bank ownership tags are touched. $0200 0.5K
+
SHIM EXPANSION RESERVE Resident ReadyOS capacity; not ReadyBASIC or app RAM. $0200 0.5K
$C800-$C9FF
SHIM ABI ReadyOS jump table/data. Not ReadyBASIC RAM. $0200 0.5K
@@ -1128,7 +1145,7 @@
ZRANGENUMARRAY(START,COUNT,A%(0))
Stages consecutive integer values in the result frame; resident code writes them into the output array.
-
BUFNEW(LEN,H%) / BUFNEW(LEN)
+
BUFMAKE(LEN,H%) / BUFMAKE(LEN)
slot 0 $A800 REU handle copy $06C7 / 1.7K
Allocates contiguous 256-byte buffer pages inside the assigned core bank and returns a one-based handle.
@@ -1138,7 +1155,7 @@ BUFFILL(H%,BYTE)
Fills `$C500` with a byte and stashes it page by page into a type-1 buffer handle.
-
BUFFREE(H%)
+
BUFDROP(H%)
slot 0 $A800 metadata copy $06C7 / 1.7K
Clears the REU-backed page bitmap and handle descriptor for any valid handle type.
@@ -1153,7 +1170,7 @@ ZFAIL(CODE,OUT%)
Proves outputs are cleared before execution and stale result frames are not committed after failure.
-
FREEMEM()
+
MEMAVL()
slot 0 $A800 free-byte probe small slice
Prints current live BASIC free bytes and refreshes the header.
@@ -1178,8 +1195,8 @@ Hard Invariants
$2AC0 remains zero before stored-program RUN.
RESIDENT stays below $2AC0.
BRIDGE stays below $C200, leaving $C200-$C5FF for shared frames.
- $C600-$C7FF is shared ReadyOS REU metadata.
- $C800-$C9FF is shim ABI, not app scratch.
+ $C600-$C7FF is resident ReadyOS shim expansion capacity, not app scratch.
+ $C800-$C9FF is the stable shim ABI; the full resident shim is 1 KB.
Warm resume restores $A000 from $C280 before hidden calls.
Warm restore preserves live FRETOP, variables, arrays, and string heap.
ReadyBASIC restores owned page-3 vectors before yielding to ReadyOS.
diff --git a/src/apps/readybasic/readybasic_making_command_guide.html b/src/apps/readybasic/readybasic_making_command_guide.html
index e6a0e37..d2f1f7e 100644
--- a/src/apps/readybasic/readybasic_making_command_guide.html
+++ b/src/apps/readybasic/readybasic_making_command_guide.html
@@ -146,10 +146,13 @@
+
+CURRENT DOCUMENT Current ReadyBASIC command-authoring counterpart generated from READYBASIC_MAKING_COMMAND_GUIDE.md.
+
ReadyBASIC Making Command Guide
A teaching guide for how current bare COMMAND(...) examples are wired into descriptors, parser signatures, under-ROM module payloads, overlays, and REU handles.
- 128 descriptor slots SCRCAP slot 14 SCRPUT slot 128 3 x 2KB submodule slots
+ 128 descriptor slots 94 real descriptors 34 filler descriptors SCRPUT slot 128 3 x 2KB submodule slots
@@ -174,7 +177,7 @@ What You Are Building
Built-In And Module Command Growth
-
ReadyBASIC's built-in command set is intended to include the core commands and the 100+ additional file, graphics, sound, REU, and utility commands that are similar in spirit to other BASIC extensions. The current REU code bank still leaves about 62.4K of addressable command-code space; today's C64 CMDPACK seed window has about 3.6K unused before it needs a larger or additional cold-load seed range.
+
ReadyBASIC's built-in command set is intended to include the core commands and the 100+ additional file, graphics, sound, REU, and utility commands that are similar in spirit to other BASIC extensions. The current built-in code-bank reservations leave the contiguous tail $8000-$FFFF free for future built-in payloads; today's first C64 CMDPACK seed window has about $00AB / 171 bytes unused, while replacement overlays are seeded from CMDPACK2.
Beyond that built-in set, ReadyBASIC will also support dynamically loaded command modules that can use additional REU banks, so other authors can add hundreds more commands without forcing everything into the core command bank.
@@ -208,10 +211,135 @@
When To Use PROC/FUNC Instead
+
+ SID Sound Command Tutorial
+ Sound Phase 1 commands are descriptor-backed module 4 commands in the SIDCORE slot-2 replacement overlay. The overlay is prestashed at code-bank offset $7800 and runs at $B800-$BA0D.
+
+
+ SIDRST() / SIDOFF()Clear SID registers $D400-$D418.
+ VOL(V)Set master volume 0..15.
+ FRQ(V,F) / PITCH(V,N,O)Set raw SID frequency or PAL note table frequency.
+ PULSE, ADSR, WAVE, GATEExplicit voice setup helpers.
+ VOICE(V,F,W,AD,SR)Fast packed SID setup. AD and SR are the hardware envelope bytes.
+ FILTER(CUTOFF,RES,ROUTE,MODE)Filter cutoff, resonance, routing, and mode bits.
+ SOUND(V,F,D,W)Blocking tone helper for demos and simple effects.
+
+
+10 SIDRST():VOL(15):PULSE(1,2048)
+20 VOICE(1,4455,65,9,195)
+30 ZPAUSE(80):WAVE(1,64)
+
+ The packed VOICE form was chosen deliberately. A seven-argument parser shape was tested but grew resident code; the implemented form reuses an existing numeric signature and keeps BASIC free bytes unchanged.
+
+
+
+ Graphics Command Tutorial
+ The built-in graphics commands are descriptor-backed command families. They use ordinary COMMAND(...) syntax; resident signatures fill call-frame fields, and assembler workers do the Bank D, VIC, color RAM, and REU work.
+
+
+ $CA00-$CBFFEight hardware sprite definitions.
+ $CC00-$CFFFBank D screen RAM and sprite pointers at $CFF8.
+ $D800-$DBE7Color RAM.
+ $E000-$FFFFBitmap/charset RAM, written with ROM hidden.
+
+
+10 GFXMODE("HIRES") : REM 320X200 ONE-BIT BITMAP
+20 GFXMODE("MBITMAP") : REM 160X200 MULTICOLOR BITMAP
+30 GFXMODE("TILE") : REM BANK D TEXT/TILE SCREEN
+40 GFXMODE("MTILE") : REM BANK D MULTICOLOR TEXT/TILE
+50 GFXTEXT() : REM RETURN TO NORMAL TEXT
+
+
+
Surface Handles And Blit
+
10 GFXMODE("HIRES"):GFXCLEAR(0)
+20 LINE(20,20,300,170,1):RECT(40,50,140,130,1)
+30 H%=GFXSURF("HIRES")
+40 GFXTGT(H%):GFXSYNC():GFXTGT(0)
+50 GFXCLEAR(0):GFXBLIT(H%)
+
GFXTGT selects the visible target or a typed REU graphics-surface handle. GFXSYNC snapshots the visible Bank D layout into a typed REU surface, and GFXBLIT restores it. Immediate primitives still draw directly to the visible Bank D target for speed.
+
+
+
Hires Primitives
+
10 GFXMODE("HIRES"):GFXCLEAR(0)
+20 PLOT(20,20,1)
+30 LINE(20,30,300,160,1)
+40 RECT(40,50,130,120,1)
+50 FBOX(180,60,240,130,1)
+60 CIRCLE(82,82,38,1)
+70 FCIRCLE(210,92,26,1)
+80 PNT(20,20,P%)
+
LINE is compact rather than full Bresenham. CIRCLE uses a compact midpoint outline worker; FCIRCLE currently fills the bounding rectangle.
+
+
+
Multicolor Bitmap
+
10 GFXMODE("MBITMAP"):GFXCLEAR(0)
+20 LINE(4,18,155,18,17)
+30 LINE(4,30,155,70,34)
+40 RECT(8,82,72,144,20)
+50 FBOX(86,82,148,144,37)
+60 CIRCLE(46,112,28,51)
+70 FCIRCLE(118,112,22,58)
+80 PNT(46,112,P%)
+
MBITMAP uses X=0..159, Y=0..199. The color argument encodes VIC-II multicolor slots: 0 clears, 1..15 draws pair 3 and writes color RAM, 16..31 draws pair 1, 32..47 draws pair 2, and 48..63 explicitly draws pair 3. PNT returns pair code 0..3, not the resolved VIC color.
+
+
+
Tile And Text Cells
+
10 GFXTEXT():PRINT CHR$(147)
+20 GFXMODE("TILE"):GFXCLEAR(0)
+30 PLOT(4,4,5):PLOT(5,4,6):PLOT(6,4,7)
+40 LINE(1,1,38,20,3)
+50 RECT(3,5,20,16,10):FBOX(24,8,34,18,12)
+60 GFXTEXT():PRINT "TILE DEMO"
+
TILE and CHARAT write one cell. In tile modes they target Bank D screen RAM; after GFXTEXT() they target normal text screen RAM for labels and demos. GFXCLEAR seeds simple solid glyphs for immediate tile primitive demos.
+
+
+
Sprites
+
10 GFXMODE("HIRES"):GFXCLEAR(0)
+20 SPRSET(0,1,7,0)
+30 FOR R=0 TO 20:SPRROW(0,R,60,126,60):NEXT R
+40 SPRMOVE(0,120,100)
+50 SPRSIZE(0,1,1)
+60 SPRMUL(0,1):SPRMCO(2,5):SPRCOL(0,10)
+
SPRROW writes one 24-bit row into Bank D sprite memory. SPRSIZE, SPRMUL, SPRMCO, and SPRCOL are tokenizer-safe demo names for size, multicolor, shared multicolor registers, and primary color.
+
+
+
Polygons
+
10 DIM P%(7)
+20 P%(0)=40:P%(1)=20:P%(2)=120:P%(3)=42
+30 P%(4)=98:P%(5)=130:P%(6)=18:P%(7)=110
+40 POLY(P%(0),4,1):FPOLY(P%(0),4,1)
+50 PBMAKE(4,H%)
+60 PBUFSET(H%,0,40,20):PBUFSET(H%,1,120,42)
+70 POLYH(H%,4,1):PBDROP(H%)
+
POLYH and FPOLYH are explicit REU point-buffer handle commands. Filled polygons use a conservative convex fan fill; concave scanline fill remains future work.
+
+
+
Retained Lists And Tiles
+
10 GFXMODE("HIRES"):GFXCLEAR(0)
+20 DLMAKE(12,H%)
+30 DLPLOT(H%,20,20,17)
+40 DLLINE(H%,4,30,155,70)
+50 DLRECT(H%,8,82,72,144)
+60 DLFBOX(H%,86,82,148,144)
+70 DLDRAW(H%)
+
DLMAKE creates a one-page REU display-list handle. DLPLOT preserves its color; line and rectangle records currently replay with color 1 to keep the overlay small. Tile resources use CHRMAKE, CHRROW, CHRUSE, TSMAKE, TSSET, TMMAKE, TMSET, and TMDRAW. Phase 5 screenshots prove visible Bank D tile and multicolor-tile rendering.
+
+
+
Multicolor Cells
+
10 GFXMODE("MBITMAP"):GFXCLEAR(0):MCBG(0)
+20 MCELL(2,2,6,10,2)
+30 FBOX(8,16,31,47,17)
+
MCELL writes the three per-cell multicolor bitmap attributes: screen high nibble, screen low nibble, and color RAM. MCBG sets the shared background color.
+
+
+ Multicolor bitmap colors are per 8x8 cell. A later slot-1, slot-2, or slot-3 write in the same cell can recolor earlier pixels that used that same slot.
+
+
Naming Rules
-
ReadyBASIC names are visible BASIC text, not private tokens. Avoid substrings that C64 BASIC can tokenize inside the command name; array demos use NUM instead of INT.
+
ReadyBASIC names are visible BASIC text, not private tokens. New command names must avoid substrings that C64 BASIC can tokenize inside the command name, including CLR, FRE, NOT, INT, FN, LEN, OR, and TO. Host .bas demos should spell ReadyBASIC commands lowercase so petcat writes ordinary PETSCII letters.
+
This alpha build registers no duplicate public command spellings. ReadyBASIC can implement an alias by adding another 32-byte descriptor that points at the same command id, signature, payload, and entrypoint, but that spends a registry slot, expands QA/documentation surface, and can preserve tokenizer hazards. Current demos and tests must use the canonical names only.
Z*Example, demo, and proof commands.
@@ -220,7 +348,7 @@ Naming Rules
XU*Alpha/beta Ultimate-specific commands whose behavior or parameter shape is not settled yet.
-
Current public names include ZECHO1, ZADD16, UPPER, LOWER, ZHIDDENRAM, ZSUMNUMARRAY, ZRANGENUMARRAY, BUFNEW, BUFFILL, BUFFREE, SCRCAP, SCRPUT, ZTEMPSCRATCH, ZPAUSE, ZFAIL, FREEMEM, ERRCODE, ERRLINE, ZSLOT0, ZSLOT1, ZSLOT2, ZSPAN, ZOVL1, ZOVL2, ZCPYRST, ZCOPY, and ZMODLD. Disk-module samples add ZDM1, ZDM2S, ZDOV1, ZDOV2, and ZSAA-ZUEB after loading RBM.SAMPLE1, RBM.SAMPLE2, or RBM.SAMPLE3.
+
Current public names include ZECHO1, ZADD16, UPPER, LOWER, ZHIDDENRAM, ZSUMNUMARRAY, ZRANGENUMARRAY, BUFMAKE, BUFFILL, BUFDROP, SCRCAP, SCRPUT, ZTEMPSCRATCH, ZPAUSE, ZFAIL, MEMAVL, ERRCODE, ERRLINE, ZSLOT0, ZSLOT1, ZSLOT2, ZSPAN, ZOVL1, ZOVL2, ZCPYRST, ZCOPY, and ZMODLD. Disk-module samples add ZDM1, ZDM2S, ZDOV1, ZDOV2, and ZSAA-ZUEB after loading RBM.SAMPLE1, RBM.SAMPLE2, or RBM.SAMPLE3.
@@ -635,24 +763,24 @@ Nested Expressions
REU Handle Commands
BASIC sees a small integer handle. Canonical descriptors live in assigned core-bank offsets $0800-$09FF, the bitmap at $0C00, and data in the 48KB typed heap at $4000-$FFFF.
-10 BUFNEW(64,H%)
+10 BUFMAKE(64,H%)
20 BUFFILL(H%,170)
-30 BUFFREE(H%)
+30 BUFDROP(H%)
-40 H%=BUFNEW(64)
-50 BUFFREE(H%)
+40 H%=BUFMAKE(64)
+50 BUFDROP(H%)
10 H%=SCRCAP()
20 PRINT CHR$(147);"CHANGED"
30 SCRPUT(H%)
-40 BUFFREE(H%)
+40 BUFDROP(H%)
Command Pattern
- BUFNEWAllocate pages, store type-1 descriptor, return one-based handle.
+ BUFMAKEAllocate pages, store type-1 descriptor, return one-based handle.
BUFFILLValidate type-1 buffer handle, fill pages through $C500.
- BUFFREEFree any valid handle type and clear metadata.
+ BUFDROPFree any valid handle type and clear metadata.
SCRCAPAllocate type-2 screen text+color handle and stash text/color RAM.
SCRPUTValidate type-2 handle and restore text/color RAM from slot-128 lookup.
@@ -673,9 +801,9 @@ REU Handle Commands
lda #RB_VAL_NONE
sta RF_TAG
rts
-CMD_LOW_ALL CMD_BUFNEW, SIG_BUFNEW, cmd_bufnew_low, "BUFNEW"
+CMD_LOW_ALL CMD_BUFNEW, SIG_BUFNEW, cmd_bufnew_low, "BUFMAKE"
CMD_LOW_ALL CMD_BUFFILL, SIG_BUFFILL, cmd_buffill_low, "BUFFILL"
-CMD_LOW_ALL CMD_BUFFREE, SIG_BUFFREE, cmd_buffree_low, "BUFFREE"
+CMD_LOW_ALL CMD_BUFFREE, SIG_BUFFREE, cmd_buffree_low, "BUFDROP"
CMD_LOW_ALL CMD_SCRCAP, SIG_SCRCAP, cmd_scrcap_low, "SCRCAP"
CMD_LOW_ALL CMD_SCRPUT, SIG_SCRPUT, cmd_scrput_low, "SCRPUT"
@@ -691,7 +819,7 @@ REU Handle Commands
CMD_LOW_ALL ...These commands call shared helpers, so the descriptor copies the whole slot-0 payload instead of just the wrapper bytes.
- The handle lesson is to keep BASIC-visible values small, keep canonical resource metadata in REU, and validate handle type at command boundaries. BUFFILL accepts only type-1 buffer handles; SCRPUT accepts only type-2 screen text+color handles; BUFFREE frees any valid type.
+ The handle lesson is to keep BASIC-visible values small, keep canonical resource metadata in REU, and validate handle type at command boundaries. BUFFILL accepts only type-1 buffer handles; SCRPUT accepts only type-2 screen text+color handles; BUFDROP frees any valid type.
@@ -700,7 +828,7 @@ Other Current Command Invocations
Memory And Temporary Pages
-10 FREEMEM()
+10 MEMAVL()
20 P%=ZTEMPSCRATCH(512)
30 PRINT "PAGES";P%
@@ -745,8 +873,9 @@ Naming Lessons And Add-Command Checklist
Add a low or hidden worker that writes the result frame only on success.
Add a descriptor entry; use CMD_LOW_ALL only when shared helpers require the full slot-0 payload.
Keep resident growth minimal; prefer REU metadata and existing scratch pages.
- Add direct, stored-program, error-path, and resume/slot coverage.
- Update Markdown and HTML docs with measured map values after tests pass.
+ Update the descriptor filler count so real descriptors plus filler still fit exactly in RB_CMD_DESC_COUNT.
+ Add direct, stored-program, error-path, and resume/slot coverage.
+ Update Markdown and HTML docs with measured map values after tests pass.
@@ -755,8 +884,9 @@ Appendix: Descriptor And Registry Labels
REGSEEDCold-load descriptor image. It is copied to REU and then reclaimed so BASIC free bytes do not shrink.
- RB_CMD_DESC_COUNTRegistry capacity, currently 128 command descriptors.
- core+$1000-$1FFFREU location of the descriptor table. Lookup pages through this range.
+ RB_CMD_DESC_COUNTRegistry capacity, currently 128 command descriptors.
+ core+$1000-$1FFFREU location of the descriptor table. Lookup pages through this range.
+ Descriptor filler count The .res (RB_CMD_DESC_COUNT - N) * RB_CMD_DESC_SIZE expression must use the current real descriptor count; otherwise late commands can fall outside lookup range and appear as native BASIC syntax errors.
RB_PAGEBUFRAM page buffer used to fetch one 256-byte descriptor page, eight descriptors at a time.
RB_DESC_BUFResident copy of the single matched descriptor.
__LOWPACK_LOAD__ / __LOWPACK_RUN__Historical symbol names for the current built-in slot-0 payload seed and runtime image. Runtime slot 0 is $A800-$AFFF.
@@ -815,7 +945,7 @@ Statement Output
30 UPPER("ready",T$)
40 PRINT T$
-50 BUFNEW(64,H%)
+50 BUFMAKE(64,H%)
60 PRINT "HANDLE";H%
@@ -828,7 +958,7 @@ Expression Return
30 PRINT ZADD16(5,10)
40 T$=UPPER("ready")
-50 H%=BUFNEW(64)
+50 H%=BUFMAKE(64)
60 PRINT "HANDLE";H%
@@ -858,7 +988,7 @@ Actual Parameters
-
Commands with array outputs or no scalar result remain statement-only. For example, ZRANGENUMARRAY(7,4,R%(0)) writes several array elements after success, so it is not an expression return. Scalar handle commands such as BUFNEW(n) and SCRCAP() are expression-enabled because the returned handle is a simple integer.
+
Commands with array outputs or no scalar result remain statement-only. For example, ZRANGENUMARRAY(7,4,R%(0)) writes several array elements after success, so it is not an expression return. Scalar handle commands such as BUFMAKE(n) and SCRCAP() are expression-enabled because the returned handle is a simple integer.
True Expression Examples
diff --git a/src/apps/readybasic/readybasiclessonslearnt.md b/src/apps/readybasic/readybasiclessonslearnt.md
index 6237eac..8999c24 100644
--- a/src/apps/readybasic/readybasiclessonslearnt.md
+++ b/src/apps/readybasic/readybasiclessonslearnt.md
@@ -1,5 +1,12 @@
# ReadyBASIC Lessons Learnt
+> Current contract note (schema v5): ReadyOS snapshots `$1000-$C5FF`
+> (`$B600` bytes) and keeps mappings/status/registry state only in the combined
+> ReadyOS bank at physical `Skip`. The resident 1 KB shim owns `$C600-$C9FF`. Any
+> dated observations below that call `$C600-$C7FF` shared ReadyOS metadata or
+> describe a `$B800` snapshot are retained as historical debugging evidence and
+> are superseded by this contract.
+
This is the running lab notebook for ReadyBASIC. Keep entries small, falsifiable,
and updated when a hypothesis turns out to be wrong. The goal is to preserve the
actual C64/ReadyOS evidence trail rather than a pile of confident guesses.
@@ -8,7 +15,7 @@ actual C64/ReadyOS evidence trail rather than a pile of confident guesses.
- ReadyBASIC is a ReadyOS-native PRG host for BASIC, not a normal C64 BASIC PRG.
- The app PRG loads at `$1000` and must obey the ReadyOS app/shim window:
- `$1000-$C5FF` is app-owned, `$C600-$C9FF` is reserved metadata/shim space.
+ `$1000-$C5FF` is app-owned and `$C600-$C9FF` is resident shim space.
- BASIC programs are data inside the host. The scoped BASIC workspace is now
`$2AC1-$9FFF`, with `30013` formula empty free bytes (29.3K); ReadyBASIC
extension lines are left as readable text rather than crunched into private
@@ -18,16 +25,16 @@ actual C64/ReadyOS evidence trail rather than a pile of confident guesses.
mode, and line-chain guards live in bridge metadata.
- Hidden services live under BASIC ROM RAM at `$A000-$BFFF` and visible
trampolines/state/mailbox live at `$C000-$C5FF`.
-- A refreshed visible shadow copy of the hidden helper image lives at `$C280-$C5F6`,
- inside the ReadyOS app snapshot window. Warm
- entry restores `$A000` from that shadow before using hidden helpers.
-- The plugin spine keeps visible resident code at `$1200-$2AB9`, command
+- A refreshed REU shadow copy of the hidden helper image lives in the
+ launcher-assigned ReadyBASIC core bank at offset `$3000`. Warm entry restores
+ `$A000` from that shadow before using hidden helpers.
+- The plugin spine keeps visible resident code at `$1200-$2AB8`, command
overlays under BASIC ROM, shared frames at `$C200-$C5FF`, and
launcher-assigned ReadyBASIC core/code REU banks. Older entries below may
mention `$44/$45`; treat those as historical fixed-bank examples, not the
current contract.
- Module/submodule branch update: the current visible resident range is
- `$1200-$2ABB`, the bridge is `$C000-$C1F6`, and command payloads now use a
+ `$1200-$2AB8`, the bridge is `$C000-$C1FD`, and command payloads now use a
common under-ROM helper area `$A000-$A7FF` plus three 2KB submodule slots:
`$A800-$AFFF`, `$B000-$B7FF`, and `$B800-$BFFF`.
- Current command descriptors are module-aware 32-byte records: command id,
@@ -35,8 +42,8 @@ actual C64/ReadyOS evidence trail rather than a pile of confident guesses.
overlay id, slot mask, generation/check byte, runtime destination, entry
offset, signature id, and name.
- Built-in payload bytes are prestashed into the assigned code bank: module 1 slot 0 at
- `$0000-$06C6`, module 2 slot 1 at `$06C7-$0807`, slot 2/span/overlay proofs
- through `$085B`, and disk sample payloads currently starting at `$3000`.
+ `$0000-$06CD`, module 2 slot 1 at `$06CE-$0908`, slot 2/span/overlay proofs
+ through `$095C`, and disk sample payloads currently starting at `$3000`.
- The current registry has 128 descriptor slots in REU bank `$44` at
`$1000-$1FFF`. Lookup fetches one 256-byte page at a time into `$C500`, scans
eight descriptors locally, and copies a match into `$C480`.
@@ -50,15 +57,17 @@ actual C64/ReadyOS evidence trail rather than a pile of confident guesses.
## Live Discipline Notes
-### Distinguish App RAM From Shared ReadyOS Metadata
+### Distinguish Available App RAM From The Stable ReadyBASIC Image Shape
-ReadyOS app snapshots own `$1000-$C5FF`. `$C600-$C7FF` is not app-private RAM,
-but it is also not unused; ReadyOS uses it for shared REU metadata. The launcher
-marks ReadyBASIC's assigned `rbcore` banks as `REU_RB_CORE` and `REU_RB_CODE`,
-and ReadyBASIC may refresh those exact ownership tags after resolving them. It
-must never treat that page as a general ReadyBasic buffer. If a future probe
-sees boot or app-load instability, check whether ReadyBasic is writing more
-than those ownership tags before blaming the launcher or VICE.
+ReadyOS app snapshots own `$1000-$C5FF`. The `$C600-$C9FF` resident shim region
+is outside ReadyBASIC, so its custom assembler/linker shape and runtime
+assumptions must remain below that boundary. The launcher
+publishes ReadyBASIC's assigned `rbcore` banks as `REU_RB_CORE` and
+`REU_RB_CODE` in the ReadyOS bank at physical `Skip`; ReadyBASIC may refresh
+those exact ReadyOS-bank ownership tags after resolving them. If a future probe
+sees boot or app-load instability, check for an unintended custom-image layout
+change or writes outside the documented bridge/shared-frame ranges before
+blaming the launcher or VICE.
### Interrupted VICE Runs Still Need A Ledger Entry
@@ -72,6 +81,29 @@ UI, not which address or routine was stuck.
## Proven
+### Hidden Helper Calls Need Their Own CPU-Port Save
+
+Proven on 2026-06-09 while debugging the ReadyBASIC hotkey branch. The common
+hidden-call trampoline may run while a LOWPACK command is already executing under
+BASIC ROM. Sharing the same saved CPU-port byte used by the under-ROM payload
+call path can restore the wrong `$01` value after the nested helper returns,
+leaving BASIC ROM/helper visibility confused and causing later parser failures.
+
+Current rule: shared helper trampolines such as `call_hidden_common` must use a
+distinct CPU-port save byte from LOWPACK/under-ROM payload call machinery.
+
+### ReadyBASIC Hotkeys Must Prove The BASIC-Editor Path
+
+Proven on 2026-06-09 after `input.sequence [2]` appeared to test Ctrl+B but only
+fed a byte to the BASIC editor path, where it could render as text and bypass the
+actual key decode logic. ReadyBASIC runs inside the ROM editor, so hotkey tests
+must assert the installed vectors and exercise the ReadyBASIC keylog/IRQ decode
+or a real matrix path, then prove the internal dispatcher reaches the normal
+ReadyOS suspend/switch flow without typed `EXIT`.
+
+Current rule: do not accept a ReadyBASIC hotkey probe that only seeds
+`rb_hotkey_pending`, injects `EXIT`, or feeds KERNAL keyboard-buffer bytes.
+
### Lean Plugin Spine Needs Seed-Only Tables Outside Resident RAM
Proven on 2026-05-11 while moving ReadyBASIC from demo `RB` commands to the
@@ -166,9 +198,10 @@ when an app returns to the launcher. ReadyBASIC's hidden helper code under
`$A000-$BFFF` is not part of that transfer, so warm entry cannot assume it is
still valid after the launcher or another app has run.
-Current rule: keep the hidden helper shadow at `$C280-$C5B6`, refresh it during
-manual prompt `EXIT`, and restore `$A000` from that shadow on every warm entry.
-BASIC top is `$A000`; the old `$9A00-$9FFF` shadow reservation has been reclaimed.
+Current rule: keep the hidden helper shadow in the assigned ReadyBASIC core
+bank at offset `$3000`, refresh it during cold seed and manual prompt `EXIT`,
+and restore `$A000` from that REU shadow on every warm entry. BASIC top is
+`$A000`; the old `$9A00-$9FFF` shadow reservation has been reclaimed.
### `$0000` DDR Is Part Of The Banking Contract
@@ -261,7 +294,7 @@ or the conditions that ROM helpers such as `CHRGOT`, `FRMNUM`, `GETADR`, and
The concrete regression was that pointer/register preservation was relaxed while
renaming and refactoring lookup. Direct commands still reached parts of the
-dispatcher, but parser-sensitive commands such as `BUFNEW` and output-variable
+dispatcher, but parser-sensitive commands such as `BUFMAKE` and output-variable
forms could fail because the follow-on BASIC ROM helper contract was no longer
exactly intact. The fix was to restore the parser contract, including ensuring
the whitespace-skip/`CHRGOT` path leaves `Y` in the expected state before
@@ -345,11 +378,10 @@ reserved words that appear inside the typed command name. Names such as
`LOAD` tokens after crunching. The implemented names became `SCRCAP` and
`SCRPUT` to avoid those embedded tokens.
-The same class of problem showed up in shorter examples too: `BUFNEW` can carry
-an `FN` token, `FREEMEM` can carry a `FRE` token, and historical `PING` could
-carry a `PI` token. ReadyBASIC currently has parser accommodations for shipped
-names that still need them, but future command names should not rely on adding
-more special cases.
+The same class of problem showed up in shorter examples too: early buffer and
+free-memory spellings could carry BASIC `FN`/`FRE` tokens, and a historical echo
+probe could carry a `PI` token. ReadyBASIC now favors names that avoid those
+token substrings instead of carrying compatibility aliases.
The 2026-05-22 command rename pass made that rule practical: proof/demo
commands now live under a `Z...` namespace, `STRUP` became useful command
@@ -405,12 +437,67 @@ draw failure, and `../agenticdevharness/logs/vice_auto_20260509_174140/`
demonstrated visible `RB 2`, visible `RB 3`, mailbox `$C004/$C005 == $000F`,
and `EXIT` returning to the launcher.
-### EXIT Is The Current Supported Launcher Return
-
-`CTRL+B`/F-key prompt interception is deferred until the editor-safe keyboard
-hook is proven. `EXIT`/`exit` is now the explicit ReadyBASIC wedge command for
-returning to the launcher: it restores ReadyBASIC-owned vectors, clears pending
-keyboard input, marks the app ready, and jumps to the ReadyOS shim return entry.
+### Prompt Hotkeys Need A CHRIN-Safe Abort Path
+
+ReadyBASIC now supports prompt-level `CTRL+B`, `F2`, and `F4` with KEYLOG at
+`$028F/$0290` plus a CHRIN wrapper at `$0324/$0325`. KEYLOG is allowed to act
+only while the CHRIN wrapper has entered the ROM editor, the default input
+device is the keyboard, and BASIC is at a direct prompt. It records the pending
+ReadyOS action, consumes the decoded key state, and queues only Return.
+
+The CHRIN wrapper calls the original CHRIN first and preserves ordinary return
+semantics, including the status flags. If a pending prompt hotkey exists after
+the editor unwinds, it discards the returned character and dispatches the
+ReadyOS action before BASIC can store or execute the partial line. This
+supersedes the earlier CINV-plus-`REM` defer path, which visibly inserted text,
+could combine with partial prompt lines, and disturbed ordinary typing in VICE
+fast/warp mode.
+
+Ordinary keys stay inside the ROM editor path. ReadyBASIC does not install a
+CINV IRQ scanner for prompt hotkeys; cursor blink, logical-line editing, key
+repeat, and space handling remain KERNAL/BASIC-owned. The older field finding
+still stands: reading `SHFLAG`/`SFDX` before KERNAL's scan samples stale state
+and is not a valid prompt-hotkey detector.
+
+VICE Binary `input.sequence` writes through the KERNAL keyboard buffer rather
+than driving physical keyboard matrix timing. The ReadyBASIC hotkey probe
+therefore cannot be used as physical-key proof. A valid automated probe must
+separate the claims: assert that KEYLOG/CHRIN/IMAIN point at ReadyBASIC hooks,
+drive the KEYLOG path while ReadyBASIC has marked the direct prompt active, and
+prove that Return-only unwind dispatches without storing partial lines or
+printing `REM`. Manual or GUI-host key testing is still useful to prove the
+host-to-matrix path in VICE.
+
+The hotkey helper acts only at a ReadyBASIC direct prompt. Do not use
+`CURLIN`/`TXTPTR` alone as that proof: after `RUN` completes, BASIC may visibly
+be at `READY.` while those pointers still describe the just-run program line.
+ReadyBASIC therefore marks prompt ownership through the IMAIN vector and clears
+that flag in the execute hook. Running BASIC program input is left alone.
+`CTRL+B` follows the existing `EXIT` yield path. `F2`/`F4` scan the shim
+loaded-bank bitmap at `$C836-$C838`, write the target bank to `$C820`, and jump
+through `$C80F`. If no neighbor app is loaded, the function key is consumed so
+the BASIC editor does not see a stray app-navigation byte.
+
+Multi-hop switching exposed one extra rule: the selected `F2`/`F4` target must
+be copied into bridge state before ReadyBASIC prepares the shim yield, then
+written to `$C820` only after save-state, `CLRCHN`, and vector restore. The
+loaded-bank scan scratch bytes are not a durable handoff register. Before every
+`EXIT`, `CTRL+B`, `F2`, or `F4` yield, ReadyBASIC must also clear its pending
+hotkey byte, `$C6`, `$0277`, `SHFLAG`, `LSTX`, and `SFDX` so the destination app
+does not inherit stale editor state.
+
+A later F2/F4 double-switch failure proved that clearing state alone is not
+enough when the physical key is still held across a ReadyOS app switch. Current
+rule: on cold/warm entry, scan the CIA1 matrix and quarantine any still-held
+ReadyBASIC hotkey until it is released. Before yielding for a prompt hotkey,
+wait for the exact selected chord to release with a bounded jiffy-clock timeout,
+then clear editor/KERNAL key state again. The accepted quiet path is now
+Return-only plus CHRIN abort dispatch; visible `REM` injection is no longer part
+of the design.
+
+`EXIT`/`exit` remains the explicit ReadyBASIC wedge command for returning to the
+launcher: it restores ReadyBASIC-owned vectors, clears pending keyboard input,
+marks the app ready, and jumps to the ReadyOS shim return entry.
Automation caveat: the current harness key helper sends lowercase host ASCII in
a way that does not match manual C64 lowercase/PETSCII entry. Automated `exit`
@@ -581,9 +668,12 @@ there were independent BASIC/KERNAL vector contract bugs after the app loaded.
### Hypothesis: Hooking `CHRIN` After Original Return Is Enough For Prompt Hotkeys
-Disproven. The ROM screen editor consumes the interactive key stream internally
-and returns the completed logical line. Prompt navigation needs a pre-editor
-keyboard-buffer check or a deeper screen-editor hook.
+Revised. The ROM screen editor consumes the interactive key stream internally
+and returns the completed logical line, so CHRIN alone is not enough. KEYLOG
+runs inside that editor path before print, though, so the working design uses
+KEYLOG to accept the hotkey, queues Return only, and lets the CHRIN wrapper
+dispatch the pending action after the editor unwinds but before BASIC stores or
+executes the partial prompt line.
### Hypothesis: Pre-Editor `CHRIN` Keyboard-Buffer Peek Is Safe
@@ -591,7 +681,9 @@ Disproven. The pre-editor peek was changed into a blocking wait for `$C6 != 0`.
That starved the ROM screen editor before it could manage cursor/input state,
matching delayed prompts, missing cursor blink, and fragile line entry. The
stabilization pass removes it and accepts that prompt-level hotkeys need a
-separate, editor-safe design.
+separate, editor-safe design. The implemented design lets the ROM editor run,
+uses KEYLOG only during the CHRIN-owned editor call, and dispatches from CHRIN
+after Return unwinds the editor.
### Hypothesis: Tokenizing ReadyBASIC Commands Immediately Is The Best POC Path
@@ -641,7 +733,7 @@ contract is fully proven.
- For cross-app churn after `EXIT`, use:
`bash build_support/run_readybasic_cross_app_resume_probe.sh`
It builds the same larger BASIC/string/array case, then repeats:
- `EXIT -> launcher -> ReadyShell -> CTRL+B -> launcher -> ReadyBASIC -> LIST
+ `EXIT -> launcher -> another app -> CTRL+B -> launcher -> ReadyBASIC -> LIST
and one-at-a-time PRINT checks`. On 2026-05-11, 10 full cycles passed: all 206
plan steps were `ok`; the run was marked `partial` only because the harness
final automatic REU debug-ring fetch returned short after the successful plan.
@@ -658,8 +750,9 @@ contract is fully proven.
- After relaunching ReadyBASIC from the launcher:
- existing BASIC text, variables, strings, arrays, screen state, and `NEW`
state should resume coherently after a manual prompt `exit`.
-- `CTRL+B`/F-key interception remains deferred until the editor-safe hook is
- implemented and proven.
+- `CTRL+B`, `F2`, and `F4` prompt interception uses KEYLOG plus the CHRIN
+ Return-only abort path and must keep restoring page-3 vectors before every
+ shim yield.
### Expression Hooks Need Narrow, Purpose-Built Paths
@@ -704,18 +797,107 @@ Added on 2026-05-24 with `build_support/run_readybasic_demo_suite.sh`. A demo
suite is different from a regression probe: it should pause long enough for a
viewer to read the screen, describe each section with visible `REM` text before
running it, and state expected outcomes before printing or intentionally causing
-errors. The ReadyBASIC demo covers `FREEMEM`, app suspend/restore through the
+errors. The ReadyBASIC demo covers `MEMAVL`, app suspend/restore through the
Editor, assembler command groups, `PROC`/`FUNC`, array/float/string parameters,
REU handles, expected syntax/runtime errors, and nested expression forms. The
same script keeps `READYBASIC_DEMO_FAST=1` for tight development runs.
+### Prompt Hotkeys Must Abort Through The Editor, Not Type Commands
+
+Proven on 2026-06-12 in `readybasic-hotkeys-experiment`. ReadyBASIC hotkeys
+run inside the C64 BASIC screen editor, so they cannot be treated like normal
+ReadyOS C app hotkeys and they cannot be faked by injecting command text.
+Branch status at checkpoint: should be done working.
+
+Failed approaches and regressions:
+
+- Injecting visible `REM` plus Return as a deferred dispatch marker was unsafe.
+ It could appear on screen, combine with a partial prompt line such as `10`,
+ store unintended BASIC text, or lock the prompt.
+- Installing a prompt CINV/IRQ matrix scanner was too invasive. It competed
+ with the ROM editor and produced normal-typing regressions, including repeated
+ spaces in VICE fast/warp mode.
+- Accepting a hotkey without a release/quarantine rule let one physical F2/F4
+ act twice, producing double app switches.
+- Treating the ReadyBASIC title or any `READY.` text as sufficient automation
+ proof was weak. Boot and cartridge preload screens can contain misleading
+ text before the BASIC prompt is actually keyboard-live.
+- Preserving the transient CHRIN/editor stack depth for a ReadyOS yield was
+ wrong. READY-mode hotkey yields need a known BASIC-ready resume stack state.
+
+Current rule: prompt hotkeys are accepted only at the direct keyboard prompt.
+KEYLOG records Ctrl+B/F2/F4, consumes the hotkey state, and queues only Return.
+The CHRIN hook then discards the editor-returned character and dispatches the
+pending ReadyOS return/switch before BASIC can store or execute a partial line.
+Do not inject visible command text for navigation.
+
+Current rule: the ROM editor owns ordinary typing, cursor editing, and repeat
+timing. ReadyBASIC does not install an IRQ scanner for normal prompt hotkeys.
+Future keyboard extensions must prove single-space behavior under VICE warp,
+cursor/delete behavior, and ordinary `PRINT`/`LIST`/`RUN` input after repeated
+app reentry.
+
+Current rule: every accepted Ctrl+B/F2/F4 yield must clear `rb_hotkey_pending`,
+`KEYD_COUNT/$C6`, `KEYD_BUFFER/$0277`, `SHFLAG`, `LSTX`, and `SFDX`; wait for
+the selected physical chord to release with a bounded timeout; restore owned
+page-3 vectors; then call the ReadyOS shim. Cold/warm entry also quarantines a
+still-held hotkey until release.
+
+Current rule: F2/F4 target selection must persist across suspend preparation.
+Store the selected target bank immediately after the loaded-app scan and write
+the shim switch target only after `prepare_shim_yield`; do not depend on scratch
+bytes that hidden save logic can reuse.
+
+Current rule: prompt readiness is explicit state, not a visual guess. The IMAIN
+hook marks the direct prompt active and execute entry clears it. Ctrl+B/F2/F4
+remain ignored while a BASIC program is running or while input is not from the
+keyboard.
+
+Acceptance tests for future BASIC-editor work must include:
+
+- partial-line `10`+Ctrl+B and `20`+F2/F4 with no stored line, no `REM`, no
+ lockup, and keyboard-live reentry;
+- a single F2/F4 followed by a delayed stability check proving no double-hop;
+- launcher-owned multi-app cycling through at least ReadyBASIC, Editor, and REU
+ Viewer in both F2 and F4 directions;
+- app-bank `$C834`, vector, keyboard-buffer `$C6`, screen, screenshot/capture,
+ and typed-input assertions after every switch;
+- typed `EXIT` after hotkey journeys, proving the launcher stays stable and
+ does not auto-reenter ReadyBASIC.
+
+Cartridge/EasyFlash tests need their own app-order expectations. The cartridge
+preloads a wider set of apps, so hotkey tests should walk a few known apps
+forward/back and verify each destination rather than assuming the regular D81
+three-app set or cycling the entire cartridge list. Cartridge automation should
+also wait for the real BASIC `READY.` prompt, not only the ReadyBASIC title, and
+allow for occasional EasyFlash cold preload retries before the launcher.
+
+Current rule: ReadyBASIC command names are visible BASIC text, not private
+tokens. New public command spellings must avoid embedded BASIC V2 token words
+such as `CLR`, `FRE`, `NOT`, `INT`, `FN`, `LEN`, `OR`, and `TO`; otherwise
+`petcat` and BASIC `LIST` can split a command name into misleading keywords or
+raise a syntax error while `RUN` still appears to work. Host `.bas` demos should
+spell ReadyBASIC commands lowercase so `petcat` emits ordinary PETSCII letters.
+Legacy friendly names stay registered only with token-safe preferred aliases
+such as `SIDRST`, `SIDOFF`, `FRQ`, `PITCH`, `BUFMAKE`, `BUFDROP`, `MEMAVL`,
+`FBOX`, `PBMAKE`, `PBDROP`, `DLRST`, and `DLFBOX`.
+
+Current rule: aliases are descriptor entries, not free metadata. When adding a
+token-safe alias, update the descriptor-table filler expression so real
+descriptors plus zero-filled filler remain exactly `RB_CMD_DESC_COUNT`. If the
+filler is too large, late commands can be pushed past the searchable 128-slot
+range; the resulting symptom looks like a native BASIC `?SYNTAX ERROR` on an
+otherwise valid command line. `SCRPUT(H%(S))` exposed this on 2026-06-17 after
+alias additions pushed `SCRPUT` out of the registry. The static plugin check now
+counts descriptor macros and fails if the filler count drifts.
+
## Open Questions
- Deferred hypothesis: ReadyBASIC may leave KERNAL `MSGFLG` (`$009D`) nonzero
- when returning to ReadyOS, which would make later shim/ReadyShell `LOAD` calls
+ when returning to ReadyOS, which would make later shim/app `LOAD` calls
print `SEARCHING FOR` / `LOADING` chatter that normally stays hidden. Prove
later by dumping `$009D` before ReadyBASIC, after direct BASIC use, after
- `exit`, and immediately before launcher/shim/ReadyShell loads. Likely fix, if
+ `exit`, and immediately before launcher/shim/app loads. Likely fix, if
proven: save/restore or clear `MSGFLG` around ReadyBASIC yield, and consider
defensive `SETMSG 0` around shim/overlay loads.
- Should the prompt hotkey handler eventually hook the screen editor more
diff --git a/src/apps/readyirc/readyirc.c b/src/apps/readyirc/readyirc.c
index 554dd5d..2656a90 100644
--- a/src/apps/readyirc/readyirc.c
+++ b/src/apps/readyirc/readyirc.c
@@ -26,20 +26,56 @@
#define REU_MAX_LINES 512u
#define RAM_MAX_LINES OUTPUT_H
#define INPUT_MAX 96u
-#define IRC_IN_MAX 150u
+#define IRC_IN_MAX 510u
#define NET_READ_CHUNK 64u
#define NET_READ_BURST 2u
-#define READYIRC_RESUME_APP_SCHEMA RESUME_SCHEMA_V1
+#define READYIRC_RESUME_APP_SCHEMA 3u
-typedef struct ReadyIrcResumeV1 {
+#define UI_MODE_SETUP 0u
+#define UI_MODE_CHAT 1u
+
+#define SERVER_MAX 26u
+#define NICK_MAX 30u
+#define CHANNEL_MAX 30u
+#define PORT_TEXT_MAX 5u
+#define SETUP_FIELD_COUNT 4u
+
+#define UCI_STATUS_OK 0u
+/* Ultimate firmware reports its normal 40 ms receive timeout as 02,NO DATA. */
+#define UCI_STATUS_NO_DATA 2u
+
+typedef struct ReadyIrcResumeV2 {
+ char server[SERVER_MAX + 1u];
+ char port_text[PORT_TEXT_MAX + 1u];
+ char nick[NICK_MAX + 1u];
+ char channel[CHANNEL_MAX + 1u];
char input[INPUT_MAX + 1u];
+ char partial_line[IRC_IN_MAX + 1u];
+ char ram_chars[RAM_MAX_LINES][IRC_LINE_W];
+ unsigned char ram_colors[RAM_MAX_LINES][IRC_LINE_W];
+ unsigned int first_line;
+ unsigned int line_count;
+ unsigned int port;
unsigned char input_len;
+ unsigned char input_cursor;
+ unsigned int partial_len;
+ unsigned char dropping_line;
unsigned char scroll_back;
-} ReadyIrcResumeV1;
+ unsigned char scroll_bank;
+ unsigned char reu_scroll;
+ unsigned char ui_mode;
+ unsigned char connected;
+ unsigned char connection_wanted;
+ unsigned char socket_id;
+ unsigned char setup_focus;
+ unsigned char setup_cursor[SETUP_FIELD_COUNT];
+} ReadyIrcResumeV2;
static unsigned char running;
static unsigned char connected;
+static unsigned char connection_wanted;
+static unsigned char ui_mode;
static unsigned char socket_id;
static unsigned char scroll_bank;
static unsigned char reu_scroll;
@@ -48,11 +84,20 @@ static unsigned int first_line;
static unsigned int line_count;
static unsigned int max_lines;
+static char server_buf[SERVER_MAX + 1u];
+static char port_text_buf[PORT_TEXT_MAX + 1u];
+static char nick_buf[NICK_MAX + 1u];
+static char channel_buf[CHANNEL_MAX + 1u];
+static unsigned int port_value;
+static TuiInput setup_inputs[SETUP_FIELD_COUNT];
+static unsigned char setup_focus;
+static char setup_status[41];
+
static char input_buf[INPUT_MAX + 1u];
static unsigned char input_len;
static unsigned char input_cursor;
static char in_line[IRC_IN_MAX + 1u];
-static unsigned char in_len;
+static unsigned int in_len;
static unsigned char dropping_line;
static char build_chars[IRC_LINE_W];
@@ -63,7 +108,7 @@ static unsigned char line_chars[IRC_LINE_W];
static unsigned char line_colors[IRC_LINE_W];
static unsigned char net_buf[NET_READ_CHUNK];
static char send_buf[128];
-static ReadyIrcResumeV1 resume_blob;
+static ReadyIrcResumeV2 resume_blob;
static char ram_chars[RAM_MAX_LINES][IRC_LINE_W];
static unsigned char ram_colors[RAM_MAX_LINES][IRC_LINE_W];
@@ -71,7 +116,12 @@ static unsigned char ram_colors[RAM_MAX_LINES][IRC_LINE_W];
static void draw_shell(void);
static void draw_header(void);
static void draw_output(void);
+static void draw_output_row(unsigned char row, unsigned int rel_index);
+static unsigned int output_start_rel(void);
+static void shift_output_up(void);
+static void shift_output_down(void);
static void draw_input(void);
+static void draw_setup(void);
static void draw_status(const char *msg, unsigned char color);
static void add_status_line(const char *msg);
static void add_text_line(const char *msg, unsigned char color);
@@ -84,12 +134,15 @@ static void fetch_line(unsigned int rel_index);
static unsigned int physical_line(unsigned int rel_index);
static unsigned char screen_ch(unsigned char ch);
static unsigned char lower_ascii(unsigned char ch);
-static void normalize_in_place(char *s);
+static void normalize_display_in_place(char *s);
+static void lowercase_in_place(char *s);
static unsigned char text_eq(const char *a, const char *b);
static unsigned char starts_with(const char *s, const char *prefix);
static char *find_substr(char *s, const char *needle);
static char *find_char(char *s, char needle);
static void append_fit(char *dst, unsigned char cap, const char *src);
+static void append_wire_lower(char *dst, unsigned char cap, const char *src);
+static void append_wire_eol(char *dst, unsigned char cap);
static unsigned char nick_color(const char *nick);
static void add_privmsg(const char *nick, const char *msg);
static void add_action(const char *nick, const char *msg);
@@ -99,23 +152,38 @@ static void poll_network(void);
static void process_rx_byte(unsigned char ch);
static void send_raw(const char *s);
static void send_login(void);
-static void connect_irc(void);
+static unsigned char connect_irc(void);
static void disconnect_irc(void);
+static void disconnect_to_setup(void);
+static void connection_lost(void);
+static void probe_resumed_connection(void);
+static void setup_connect(void);
static void handle_input_submit(void);
static void handle_key(unsigned char key);
+static void handle_setup_key(unsigned char key);
+static void handle_chat_key(unsigned char key);
+static void setup_inputs_init(void);
+static void load_defaults(void);
+static unsigned char validate_settings(void);
+static unsigned char valid_channel(const char *channel);
+static unsigned char parse_port_text(unsigned int *value_out);
static void resume_save_state(void);
-static void resume_restore_state(void);
+static unsigned char resume_restore_state(void);
static void readyirc_return_to_launcher(void);
static void readyirc_switch_to_app(unsigned char bank);
static unsigned char lower_ascii(unsigned char ch) {
- if (ch >= 'A' && ch <= 'Z') {
- return (unsigned char)(ch + 32u);
+ /* Canonical lowercase PETSCII letters occupy $41-$5A. */
+ if (ch >= 0x61u && ch <= 0x7au) {
+ return (unsigned char)(ch - 0x20u);
+ }
+ if (ch >= 0xc1u && ch <= 0xdau) {
+ return (unsigned char)(ch - 0x80u);
}
return ch;
}
-static void normalize_in_place(char *s) {
+static void normalize_display_in_place(char *s) {
unsigned char i;
unsigned char ch;
@@ -129,6 +197,13 @@ static void normalize_in_place(char *s) {
}
}
+static void lowercase_in_place(char *s) {
+ while (*s != 0) {
+ *s = (char)lower_ascii((unsigned char)*s);
+ ++s;
+ }
+}
+
static unsigned char text_eq(const char *a, const char *b) {
while (*a != 0 && *b != 0) {
if (lower_ascii((unsigned char)*a) != lower_ascii((unsigned char)*b)) {
@@ -194,6 +269,40 @@ static void append_fit(char *dst, unsigned char cap, const char *src) {
dst[len] = 0;
}
+static void append_wire_lower(char *dst, unsigned char cap, const char *src) {
+ unsigned char ch;
+ unsigned char len;
+
+ if (cap == 0u) {
+ return;
+ }
+ len = (unsigned char)strlen(dst);
+ while (*src != 0 && len + 1u < cap) {
+ ch = (unsigned char)*src;
+ if (ch >= 0x41u && ch <= 0x5au) {
+ ch = (unsigned char)(ch + 0x20u);
+ } else if (ch >= 0xc1u && ch <= 0xdau) {
+ ch = (unsigned char)(ch - 0x60u);
+ }
+ dst[len] = (char)ch;
+ ++len;
+ ++src;
+ }
+ dst[len] = 0;
+}
+
+static void append_wire_eol(char *dst, unsigned char cap) {
+ unsigned char len;
+
+ len = (unsigned char)strlen(dst);
+ if (len + 2u >= cap) {
+ return;
+ }
+ dst[len] = 0x0d;
+ dst[(unsigned char)(len + 1u)] = 0x0a;
+ dst[(unsigned char)(len + 2u)] = 0;
+}
+
static unsigned char screen_ch(unsigned char ch) {
if (ch == 1u) {
return 32u;
@@ -220,27 +329,210 @@ static unsigned char nick_color(const char *nick) {
return colors[(unsigned char)(hash % sizeof(colors))];
}
+static void force_lowercase_charset(void) {
+ VIC.addr = 0x16u;
+}
+
+static void format_port_text(unsigned int value) {
+ char reversed[PORT_TEXT_MAX];
+ unsigned char len;
+ unsigned char i;
+
+ len = 0u;
+ do {
+ reversed[len] = (char)('0' + (value % 10u));
+ value /= 10u;
+ ++len;
+ } while (value != 0u && len < PORT_TEXT_MAX);
+
+ for (i = 0u; i < len; ++i) {
+ port_text_buf[i] = reversed[(unsigned char)(len - i - 1u)];
+ }
+ port_text_buf[len] = 0;
+}
+
+static void setup_inputs_init(void) {
+ tui_input_init(&setup_inputs[0], 10u, 4u, 29u, SERVER_MAX,
+ server_buf, TUI_COLOR_WHITE);
+ tui_input_init(&setup_inputs[1], 10u, 7u, 8u, PORT_TEXT_MAX,
+ port_text_buf, TUI_COLOR_WHITE);
+ tui_input_init(&setup_inputs[2], 10u, 10u, 29u, NICK_MAX,
+ nick_buf, TUI_COLOR_WHITE);
+ tui_input_init(&setup_inputs[3], 10u, 13u, 29u, CHANNEL_MAX,
+ channel_buf, TUI_COLOR_WHITE);
+ setup_focus = 0u;
+}
+
+static void load_defaults(void) {
+ strcpy(server_buf, readyirc_config_server);
+ strcpy(nick_buf, readyirc_config_nick);
+ strcpy(channel_buf, readyirc_config_channel);
+ port_value = readyirc_config_port;
+ format_port_text(port_value);
+ setup_inputs[0].cursor = (unsigned char)strlen(server_buf);
+ setup_inputs[1].cursor = (unsigned char)strlen(port_text_buf);
+ setup_inputs[2].cursor = (unsigned char)strlen(nick_buf);
+ setup_inputs[3].cursor = (unsigned char)strlen(channel_buf);
+ setup_status[0] = 0;
+}
+
+static unsigned char parse_port_text(unsigned int *value_out) {
+ unsigned int value;
+ unsigned char digit;
+ unsigned char i;
+
+ if (port_text_buf[0] == 0) {
+ return 0u;
+ }
+ value = 0u;
+ for (i = 0u; port_text_buf[i] != 0; ++i) {
+ if (port_text_buf[i] < '0' || port_text_buf[i] > '9') {
+ return 0u;
+ }
+ digit = (unsigned char)(port_text_buf[i] - '0');
+ if (value > 6553u || (value == 6553u && digit > 5u)) {
+ return 0u;
+ }
+ value = (unsigned int)(value * 10u + digit);
+ }
+ if (value == 0u) {
+ return 0u;
+ }
+ *value_out = value;
+ return 1u;
+}
+
+static unsigned char valid_channel(const char *channel) {
+ unsigned char i;
+ unsigned char ch;
+
+ if ((channel[0] != '#' && channel[0] != '&') ||
+ channel[1] == 0 || strlen(channel) > CHANNEL_MAX) {
+ return 0u;
+ }
+ for (i = 1u; channel[i] != 0; ++i) {
+ ch = (unsigned char)channel[i];
+ if (ch < 33u || ch == ',') {
+ return 0u;
+ }
+ }
+ return 1u;
+}
+
+static unsigned char validate_settings(void) {
+ unsigned char i;
+ unsigned char ch;
+
+ lowercase_in_place(server_buf);
+ lowercase_in_place(nick_buf);
+ lowercase_in_place(channel_buf);
+
+ if (server_buf[0] == 0 || strlen(server_buf) > SERVER_MAX) {
+ strcpy(setup_status, "server is required");
+ return 0u;
+ }
+ for (i = 0u; server_buf[i] != 0; ++i) {
+ ch = (unsigned char)server_buf[i];
+ if (!((ch >= 'a' && ch <= 'z') ||
+ (ch >= '0' && ch <= '9') || ch == '.' || ch == '-' ||
+ ch == ':')) {
+ strcpy(setup_status, "invalid server");
+ return 0u;
+ }
+ }
+ if (!parse_port_text(&port_value)) {
+ strcpy(setup_status, "port must be 1-65535");
+ return 0u;
+ }
+ if (nick_buf[0] == 0 || strlen(nick_buf) > NICK_MAX) {
+ strcpy(setup_status, "nickname is required");
+ return 0u;
+ }
+ for (i = 0u; nick_buf[i] != 0; ++i) {
+ ch = (unsigned char)nick_buf[i];
+ if (!((ch >= 'a' && ch <= 'z') ||
+ (ch >= '0' && ch <= '9') || ch == '_' || ch == '-')) {
+ strcpy(setup_status, "invalid nickname");
+ return 0u;
+ }
+ }
+ if ((channel_buf[0] != '#' && channel_buf[0] != '&') ||
+ channel_buf[1] == 0 || strlen(channel_buf) > CHANNEL_MAX) {
+ strcpy(setup_status, "channel must start with # or &");
+ return 0u;
+ }
+ if (!valid_channel(channel_buf)) {
+ strcpy(setup_status, "invalid channel");
+ return 0u;
+ }
+ setup_status[0] = 0;
+ return 1u;
+}
+
+static void draw_setup_field(unsigned char index, unsigned char y,
+ const char *label) {
+ TuiInput *input;
+ unsigned char color;
+
+ input = &setup_inputs[index];
+ color = (index == setup_focus) ? TUI_COLOR_CYAN : TUI_COLOR_GRAY3;
+ tui_putc(1u, y, (index == setup_focus) ? tui_ascii_to_screen('>') : 32u,
+ color);
+ tui_puts_n(3u, y, label, 7u, color);
+ if (index == setup_focus) {
+ input->color = TUI_COLOR_YELLOW;
+ tui_input_draw(input);
+ } else {
+ tui_puts_n(input->x, input->y, input->buffer, input->width,
+ TUI_COLOR_WHITE);
+ }
+}
+
+static void draw_setup(void) {
+ tui_init();
+ force_lowercase_charset();
+ tui_clear(TUI_THEME_BG);
+ tui_puts_n(0u, 0u, "readyirc setup", 40u, TUI_COLOR_WHITE);
+ tui_hline(0u, 1u, 40u, TUI_COLOR_LIGHTBLUE);
+ draw_setup_field(0u, 4u, "server");
+ draw_setup_field(1u, 7u, "port");
+ draw_setup_field(2u, 10u, "nick");
+ draw_setup_field(3u, 13u, "channel");
+ tui_hline(0u, 16u, 40u, TUI_COLOR_LIGHTBLUE);
+ tui_puts_n(0u, 18u,
+ setup_status[0] != 0 ? setup_status : "return connects",
+ 40u, setup_status[0] != 0 ? TUI_COLOR_LIGHTRED :
+ TUI_COLOR_LIGHTGREEN);
+ tui_puts_n(0u, 22u, "up/down field left/right/home edit", 40u,
+ TUI_COLOR_GRAY3);
+ tui_puts_n(0u, 23u, "del erases return connect", 40u, TUI_COLOR_GRAY3);
+ tui_puts_n(0u, 24u, "ctrl+b home f2/f4 apps runstop exit", 40u,
+ TUI_COLOR_GRAY3);
+}
+
static void draw_header(void) {
char title[41];
title[0] = 0;
append_fit(title, sizeof(title), "readyirc ");
append_fit(title, sizeof(title), connected ? "online " : "offline ");
- append_fit(title, sizeof(title), readyirc_config_channel);
+ append_fit(title, sizeof(title), channel_buf);
tui_clear_line(0u, 0u, 40u, TUI_COLOR_WHITE);
tui_puts_n(0u, 0u, title, 40u, TUI_COLOR_WHITE);
tui_clear_line(1u, 0u, 40u, TUI_COLOR_GRAY3);
- tui_puts_n(0u, 1u, readyirc_config_server, 24u, TUI_COLOR_GRAY3);
- tui_puts_n(25u, 1u, "tcp 6667", 15u, TUI_COLOR_GRAY3);
+ tui_puts_n(0u, 1u, server_buf, 24u, TUI_COLOR_GRAY3);
+ tui_puts_n(25u, 1u, "tcp", 4u, TUI_COLOR_GRAY3);
+ tui_puts_n(29u, 1u, port_text_buf, 11u, TUI_COLOR_GRAY3);
}
static void draw_shell(void) {
tui_init();
+ force_lowercase_charset();
tui_clear(TUI_THEME_BG);
draw_header();
tui_hline(0u, (unsigned char)(OUTPUT_TOP - 1u), 40u, TUI_COLOR_LIGHTBLUE);
tui_hline(0u, (unsigned char)(INPUT_Y - 1u), 40u, TUI_COLOR_LIGHTBLUE);
- tui_puts_n(0u, HELP_Y, "ctrl+b home f2/f4 apps up/down scroll", 40u, TUI_COLOR_GRAY3);
+ tui_puts_n(0u, HELP_Y, "f1 disconnect ctrl+b home f2/f4 apps", 40u, TUI_COLOR_GRAY3);
draw_status("starting", TUI_COLOR_GRAY3);
draw_output();
draw_input();
@@ -270,46 +562,66 @@ static void fetch_line(unsigned int rel_index) {
}
}
-static void draw_output(void) {
- unsigned char row;
- unsigned char col;
+static unsigned int output_start_rel(void) {
unsigned int start;
- unsigned int rel;
+
+ if (line_count <= OUTPUT_H) {
+ return 0u;
+ }
+ start = (unsigned int)(line_count - OUTPUT_H);
+ if (scroll_back > start) {
+ scroll_back = (unsigned char)start;
+ }
+ return (unsigned int)(start - scroll_back);
+}
+
+static void draw_output_row(unsigned char row, unsigned int rel_index) {
+ unsigned char col;
unsigned int offset;
- for (row = 0u; row < OUTPUT_H; ++row) {
- offset = (unsigned int)(OUTPUT_TOP + row) * 40u;
+ offset = (unsigned int)(OUTPUT_TOP + row) * 40u;
+ if (rel_index >= line_count) {
for (col = 0u; col < 40u; ++col) {
TUI_SCREEN[offset + col] = 32u;
TUI_COLOR_RAM[offset + col] = TUI_COLOR_WHITE;
}
- }
-
- if (line_count == 0u) {
return;
}
- if (line_count > OUTPUT_H) {
- start = (unsigned int)(line_count - OUTPUT_H);
- if (scroll_back > start) {
- scroll_back = (unsigned char)start;
- }
- start = (unsigned int)(start - scroll_back);
- } else {
- start = 0u;
- scroll_back = 0u;
+
+ fetch_line(rel_index);
+ for (col = 0u; col < 40u; ++col) {
+ TUI_SCREEN[offset + col] = screen_ch(line_chars[col]);
}
+ memcpy(TUI_COLOR_RAM + offset, line_colors, IRC_LINE_W);
+}
+
+static void shift_output_up(void) {
+ unsigned int offset;
+
+ offset = (unsigned int)OUTPUT_TOP * 40u;
+ memmove(TUI_SCREEN + offset, TUI_SCREEN + offset + 40u,
+ (unsigned int)(OUTPUT_H - 1u) * 40u);
+ memmove(TUI_COLOR_RAM + offset, TUI_COLOR_RAM + offset + 40u,
+ (unsigned int)(OUTPUT_H - 1u) * 40u);
+}
+static void shift_output_down(void) {
+ unsigned int offset;
+
+ offset = (unsigned int)OUTPUT_TOP * 40u;
+ memmove(TUI_SCREEN + offset + 40u, TUI_SCREEN + offset,
+ (unsigned int)(OUTPUT_H - 1u) * 40u);
+ memmove(TUI_COLOR_RAM + offset + 40u, TUI_COLOR_RAM + offset,
+ (unsigned int)(OUTPUT_H - 1u) * 40u);
+}
+
+static void draw_output(void) {
+ unsigned char row;
+ unsigned int start;
+
+ start = output_start_rel();
for (row = 0u; row < OUTPUT_H; ++row) {
- rel = (unsigned int)(start + row);
- if (rel >= line_count) {
- break;
- }
- fetch_line(rel);
- offset = (unsigned int)(OUTPUT_TOP + row) * 40u;
- for (col = 0u; col < 40u; ++col) {
- TUI_SCREEN[offset + col] = screen_ch(line_chars[col]);
- TUI_COLOR_RAM[offset + col] = line_colors[col];
- }
+ draw_output_row(row, (unsigned int)(start + row));
}
}
@@ -385,6 +697,12 @@ static void line_text(const char *msg, unsigned char color) {
static void store_line(const char *chars, const unsigned char *colors) {
unsigned int idx;
+ unsigned int old_count;
+ unsigned int start;
+ unsigned char old_scroll;
+
+ old_count = line_count;
+ old_scroll = scroll_back;
if (line_count < max_lines) {
idx = physical_line(line_count);
@@ -404,8 +722,28 @@ static void store_line(const char *chars, const unsigned char *colors) {
memcpy(ram_colors[idx], colors, IRC_LINE_W);
}
- scroll_back = 0u;
- draw_output();
+ if (old_scroll != 0u) {
+ start = line_count > OUTPUT_H ?
+ (unsigned int)(line_count - OUTPUT_H) : 0u;
+ if (scroll_back < start && scroll_back < 255u) {
+ ++scroll_back;
+ return;
+ }
+ shift_output_up();
+ start = output_start_rel();
+ draw_output_row((unsigned char)(OUTPUT_H - 1u),
+ (unsigned int)(start + OUTPUT_H - 1u));
+ return;
+ }
+
+ if (old_count < OUTPUT_H) {
+ draw_output_row((unsigned char)old_count, old_count);
+ return;
+ }
+ shift_output_up();
+ start = output_start_rel();
+ draw_output_row((unsigned char)(OUTPUT_H - 1u),
+ (unsigned int)(start + OUTPUT_H - 1u));
}
static void add_text_line(const char *msg, unsigned char color) {
@@ -457,47 +795,50 @@ static void send_raw(const char *s) {
static void send_login(void) {
send_buf[0] = 0;
append_fit(send_buf, sizeof(send_buf), "nick ");
- append_fit(send_buf, sizeof(send_buf), readyirc_config_nick);
- append_fit(send_buf, sizeof(send_buf), "\r\n");
+ append_wire_lower(send_buf, sizeof(send_buf), nick_buf);
+ append_wire_eol(send_buf, sizeof(send_buf));
send_raw(send_buf);
send_buf[0] = 0;
append_fit(send_buf, sizeof(send_buf), "user ");
- append_fit(send_buf, sizeof(send_buf), readyirc_config_nick);
+ append_wire_lower(send_buf, sizeof(send_buf), nick_buf);
append_fit(send_buf, sizeof(send_buf), " * 0 :");
- append_fit(send_buf, sizeof(send_buf), readyirc_config_nick);
- append_fit(send_buf, sizeof(send_buf), "\r\n");
+ append_wire_lower(send_buf, sizeof(send_buf), nick_buf);
+ append_wire_eol(send_buf, sizeof(send_buf));
send_raw(send_buf);
send_buf[0] = 0;
append_fit(send_buf, sizeof(send_buf), "join ");
- append_fit(send_buf, sizeof(send_buf), readyirc_config_channel);
- append_fit(send_buf, sizeof(send_buf), "\r\n");
+ append_wire_lower(send_buf, sizeof(send_buf), channel_buf);
+ append_wire_eol(send_buf, sizeof(send_buf));
send_raw(send_buf);
}
-static void connect_irc(void) {
+static unsigned char connect_irc(void) {
if (!readyirc_uci_detect()) {
add_status_line("uci command interface not detected");
draw_status("uci not detected", TUI_COLOR_LIGHTRED);
- return;
+ strcpy(setup_status, "uci not detected");
+ return 0u;
}
add_status_line("connecting");
draw_status("connecting", TUI_COLOR_YELLOW);
- if (!readyirc_uci_tcp_connect(readyirc_config_server,
- readyirc_config_port,
+ if (!readyirc_uci_tcp_connect(server_buf,
+ port_value,
&socket_id)) {
add_status_line("connect failed");
add_text_line(readyirc_uci_last_status(), TUI_COLOR_GRAY3);
draw_status("connect failed", TUI_COLOR_LIGHTRED);
connected = 0u;
- return;
+ strcpy(setup_status, "connect failed");
+ return 0u;
}
connected = 1u;
draw_header();
draw_status("connected", TUI_COLOR_LIGHTGREEN);
add_status_line("connected");
send_login();
+ return 1u;
}
static void disconnect_irc(void) {
@@ -510,22 +851,64 @@ static void disconnect_irc(void) {
}
}
+static void disconnect_to_setup(void) {
+ if (connected) {
+ strcpy(send_buf, "quit :readyirc disconnect");
+ append_wire_eol(send_buf, sizeof(send_buf));
+ send_raw(send_buf);
+ }
+ disconnect_irc();
+ connection_wanted = 0u;
+ ui_mode = UI_MODE_SETUP;
+ strcpy(setup_status, "disconnected");
+ draw_setup();
+}
+
+static void connection_lost(void) {
+ connected = 0u;
+ add_status_line("connection expired");
+ draw_status("reconnecting", TUI_COLOR_YELLOW);
+ readyirc_uci_socket_close(socket_id);
+ if (connection_wanted && connect_irc()) {
+ add_status_line("reconnected");
+ return;
+ }
+ connection_wanted = 0u;
+ ui_mode = UI_MODE_SETUP;
+ strcpy(setup_status, "reconnect failed");
+ draw_setup();
+}
+
+static void setup_connect(void) {
+ if (!validate_settings()) {
+ draw_setup();
+ return;
+ }
+ connection_wanted = 1u;
+ ui_mode = UI_MODE_CHAT;
+ draw_shell();
+ if (!connect_irc()) {
+ connection_wanted = 0u;
+ ui_mode = UI_MODE_SETUP;
+ draw_setup();
+ }
+}
+
static void parse_irc_line(char *line) {
char *p;
char *cmd;
char *target;
char *msg;
+ char *channel;
char *end;
char nick[32];
unsigned char i;
- normalize_in_place(line);
-
if (starts_with(line, "ping ")) {
send_buf[0] = 0;
append_fit(send_buf, sizeof(send_buf), "pong ");
append_fit(send_buf, sizeof(send_buf), line + 5);
- append_fit(send_buf, sizeof(send_buf), "\r\n");
+ append_wire_eol(send_buf, sizeof(send_buf));
send_raw(send_buf);
return;
}
@@ -567,6 +950,52 @@ static void parse_irc_line(char *line) {
*target = 0;
++target;
+ if (text_eq(cmd, "353")) {
+ msg = find_substr(target, " :");
+ if (msg == 0) {
+ return;
+ }
+ *msg = 0;
+ msg += 2;
+ channel = target;
+ while (*channel != 0 && *channel != '#' && *channel != '&') {
+ ++channel;
+ }
+ end = channel;
+ while (*end != 0 && *end != ' ') {
+ ++end;
+ }
+ if (*end != 0) {
+ *end = 0;
+ }
+ line_begin();
+ line_text("names ", TUI_COLOR_GRAY3);
+ line_text(*channel != 0 ? channel : channel_buf, TUI_COLOR_CYAN);
+ line_text(": ", TUI_COLOR_GRAY3);
+ line_text(msg, TUI_COLOR_WHITE);
+ line_flush();
+ return;
+ }
+
+ if (text_eq(cmd, "366")) {
+ channel = target;
+ while (*channel != 0 && *channel != '#' && *channel != '&') {
+ ++channel;
+ }
+ end = channel;
+ while (*end != 0 && *end != ' ' && *end != ':') {
+ ++end;
+ }
+ if (*end != 0) {
+ *end = 0;
+ }
+ line_begin();
+ line_text("end names ", TUI_COLOR_GRAY3);
+ line_text(*channel != 0 ? channel : channel_buf, TUI_COLOR_CYAN);
+ line_flush();
+ return;
+ }
+
if (text_eq(cmd, "privmsg")) {
msg = find_substr(target, " :");
if (msg == 0) {
@@ -574,7 +1003,7 @@ static void parse_irc_line(char *line) {
}
*msg = 0;
msg += 2;
- if (!text_eq(target, readyirc_config_channel)) {
+ if (!text_eq(target, channel_buf)) {
add_join_part(nick, "dm ignored");
return;
}
@@ -621,10 +1050,10 @@ static void parse_irc_line(char *line) {
}
static void process_rx_byte(unsigned char ch) {
- if (ch == '\n') {
+ if (ch == 0x0au) {
return;
}
- if (ch == '\r') {
+ if (ch == 0x0du) {
if (!dropping_line && in_len != 0u) {
in_line[in_len] = 0;
parse_irc_line(in_line);
@@ -648,6 +1077,7 @@ static void process_rx_byte(unsigned char ch) {
static void poll_network(void) {
unsigned char burst;
unsigned char i;
+ unsigned char status_code;
unsigned int n;
if (!connected) {
@@ -655,6 +1085,14 @@ static void poll_network(void) {
}
for (burst = 0u; burst < NET_READ_BURST; ++burst) {
n = readyirc_uci_socket_read(socket_id, net_buf, NET_READ_CHUNK);
+ status_code = readyirc_uci_last_status_code();
+ if (status_code == UCI_STATUS_NO_DATA) {
+ break;
+ }
+ if (status_code != UCI_STATUS_OK) {
+ connection_lost();
+ return;
+ }
if (n == 0u) {
break;
}
@@ -664,40 +1102,149 @@ static void poll_network(void) {
}
}
+static void probe_resumed_connection(void) {
+ unsigned int n;
+ unsigned char i;
+ unsigned char status_code;
+
+ if (!connection_wanted || !connected) {
+ return;
+ }
+ n = readyirc_uci_socket_read(socket_id, net_buf, NET_READ_CHUNK);
+ status_code = readyirc_uci_last_status_code();
+ if (status_code == UCI_STATUS_NO_DATA) {
+ draw_status("connected", TUI_COLOR_LIGHTGREEN);
+ return;
+ }
+ if (status_code != UCI_STATUS_OK) {
+ connection_lost();
+ return;
+ }
+ for (i = 0u; i < n; ++i) {
+ process_rx_byte(net_buf[i]);
+ }
+ draw_status("connected", TUI_COLOR_LIGHTGREEN);
+}
+
static void handle_input_submit(void) {
+ char *arg;
+
if (input_len == 0u) {
return;
}
input_buf[input_len] = 0;
- normalize_in_place(input_buf);
+ normalize_display_in_place(input_buf);
+
+ if (text_eq(input_buf, "/disconnect")) {
+ input_len = 0u;
+ input_cursor = 0u;
+ input_buf[0] = 0;
+ disconnect_to_setup();
+ return;
+ }
+
+ if (text_eq(input_buf, "/join") || starts_with(input_buf, "/join ")) {
+ if (!connected) {
+ add_status_line("not connected");
+ } else {
+ arg = input_buf + 5;
+ if (*arg == ' ') {
+ ++arg;
+ }
+ if (!valid_channel(arg)) {
+ add_status_line("usage /join #channel");
+ } else if (text_eq(arg, channel_buf)) {
+ add_status_line("already in channel");
+ } else {
+ send_buf[0] = 0;
+ append_fit(send_buf, sizeof(send_buf), "part ");
+ append_wire_lower(send_buf, sizeof(send_buf), channel_buf);
+ append_fit(send_buf, sizeof(send_buf), " :changing channel");
+ append_wire_eol(send_buf, sizeof(send_buf));
+ send_raw(send_buf);
+
+ strcpy(channel_buf, arg);
+ lowercase_in_place(channel_buf);
+ send_buf[0] = 0;
+ append_fit(send_buf, sizeof(send_buf), "join ");
+ append_wire_lower(send_buf, sizeof(send_buf), channel_buf);
+ append_wire_eol(send_buf, sizeof(send_buf));
+ send_raw(send_buf);
+ draw_header();
+
+ send_buf[0] = 0;
+ append_fit(send_buf, sizeof(send_buf), "joining ");
+ append_fit(send_buf, sizeof(send_buf), channel_buf);
+ add_status_line(send_buf);
+ }
+ }
+ input_len = 0u;
+ input_cursor = 0u;
+ input_buf[0] = 0;
+ draw_input();
+ return;
+ }
+
+ if (text_eq(input_buf, "/names") || starts_with(input_buf, "/names ")) {
+ if (!connected) {
+ add_status_line("not connected");
+ } else {
+ arg = input_buf + 6;
+ if (*arg == ' ') {
+ ++arg;
+ }
+ if (*arg == 0) {
+ arg = channel_buf;
+ }
+ if (!valid_channel(arg)) {
+ add_status_line("usage /names #channel");
+ } else {
+ send_buf[0] = 0;
+ append_fit(send_buf, sizeof(send_buf), "names ");
+ append_wire_lower(send_buf, sizeof(send_buf), arg);
+ append_wire_eol(send_buf, sizeof(send_buf));
+ send_raw(send_buf);
+ }
+ }
+ input_len = 0u;
+ input_cursor = 0u;
+ input_buf[0] = 0;
+ draw_input();
+ return;
+ }
if (starts_with(input_buf, "/quit")) {
- send_raw("quit :readyirc\r\n");
+ strcpy(send_buf, "quit :readyirc");
+ append_wire_eol(send_buf, sizeof(send_buf));
+ send_raw(send_buf);
disconnect_irc();
+ connection_wanted = 0u;
+ ui_mode = UI_MODE_SETUP;
readyirc_return_to_launcher();
return;
}
if (starts_with(input_buf, "/me ")) {
send_buf[0] = 0;
append_fit(send_buf, sizeof(send_buf), "privmsg ");
- append_fit(send_buf, sizeof(send_buf), readyirc_config_channel);
+ append_wire_lower(send_buf, sizeof(send_buf), channel_buf);
append_fit(send_buf, sizeof(send_buf), " :\x01");
append_fit(send_buf, sizeof(send_buf), "action ");
- append_fit(send_buf, sizeof(send_buf), input_buf + 4);
- append_fit(send_buf, sizeof(send_buf), "\x01\r\n");
+ append_wire_lower(send_buf, sizeof(send_buf), input_buf + 4);
+ append_fit(send_buf, sizeof(send_buf), "\x01");
+ append_wire_eol(send_buf, sizeof(send_buf));
send_raw(send_buf);
- add_action(readyirc_config_nick, input_buf + 4);
+ add_action(nick_buf, input_buf + 4);
} else if (starts_with(input_buf, "/msg ")) {
add_status_line("dm support disabled");
} else if (connected) {
send_buf[0] = 0;
append_fit(send_buf, sizeof(send_buf), "privmsg ");
- append_fit(send_buf, sizeof(send_buf), readyirc_config_channel);
+ append_wire_lower(send_buf, sizeof(send_buf), channel_buf);
append_fit(send_buf, sizeof(send_buf), " :");
- append_fit(send_buf, sizeof(send_buf), input_buf);
- append_fit(send_buf, sizeof(send_buf), "\r\n");
+ append_wire_lower(send_buf, sizeof(send_buf), input_buf);
+ append_wire_eol(send_buf, sizeof(send_buf));
send_raw(send_buf);
- add_privmsg(readyirc_config_nick, input_buf);
+ add_privmsg(nick_buf, input_buf);
} else {
add_status_line("not connected");
}
@@ -708,28 +1255,19 @@ static void handle_input_submit(void) {
draw_input();
}
-static void handle_key(unsigned char key) {
+static void handle_chat_key(unsigned char key) {
unsigned char i;
- unsigned char nav_action;
unsigned int max_scroll;
- nav_action = tui_handle_global_hotkey(key, SHIM_CURRENT_BANK, 1u);
- if (nav_action == TUI_HOTKEY_LAUNCHER) {
- readyirc_return_to_launcher();
- }
- if (nav_action >= TUI_APP_BANK_MIN && nav_action <= TUI_APP_BANK_MAX) {
- readyirc_switch_to_app(nav_action);
- return;
- }
- if (nav_action == TUI_HOTKEY_BIND_ONLY) {
- return;
- }
-
switch (key) {
case TUI_KEY_RUNSTOP:
disconnect_irc();
+ connection_wanted = 0u;
running = 0u;
break;
+ case TUI_KEY_F1:
+ disconnect_to_setup();
+ break;
case TUI_KEY_RETURN:
handle_input_submit();
break;
@@ -761,14 +1299,18 @@ static void handle_key(unsigned char key) {
max_scroll = (unsigned int)(line_count - OUTPUT_H);
if (scroll_back < max_scroll && scroll_back < 255u) {
++scroll_back;
- draw_output();
+ shift_output_down();
+ draw_output_row(0u, output_start_rel());
}
}
break;
case TUI_KEY_DOWN:
if (scroll_back > 0u) {
--scroll_back;
- draw_output();
+ shift_output_up();
+ max_scroll = output_start_rel();
+ draw_output_row((unsigned char)(OUTPUT_H - 1u),
+ (unsigned int)(max_scroll + OUTPUT_H - 1u));
}
break;
default:
@@ -786,24 +1328,161 @@ static void handle_key(unsigned char key) {
}
}
+static void handle_setup_key(unsigned char key) {
+ if (key == TUI_KEY_RUNSTOP) {
+ connection_wanted = 0u;
+ running = 0u;
+ return;
+ }
+ if (key == TUI_KEY_UP) {
+ if (setup_focus == 0u) {
+ setup_focus = SETUP_FIELD_COUNT - 1u;
+ } else {
+ --setup_focus;
+ }
+ draw_setup();
+ return;
+ }
+ if (key == TUI_KEY_DOWN) {
+ ++setup_focus;
+ if (setup_focus >= SETUP_FIELD_COUNT) {
+ setup_focus = 0u;
+ }
+ draw_setup();
+ return;
+ }
+ if (key == TUI_KEY_RETURN) {
+ setup_connect();
+ return;
+ }
+ if (key >= 'A' && key <= 'Z') {
+ key = lower_ascii(key);
+ }
+ if (tui_input_key(&setup_inputs[setup_focus], key)) {
+ setup_connect();
+ return;
+ }
+ setup_status[0] = 0;
+ draw_setup();
+}
+
+static void handle_key(unsigned char key) {
+ unsigned char nav_action;
+
+ nav_action = tui_handle_global_hotkey(key, SHIM_CURRENT_BANK, 1u);
+ if (nav_action == TUI_HOTKEY_LAUNCHER) {
+ readyirc_return_to_launcher();
+ return;
+ }
+ if (nav_action >= TUI_APP_BANK_MIN && nav_action <= TUI_APP_BANK_MAX) {
+ readyirc_switch_to_app(nav_action);
+ return;
+ }
+ if (nav_action == TUI_HOTKEY_BIND_ONLY) {
+ return;
+ }
+
+ if (ui_mode == UI_MODE_SETUP) {
+ handle_setup_key(key);
+ } else {
+ handle_chat_key(key);
+ }
+}
+
static void resume_save_state(void) {
+ unsigned char i;
+
+ memcpy(resume_blob.server, server_buf, sizeof(server_buf));
+ memcpy(resume_blob.port_text, port_text_buf, sizeof(port_text_buf));
+ memcpy(resume_blob.nick, nick_buf, sizeof(nick_buf));
+ memcpy(resume_blob.channel, channel_buf, sizeof(channel_buf));
memcpy(resume_blob.input, input_buf, sizeof(input_buf));
+ memcpy(resume_blob.partial_line, in_line, sizeof(in_line));
+ memcpy(resume_blob.ram_chars, ram_chars, sizeof(ram_chars));
+ memcpy(resume_blob.ram_colors, ram_colors, sizeof(ram_colors));
+ resume_blob.first_line = first_line;
+ resume_blob.line_count = line_count;
+ resume_blob.port = port_value;
resume_blob.input_len = input_len;
+ resume_blob.input_cursor = input_cursor;
+ resume_blob.partial_len = in_len;
+ resume_blob.dropping_line = dropping_line;
resume_blob.scroll_back = scroll_back;
+ resume_blob.scroll_bank = scroll_bank;
+ resume_blob.reu_scroll = reu_scroll;
+ resume_blob.ui_mode = ui_mode;
+ resume_blob.connected = connected;
+ resume_blob.connection_wanted = connection_wanted;
+ resume_blob.socket_id = socket_id;
+ resume_blob.setup_focus = setup_focus;
+ for (i = 0u; i < SETUP_FIELD_COUNT; ++i) {
+ resume_blob.setup_cursor[i] = setup_inputs[i].cursor;
+ }
(void)resume_save(&resume_blob, sizeof(resume_blob));
}
-static void resume_restore_state(void) {
+static unsigned char resume_restore_state(void) {
unsigned int payload_len;
+ unsigned int restored_max;
+ unsigned char i;
- if (resume_try_load(&resume_blob, sizeof(resume_blob), &payload_len) &&
- payload_len == sizeof(resume_blob) &&
- resume_blob.input_len <= INPUT_MAX) {
- memcpy(input_buf, resume_blob.input, sizeof(input_buf));
- input_len = resume_blob.input_len;
- input_cursor = input_len;
- scroll_back = resume_blob.scroll_back;
+ if (!resume_try_load(&resume_blob, sizeof(resume_blob), &payload_len) ||
+ payload_len != sizeof(resume_blob)) {
+ return 0u;
}
+ restored_max = resume_blob.reu_scroll ? REU_MAX_LINES : RAM_MAX_LINES;
+ if (resume_blob.server[SERVER_MAX] != 0 ||
+ resume_blob.port_text[PORT_TEXT_MAX] != 0 ||
+ resume_blob.nick[NICK_MAX] != 0 ||
+ resume_blob.channel[CHANNEL_MAX] != 0 ||
+ resume_blob.input[INPUT_MAX] != 0 ||
+ resume_blob.partial_line[IRC_IN_MAX] != 0 ||
+ resume_blob.input_len > INPUT_MAX ||
+ resume_blob.input_cursor > resume_blob.input_len ||
+ resume_blob.partial_len > IRC_IN_MAX ||
+ resume_blob.ui_mode > UI_MODE_CHAT ||
+ resume_blob.setup_focus >= SETUP_FIELD_COUNT ||
+ resume_blob.line_count > restored_max ||
+ (resume_blob.line_count != 0u && resume_blob.first_line >= restored_max) ||
+ (resume_blob.reu_scroll && resume_blob.scroll_bank == 0xFFu) ||
+ resume_blob.port == 0u) {
+ return 0u;
+ }
+ memcpy(server_buf, resume_blob.server, sizeof(server_buf));
+ memcpy(port_text_buf, resume_blob.port_text, sizeof(port_text_buf));
+ memcpy(nick_buf, resume_blob.nick, sizeof(nick_buf));
+ memcpy(channel_buf, resume_blob.channel, sizeof(channel_buf));
+ memcpy(input_buf, resume_blob.input, sizeof(input_buf));
+ memcpy(in_line, resume_blob.partial_line, sizeof(in_line));
+ memcpy(ram_chars, resume_blob.ram_chars, sizeof(ram_chars));
+ memcpy(ram_colors, resume_blob.ram_colors, sizeof(ram_colors));
+ first_line = resume_blob.first_line;
+ line_count = resume_blob.line_count;
+ port_value = resume_blob.port;
+ input_len = resume_blob.input_len;
+ input_cursor = resume_blob.input_cursor;
+ in_len = resume_blob.partial_len;
+ dropping_line = resume_blob.dropping_line;
+ scroll_back = resume_blob.scroll_back;
+ scroll_bank = resume_blob.scroll_bank;
+ reu_scroll = resume_blob.reu_scroll;
+ max_lines = restored_max;
+ ui_mode = resume_blob.ui_mode;
+ connected = resume_blob.connected;
+ connection_wanted = resume_blob.connection_wanted;
+ socket_id = resume_blob.socket_id;
+ setup_focus = resume_blob.setup_focus;
+ for (i = 0u; i < SETUP_FIELD_COUNT; ++i) {
+ setup_inputs[i].cursor = resume_blob.setup_cursor[i];
+ if (setup_inputs[i].cursor > strlen(setup_inputs[i].buffer)) {
+ setup_inputs[i].cursor = (unsigned char)strlen(setup_inputs[i].buffer);
+ }
+ }
+ if (!connection_wanted) {
+ connected = 0u;
+ }
+ setup_status[0] = 0;
+ return 1u;
}
static void readyirc_return_to_launcher(void) {
@@ -818,16 +1497,20 @@ static void readyirc_switch_to_app(unsigned char bank) {
int main(void) {
unsigned char key;
+ unsigned char resumed;
reu_mgr_init();
resume_init_for_app(SHIM_CURRENT_BANK, SHIM_CURRENT_BANK, READYIRC_RESUME_APP_SCHEMA);
+ setup_inputs_init();
running = 1u;
connected = 0u;
+ connection_wanted = 0u;
+ ui_mode = UI_MODE_SETUP;
socket_id = 0u;
- scroll_bank = reu_alloc_owned_bank(1u, "scrl");
- reu_scroll = (unsigned char)(scroll_bank != 0xFFu);
- max_lines = reu_scroll ? REU_MAX_LINES : RAM_MAX_LINES;
+ scroll_bank = 0xFFu;
+ reu_scroll = 0u;
+ max_lines = RAM_MAX_LINES;
first_line = 0u;
line_count = 0u;
input_len = 0u;
@@ -837,15 +1520,36 @@ int main(void) {
dropping_line = 0u;
scroll_back = 0u;
- resume_restore_state();
- draw_shell();
- if (!reu_scroll) {
- add_status_line("reu scrollback unavailable");
+ resumed = resume_restore_state();
+ if (!resumed) {
+ load_defaults();
+ scroll_bank = reu_alloc_owned_bank(1u, "scrl");
+ reu_scroll = (unsigned char)(scroll_bank != 0xFFu);
+ max_lines = reu_scroll ? REU_MAX_LINES : RAM_MAX_LINES;
+ draw_setup();
+ } else if (ui_mode == UI_MODE_SETUP) {
+ draw_setup();
+ } else {
+ draw_shell();
+ if (!reu_scroll) {
+ add_status_line("reu scrollback unavailable");
+ }
+ if (connection_wanted && connected) {
+ probe_resumed_connection();
+ } else if (connection_wanted) {
+ if (!connect_irc()) {
+ connection_wanted = 0u;
+ ui_mode = UI_MODE_SETUP;
+ strcpy(setup_status, "reconnect failed");
+ draw_setup();
+ }
+ }
}
- connect_irc();
while (running) {
- poll_network();
+ if (ui_mode == UI_MODE_CHAT) {
+ poll_network();
+ }
if (tui_kbhit()) {
key = tui_getkey();
handle_key(key);
diff --git a/src/apps/readyirc/readyirc_config.inc b/src/apps/readyirc/readyirc_config.inc
index 5a04fda..b01a3a0 100644
--- a/src/apps/readyirc/readyirc_config.inc
+++ b/src/apps/readyirc/readyirc_config.inc
@@ -10,7 +10,7 @@ _readyirc_config_channel:
.asciiz "#readyos"
_readyirc_config_nick:
- .asciiz "readyos64"
+ .asciiz "enteryournick"
_readyirc_config_port:
.word 6667
diff --git a/src/apps/readyirc/readyirc_uci.c b/src/apps/readyirc/readyirc_uci.c
index 84b61e3..0ddfcba 100644
--- a/src/apps/readyirc/readyirc_uci.c
+++ b/src/apps/readyirc/readyirc_uci.c
@@ -30,6 +30,7 @@ static unsigned char uci_stat[READYIRC_UCI_STAT_MAX];
static unsigned char uci_data_len;
static unsigned char uci_stat_len;
static char last_status[READYIRC_UCI_STAT_MAX + 1u];
+static unsigned char last_status_code = 0xFFu;
static unsigned char id_matches(unsigned char id) {
return (unsigned char)((id & UCI_ID_MASK) == UCI_ID_MATCH);
@@ -56,6 +57,12 @@ static void save_status(void) {
last_status[i] = (char)uci_stat[i];
}
last_status[n] = 0;
+ last_status_code = 0xFFu;
+ if (n >= 2u && last_status[0] >= '0' && last_status[0] <= '9' &&
+ last_status[1] >= '0' && last_status[1] <= '9') {
+ last_status_code = (unsigned char)(((unsigned char)(last_status[0] - '0') * 10u) +
+ (unsigned char)(last_status[1] - '0'));
+ }
}
static unsigned char status_ok(void) {
@@ -154,6 +161,7 @@ static unsigned char command(const unsigned char *cmd,
uci_data_len = 0u;
uci_stat_len = 0u;
last_status[0] = 0;
+ last_status_code = 0xFFu;
if (!readyirc_uci_detect() || cmd == 0 || cmd_len == 0u) {
return 0u;
@@ -264,6 +272,7 @@ unsigned char readyirc_uci_tcp_connect(const char *host,
unsigned int port,
unsigned char *socket_out) {
static unsigned char cmd[32];
+ unsigned char ch;
unsigned char i;
if (socket_out != 0) {
@@ -278,7 +287,13 @@ unsigned char readyirc_uci_tcp_connect(const char *host,
cmd[2] = (unsigned char)(port & 0xFFu);
cmd[3] = (unsigned char)(port >> 8);
for (i = 0u; host[i] != 0 && i < 26u; ++i) {
- cmd[(unsigned char)(4u + i)] = (unsigned char)host[i];
+ ch = (unsigned char)host[i];
+ if (ch >= 0x41u && ch <= 0x5au) {
+ ch = (unsigned char)(ch + 0x20u);
+ } else if (ch >= 0xc1u && ch <= 0xdau) {
+ ch = (unsigned char)(ch - 0x60u);
+ }
+ cmd[(unsigned char)(4u + i)] = ch;
}
cmd[(unsigned char)(4u + i)] = 0u;
@@ -383,3 +398,7 @@ void readyirc_uci_socket_close(unsigned char socket_id) {
const char *readyirc_uci_last_status(void) {
return last_status;
}
+
+unsigned char readyirc_uci_last_status_code(void) {
+ return last_status_code;
+}
diff --git a/src/apps/readyirc/readyirc_uci.h b/src/apps/readyirc/readyirc_uci.h
index 40fdaa1..7203661 100644
--- a/src/apps/readyirc/readyirc_uci.h
+++ b/src/apps/readyirc/readyirc_uci.h
@@ -22,6 +22,7 @@ unsigned char readyirc_uci_socket_write(unsigned char socket_id,
unsigned int len);
void readyirc_uci_socket_close(unsigned char socket_id);
const char *readyirc_uci_last_status(void);
+unsigned char readyirc_uci_last_status_code(void);
void __fastcall__ readyirc_uci_asm_set_base(unsigned int base);
unsigned char __fastcall__ readyirc_uci_asm_write_cmd(unsigned char value);
diff --git a/src/apps/readyshell/README.md b/src/apps/readyshell/README.md
index b97c1d0..b3a4c0b 100644
--- a/src/apps/readyshell/README.md
+++ b/src/apps/readyshell/README.md
@@ -116,12 +116,15 @@ Streaming output pause:
Current release build memory layout:
-- Resident app window: `$1000-$C5FF` (`46592` bytes)
+- ReadyOS snapshot window: `$1000-$C5FF` (`46592` bytes); ReadyShell's overlay
+ execution ABI intentionally remains `$8E00-$C5FF`, immediately below the shim
- Overlay load-address bytes: `$8DFE-$8DFF`
- Overlay execution window: `$8E00-$C5FF` (`14336` bytes)
-- Resident BSS: `$7D37-$7EE0` (`426` bytes)
-- Resident heap: `$7EE2-$8DFD` (`3868` bytes)
+- Resident BSS: `$7DEB-$7F94` (`426` bytes)
+- Resident heap: `$7F96-$8DFD` (`3688` bytes)
- High RAM runtime outside the app snapshot: `$CA00-$CFFF`
+- Overlay diagnostics are REU-only in the loader-assigned ReadyShell state
+ bank; the obsolete `$C7A0-$C7DF` / `$C7F0` RAM mirror is retired.
Overlay policy:
diff --git a/src/apps/readyshell/platform/c64/rs_overlay_c64.c b/src/apps/readyshell/platform/c64/rs_overlay_c64.c
index 45101d5..04e4189 100644
--- a/src/apps/readyshell/platform/c64/rs_overlay_c64.c
+++ b/src/apps/readyshell/platform/c64/rs_overlay_c64.c
@@ -20,9 +20,6 @@
#include
#define RS_OVERLAY_COUNT 9u
-#define RS_RAM_DBG_HEAD (*(unsigned char*)0xC7F0)
-#define RS_RAM_DBG_BASE ((unsigned char*)0xC7A0)
-#define RS_RAM_DBG_LEN 0x40u
#define RS_OVL_RC_NOT_BOOTED 0xE3u
#define RS_OVL_RC_REU_PARSE 0xE4u
#define RS_OVL_RC_REU_EXEC 0xE5u
@@ -41,7 +38,6 @@ static int g_overlay_cached_reu = 0;
static unsigned char g_overlay_last_rc = 0u;
static unsigned char g_overlay_active_phase = RS_OVERLAY_PHASE_NONE;
static unsigned short g_dbg_pos = 0u;
-static unsigned char g_ram_dbg_pos = 0u;
static unsigned char g_overlay_meta_buf[RS_REU_OVL_CACHE_META_LEN];
static unsigned char g_overlay_cache_banks[RS_OVERLAY_COUNT];
static unsigned short g_overlay_cache_offsets[RS_OVERLAY_COUNT];
@@ -83,38 +79,20 @@ static unsigned long rs_overlay_edit_off(void) {
static void rs_overlay_dbg_reset(void) {
unsigned char head[2];
- unsigned char i;
g_dbg_pos = 0u;
- g_ram_dbg_pos = 0u;
head[0] = 0u;
head[1] = 0u;
(void)rs_reu_write(RS_REU_DBG_HEAD_OFF, head, 2u);
- for (i = 0u; i < RS_RAM_DBG_LEN; ++i) {
- RS_RAM_DBG_BASE[i] = 0u;
- }
- RS_RAM_DBG_HEAD = 0u;
}
static void rs_overlay_dbg_put(unsigned char code) {
unsigned char b;
unsigned char head[2];
- RS_RAM_DBG_BASE[g_ram_dbg_pos] = code;
- ++g_ram_dbg_pos;
- if (g_ram_dbg_pos >= RS_RAM_DBG_LEN) {
- g_ram_dbg_pos = 0u;
- }
- RS_RAM_DBG_HEAD = g_ram_dbg_pos;
if (g_dbg_state == 0u) {
g_dbg_state = rs_reu_available() ? 2u : 1u;
if (g_dbg_state == 2u) {
rs_overlay_dbg_reset();
- RS_RAM_DBG_BASE[g_ram_dbg_pos] = code;
- ++g_ram_dbg_pos;
- if (g_ram_dbg_pos >= RS_RAM_DBG_LEN) {
- g_ram_dbg_pos = 0u;
- }
- RS_RAM_DBG_HEAD = g_ram_dbg_pos;
}
}
if (g_dbg_state != 2u) {
diff --git a/src/apps/readyshell/platform/c64/rs_platform_c64.c b/src/apps/readyshell/platform/c64/rs_platform_c64.c
index 1ebd05a..a5f2081 100644
--- a/src/apps/readyshell/platform/c64/rs_platform_c64.c
+++ b/src/apps/readyshell/platform/c64/rs_platform_c64.c
@@ -1,6 +1,7 @@
#include "../rs_platform.h"
#include "../../core/rs_ui_state.h"
#include "reu_mgr.h"
+#include "reu_control_bank.h"
#define RS_REU_STATE_BANK_CACHE (*(unsigned char*)0xCFF2)
@@ -25,12 +26,15 @@ unsigned char rs_reu_state_bank(void) {
unsigned int bank;
if (RS_REU_STATE_BANK_CACHE != 0u &&
- REU_ALLOC_TABLE[RS_REU_STATE_BANK_CACHE] == REU_RS_SCRATCH) {
+ readyos_bank_read_byte((unsigned int)(REUCB_BANK_TYPE_OFF +
+ RS_REU_STATE_BANK_CACHE)) ==
+ REU_RS_SCRATCH) {
return RS_REU_STATE_BANK_CACHE;
}
for (bank = 0u; bank < REU_TOTAL_BANKS; ++bank) {
- if (REU_ALLOC_TABLE[bank] == REU_RS_SCRATCH) {
+ if (readyos_bank_read_byte((unsigned int)(REUCB_BANK_TYPE_OFF + bank)) ==
+ REU_RS_SCRATCH) {
RS_REU_STATE_BANK_CACHE = (unsigned char)bank;
return (unsigned char)bank;
}
diff --git a/src/apps/reuviewer/reuviewer.c b/src/apps/reuviewer/reuviewer.c
index 8d8d2e1..a812940 100644
--- a/src/apps/reuviewer/reuviewer.c
+++ b/src/apps/reuviewer/reuviewer.c
@@ -109,7 +109,8 @@ static void reuviewer_read_control_bank_header(void) {
if (control_bank_ok) {
reu_dma_fetch((unsigned int)&reu_physical_banks,
REU_READYOS_GLOBAL_PHYSICAL(),
- REUCB_HEADER_PHYS_BANKS, 1u);
+ (unsigned int)(REUCB_HEADER_OFF +
+ REUCB_HEADER_PHYS_BANKS), 1u);
} else {
reu_physical_banks = reu_phys_count_from_alloc_table();
}
@@ -129,17 +130,31 @@ static void reuviewer_fetch_app_name(unsigned char app_index) {
static unsigned char reuviewer_find_app_for_logical(unsigned char logical,
unsigned char *out_app) {
- unsigned char i;
- unsigned char app_bank;
+ unsigned char app_index;
if (!control_bank_ok) {
return 0u;
}
- for (i = 0u; i < REUCB_APP_REG_COUNT; ++i) {
- reu_dma_fetch((unsigned int)&app_bank, REU_READYOS_GLOBAL_PHYSICAL(),
- (unsigned int)(REUCB_APP_REG_OFF + i), 1u);
- if (app_bank == logical) {
- *out_app = i;
+ app_index = readyos_bank_read_byte((unsigned int)(REUCB_TOKEN_APP_OFF +
+ logical));
+ if (app_index < REUCB_APP_REG_COUNT) {
+ *out_app = app_index;
+ return 1u;
+ }
+ return 0u;
+}
+
+static unsigned char reuviewer_find_logical_for_physical(unsigned char physical,
+ unsigned char *out_token) {
+ unsigned char token;
+ unsigned char status;
+
+ for (token = 1u; token <= TUI_APP_BANK_MAX; ++token) {
+ status = readyos_bank_read_byte((unsigned int)(REUCB_TOKEN_STATUS_OFF + token));
+ if ((status & REUCB_TOKEN_VALID) &&
+ readyos_bank_read_byte((unsigned int)(REUCB_SHIM_LOOKUP_OFF + token)) ==
+ physical) {
+ *out_token = token;
return 1u;
}
}
@@ -183,8 +198,8 @@ static void draw_summary(void) {
tui_print_uint(6, TITLE_Y + 1,
reu_phys_display_count(reu_physical_banks), TUI_COLOR_WHITE);
- tui_puts(12, TITLE_Y + 1, "SK:", TUI_COLOR_ORANGE);
- tui_print_uint(15, TITLE_Y + 1, *SHIM_REU_BANK_SKIP, TUI_COLOR_ORANGE);
+ tui_puts(12, TITLE_Y + 1, "RO:", TUI_COLOR_ORANGE);
+ tui_print_uint(15, TITLE_Y + 1, *SHIM_READYOS_BANK, TUI_COLOR_ORANGE);
tui_puts(20, TITLE_Y + 1, "FREE:", TUI_COLOR_GRAY2);
tui_print_uint(25, TITLE_Y + 1, free_count, TUI_COLOR_GRAY2);
@@ -323,7 +338,7 @@ static void draw_detail(void) {
case REU_APP_ALLOC: type_str = "APP ALLOC"; break;
case REU_RESERVED: type_str = "APP SLOT RSV"; break;
case REU_LAUNCHER: type_str = "LAUNCHER"; break;
- case REU_GLOBAL: type_str = "READYOS GLOBAL"; break;
+ case REU_GLOBAL: type_str = "READYOS BANK"; break;
case REU_SKIPPED: type_str = "SKIPPED"; break;
case REU_UNAVAIL: type_str = "UNAVAILABLE"; break;
case REU_RS_CACHE: type_str = "RS CACHE"; break;
@@ -338,8 +353,7 @@ static void draw_detail(void) {
tui_print_uint(6, DETAIL_Y + 1, bank, TUI_COLOR_WHITE);
tui_puts(12, DETAIL_Y + 1, "LOG: ", TUI_COLOR_GRAY3);
if (!bank_is_unavailable(bank) &&
- bank >= (unsigned char)(*SHIM_REU_BANK_SKIP + 2u)) {
- logical = (unsigned char)(bank - *SHIM_REU_BANK_SKIP - 1u);
+ reuviewer_find_logical_for_physical(bank, &logical)) {
tui_print_hex8(17, DETAIL_Y + 1, logical, TUI_COLOR_CYAN);
if (reuviewer_find_app_for_logical(logical, &app_index)) {
reuviewer_fetch_app_name(app_index);
diff --git a/src/boot/boot_asm.s b/src/boot/boot_asm.s
index 1531da7..7cf70e7 100644
--- a/src/boot/boot_asm.s
+++ b/src/boot/boot_asm.s
@@ -3,14 +3,15 @@
;
; Memory Map:
; $0801-$08FF: Boot loader (this code, freed after boot)
-; $C800-$C9FF: Shim (512 bytes) - copied here, stays resident
-; (Using $C800 to avoid cc65 runtime overwriting $0800)
+; $C600-$C9FF: Shim area (1024 bytes) - copied here, stays resident
+; (public jump table/data ABI remains at $C800-$C9FF)
; $1000-$C5FF: App snapshot window ($B600 / 46592 bytes)
;
-; REU Banks are physical = READYOS_REU_BANK_SKIP + offset.
-; Start: ReadyOS global bank
-; Start+1: logical launcher bank 0
-; Start+2: logical app/resource bank 1
+; READYOS_REU_BANK_SKIP names the ReadyOS physical bank.
+; Skip: ReadyOS bank (launcher snapshot + schema-v5 state)
+; Skip+1: first dynamic app/resource bank
+; Other dynamic banks are assigned through the schema token map; token 1 is
+; not an arithmetic alias for Skip+2.
;-----------------------------------------------------------------------------
.segment "LOADADDR"
@@ -364,14 +365,20 @@ start:
lda #(msg_kernel_end - msg_kernel)
jsr print_progress ; prints at row 19, col 4
- ; Copy shim to $C800 (512 bytes in two chunks)
+ ; Install the complete 1KB resident shim area at $C600-$C9FF. Clear the
+ ; reserved lower half in place, then copy the embedded 512-byte ABI half.
+ ; Avoiding 512 literal zero bytes keeps the bootstrap below app RAM.
ldx #$00
+ lda #$00
copy_shim:
dex
+ sta $C600,x
+ sta $C700,x
lda shim_data,x
sta $C800,x
lda shim_data+256,x
sta $C900,x
+ lda #$00
cpx #$00
bne copy_shim
@@ -395,18 +402,8 @@ copy_shim:
lda #(msg_memory_end - msg_memory)
jsr print_progress
- ; Initialize REU allocation table at $C600-$C7FF
- ldx #0
- lda #0
-init_reu_table:
- sta $C600,x
- sta $C700,x
- inx
- bne init_reu_table
-
- ; Set magic byte
- lda #$A5
- sta $C700
+ ; $C600-$C7FF remains resident shim expansion space. The launcher
+ ; initializes authoritative allocation/mapping state in the ReadyOS bank.
;--- Phase 3: "LOADING LAUNCHER..." ---
ldx #EASYFLASH_LAUNCHER_PAYLOAD_LEN
sta rem_hi
jsr copy_payload_from_cart
- lda #(READYOS_REU_BANK_SKIP + 1)
+ lda #READYOS_REU_BANK_SKIP
sta reu_bank_zp
lda #$00
sta reu_off_lo
@@ -790,7 +788,7 @@ restore_launcher_ram:
sta dst_lo
lda #>APP_LOAD_START
sta dst_hi
- lda #(READYOS_REU_BANK_SKIP + 1)
+ lda #READYOS_REU_BANK_SKIP
sta reu_bank_zp
lda #$00
sta reu_off_lo
@@ -813,10 +811,9 @@ preload_app_banks:
beq @done
jsr clear_app_window
ldy #$00
+ iny
+ ; The generated table carries an explicit token-to-physical mapping.
lda (table_lo),y
- clc
- ; Logical app bank N stashes to physical Start+1+N.
- adc #(READYOS_REU_BANK_SKIP + 1)
sta reu_bank_zp
iny
lda (table_lo),y
@@ -835,7 +832,7 @@ preload_app_banks:
lda (table_lo),y
sta rem_hi
jsr show_app_progress
- ldy #$03
+ ldy #$04
lda (table_lo),y
sta dst_lo
iny
@@ -854,12 +851,9 @@ preload_app_banks:
lda #>APP_WINDOW_LEN
sta rem_hi
jsr reu_stash_window
- ldy #$00
- lda (table_lo),y
- jsr set_bitmap
clc
lda table_lo
- adc #9
+ adc #10
sta table_lo
bcc @no_carry
inc table_hi
@@ -1217,39 +1211,6 @@ reu_fetch_window:
sta $01
rts
-set_bitmap:
- cmp #8
- bcc @lo
- cmp #16
- bcc @hi
- cmp #24
- bcs @done
- sec
- sbc #16
- tax
- lda bit_masks,x
- ora $C838
- sta $C838
- rts
-@hi:
- sec
- sbc #8
- tax
- lda bit_masks,x
- ora $C837
- sta $C837
- rts
-@lo:
- tax
- lda bit_masks,x
- ora $C836
- sta $C836
-@done:
- rts
-
-bit_masks:
- .byte $01, $02, $04, $08, $10, $20, $40, $80
-
.segment "RODATA"
msg_banner:
diff --git a/src/boot/readyos_shim.inc b/src/boot/readyos_shim.inc
index 09f8e2c..97ae0b6 100644
--- a/src/boot/readyos_shim.inc
+++ b/src/boot/readyos_shim.inc
@@ -1,11 +1,21 @@
;-----------------------------------------------------------------------------
-; Shared ReadyOS shim image ($C800-$C9FF, 512 bytes)
+; Shared ReadyOS shim image ($C600-$C9FF, 1024 bytes)
; This file is the canonical shim byte layout used by both the disk boot path
; and the EasyFlash cartridge flavor. Keep it identical across all variants.
;-----------------------------------------------------------------------------
;-----------------------------------------------------------------------------
-; Page 1: $C800-$C8FF - Jump table, data, and helper routines
+; Pages 1-2: $C600-$C7FF - reserved resident expansion space
+;-----------------------------------------------------------------------------
+; This space used to contain the C64-RAM REU allocation/metadata mirror. The
+; authoritative state now lives in the ReadyOS REU bank, but the RAM remains
+; resident shim-owned capacity rather than becoming app snapshot memory.
+.ifndef READYOS_SHIM_ABI_ONLY
+.res $0200, $00
+.endif
+
+;-----------------------------------------------------------------------------
+; Page 3: $C800-$C8FF - Jump table, data, and helper routines
;-----------------------------------------------------------------------------
; $C800-$C817: Jump Table (24 bytes, 8 entries)
@@ -15,7 +25,7 @@ jt_run_app = $C806 ; Just run app
jt_preload = $C809 ; Preload to REU, return
jt_return = $C80C ; Return to launcher
jt_switch = $C80F ; Switch to another app
-jt_stash_cur = $C812 ; Helper: stash current app
+jt_reserved = $C812 ; Reserved compatibility slot (safe no-op)
jt_fetch_bank = $C815 ; Helper: fetch from bank in A
.byte $4C, $40, $C8 ; $C800: JMP load_disk ($C840)
@@ -24,49 +34,48 @@ jt_fetch_bank = $C815 ; Helper: fetch from bank in A
.byte $4C, $80, $C8 ; $C809: JMP preload ($C880)
.byte $4C, $00, $C9 ; $C80C: JMP return_to_launcher ($C900)
.byte $4C, $40, $C9 ; $C80F: JMP switch_app ($C940)
-.byte $4C, $C0, $C8 ; $C812: JMP stash_current ($C8C0) - placeholder
+.byte $4C, $FF, $C9 ; $C812: reserved helper -> safe RTS
.byte $4C, $F0, $C8 ; $C815: JMP fetch_bank ($C8F0)
-; $C818: JMP log_byte ($C9E0)
-.byte $4C, $E0, $C9 ; $C818: JMP log_byte
-.byte $00,$00,$00,$00,$00 ; $C81B-$C81F: Padding
+; $C818: deprecated logger compatibility slot
+.byte $4C, $FF, $C9 ; $C818: deprecated logger -> safe RTS
+.byte $4C, $C0, $C9 ; $C81B: JMP mark_loaded (token in A)
+.byte $00,$00 ; $C81E-$C81F: reserved
; $C820-$C83F: Data Area (32 bytes)
; $C820: target_bank - bank to load/switch to
; $C821: filename_len
-; $C822-$C823: unused
+; $C822-$C823: launcher-side app-size scratch (not consumed by the shim)
; $C824-$C82F: filename (12 bytes)
; $C830: load_end_lo (KERNAL LOAD end addr low byte, saved by preload)
; $C831: load_end_hi (KERNAL LOAD end addr high byte, saved by preload)
; $C832-$C833: unused
; $C834: current_bank - currently running app
; $C835: last_saved
-; $C836: reu_bitmap_lo (banks 0-7)
-; $C837: reu_bitmap_hi (banks 8-15)
-; $C838: reu_bitmap_xhi (banks 16-23)
+; $C836-$C838: retired bitmap bytes (reserved; authoritative state is in REU)
; $C839: storage_drive - shim-global default storage drive for D8/D9 app dialogs
; This persists across app switches and is shared by apps that use the
; common file-dialog default-drive contract.
-; $C83A: log_index - debug byte ring head
-; $C83B: reu_bank_skip - physical 64K banks reserved before ReadyOS bank start
+; $C83A: reserved (formerly log_index)
+; $C83B: readyos_bank - direct physical ReadyOS bank number (Skip)
; $C83C: launcher_flags - launcher-owned one-shot state flags
-; $C83D: reu_lookup_scratch - one-byte physical bank fetched from REU bank 0
-; $C83E-$C83F: reserved
+; $C83D: reu_lookup_scratch - one-byte ReadyOS-bank DMA scratch
+; $C83E: token_scratch; $C83F: reserved
.byte $00 ; $C820: target_bank
.byte $08 ; $C821: filename_len
-.byte $00, $00 ; $C822-$C823: unused
+.byte $00, $00 ; $C822-$C823: launcher app-size scratch
.byte "LAUNCHER " ; $C824-$C82F: filename (12 bytes)
.byte $00,$00 ; $C830-$C831: load_end_lo, load_end_hi
.byte $00,$00 ; $C832-$C833: unused
.byte $00 ; $C834: current_bank
.byte $FF ; $C835: last_saved
-.byte $00 ; $C836: reu_bitmap_lo
-.byte $00 ; $C837: reu_bitmap_hi
-.byte $00 ; $C838: reu_bitmap_xhi
+.byte $00 ; $C836: reserved (retired bitmap byte)
+.byte $00 ; $C837: reserved (retired bitmap byte)
+.byte $00 ; $C838: reserved (retired bitmap byte)
.byte $08 ; $C839: storage_drive (default drive 8)
-.byte $00 ; $C83A: log_index (for debug buffer)
-.byte READYOS_REU_BANK_SKIP ; $C83B: reu_bank_skip (compiled into boot image)
+.byte $00 ; $C83A: reserved (retired debug-ring head)
+.byte READYOS_REU_BANK_SKIP ; $C83B: readyos_bank (physical Skip)
.byte $00 ; $C83C: launcher_flags
.byte $00 ; $C83D: reu_lookup_scratch
.byte $00,$00 ; $C83E-$C83F: reserved
@@ -79,13 +88,13 @@ jt_fetch_bank = $C815 ; Helper: fetch from bank in A
.byte $A0, $C8 ; LDY #$C8 (filename at $C824)
.byte $20, $BD, $FF ; JSR $FFBD (SETNAM)
.byte $A9, $00 ; LDA #0
-.byte $A2, $08 ; LDX #8
+.byte $AE, $39, $C8 ; LDX $C839 (storage drive)
.byte $A0, $01 ; LDY #1
.byte $20, $BA, $FF ; JSR $FFBA (SETLFS)
.byte $A9, $00 ; LDA #0
.byte $20, $D5, $FF ; JSR $FFD5 (LOAD)
.byte $4C, $00, $10 ; JMP $1000
-.byte $00,$00,$00,$00,$00 ; Padding to $C860
+.byte $00,$00,$00,$00 ; Padding to $C860
;-----------------------------------------------------------------------------
; $C860: load_reu - Fetch app from REU and run (32 bytes)
@@ -100,30 +109,20 @@ jt_fetch_bank = $C815 ; Helper: fetch from bank in A
;-----------------------------------------------------------------------------
; $C880: preload - Load to REU, return to launcher
; Called via JSR $C809
-; DEBUG: writes markers to $C007-$C00C
;-----------------------------------------------------------------------------
-.byte $A9, $AA ; LDA #$AA (170 = "preload entered")
-.byte $8D, $07, $C0 ; STA $C007
-
-.byte $A9, $00 ; LDA #0 (bank 0)
+.byte $A9, $00 ; LDA #0 (launcher token -> ReadyOS bank)
.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
-.byte $A9, $BB ; LDA #$BB (187 = "launcher stashed")
-.byte $8D, $08, $C0 ; STA $C008
-
.byte $AD, $21, $C8 ; LDA $C821 (len)
.byte $A2, $24 ; LDX #$24
.byte $A0, $C8 ; LDY #$C8 (filename at $C824)
.byte $20, $BD, $FF ; JSR SETNAM
.byte $A9, $00 ; LDA #0
-.byte $A2, $08 ; LDX #8
+.byte $AE, $39, $C8 ; LDX $C839 (storage drive)
.byte $A0, $01 ; LDY #1
.byte $20, $BA, $FF ; JSR SETLFS
-.byte $A9, $CC ; LDA #$CC (204 = "about to LOAD")
-.byte $8D, $09, $C0 ; STA $C009
-
.byte $A9, $00 ; LDA #0
.byte $20, $D5, $FF ; JSR LOAD
@@ -133,22 +132,20 @@ jt_fetch_bank = $C815 ; Helper: fetch from bank in A
.byte $AD, $20, $C8 ; LDA $C820 (target bank)
.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
-.byte $A9, $EE ; LDA #$EE (238 = "app stashed")
-.byte $8D, $0B, $C0 ; STA $C00B
-
.byte $AD, $20, $C8 ; LDA $C820 (target bank)
-.byte $20, $C0, $C9 ; JSR set_bitmap ($C9C0)
+.byte $20, $C0, $C9 ; JSR mark_loaded ($C9C0)
.byte $A9, $00 ; LDA #0
.byte $20, $F0, $C8 ; JSR fetch_bank ($C8F0)
-.byte $A9, $FF ; LDA #$FF (255 = "launcher restored")
-.byte $8D, $0C, $C0 ; STA $C00C
-
.byte $60 ; RTS
-.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00,$00,$00,$00,$00
+.byte $00,$00
;-----------------------------------------------------------------------------
; $C8E0: stash_to_bank - Stash $1000-$C5FF to REU bank in A (16 bytes)
@@ -169,7 +166,7 @@ jt_fetch_bank = $C815 ; Helper: fetch from bank in A
.byte $00,$00,$00,$00,$00,$00,$00
;-----------------------------------------------------------------------------
-; Page 2: $C900-$C9FF - Main routines
+; Page 4: $C900-$C9FF - Main routines
;-----------------------------------------------------------------------------
;-----------------------------------------------------------------------------
@@ -178,7 +175,7 @@ jt_fetch_bank = $C815 ; Helper: fetch from bank in A
.byte $AD, $34, $C8 ; LDA $C834 (current bank)
.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
.byte $AD, $34, $C8 ; LDA $C834 (current bank)
-.byte $20, $C0, $C9 ; JSR set_bitmap ($C9C0)
+.byte $20, $C0, $C9 ; JSR mark_loaded ($C9C0)
.byte $AD, $34, $C8 ; LDA $C834
.byte $8D, $35, $C8 ; STA $C835
.byte $A9, $00 ; LDA #0
@@ -198,7 +195,7 @@ jt_fetch_bank = $C815 ; Helper: fetch from bank in A
.byte $AD, $34, $C8 ; LDA $C834 (current bank)
.byte $20, $E0, $C8 ; JSR stash_to_bank ($C8E0)
.byte $AD, $34, $C8 ; LDA $C834 (current bank)
-.byte $20, $C0, $C9 ; JSR set_bitmap ($C9C0)
+.byte $20, $C0, $C9 ; JSR mark_loaded ($C9C0)
.byte $AD, $20, $C8 ; LDA $C820 (target bank)
.byte $20, $F0, $C8 ; JSR fetch_bank ($C8F0)
.byte $AD, $20, $C8 ; LDA $C820
@@ -207,13 +204,11 @@ jt_fetch_bank = $C815 ; Helper: fetch from bank in A
.byte $00,$00,$00,$00,$00
;-----------------------------------------------------------------------------
-; $C960: reu_setup_logical - Resolve logical token via REU bank 0, then setup regs
+; $C960: reu_setup_logical - Resolve token via the ReadyOS bank, then setup regs
;-----------------------------------------------------------------------------
.byte $C9, $00 ; CMP #0 (logical launcher bank?)
-.byte $D0, $09 ; BNE lookup_app_bank
-.byte $AD, $3B, $C8 ; LDA $C83B (reu_bank_skip)
-.byte $18 ; CLC
-.byte $69, $01 ; ADC #$01 (launcher is Start+1)
+.byte $D0, $06 ; BNE lookup_app_bank
+.byte $AD, $3B, $C8 ; LDA $C83B (ReadyOS bank contains launcher)
.byte $4C, $A0, $C9 ; JMP reu_setup ($C9A0)
.byte $AA ; lookup_app_bank: TAX (preserve logical token)
.byte $A9, $3D ; LDA #<$C83D
@@ -221,9 +216,12 @@ jt_fetch_bank = $C815 ; Helper: fetch from bank in A
.byte $A9, $C8 ; LDA #>$C83D
.byte $8D, $03, $DF ; STA $DF03 (C64 addr hi)
.byte $8A ; TXA
-.byte $8D, $04, $DF ; STA $DF04 (REU offset lo = logical token)
-.byte $A9, $2F ; LDA #$2F
-.byte $8D, $05, $DF ; STA $DF05 (REU offset hi = lookup page)
+.byte $18 ; CLC
+.byte $69, $40 ; ADC #<$B740 (mapping offset + token)
+.byte $8D, $04, $DF ; STA $DF04 (REU offset lo)
+.byte $A9, $B7 ; LDA #>$B740
+.byte $69, $00 ; ADC #0 (include low-byte carry)
+.byte $8D, $05, $DF ; STA $DF05 (REU offset hi)
.byte $AD, $3B, $C8 ; LDA $C83B (ReadyOS global physical bank)
.byte $8D, $06, $DF ; STA $DF06
.byte $A9, $01 ; LDA #1
@@ -234,7 +232,7 @@ jt_fetch_bank = $C815 ; Helper: fetch from bank in A
.byte $8D, $01, $DF ; STA $DF01 - fetch physical bank byte
.byte $AD, $3D, $C8 ; LDA $C83D (resolved physical bank)
.byte $4C, $A0, $C9 ; JMP reu_setup ($C9A0)
-.byte $00,$00,$00,$00 ; Padding to $C9A0
+.byte $00,$00 ; Padding to $C9A0
;-----------------------------------------------------------------------------
; $C9A0: reu_setup - Set up REU registers for $B600 transfer at $1000
@@ -254,41 +252,32 @@ jt_fetch_bank = $C815 ; Helper: fetch from bank in A
.byte $00,$00
;-----------------------------------------------------------------------------
-; $C9C0: set_bitmap - Set bit for bank in A in reu_bitmap ($C836-$C838)
-;-----------------------------------------------------------------------------
-.byte $C9, $18 ; CMP #$18 (only banks 0-23 are tracked)
-.byte $B0, $17 ; BCS done
-.byte $AA ; TAX - preserve full bank
-.byte $29, $07 ; AND #$07 - bit index within byte
-.byte $A8 ; TAY - Y = bit index
-.byte $8A ; TXA - restore full bank
-.byte $4A ; LSR A
-.byte $4A ; LSR A
-.byte $4A ; LSR A
-.byte $AA ; TAX - X = byte offset 0..2
-.byte $A9, $01 ; LDA #$01
-.byte $88 ; DEY
-.byte $30, $03 ; BMI store_bit
-.byte $0A ; ASL A
-.byte $10, $FA ; BPL shift_loop
-.byte $1D, $36, $C8 ; ORA $C836,X
-.byte $9D, $36, $C8 ; STA $C836,X
-.byte $60 ; RTS
-.byte $00,$00,$00,$00
-
-;-----------------------------------------------------------------------------
-; $C9E0: log_byte - Write debug marker to buffer at $C980
+; $C9C0: mark_loaded - Commit token status after a successful snapshot stash
+; A = logical token. Status $07 means valid, loaded, and resumable.
;-----------------------------------------------------------------------------
-.byte $48 ; PHA - save the byte to log
-.byte $8E, $FC, $00 ; STX $00FC - save X to ZP temp
-.byte $AE, $3A, $C8 ; LDX $C83A - get log_index
-.byte $68 ; PLA - get byte back
-.byte $9D, $80, $C9 ; STA $C980,X - write to buffer
-.byte $E8 ; INX - increment index
-.byte $E0, $20 ; CPX #$20 - wrap at 32
-.byte $D0, $02 ; BNE +2 (skip reset)
-.byte $A2, $00 ; LDX #$00 - reset to 0
-.byte $8E, $3A, $C8 ; STX $C83A - store new index
-.byte $AE, $FC, $00 ; LDX $00FC - restore X
+.byte $8D, $3E, $C8 ; STA $C83E (preserve token)
+.byte $A9, $07 ; LDA #VALID|LOADED|RESUMABLE
+.byte $8D, $3D, $C8 ; STA $C83D
+.byte $A9, $3D ; C64 source = $C83D
+.byte $8D, $02, $DF
+.byte $A9, $C8
+.byte $8D, $03, $DF
+.byte $AD, $3E, $C8 ; token
+.byte $18 ; CLC
+.byte $69, $40 ; + <$B840 (token status table)
+.byte $8D, $04, $DF
+.byte $A9, $B8 ; >$B840
+.byte $69, $00 ; include low-byte carry
+.byte $8D, $05, $DF
+.byte $AD, $3B, $C8 ; ReadyOS physical bank
+.byte $8D, $06, $DF
+.byte $A9, $01 ; one byte
+.byte $8D, $07, $DF
+.byte $A9, $00
+.byte $8D, $08, $DF
+.byte $A9, $90 ; STASH C64 byte to ReadyOS bank
+.byte $8D, $01, $DF
+.byte $AD, $3E, $C8 ; preserve caller-visible token in A
.byte $60 ; RTS
-.byte $00,$00,$00,$00,$00,$00,$00
+.byte $00,$00,$00,$00 ; reserved through $C9FE
+.byte $60 ; $C9FF: compatibility no-op RTS
diff --git a/src/generated/build_version.h b/src/generated/build_version.h
index 38d9901..297ac57 100644
--- a/src/generated/build_version.h
+++ b/src/generated/build_version.h
@@ -2,10 +2,10 @@
#ifndef READYOS_BUILD_VERSION_H
#define READYOS_BUILD_VERSION_H
-#define READYOS_VERSION_BASE "0.2.4"
-#define READYOS_VERSION_SUFFIX ""
-#define READYOS_VERSION_TEXT "0.2.4"
-#define READYOS_TITLE_TEXT "READY OS v0.2.4"
-#define READYOS_BOOT_VERSION_TEXT "v0.2.4"
+#define READYOS_VERSION_BASE "0.2.5"
+#define READYOS_VERSION_SUFFIX "Y"
+#define READYOS_VERSION_TEXT "0.2.5Y"
+#define READYOS_TITLE_TEXT "READY OS v0.2.5Y"
+#define READYOS_BOOT_VERSION_TEXT "v0.2.5Y"
#endif /* READYOS_BUILD_VERSION_H */
diff --git a/src/generated/easyflash_layout.inc b/src/generated/easyflash_layout.inc
index b4691f6..56df67f 100644
--- a/src/generated/easyflash_layout.inc
+++ b/src/generated/easyflash_layout.inc
@@ -6,45 +6,45 @@ READYOS_REU_BANK_SKIP = 32
EASYFLASH_LAUNCHER_BANK = 1
EASYFLASH_LAUNCHER_BANK_SPAN = 2
EASYFLASH_LAUNCHER_LOAD_ADDR = $1000
-EASYFLASH_LAUNCHER_PAYLOAD_LEN = $6928
-EASYFLASH_LAUNCHER_CHECKSUM16 = $A655
-READYSHELL_CACHE_BANK = $37
-READYSHELL_CACHE_BANK2 = $38
-READYSHELL_CACHE_BANK3 = $39
-READYSHELL_STATE_BANK = $3A
+EASYFLASH_LAUNCHER_PAYLOAD_LEN = $6961
+EASYFLASH_LAUNCHER_CHECKSUM16 = $74EE
+READYSHELL_CACHE_BANK = $36
+READYSHELL_CACHE_BANK2 = $37
+READYSHELL_CACHE_BANK3 = $38
+READYSHELL_STATE_BANK = $39
READYSHELL_OVERLAY_STAGE_ADDR = $1000
READYSHELL_OVERLAY_META_OFF = $80F0
easyflash_app_table:
- .byte 1, 3, 2, <$1000, >$1000, <$605B, >$605B, <$0F67, >$0F67
- .byte 2, 5, 2, <$1000, >$1000, <$6CE7, >$6CE7, <$44B2, >$44B2
- .byte 3, 7, 2, <$1000, >$1000, <$7377, >$7377, <$B029, >$B029
- .byte 4, 9, 2, <$1000, >$1000, <$7ABA, >$7ABA, <$D890, >$D890
- .byte 5, 11, 2, <$1000, >$1000, <$5200, >$5200, <$05EE, >$05EE
- .byte 6, 13, 2, <$1000, >$1000, <$7FC1, >$7FC1, <$B972, >$B972
- .byte 7, 15, 2, <$1000, >$1000, <$7A1F, >$7A1F, <$0C8B, >$0C8B
- .byte 8, 17, 2, <$1000, >$1000, <$420D, >$420D, <$A4DB, >$A4DB
- .byte 9, 19, 1, <$1000, >$1000, <$3FA6, >$3FA6, <$1E9B, >$1E9B
- .byte 10, 20, 2, <$1000, >$1000, <$7A95, >$7A95, <$D7EC, >$D7EC
- .byte 11, 22, 3, <$1000, >$1000, <$9475, >$9475, <$3706, >$3706
- .byte 12, 25, 1, <$1000, >$1000, <$34E5, >$34E5, <$C836, >$C836
- .byte 13, 26, 3, <$1000, >$1000, <$88E3, >$88E3, <$4F31, >$4F31
- .byte 14, 29, 2, <$1000, >$1000, <$41A9, >$41A9, <$A519, >$A519
- .byte 15, 31, 1, <$1000, >$1000, <$3C26, >$3C26, <$EAAB, >$EAAB
- .byte 16, 32, 2, <$1000, >$1000, <$4EB5, >$4EB5, <$DCB5, >$DCB5
- .byte 17, 34, 3, <$1000, >$1000, <$961F, >$961F, <$89AA, >$89AA
- .byte 18, 37, 1, <$1000, >$1000, <$3BF4, >$3BF4, <$FDCC, >$FDCC
- .byte 19, 38, 2, <$1000, >$1000, <$587E, >$587E, <$2696, >$2696
- .byte 20, 40, 2, <$1000, >$1000, <$5534, >$5534, <$BC71, >$BC71
- .byte 21, 42, 2, <$1000, >$1000, <$5D89, >$5D89, <$7DBA, >$7DBA
+ .byte 1, 33, 3, 2, <$1000, >$1000, <$5FC6, >$5FC6, <$3ECE, >$3ECE
+ .byte 2, 34, 5, 2, <$1000, >$1000, <$6D85, >$6D85, <$0951, >$0951
+ .byte 3, 35, 7, 2, <$1000, >$1000, <$743B, >$743B, <$D69E, >$D69E
+ .byte 4, 36, 9, 2, <$1000, >$1000, <$78AD, >$78AD, <$DD02, >$DD02
+ .byte 5, 37, 11, 2, <$1000, >$1000, <$7000, >$7000, <$A3B5, >$A3B5
+ .byte 6, 38, 13, 2, <$1000, >$1000, <$7F68, >$7F68, <$25D9, >$25D9
+ .byte 7, 39, 15, 2, <$1000, >$1000, <$7A23, >$7A23, <$ED56, >$ED56
+ .byte 8, 40, 17, 1, <$1000, >$1000, <$3B2F, >$3B2F, <$8AAF, >$8AAF
+ .byte 9, 41, 18, 1, <$1000, >$1000, <$3F67, >$3F67, <$D74B, >$D74B
+ .byte 10, 42, 19, 2, <$1000, >$1000, <$7A15, >$7A15, <$F75B, >$F75B
+ .byte 11, 43, 21, 3, <$1000, >$1000, <$9291, >$9291, <$3E67, >$3E67
+ .byte 12, 44, 24, 1, <$1000, >$1000, <$3227, >$3227, <$682F, >$682F
+ .byte 13, 45, 25, 3, <$1000, >$1000, <$8886, >$8886, <$FC4B, >$FC4B
+ .byte 14, 46, 28, 2, <$1000, >$1000, <$41F4, >$41F4, <$B21B, >$B21B
+ .byte 15, 47, 30, 1, <$1000, >$1000, <$3CB7, >$3CB7, <$9E1A, >$9E1A
+ .byte 16, 48, 31, 2, <$1000, >$1000, <$4F00, >$4F00, <$4D00, >$4D00
+ .byte 17, 49, 33, 3, <$1000, >$1000, <$971D, >$971D, <$AFDE, >$AFDE
+ .byte 18, 50, 36, 2, <$1000, >$1000, <$55A9, >$55A9, <$EEA1, >$EEA1
+ .byte 19, 51, 38, 2, <$1000, >$1000, <$583F, >$583F, <$0D14, >$0D14
+ .byte 20, 52, 40, 2, <$1000, >$1000, <$5401, >$5401, <$432B, >$432B
+ .byte 21, 53, 42, 2, <$1000, >$1000, <$5E57, >$5E57, <$300D, >$300D
easyflash_overlay_table:
- .byte 44, 1, <$8E00, >$8E00, <$32CD, >$32CD, <$937F, >$937F, 55, <$0000, >$0000, 1
- .byte 45, 1, <$8E00, >$8E00, <$36CC, >$36CC, <$63E0, >$63E0, 55, <$3800, >$3800, 2
- .byte 46, 1, <$8E00, >$8E00, <$2BFA, >$2BFA, <$2919, >$2919, 55, <$7000, >$7000, 4
- .byte 47, 1, <$8E00, >$8E00, <$2E76, >$2E76, <$6010, >$6010, 56, <$0000, >$0000, 8
- .byte 48, 1, <$8E00, >$8E00, <$2809, >$2809, <$BE1D, >$BE1D, 55, <$A800, >$A800, 16
- .byte 49, 1, <$8E00, >$8E00, <$37F5, >$37F5, <$AA53, >$AA53, 56, <$3800, >$3800, 32
- .byte 50, 1, <$8E00, >$8E00, <$1F91, >$1F91, <$1E7C, >$1E7C, 56, <$7000, >$7000, 64
- .byte 51, 1, <$8E00, >$8E00, <$19C7, >$19C7, <$7731, >$7731, 56, <$A800, >$A800, 128
- .byte 52, 1, <$8E00, >$8E00, <$07D2, >$07D2, <$0E2C, >$0E2C, 57, <$0000, >$0000, 0
+ .byte 44, 1, <$8E00, >$8E00, <$32CD, >$32CD, <$5DD5, >$5DD5, 54, <$0000, >$0000, 1
+ .byte 45, 1, <$8E00, >$8E00, <$36CC, >$36CC, <$4CA4, >$4CA4, 54, <$3800, >$3800, 2
+ .byte 46, 1, <$8E00, >$8E00, <$2BFA, >$2BFA, <$CCF9, >$CCF9, 54, <$7000, >$7000, 4
+ .byte 47, 1, <$8E00, >$8E00, <$2E76, >$2E76, <$F281, >$F281, 55, <$0000, >$0000, 8
+ .byte 48, 1, <$8E00, >$8E00, <$2809, >$2809, <$5A26, >$5A26, 54, <$A800, >$A800, 16
+ .byte 49, 1, <$8E00, >$8E00, <$37F5, >$37F5, <$4EEA, >$4EEA, 55, <$3800, >$3800, 32
+ .byte 50, 1, <$8E00, >$8E00, <$1F91, >$1F91, <$6E2C, >$6E2C, 55, <$7000, >$7000, 64
+ .byte 51, 1, <$8E00, >$8E00, <$19C7, >$19C7, <$A914, >$A914, 55, <$A800, >$A800, 128
+ .byte 52, 1, <$8E00, >$8E00, <$07D2, >$07D2, <$000D, >$000D, 56, <$0000, >$0000, 0
diff --git a/src/generated/launcher_easyflash_catalog.h b/src/generated/launcher_easyflash_catalog.h
index 6cbd64e..806add1 100644
--- a/src/generated/launcher_easyflash_catalog.h
+++ b/src/generated/launcher_easyflash_catalog.h
@@ -8,17 +8,21 @@
#define READYOS_EASYFLASH_RESOURCE_NONE 0
#define READYOS_EASYFLASH_RESOURCE_READYSHELL_OVL 1
#define READYOS_EASYFLASH_RESOURCE_READYBASIC_CORE 2
-#define READYOS_EASYFLASH_RS_CACHE_BANK1 55
-#define READYOS_EASYFLASH_RS_CACHE_BANK2 56
-#define READYOS_EASYFLASH_RS_CACHE_BANK3 57
-#define READYOS_EASYFLASH_RS_STATE_BANK 58
-#define READYOS_EASYFLASH_RB_CORE_BANK 59
-#define READYOS_EASYFLASH_RB_CODE_BANK 60
+#define READYOS_EASYFLASH_RS_CACHE_BANK1 54
+#define READYOS_EASYFLASH_RS_CACHE_BANK2 55
+#define READYOS_EASYFLASH_RS_CACHE_BANK3 56
+#define READYOS_EASYFLASH_RS_STATE_BANK 57
+#define READYOS_EASYFLASH_RB_CORE_BANK 58
+#define READYOS_EASYFLASH_RB_CODE_BANK 59
static const unsigned char readyos_easyflash_app_banks[READYOS_EASYFLASH_APP_COUNT] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21
};
+static const unsigned char readyos_easyflash_app_physical_banks[READYOS_EASYFLASH_APP_COUNT] = {
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53
+};
+
static const unsigned char readyos_easyflash_default_slots[READYOS_EASYFLASH_APP_COUNT] = {
1, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
@@ -29,7 +33,7 @@ static const unsigned char readyos_easyflash_resource_sets[READYOS_EASYFLASH_APP
#define READYOS_EASYFLASH_RS_OVERLAY_COUNT 9
static const unsigned char readyos_easyflash_rs_overlay_banks[READYOS_EASYFLASH_RS_OVERLAY_COUNT] = {
- 55, 55, 55, 56, 55, 56, 56, 56, 57
+ 54, 54, 54, 55, 54, 55, 55, 55, 56
};
static const unsigned int readyos_easyflash_rs_overlay_offsets[READYOS_EASYFLASH_RS_OVERLAY_COUNT] = {
diff --git a/src/generated/msg_version.inc b/src/generated/msg_version.inc
index eb7e7ae..229e675 100644
--- a/src/generated/msg_version.inc
+++ b/src/generated/msg_version.inc
@@ -1,5 +1,5 @@
; Auto-generated by update_build_version.py. Do not edit by hand.
msg_version:
- .byte "v0.2.4"
+ .byte "v0.2.5Y"
msg_version_end:
diff --git a/src/generated/readme_pages.c b/src/generated/readme_pages.c
index 7c46371..73fc82a 100644
--- a/src/generated/readme_pages.c
+++ b/src/generated/readme_pages.c
@@ -3,7 +3,7 @@
const char *const readme_page_line_text[README_PAGE_COUNT][README_LINES_PER_PAGE] = {
{
- "ReadyOS PRECOG 0.2.4",
+ "ReadyOS PRECOG 0.2.5",
"",
"The goal is ~Bfast app switching~B for",
"Commodore 64 Ultimate use,",
@@ -12,7 +12,7 @@ const char *const readme_page_line_text[README_PAGE_COUNT][README_LINES_PER_PAGE
"C64-class practical.",
"",
"Current snapshot:",
- "* Base release: ~B0.2.4~B",
+ "* Base release: ~B0.2.5~B",
"* Runtime target: clean behavior from",
" stock-speed C64 use up through",
"Ultimate turbo workflows",
@@ -24,17 +24,17 @@ const char *const readme_page_line_text[README_PAGE_COUNT][README_LINES_PER_PAGE
},
{
"* Development artifacts use the plain",
- " ~B0.2.4~B version stamp.",
+ " ~B0.2.5~B version stamp.",
"Local development builds may still",
"include an internal trailing letter.",
"* New since 0.1.5: ~Bquicknotes~B, ~Bsimple~B",
" ~Bfiles~B, ~Bsimple cells~B,",
"~Bsidetris~B, ~Bdeminer~B, ~Bsystem info~B, and",
"~BEasyFlash~B",
- "",
- "",
- "",
- "",
+ "* Experimental C64U direct-to-REU",
+ " disk loading exists as an opt-in",
+ "build; normal release builds retain",
+ "the portable disk loader.",
"",
"",
"",
diff --git a/src/lib/clipboard.c b/src/lib/clipboard.c
index 2c07f73..f9c14bf 100644
--- a/src/lib/clipboard.c
+++ b/src/lib/clipboard.c
@@ -1,8 +1,13 @@
-/*
- * clipboard.c - Multi-Item Clipboard Implementation
- * Uses REU banks for storage via reu_mgr
+/* RETIRED LEGACY SOURCE -- intentionally preserved, never linked.
+ *
+ * Clipboard metadata is authoritative in the ReadyOS bank at $BB40. The
+ * production implementation is split across clipboard_copy.c,
+ * clipboard_paste.c, clipboard_count.c, clipboard_admin.c, and
+ * clipboard_insert.c so applications link only the operations they use.
*/
+#if 0
+
#include "clipboard.h"
#include "reu_mgr.h"
#include
@@ -165,3 +170,5 @@ void clip_clear(void) {
memset(CLIP_TABLE, 0, CLIP_MAX_ITEMS * 8);
*CLIP_COUNT = 0;
}
+
+#endif /* retired legacy source */
diff --git a/src/lib/clipboard.h b/src/lib/clipboard.h
index edb3f55..0d06dad 100644
--- a/src/lib/clipboard.h
+++ b/src/lib/clipboard.h
@@ -6,15 +6,18 @@
#ifndef CLIPBOARD_H
#define CLIPBOARD_H
+#include "reu_control_bank.h"
+
/* Clipboard limits */
#define CLIP_MAX_ITEMS 16
/* Clipboard data types */
#define CLIP_TYPE_TEXT 1
-/* Memory-mapped clipboard state at $C700 area (persists across app switches) */
-#define CLIP_COUNT ((unsigned char*)0xC702)
-#define CLIP_TABLE ((unsigned char*)0xC710) /* 16 items x 8 bytes = 128 bytes */
+/* Authoritative clipboard metadata is in the ReadyOS bank. */
+#define CLIP_COUNT_OFF REUCB_CLIPBOARD_OFF
+#define CLIP_TABLE_OFF (REUCB_CLIPBOARD_OFF + 0x10u)
+#define CLIP_ENTRY_SIZE 8u
/* Per-item table layout (8 bytes each):
* [0] bank - REU bank holding this item's data
@@ -37,6 +40,13 @@ unsigned char clip_get_type(unsigned char index);
/* Get size of item at index */
unsigned int clip_get_size(unsigned char index);
+/* Get the physical payload bank for an item, or $FF when out of range. */
+unsigned char clip_get_bank(unsigned char index);
+
+/* Commit an already-populated payload bank as the newest clipboard item. */
+unsigned char clip_insert_bank_item(unsigned char bank, unsigned char type,
+ unsigned int size);
+
/* Paste item at index into buffer. Returns actual bytes copied. */
unsigned int clip_paste(unsigned char index, void *buffer, unsigned int maxsize);
diff --git a/src/lib/clipboard_admin.c b/src/lib/clipboard_admin.c
index e96cd70..e3e7ab6 100644
--- a/src/lib/clipboard_admin.c
+++ b/src/lib/clipboard_admin.c
@@ -4,11 +4,9 @@
#include "clipboard.h"
#include "reu_mgr.h"
+#include "reu_control_bank.h"
#include
-/* Access item entry in the table (8 bytes per item) */
-#define ITEM_ENTRY(idx) (CLIP_TABLE + ((unsigned char)(idx) * 8))
-
/* Item field offsets */
#define ITEM_BANK 0
#define ITEM_TYPE 1
@@ -16,57 +14,82 @@
#define ITEM_SIZE_HI 3
unsigned char clip_get_type(unsigned char index) {
- unsigned char *entry;
+ unsigned char entry[CLIP_ENTRY_SIZE];
- if (index >= *CLIP_COUNT) return 0;
- entry = ITEM_ENTRY(index);
+ if (index >= clip_item_count()) return 0;
+ readyos_bank_read((unsigned int)(CLIP_TABLE_OFF +
+ ((unsigned int)index * CLIP_ENTRY_SIZE)),
+ entry, CLIP_ENTRY_SIZE);
return entry[ITEM_TYPE];
}
unsigned int clip_get_size(unsigned char index) {
- unsigned char *entry;
+ unsigned char entry[CLIP_ENTRY_SIZE];
- if (index >= *CLIP_COUNT) return 0;
- entry = ITEM_ENTRY(index);
+ if (index >= clip_item_count()) return 0;
+ readyos_bank_read((unsigned int)(CLIP_TABLE_OFF +
+ ((unsigned int)index * CLIP_ENTRY_SIZE)),
+ entry, CLIP_ENTRY_SIZE);
return (unsigned int)entry[ITEM_SIZE_LO] | ((unsigned int)entry[ITEM_SIZE_HI] << 8);
}
+unsigned char clip_get_bank(unsigned char index) {
+ unsigned char entry[CLIP_ENTRY_SIZE];
+
+ if (index >= clip_item_count()) return 0xFFu;
+ readyos_bank_read((unsigned int)(CLIP_TABLE_OFF +
+ ((unsigned int)index * CLIP_ENTRY_SIZE)),
+ entry, CLIP_ENTRY_SIZE);
+ return entry[ITEM_BANK];
+}
+
void clip_delete(unsigned char index) {
- unsigned char *entry;
+ unsigned char entry[CLIP_ENTRY_SIZE];
unsigned char count;
- count = *CLIP_COUNT;
+ count = clip_item_count();
if (index >= count) return;
- entry = ITEM_ENTRY(index);
+ readyos_bank_read((unsigned int)(CLIP_TABLE_OFF +
+ ((unsigned int)index * CLIP_ENTRY_SIZE)),
+ entry, CLIP_ENTRY_SIZE);
reu_free_bank(entry[ITEM_BANK]);
- if (index < count - 1) {
- memmove(CLIP_TABLE + (unsigned int)index * 8,
- CLIP_TABLE + (unsigned int)(index + 1) * 8,
- (unsigned int)(count - index - 1) * 8);
+ while ((unsigned char)(index + 1u) < count) {
+ readyos_bank_read((unsigned int)(CLIP_TABLE_OFF +
+ ((unsigned int)(index + 1u) * CLIP_ENTRY_SIZE)),
+ entry, CLIP_ENTRY_SIZE);
+ readyos_bank_write((unsigned int)(CLIP_TABLE_OFF +
+ ((unsigned int)index * CLIP_ENTRY_SIZE)),
+ entry, CLIP_ENTRY_SIZE);
+ ++index;
}
-
- {
- unsigned char *last = ITEM_ENTRY(count - 1);
- memset(last, 0, 8);
- }
-
- *CLIP_COUNT = count - 1;
+ memset(entry, 0, sizeof(entry));
+ readyos_bank_write((unsigned int)(CLIP_TABLE_OFF +
+ ((unsigned int)(count - 1u) * CLIP_ENTRY_SIZE)),
+ entry, CLIP_ENTRY_SIZE);
+ readyos_bank_write_byte(CLIP_COUNT_OFF, (unsigned char)(count - 1u));
}
void clip_clear(void) {
unsigned char count;
unsigned char i;
- unsigned char *entry;
+ unsigned char entry[CLIP_ENTRY_SIZE];
- count = *CLIP_COUNT;
+ count = clip_item_count();
for (i = 0; i < count; ++i) {
- entry = ITEM_ENTRY(i);
+ readyos_bank_read((unsigned int)(CLIP_TABLE_OFF +
+ ((unsigned int)i * CLIP_ENTRY_SIZE)),
+ entry, CLIP_ENTRY_SIZE);
reu_free_bank(entry[ITEM_BANK]);
}
- memset(CLIP_TABLE, 0, CLIP_MAX_ITEMS * 8);
- *CLIP_COUNT = 0;
+ memset(entry, 0, sizeof(entry));
+ for (i = 0u; i < CLIP_MAX_ITEMS; ++i) {
+ readyos_bank_write((unsigned int)(CLIP_TABLE_OFF +
+ ((unsigned int)i * CLIP_ENTRY_SIZE)),
+ entry, CLIP_ENTRY_SIZE);
+ }
+ readyos_bank_write_byte(CLIP_COUNT_OFF, 0u);
}
diff --git a/src/lib/clipboard_copy.c b/src/lib/clipboard_copy.c
index e292bb9..a38c7f3 100644
--- a/src/lib/clipboard_copy.c
+++ b/src/lib/clipboard_copy.c
@@ -4,9 +4,8 @@
#include "clipboard.h"
#include "reu_mgr.h"
-#include
+#include "reu_control_bank.h"
-#define ITEM_ENTRY(idx) (CLIP_TABLE + ((unsigned char)(idx) * 8))
#define ITEM_BANK 0
#define ITEM_TYPE 1
#define ITEM_SIZE_LO 2
@@ -14,35 +13,21 @@
unsigned char clip_copy(unsigned char type, const void *data, unsigned int size) {
unsigned char bank;
- unsigned char count;
- unsigned char *entry;
bank = reu_alloc_bank(REU_CLIPBOARD);
if (bank == 0xFF) {
return 0xFF;
}
- count = *CLIP_COUNT;
- if (count >= CLIP_MAX_ITEMS) {
+ if (clip_item_count() >= CLIP_MAX_ITEMS) {
reu_free_bank(bank);
return 0xFF;
}
- if (count > 0) {
- memmove(CLIP_TABLE + 8, CLIP_TABLE, (unsigned int)count * 8);
- }
-
- entry = ITEM_ENTRY(0);
- entry[ITEM_BANK] = bank;
- entry[ITEM_TYPE] = type;
- entry[ITEM_SIZE_LO] = (unsigned char)(size & 0xFF);
- entry[ITEM_SIZE_HI] = (unsigned char)(size >> 8);
- entry[4] = 0;
- entry[5] = 0;
- entry[6] = 0;
- entry[7] = 0;
-
reu_dma_stash((unsigned int)data, bank, 0, size);
- *CLIP_COUNT = count + 1;
- return 0;
+ if (clip_insert_bank_item(bank, type, size) != 0u) {
+ reu_free_bank(bank);
+ return 0xFFu;
+ }
+ return 0u;
}
diff --git a/src/lib/clipboard_count.c b/src/lib/clipboard_count.c
index 5f506d2..0a6faf6 100644
--- a/src/lib/clipboard_count.c
+++ b/src/lib/clipboard_count.c
@@ -3,7 +3,11 @@
*/
#include "clipboard.h"
+#include "reu_control_bank.h"
unsigned char clip_item_count(void) {
- return *CLIP_COUNT;
+ unsigned char count;
+
+ count = readyos_bank_read_byte(CLIP_COUNT_OFF);
+ return (count <= CLIP_MAX_ITEMS) ? count : 0u;
}
diff --git a/src/lib/clipboard_insert.c b/src/lib/clipboard_insert.c
new file mode 100644
index 0000000..740f620
--- /dev/null
+++ b/src/lib/clipboard_insert.c
@@ -0,0 +1,39 @@
+/* clipboard_insert.c - Atomic ReadyOS-bank clipboard record insertion */
+
+#include "clipboard.h"
+#include "reu_mgr.h"
+#include
+
+#define ITEM_BANK 0
+#define ITEM_TYPE 1
+#define ITEM_SIZE_LO 2
+#define ITEM_SIZE_HI 3
+
+unsigned char clip_insert_bank_item(unsigned char bank, unsigned char type,
+ unsigned int size) {
+ unsigned char count;
+ unsigned char index;
+ unsigned char entry[CLIP_ENTRY_SIZE];
+
+ count = clip_item_count();
+ if (count >= CLIP_MAX_ITEMS) return 1u;
+ index = count;
+ while (index > 0u) {
+ readyos_bank_read((unsigned int)(CLIP_TABLE_OFF +
+ ((unsigned int)(index - 1u) * CLIP_ENTRY_SIZE)),
+ entry, CLIP_ENTRY_SIZE);
+ readyos_bank_write((unsigned int)(CLIP_TABLE_OFF +
+ ((unsigned int)index * CLIP_ENTRY_SIZE)),
+ entry, CLIP_ENTRY_SIZE);
+ --index;
+ }
+ memset(entry, 0, sizeof(entry));
+ entry[ITEM_BANK] = bank;
+ entry[ITEM_TYPE] = type;
+ entry[ITEM_SIZE_LO] = (unsigned char)size;
+ entry[ITEM_SIZE_HI] = (unsigned char)(size >> 8);
+ readyos_bank_write(CLIP_TABLE_OFF, entry, CLIP_ENTRY_SIZE);
+ /* Commit count last so interrupted copies never expose a partial record. */
+ readyos_bank_write_byte(CLIP_COUNT_OFF, (unsigned char)(count + 1u));
+ return 0u;
+}
diff --git a/src/lib/clipboard_paste.c b/src/lib/clipboard_paste.c
index a7cb89c..43658a2 100644
--- a/src/lib/clipboard_paste.c
+++ b/src/lib/clipboard_paste.c
@@ -4,22 +4,24 @@
#include "clipboard.h"
#include "reu_mgr.h"
+#include "reu_control_bank.h"
-#define ITEM_ENTRY(idx) (CLIP_TABLE + ((unsigned char)(idx) * 8))
#define ITEM_BANK 0
#define ITEM_SIZE_LO 2
#define ITEM_SIZE_HI 3
unsigned int clip_paste(unsigned char index, void *buffer, unsigned int maxsize) {
- unsigned char *entry;
+ unsigned char entry[CLIP_ENTRY_SIZE];
unsigned int size;
unsigned int copy_size;
- if (index >= *CLIP_COUNT) {
+ if (index >= clip_item_count()) {
return 0;
}
- entry = ITEM_ENTRY(index);
+ readyos_bank_read((unsigned int)(CLIP_TABLE_OFF +
+ ((unsigned int)index * CLIP_ENTRY_SIZE)),
+ entry, CLIP_ENTRY_SIZE);
size = (unsigned int)entry[ITEM_SIZE_LO] | ((unsigned int)entry[ITEM_SIZE_HI] << 8);
copy_size = (size < maxsize) ? size : maxsize;
diff --git a/src/lib/ready_os.c b/src/lib/ready_os.c
index 48eb2d6..07c125c 100644
--- a/src/lib/ready_os.c
+++ b/src/lib/ready_os.c
@@ -1,10 +1,15 @@
-/*
+/* RETIRED LEGACY SOURCE -- intentionally preserved, never linked.
+ * These speculative syscall wrappers do not describe the current $C800 shim
+ * ABI. Applications use the focused TUI/REU/resume micromodules instead.
+ *
* ready_os.c - Ready OS API Implementation
* Syscall wrappers that call into the shim
*
* For Commodore 64, compiled with CC65
*/
+#if 0
+
#include "ready_os.h"
#include
@@ -104,6 +109,8 @@ void ready_launch(const char *app_name) {
ready_deeplink(&link);
}
+#endif /* retired legacy source */
+
void ready_open_file(const char *app_name, const char *filename) {
static DeepLink link;
unsigned char len;
diff --git a/src/lib/ready_os.h b/src/lib/ready_os.h
index 739280d..d607edb 100644
--- a/src/lib/ready_os.h
+++ b/src/lib/ready_os.h
@@ -1,4 +1,7 @@
-/*
+/* RETIRED LEGACY HEADER -- intentionally preserved, never include it.
+ * Its speculative syscall names do not match the current $C800 shim ABI.
+ * See tui.h, reu_mgr.h, reu_control_bank.h, and resume_state.h instead.
+ *
* ready_os.h - Ready OS API for Applications
* Syscall wrappers and data structures for app development
*
@@ -8,6 +11,8 @@
#ifndef READY_OS_H
#define READY_OS_H
+#if 0
+
/*---------------------------------------------------------------------------
* Constants
*---------------------------------------------------------------------------*/
@@ -232,4 +237,5 @@ void ready_open_file(const char *app_name, const char *filename);
ver \
}
+#endif /* retired legacy header */
#endif /* READY_OS_H */
diff --git a/src/lib/resume_state_core.c b/src/lib/resume_state_core.c
index be9dfeb..3c15e33 100644
--- a/src/lib/resume_state_core.c
+++ b/src/lib/resume_state_core.c
@@ -39,7 +39,7 @@ static unsigned char header_is_valid(unsigned int max_len, unsigned int *out_len
if (len > max_len) {
return 0;
}
- if (len > (REU_RESUME_TAIL_SIZE - RESUME_HDR_SIZE)) {
+ if (len > (RS_RESUME_TAIL_SIZE() - RESUME_HDR_SIZE)) {
return 0;
}
@@ -77,18 +77,18 @@ unsigned char resume_try_load(void *dst, unsigned int dst_len,
if (rs_resume_schema == 0 || dst == 0 || dst_len == 0) {
return 0;
}
- if (dst_len > (REU_RESUME_TAIL_SIZE - RESUME_HDR_SIZE)) {
+ if (dst_len > (RS_RESUME_TAIL_SIZE() - RESUME_HDR_SIZE)) {
return 0;
}
- reu_dma_fetch((unsigned int)rs_resume_hdr, rs_resume_bank, REU_RESUME_OFF, RESUME_HDR_SIZE);
+ reu_dma_fetch((unsigned int)rs_resume_hdr, rs_resume_bank, RS_RESUME_OFF(), RESUME_HDR_SIZE);
if (!header_is_valid(dst_len, &stored_len, &stored_seq)) {
return 0;
}
reu_dma_fetch((unsigned int)dst,
rs_resume_bank,
- (unsigned int)(REU_RESUME_OFF + RESUME_HDR_SIZE),
+ (unsigned int)(RS_RESUME_OFF() + RESUME_HDR_SIZE),
stored_len);
rs_resume_last_seq = stored_seq;
if (out_len != 0) {
@@ -101,15 +101,15 @@ unsigned char resume_save(const void *src, unsigned int src_len) {
if (rs_resume_schema == 0 || src == 0 || src_len == 0) {
return 0;
}
- if (src_len > (REU_RESUME_TAIL_SIZE - RESUME_HDR_SIZE)) {
+ if (src_len > (RS_RESUME_TAIL_SIZE() - RESUME_HDR_SIZE)) {
return 0;
}
build_header(src_len);
reu_dma_stash((unsigned int)src,
rs_resume_bank,
- (unsigned int)(REU_RESUME_OFF + RESUME_HDR_SIZE),
+ (unsigned int)(RS_RESUME_OFF() + RESUME_HDR_SIZE),
src_len);
- reu_dma_stash((unsigned int)rs_resume_hdr, rs_resume_bank, REU_RESUME_OFF, RESUME_HDR_SIZE);
+ reu_dma_stash((unsigned int)rs_resume_hdr, rs_resume_bank, RS_RESUME_OFF(), RESUME_HDR_SIZE);
return 1;
}
diff --git a/src/lib/resume_state_ctx.c b/src/lib/resume_state_ctx.c
index 7f8c8d2..504dff1 100644
--- a/src/lib/resume_state_ctx.c
+++ b/src/lib/resume_state_ctx.c
@@ -15,7 +15,20 @@ unsigned char rs_resume_zero_hdr[RESUME_HDR_SIZE];
void resume_init_for_app(unsigned char bank, unsigned char app_id,
unsigned char schema_version) {
- rs_resume_bank = REU_LOGICAL_TO_PHYSICAL(bank);
+ unsigned char status;
+
+ if (bank == 0u) {
+ rs_resume_bank = REU_READYOS_GLOBAL_PHYSICAL();
+ } else {
+ status = readyos_bank_read_byte((unsigned int)(REUCB_TOKEN_STATUS_OFF + bank));
+ if (!(status & REUCB_TOKEN_VALID)) {
+ rs_resume_bank = 0xFFu;
+ schema_version = 0u;
+ } else {
+ rs_resume_bank = readyos_bank_read_byte(
+ (unsigned int)(REUCB_SHIM_LOOKUP_OFF + bank));
+ }
+ }
rs_resume_app_id = app_id;
rs_resume_schema = schema_version;
rs_resume_last_seq = 0;
diff --git a/src/lib/resume_state_invalidate.c b/src/lib/resume_state_invalidate.c
index 14ceaeb..e793f86 100644
--- a/src/lib/resume_state_invalidate.c
+++ b/src/lib/resume_state_invalidate.c
@@ -15,6 +15,6 @@ void resume_invalidate(void) {
for (i = 0; i < RESUME_HDR_SIZE; ++i) {
rs_resume_zero_hdr[i] = 0;
}
- reu_dma_stash((unsigned int)rs_resume_zero_hdr, rs_resume_bank, REU_RESUME_OFF, RESUME_HDR_SIZE);
+ reu_dma_stash((unsigned int)rs_resume_zero_hdr, rs_resume_bank, RS_RESUME_OFF(), RESUME_HDR_SIZE);
rs_resume_last_seq = 0;
}
diff --git a/src/lib/resume_state_priv.h b/src/lib/resume_state_priv.h
index ef21e1c..19b3726 100644
--- a/src/lib/resume_state_priv.h
+++ b/src/lib/resume_state_priv.h
@@ -6,11 +6,12 @@
#define RESUME_STATE_PRIV_H
#include "resume_state.h"
+#include "reu_control_bank.h"
-#define RESUME_MAGIC_0 'R'
-#define RESUME_MAGIC_1 'S'
-#define RESUME_MAGIC_2 'M'
-#define RESUME_MAGIC_3 '1'
+#define RESUME_MAGIC_0 0x52u /* ASCII R */
+#define RESUME_MAGIC_1 0x53u /* ASCII S */
+#define RESUME_MAGIC_2 0x4Du /* ASCII M */
+#define RESUME_MAGIC_3 0x31u /* ASCII 1 */
#define RESUME_HDR_SIZE 16
@@ -39,4 +40,12 @@ extern unsigned int rs_resume_last_seq;
extern unsigned char rs_resume_hdr[RESUME_HDR_SIZE];
extern unsigned char rs_resume_zero_hdr[RESUME_HDR_SIZE];
+/* Token 0 is the launcher snapshot in the ReadyOS bank, whose normal app tail
+ * is occupied by schema-v5 metadata. Its tiny UI resume record lives in the
+ * schema runtime block; all application tokens retain the full per-bank tail. */
+#define RS_RESUME_OFF() \
+ ((rs_resume_app_id == 0u) ? REUCB_RUNTIME_OFF : REU_RESUME_OFF)
+#define RS_RESUME_TAIL_SIZE() \
+ ((rs_resume_app_id == 0u) ? REUCB_RUNTIME_SIZE : REU_RESUME_TAIL_SIZE)
+
#endif /* RESUME_STATE_PRIV_H */
diff --git a/src/lib/resume_state_segments.c b/src/lib/resume_state_segments.c
index da23ba2..78c2852 100644
--- a/src/lib/resume_state_segments.c
+++ b/src/lib/resume_state_segments.c
@@ -39,7 +39,7 @@ static unsigned char header_is_valid(unsigned int max_len, unsigned int *out_len
if (len > max_len) {
return 0;
}
- if (len > (REU_RESUME_TAIL_SIZE - RESUME_HDR_SIZE)) {
+ if (len > (RS_RESUME_TAIL_SIZE() - RESUME_HDR_SIZE)) {
return 0;
}
@@ -129,13 +129,13 @@ unsigned char resume_save_segments(const ResumeWriteSegment *segments,
if (!write_segments_len(segments, segment_count, &payload_len)) {
return 0;
}
- if (payload_len == 0 || payload_len > (REU_RESUME_TAIL_SIZE - RESUME_HDR_SIZE)) {
+ if (payload_len == 0 || payload_len > (RS_RESUME_TAIL_SIZE() - RESUME_HDR_SIZE)) {
return 0;
}
build_header(payload_len);
- payload_off = (unsigned int)(REU_RESUME_OFF + RESUME_HDR_SIZE);
+ payload_off = (unsigned int)(RS_RESUME_OFF() + RESUME_HDR_SIZE);
for (i = 0; i < segment_count; ++i) {
if (segments[i].len == 0) {
continue;
@@ -143,7 +143,7 @@ unsigned char resume_save_segments(const ResumeWriteSegment *segments,
reu_dma_stash((unsigned int)segments[i].ptr, rs_resume_bank, payload_off, segments[i].len);
payload_off = (unsigned int)(payload_off + segments[i].len);
}
- reu_dma_stash((unsigned int)rs_resume_hdr, rs_resume_bank, REU_RESUME_OFF, RESUME_HDR_SIZE);
+ reu_dma_stash((unsigned int)rs_resume_hdr, rs_resume_bank, RS_RESUME_OFF(), RESUME_HDR_SIZE);
return 1;
}
@@ -168,11 +168,11 @@ unsigned char resume_load_segments(const ResumeReadSegment *segments,
if (!read_segments_len(segments, segment_count, &expected_len)) {
return 0;
}
- if (expected_len == 0 || expected_len > (REU_RESUME_TAIL_SIZE - RESUME_HDR_SIZE)) {
+ if (expected_len == 0 || expected_len > (RS_RESUME_TAIL_SIZE() - RESUME_HDR_SIZE)) {
return 0;
}
- reu_dma_fetch((unsigned int)rs_resume_hdr, rs_resume_bank, REU_RESUME_OFF, RESUME_HDR_SIZE);
+ reu_dma_fetch((unsigned int)rs_resume_hdr, rs_resume_bank, RS_RESUME_OFF(), RESUME_HDR_SIZE);
if (!header_is_valid(expected_len, &stored_len, &stored_seq)) {
return 0;
}
@@ -180,7 +180,7 @@ unsigned char resume_load_segments(const ResumeReadSegment *segments,
return 0;
}
- payload_off = (unsigned int)(REU_RESUME_OFF + RESUME_HDR_SIZE);
+ payload_off = (unsigned int)(RS_RESUME_OFF() + RESUME_HDR_SIZE);
for (i = 0; i < segment_count; ++i) {
if (segments[i].len == 0) {
continue;
diff --git a/src/lib/reu_control_bank.c b/src/lib/reu_control_bank.c
index c507eca..480d829 100644
--- a/src/lib/reu_control_bank.c
+++ b/src/lib/reu_control_bank.c
@@ -1,79 +1,34 @@
-/*
- * reu_control_bank.c - mirror resident REU state into logical bank 0
- */
+/* reu_control_bank.c - ReadyOS-bank schema-v5 lifecycle */
#include "reu_control_bank.h"
#include "reu_phys.h"
static unsigned char reucb_header[REUCB_HEADER_SIZE];
static unsigned char reucb_zero[REUCB_HEADER_SIZE];
-static unsigned char reucb_record[REUCB_RESOURCE_SIZE];
static unsigned char reucb_generation;
-static void reucb_zero_buf(unsigned char *buf, unsigned char len) {
+static void reucb_fill(unsigned char *buf, unsigned char value, unsigned char len) {
unsigned char i;
-
- for (i = 0; i < len; ++i) {
- buf[i] = 0;
+ for (i = 0u; i < len; ++i) {
+ buf[i] = value;
}
}
-static void reucb_mark_bitmap_slot(unsigned char logical_bank, unsigned char is_loaded) {
- unsigned char phys;
- unsigned char type;
-
- phys = REU_LOGICAL_TO_PHYSICAL(logical_bank);
- type = REU_ALLOC_TABLE[phys];
- if (type == REU_UNAVAIL) {
- return;
- }
- if (is_loaded) {
- REU_ALLOC_TABLE[phys] = REU_APP_STATE;
- } else if (type == REU_RESERVED) {
- REU_ALLOC_TABLE[phys] = REU_FREE;
- }
+unsigned char reu_control_bank_is_valid(void) {
+ readyos_bank_read(REUCB_HEADER_OFF, reucb_header, 5u);
+ return (unsigned char)(reucb_header[0] == REUCB_MAGIC0 &&
+ reucb_header[1] == REUCB_MAGIC1 &&
+ reucb_header[2] == REUCB_MAGIC2 &&
+ reucb_header[3] == REUCB_MAGIC3 &&
+ reucb_header[4] == REUCB_SCHEMA_VERSION);
}
-static void reucb_sync_from_bitmap(void) {
- unsigned char bitmap_lo = *SHIM_REU_BITMAP_LO;
- unsigned char bitmap_hi = *SHIM_REU_BITMAP_HI;
- unsigned char bitmap_xhi = *SHIM_REU_BITMAP_XHI;
- unsigned char bank;
- unsigned char mask;
- unsigned char skip = *SHIM_REU_BANK_SKIP;
-
- for (bank = 0; bank < skip; ++bank) {
- REU_ALLOC_TABLE[bank] = REU_SKIPPED;
- }
-
- REU_ALLOC_TABLE[REU_READYOS_GLOBAL_PHYSICAL()] = REU_GLOBAL;
- REU_ALLOC_TABLE[REU_LAUNCHER_PHYSICAL()] = REU_LAUNCHER;
-
- for (bank = 1; bank < 8; ++bank) {
- mask = (unsigned char)(1u << bank);
- reucb_mark_bitmap_slot(bank, (unsigned char)(bitmap_lo & mask));
- }
-
- for (bank = 0; bank < 8; ++bank) {
- mask = (unsigned char)(1u << bank);
- reucb_mark_bitmap_slot((unsigned char)(bank + 8u),
- (unsigned char)(bitmap_hi & mask));
- }
-
- for (bank = 0; bank < 8; ++bank) {
- mask = (unsigned char)(1u << bank);
- reucb_mark_bitmap_slot((unsigned char)(bank + 16u),
- (unsigned char)(bitmap_xhi & mask));
- }
-
-}
-
-static void reucb_write_header(unsigned char control_bank, unsigned char writer_id) {
- unsigned char physical_banks;
-
- reucb_zero_buf(reucb_header, REUCB_HEADER_SIZE);
- physical_banks = reu_phys_count_from_alloc_table();
+static void reucb_write_header(unsigned char writer_id,
+ unsigned char physical_banks) {
+ unsigned char readyos_bank;
+ readyos_bank = REU_READYOS_GLOBAL_PHYSICAL();
+ reucb_fill(reucb_header, 0u, REUCB_HEADER_SIZE);
reucb_header[0] = REUCB_MAGIC0;
reucb_header[1] = REUCB_MAGIC1;
reucb_header[2] = REUCB_MAGIC2;
@@ -82,123 +37,95 @@ static void reucb_write_header(unsigned char control_bank, unsigned char writer_
reucb_header[5] = REUCB_HEADER_SIZE;
reucb_header[6] = ++reucb_generation;
reucb_header[7] = writer_id;
- reucb_header[REUCB_HEADER_REU_SKIP] = *SHIM_REU_BANK_SKIP;
- reucb_header[REUCB_HEADER_CONTROL_BANK] = control_bank;
- reucb_header[REUCB_HEADER_LAUNCHER_BANK] = REU_LAUNCHER_PHYSICAL();
+ reucb_header[REUCB_HEADER_REU_SKIP] = readyos_bank;
+ reucb_header[REUCB_HEADER_CONTROL_BANK] = readyos_bank;
+ reucb_header[REUCB_HEADER_LAUNCHER_BANK] = readyos_bank;
reucb_header[REUCB_HEADER_LAUNCHER_OVL] = 0u;
reucb_header[REUCB_HEADER_FIRST_DYNAMIC] = REU_FIRST_DYNAMIC_PHYSICAL();
- reucb_header[REUCB_HEADER_LOGICAL_BANKS] = REU_TOTAL_BANKS & 0xFFu; /* 0 means 256 banks. */
- reucb_header[14] = (unsigned char)(REUCB_BANK_TYPE_OFF & 0xFFu);
+ reucb_header[REUCB_HEADER_LOGICAL_BANKS] = 0u; /* 0 encodes 256 tokens. */
+ reucb_header[14] = (unsigned char)REUCB_BANK_TYPE_OFF;
reucb_header[15] = (unsigned char)(REUCB_BANK_TYPE_OFF >> 8);
- reucb_header[16] = (unsigned char)(REUCB_BANK_TYPE_SIZE & 0xFFu);
- reucb_header[17] = (unsigned char)(REUCB_BANK_TYPE_SIZE >> 8);
- reucb_header[18] = (unsigned char)(REUCB_RESOURCE_OFF & 0xFFu);
- reucb_header[19] = (unsigned char)(REUCB_RESOURCE_OFF >> 8);
- reucb_header[20] = REUCB_RESOURCE_COUNT;
- reucb_header[21] = REUCB_RESOURCE_SIZE;
- reucb_header[22] = (unsigned char)(REUCB_APP_REG_OFF & 0xFFu);
+ reucb_header[16] = 0u; /* 0 encodes 256 bytes. */
+ reucb_header[17] = 1u;
+ reucb_header[18] = (unsigned char)REUCB_SHIM_LOOKUP_OFF;
+ reucb_header[19] = (unsigned char)(REUCB_SHIM_LOOKUP_OFF >> 8);
+ reucb_header[20] = (unsigned char)REUCB_TOKEN_STATUS_OFF;
+ reucb_header[21] = (unsigned char)(REUCB_TOKEN_STATUS_OFF >> 8);
+ reucb_header[22] = (unsigned char)REUCB_APP_REG_OFF;
reucb_header[23] = (unsigned char)(REUCB_APP_REG_OFF >> 8);
reucb_header[24] = REUCB_APP_REG_COUNT;
reucb_header[25] = REUCB_APP_REG_SIZE;
- reucb_header[26] = (unsigned char)(REUCB_APP_META_OFF & 0xFFu);
+ reucb_header[26] = (unsigned char)REUCB_APP_META_OFF;
reucb_header[27] = (unsigned char)(REUCB_APP_META_OFF >> 8);
reucb_header[28] = REUCB_APP_META_COUNT;
reucb_header[29] = REUCB_APP_META_SIZE;
- reucb_header[30] = (unsigned char)(REUCB_DEP_OFF & 0xFFu);
- reucb_header[31] = (unsigned char)(REUCB_DEP_OFF >> 8);
- reucb_header[32] = REUCB_DEP_COUNT;
- reucb_header[33] = REUCB_DEP_SIZE;
- reucb_header[34] = (unsigned char)(REUCB_AUDIT_OFF & 0xFFu);
- reucb_header[35] = (unsigned char)(REUCB_AUDIT_OFF >> 8);
- reucb_header[36] = (unsigned char)(REUCB_RSRC_REC_OFF & 0xFFu);
- reucb_header[37] = (unsigned char)(REUCB_RSRC_REC_OFF >> 8);
- reucb_header[38] = REUCB_RSRC_REC_COUNT;
- reucb_header[39] = REUCB_RSRC_REC_SIZE;
- reucb_header[40] = (unsigned char)(REUCB_DEP_LINE_OFF & 0xFFu);
- reucb_header[41] = (unsigned char)(REUCB_DEP_LINE_OFF >> 8);
- reucb_header[42] = REUCB_DEP_LINE_COUNT;
- reucb_header[43] = REUCB_DEP_LINE_SIZE;
+ reucb_header[30] = (unsigned char)REUCB_RSRC_REC_OFF;
+ reucb_header[31] = (unsigned char)(REUCB_RSRC_REC_OFF >> 8);
+ reucb_header[32] = REUCB_RSRC_REC_COUNT;
+ reucb_header[33] = REUCB_RSRC_REC_SIZE;
+ reucb_header[34] = (unsigned char)REUCB_DEP_LINE_OFF;
+ reucb_header[35] = (unsigned char)(REUCB_DEP_LINE_OFF >> 8);
+ reucb_header[36] = REUCB_DEP_LINE_COUNT;
+ reucb_header[37] = REUCB_DEP_LINE_SIZE;
+ reucb_header[38] = (unsigned char)REUCB_CLIPBOARD_OFF;
+ reucb_header[39] = (unsigned char)(REUCB_CLIPBOARD_OFF >> 8);
+ reucb_header[40] = (unsigned char)REUCB_HOTKEY_OFF;
+ reucb_header[41] = (unsigned char)(REUCB_HOTKEY_OFF >> 8);
+ reucb_header[42] = (unsigned char)REUCB_RUNTIME_OFF;
+ reucb_header[43] = (unsigned char)(REUCB_RUNTIME_OFF >> 8);
reucb_header[REUCB_HEADER_PHYS_BANKS] = physical_banks;
reucb_header[REUCB_HEADER_FIRST_UNAVAIL] = physical_banks;
reucb_header[REUCB_HEADER_FLAGS] = REUCB_HEADER_FLAG_PHYS_SIZE;
-
- reu_dma_stash((unsigned int)reucb_header, control_bank,
- REUCB_HEADER_OFF, REUCB_HEADER_SIZE);
+ readyos_bank_write(REUCB_HEADER_OFF, reucb_header, REUCB_HEADER_SIZE);
}
-static void reucb_write_resource(unsigned char control_bank,
- unsigned char index,
- unsigned char bank,
- unsigned char type,
- unsigned char owner,
- unsigned char role) {
- reucb_zero_buf(reucb_record, REUCB_RESOURCE_SIZE);
- reucb_record[0] = bank;
- reucb_record[1] = type;
- reucb_record[2] = owner;
- reucb_record[3] = 0;
- reucb_record[4] = role;
- reucb_record[5] = 0;
- reucb_record[6] = 0;
- reucb_record[7] = 0;
-
- reu_dma_stash((unsigned int)reucb_record, control_bank,
- (unsigned int)(REUCB_RESOURCE_OFF +
- ((unsigned int)index * REUCB_RESOURCE_SIZE)),
- REUCB_RESOURCE_SIZE);
-}
-
-static void reucb_write_resources(unsigned char control_bank) {
- reucb_write_resource(control_bank, 0, REU_READYOS_GLOBAL_PHYSICAL(),
- REU_GLOBAL, REUCB_OWNER_SYSTEM, REUCB_ROLE_GLOBAL);
- reucb_write_resource(control_bank, 1, REU_LAUNCHER_PHYSICAL(),
- REU_LAUNCHER, REUCB_OWNER_LAUNCHER, REUCB_ROLE_SNAPSHOT);
- reucb_write_resource(control_bank, 2, 0,
- REU_FREE, 0, 0);
- reucb_write_resource(control_bank, 6, 0,
- REU_FREE, 0, 0);
- reucb_write_resource(control_bank, 7, 0,
- REU_FREE, 0, 0);
- reucb_write_resource(control_bank, 8, 0,
- REU_FREE, 0, 0);
- reucb_write_resource(control_bank, 9, 0,
- REU_FREE, 0, 0);
-}
-
-static void reucb_write_shim_lookup(unsigned char control_bank) {
- unsigned int start;
- unsigned char i;
- unsigned int physical;
- unsigned char skip = *SHIM_REU_BANK_SKIP;
+void reu_control_bank_prepare(unsigned char physical_banks) {
+ unsigned char valid;
+ unsigned char bank;
+ unsigned char type;
+ unsigned int off;
+
+ valid = reu_control_bank_is_valid();
+ if (!valid) {
+ reucb_fill(reucb_zero, 0u, REUCB_HEADER_SIZE);
+ off = REUCB_HEADER_OFF;
+ do {
+ readyos_bank_write(off, reucb_zero, REUCB_HEADER_SIZE);
+ off = (unsigned int)(off + REUCB_HEADER_SIZE);
+ } while (off != 0u);
+ }
- for (start = 0; start < REUCB_SHIM_LOOKUP_SIZE; start += REUCB_HEADER_SIZE) {
- for (i = 0; i < REUCB_HEADER_SIZE; ++i) {
- if (start == 0u && i == 0u) {
- reucb_zero[i] = 0u;
- } else {
- physical = (unsigned int)skip + 1u + start + i;
- reucb_zero[i] = (physical > 255u) ? 0u : (unsigned char)physical;
+ bank = 0u;
+ do {
+ if (bank == REU_READYOS_GLOBAL_PHYSICAL()) {
+ type = REU_GLOBAL;
+ } else if (bank < REU_FIRST_DYNAMIC_PHYSICAL()) {
+ type = REU_SKIPPED;
+ } else if (reu_phys_is_unavailable(physical_banks, bank)) {
+ type = REU_UNAVAIL;
+ } else if (!valid) {
+ type = REU_FREE;
+ } else {
+ type = readyos_bank_read_byte((unsigned int)(REUCB_BANK_TYPE_OFF + bank));
+ if (type == REU_SKIPPED || type == REU_GLOBAL ||
+ type == REU_LAUNCHER || type == REU_UNAVAIL) {
+ type = REU_FREE;
}
}
- reu_dma_stash((unsigned int)reucb_zero, control_bank,
- (unsigned int)(REUCB_SHIM_LOOKUP_OFF + start),
- REUCB_HEADER_SIZE);
- }
+ readyos_bank_write_byte((unsigned int)(REUCB_BANK_TYPE_OFF + bank), type);
+ ++bank;
+ } while (bank != 0u);
+
+ reucb_write_header(REUCB_WRITER_LAUNCHER, physical_banks);
}
void reu_control_bank_sync_and_mirror(unsigned char writer_id) {
- unsigned char control_bank = REU_READYOS_GLOBAL_PHYSICAL();
-
- reucb_sync_from_bitmap();
- reucb_write_header(control_bank, writer_id);
-
- reucb_zero_buf(reucb_zero, REUCB_HEADER_SIZE);
- reu_dma_stash((unsigned int)reucb_zero, control_bank, 0x0040u, REUCB_HEADER_SIZE);
- reu_dma_stash((unsigned int)reucb_zero, control_bank, 0x0080u, REUCB_HEADER_SIZE);
- reu_dma_stash((unsigned int)reucb_zero, control_bank, 0x00C0u, REUCB_HEADER_SIZE);
+ unsigned char physical_banks;
- reu_dma_stash((unsigned int)REU_ALLOC_TABLE, control_bank,
- REUCB_BANK_TYPE_OFF, REUCB_BANK_TYPE_SIZE);
- reucb_write_resources(control_bank);
- reucb_write_shim_lookup(control_bank);
+ physical_banks = readyos_bank_read_byte((unsigned int)(REUCB_HEADER_OFF +
+ REUCB_HEADER_PHYS_BANKS));
+ readyos_bank_write_byte((unsigned int)(REUCB_BANK_TYPE_OFF +
+ REU_READYOS_GLOBAL_PHYSICAL()),
+ REU_GLOBAL);
+ reucb_write_header(writer_id, physical_banks);
}
diff --git a/src/lib/reu_control_bank.h b/src/lib/reu_control_bank.h
index dbd69b1..fdb77e2 100644
--- a/src/lib/reu_control_bank.h
+++ b/src/lib/reu_control_bank.h
@@ -1,8 +1,9 @@
/*
- * reu_control_bank.h - ReadyOS logical REU bank 0 control mirror
+ * reu_control_bank.h - ReadyOS bank schema and registry API
*
- * This is intentionally small. Early refactor phases mirror existing
- * resident state into bank 0; they do not make bank 0 runtime authority.
+ * Physical REU bank Skip is the ReadyOS bank. It contains the launcher
+ * snapshot at $0000-$B5FF and the authoritative ReadyOS metadata at
+ * $B600-$FFFF. There is no C64-RAM allocation/loaded-state mirror.
*/
#ifndef REU_CONTROL_BANK_H
@@ -10,46 +11,79 @@
#include "reu_mgr.h"
-#define REUCB_SCHEMA_VERSION 4
+#define REUCB_SCHEMA_VERSION 5
-#define REUCB_MAGIC0 'R'
-#define REUCB_MAGIC1 'C'
-#define REUCB_MAGIC2 'B'
-#define REUCB_MAGIC3 '0'
+/* Binary ABI bytes, deliberately numeric: cc65 translates character literals
+ * through the target character set (uppercase letters become PETSCII $C1+). */
+#define REUCB_MAGIC0 0x52u /* ASCII R */
+#define REUCB_MAGIC1 0x43u /* ASCII C */
+#define REUCB_MAGIC2 0x42u /* ASCII B */
+#define REUCB_MAGIC3 0x35u /* ASCII 5 */
-#define REUCB_HEADER_OFF 0x0000u
+#define REUCB_LAUNCHER_SNAPSHOT_OFF 0x0000u
+#define REUCB_LAUNCHER_SNAPSHOT_SIZE 0xB600u
+
+#define REUCB_HEADER_OFF 0xB600u
#define REUCB_HEADER_SIZE 0x0040u
-#define REUCB_RESERVED_OFF 0x0040u
-#define REUCB_BANK_TYPE_OFF 0x0100u
+#define REUCB_BANK_TYPE_OFF 0xB640u
#define REUCB_BANK_TYPE_SIZE 0x0100u
-#define REUCB_RESOURCE_OFF 0x0200u
-#define REUCB_RESOURCE_SIZE 8u
-#define REUCB_RESOURCE_COUNT 10u
-#define REUCB_APP_REG_OFF 0x0300u
-#define REUCB_APP_REG_SIZE 8u
+#define REUCB_SHIM_LOOKUP_OFF 0xB740u
+#define REUCB_SHIM_LOOKUP_SIZE 0x0100u
+#define REUCB_TOKEN_STATUS_OFF 0xB840u
+#define REUCB_TOKEN_STATUS_SIZE 0x0100u
+#define REUCB_CLIPBOARD_OFF 0xB940u
+#define REUCB_CLIPBOARD_SIZE 0x0090u
+#define REUCB_HOTKEY_OFF 0xB9D0u
+#define REUCB_HOTKEY_SIZE 9u
+#define REUCB_SETTINGS_OFF 0xB9D9u
+#define REUCB_SETTINGS_SIZE 39u
+#define REUCB_SETTINGS_MAGIC0 0x4Cu /* ASCII L */
+#define REUCB_SETTINGS_MAGIC1 0x53u /* ASCII S */
+#define REUCB_SETTINGS_VERSION 1u
+#define REUCB_SETTINGS_OFF_MAGIC0 0u
+#define REUCB_SETTINGS_OFF_MAGIC1 1u
+#define REUCB_SETTINGS_OFF_VERSION 2u
+#define REUCB_SETTINGS_OFF_FIRST_APP 3u
+#define REUCB_SETTINGS_OFF_APP_COUNT 4u
+#define REUCB_SETTINGS_OFF_LOAD_ALL 5u
+#define REUCB_SETTINGS_OFF_VARIANT 6u
+#define REUCB_SETTINGS_VARIANT_SIZE 32u
+#define REUCB_APP_REG_OFF 0xBA00u
+#define REUCB_APP_REG_SIZE 16u
#define REUCB_APP_REG_COUNT 64u
-#define REUCB_APP_META_OFF 0x0500u
+#define REUCB_TOKEN_APP_OFF 0xBE00u
+#define REUCB_TOKEN_APP_SIZE 0x0100u
+#define REUCB_APP_META_OFF 0xBF00u
#define REUCB_APP_META_SIZE 13u
#define REUCB_APP_META_COUNT 64u
-#define REUCB_DEP_OFF 0x0900u
-#define REUCB_DEP_SIZE 24u
-#define REUCB_DEP_COUNT 128u
-#define REUCB_RSRC_REC_OFF 0x0A00u
+#define REUCB_RSRC_REC_OFF 0xC240u
#define REUCB_RSRC_REC_SIZE 16u
#define REUCB_RSRC_REC_COUNT 64u
-#define REUCB_DEP_LINE_OFF 0x0E00u
+#define REUCB_DEP_LINE_OFF 0xC640u
#define REUCB_DEP_LINE_SIZE 128u
#define REUCB_DEP_LINE_COUNT 64u
-#define REUCB_AUDIT_OFF 0x2E00u
-#define REUCB_SHIM_LOOKUP_OFF 0x2F00u
-#define REUCB_SHIM_LOOKUP_SIZE 256u
-#define REUCB_CATALOG_TEXT_OFF 0x3000u
-#define REUCB_CATALOG_NAME_OFF 0x3000u
+#define REUCB_CATALOG_TEXT_OFF 0xE640u
+#define REUCB_CATALOG_NAME_OFF 0xE640u
#define REUCB_CATALOG_NAME_SIZE 32u
-#define REUCB_CATALOG_DESC_OFF 0x3800u
+#define REUCB_CATALOG_DESC_OFF 0xEE40u
#define REUCB_CATALOG_DESC_SIZE 39u
-#define REUCB_CATALOG_FILE_OFF 0x4200u
+#define REUCB_CATALOG_FILE_OFF 0xF800u
#define REUCB_CATALOG_FILE_SIZE 13u
+#define REUCB_AUDIT_OFF 0xFB40u
+#define REUCB_AUDIT_SIZE 0x0100u
+#define REUCB_RUNTIME_OFF 0xFC40u
+#define REUCB_RUNTIME_SIZE 0x0080u
+#define REUCB_RESERVED_OFF 0xFCC0u
+#define REUCB_RESERVED_SIZE 0x0340u
+
+/* Compatibility names for code which treats the app-record resource fields
+ * as dependency slots. Schema v5 stores those bytes in each app record. */
+#define REUCB_DEP_OFF REUCB_APP_REG_OFF
+#define REUCB_DEP_SIZE REUCB_APP_REG_SIZE
+#define REUCB_DEP_COUNT REUCB_APP_REG_COUNT
+#define REUCB_RESOURCE_OFF REUCB_RSRC_REC_OFF
+#define REUCB_RESOURCE_SIZE REUCB_RSRC_REC_SIZE
+#define REUCB_RESOURCE_COUNT REUCB_RSRC_REC_COUNT
#define REUCB_HEADER_REU_SKIP 8u
#define REUCB_HEADER_CONTROL_BANK 9u
@@ -62,6 +96,25 @@
#define REUCB_HEADER_FLAGS 46u
#define REUCB_HEADER_FLAG_PHYS_SIZE 0x01u
+#define REUCB_TOKEN_VALID 0x01u
+#define REUCB_TOKEN_LOADED 0x02u
+#define REUCB_TOKEN_RESUMABLE 0x04u
+
+#define REUCB_APP_REC_TOKEN 0u
+#define REUCB_APP_REC_PHYSICAL 1u
+#define REUCB_APP_REC_FLAGS 2u
+#define REUCB_APP_REC_DRIVE 3u
+#define REUCB_APP_REC_HOTKEY 4u
+#define REUCB_APP_REC_RSRC_SET 5u
+#define REUCB_APP_REC_RSRC_READY 6u
+#define REUCB_APP_REC_FIRST_RSRC 7u
+#define REUCB_APP_REC_RSRC1 8u
+#define REUCB_APP_REC_RSRC2 9u
+#define REUCB_APP_REC_RSRC3 10u
+#define REUCB_APP_REC_RSRC4 11u
+#define REUCB_APP_REC_SIZE_LO 12u
+#define REUCB_APP_REC_SIZE_HI 13u
+
#define REUCB_NULL_DEP 0xFFu
#define REUCB_NULL_REC 0xFFu
@@ -93,6 +146,8 @@
#define REUCB_ROLE_CODE 8u
void reu_control_bank_sync_and_mirror(unsigned char writer_id);
+void reu_control_bank_prepare(unsigned char physical_banks);
+unsigned char reu_control_bank_is_valid(void);
void reu_control_bank_write_launcher_registry(
unsigned char first_app_index,
@@ -106,6 +161,7 @@ void reu_control_bank_write_launcher_registry(
const unsigned char *app_rs_bank2,
const unsigned char *app_rs_bank3,
const unsigned char *app_rs_bank4,
- const unsigned char *apps_loaded);
+ const unsigned char *apps_loaded,
+ const unsigned int *app_sizes);
#endif /* REU_CONTROL_BANK_H */
diff --git a/src/lib/reu_control_registry.c b/src/lib/reu_control_registry.c
index 78a8324..b1db51e 100644
--- a/src/lib/reu_control_registry.c
+++ b/src/lib/reu_control_registry.c
@@ -1,13 +1,18 @@
-/*
- * reu_control_registry.c - launcher-only long-form bank 0 registry writer
- *
- * Keep this intentionally plain: bank 0 stores normalized launcher arrays in
- * separate blocks so future tools can copy just the hot subset they need.
- */
+/* reu_control_registry.c - launcher publication into schema-v5 app records */
#include "reu_control_bank.h"
-#define REUCB_APP_ARRAY_LEN 64u
+static unsigned char registry_record[REUCB_APP_REG_SIZE];
+static unsigned char registry_phys[REUCB_APP_REG_COUNT];
+static unsigned char registry_status[REUCB_APP_REG_COUNT];
+static unsigned char registry_fill[64];
+
+static void registry_fill_buf(unsigned char value) {
+ unsigned char i;
+ for (i = 0u; i < 64u; ++i) {
+ registry_fill[i] = value;
+ }
+}
void reu_control_bank_write_launcher_registry(
unsigned char first_app_index,
@@ -21,30 +26,79 @@ void reu_control_bank_write_launcher_registry(
const unsigned char *app_rs_bank2,
const unsigned char *app_rs_bank3,
const unsigned char *app_rs_bank4,
- const unsigned char *apps_loaded) {
- unsigned char control_bank = REU_READYOS_GLOBAL_PHYSICAL();
-
- (void)app_count;
-
- reu_dma_stash((unsigned int)(app_banks + first_app_index), control_bank,
- REUCB_APP_REG_OFF, REUCB_APP_ARRAY_LEN);
- reu_dma_stash((unsigned int)(apps_loaded + first_app_index), control_bank,
- REUCB_APP_REG_OFF + 0x0040u, REUCB_APP_ARRAY_LEN);
- reu_dma_stash((unsigned int)(app_resource_sets + first_app_index), control_bank,
- REUCB_APP_REG_OFF + 0x0080u, REUCB_APP_ARRAY_LEN);
- reu_dma_stash((unsigned int)(app_resource_loaded + first_app_index), control_bank,
- REUCB_APP_REG_OFF + 0x00C0u, REUCB_APP_ARRAY_LEN);
- reu_dma_stash((unsigned int)(app_drives + first_app_index), control_bank,
- REUCB_APP_REG_OFF + 0x0100u, REUCB_APP_ARRAY_LEN);
- reu_dma_stash((unsigned int)(app_default_slots + first_app_index), control_bank,
- REUCB_APP_REG_OFF + 0x0140u, REUCB_APP_ARRAY_LEN);
-
- reu_dma_stash((unsigned int)(app_rs_bank1 + first_app_index), control_bank,
- REUCB_DEP_OFF, REUCB_APP_ARRAY_LEN);
- reu_dma_stash((unsigned int)(app_rs_bank2 + first_app_index), control_bank,
- REUCB_DEP_OFF + 0x0040u, REUCB_APP_ARRAY_LEN);
- reu_dma_stash((unsigned int)(app_rs_bank3 + first_app_index), control_bank,
- REUCB_DEP_OFF + 0x0080u, REUCB_APP_ARRAY_LEN);
- reu_dma_stash((unsigned int)(app_rs_bank4 + first_app_index), control_bank,
- REUCB_DEP_OFF + 0x00C0u, REUCB_APP_ARRAY_LEN);
+ const unsigned char *apps_loaded,
+ const unsigned int *app_sizes) {
+ unsigned char i;
+ unsigned char j;
+ unsigned char app_id;
+ unsigned char token;
+ unsigned char status;
+
+ for (i = 0u; i < REUCB_APP_REG_COUNT; ++i) {
+ registry_phys[i] = 0u;
+ registry_status[i] = 0u;
+ }
+ for (i = first_app_index; i < app_count; ++i) {
+ app_id = (unsigned char)(i - first_app_index);
+ token = app_banks[i];
+ if (token != 0u && app_id < REUCB_APP_REG_COUNT) {
+ registry_phys[app_id] = readyos_bank_read_byte(
+ (unsigned int)(REUCB_SHIM_LOOKUP_OFF + token));
+ registry_status[app_id] = readyos_bank_read_byte(
+ (unsigned int)(REUCB_TOKEN_STATUS_OFF + token));
+ }
+ }
+
+ registry_fill_buf(0u);
+ for (j = 0u; j < 4u; ++j) {
+ readyos_bank_write((unsigned int)(REUCB_TOKEN_STATUS_OFF +
+ ((unsigned int)j * 64u)),
+ registry_fill, 64u);
+ }
+ registry_fill_buf(REUCB_NULL_REC);
+ for (j = 0u; j < 4u; ++j) {
+ readyos_bank_write((unsigned int)(REUCB_TOKEN_APP_OFF +
+ ((unsigned int)j * 64u)),
+ registry_fill, 64u);
+ }
+
+ for (i = first_app_index; i < app_count; ++i) {
+ app_id = (unsigned char)(i - first_app_index);
+ if (app_id >= REUCB_APP_REG_COUNT) {
+ break;
+ }
+ token = app_banks[i];
+ for (j = 0u; j < REUCB_APP_REG_SIZE; ++j) {
+ registry_record[j] = 0u;
+ }
+ registry_record[REUCB_APP_REC_TOKEN] = token;
+ registry_record[REUCB_APP_REC_PHYSICAL] = registry_phys[app_id];
+ registry_record[REUCB_APP_REC_FLAGS] = apps_loaded[i] ? REUCB_APP_FLAG_LOADED : 0u;
+ registry_record[REUCB_APP_REC_DRIVE] = app_drives[i];
+ registry_record[REUCB_APP_REC_HOTKEY] = app_default_slots[i];
+ registry_record[REUCB_APP_REC_RSRC_SET] = app_resource_sets[i];
+ registry_record[REUCB_APP_REC_RSRC_READY] = app_resource_loaded[i];
+ registry_record[REUCB_APP_REC_FIRST_RSRC] = REUCB_NULL_REC;
+ registry_record[REUCB_APP_REC_RSRC1] = app_rs_bank1[i];
+ registry_record[REUCB_APP_REC_RSRC2] = app_rs_bank2[i];
+ registry_record[REUCB_APP_REC_RSRC3] = app_rs_bank3[i];
+ registry_record[REUCB_APP_REC_RSRC4] = app_rs_bank4[i];
+ registry_record[REUCB_APP_REC_SIZE_LO] = (unsigned char)app_sizes[i];
+ registry_record[REUCB_APP_REC_SIZE_HI] = (unsigned char)(app_sizes[i] >> 8);
+ readyos_bank_write((unsigned int)(REUCB_APP_REG_OFF +
+ ((unsigned int)app_id * REUCB_APP_REG_SIZE)),
+ registry_record, REUCB_APP_REG_SIZE);
+
+ if (token != 0u && (registry_status[app_id] & REUCB_TOKEN_VALID) != 0u) {
+ status = REUCB_TOKEN_VALID;
+ if (apps_loaded[i]) {
+ status = (unsigned char)(status | REUCB_TOKEN_LOADED |
+ REUCB_TOKEN_RESUMABLE);
+ }
+ readyos_bank_write_byte((unsigned int)(REUCB_SHIM_LOOKUP_OFF + token),
+ registry_phys[app_id]);
+ readyos_bank_write_byte((unsigned int)(REUCB_TOKEN_STATUS_OFF + token), status);
+ readyos_bank_write_byte((unsigned int)(REUCB_TOKEN_APP_OFF + token), app_id);
+ }
+ }
}
diff --git a/src/lib/reu_mgr.c b/src/lib/reu_mgr.c
index f340f78..4d2ac5b 100644
--- a/src/lib/reu_mgr.c
+++ b/src/lib/reu_mgr.c
@@ -1,8 +1,14 @@
-/*
- * reu_mgr.c - REU Memory Manager Implementation
- * Manages 256 REU banks with allocation table at $C600
+/* RETIRED LEGACY SOURCE -- intentionally preserved, never linked.
+ *
+ * This was the pre-schema-v5 C64-RAM allocation-mirror implementation.
+ * Production code is split across reu_mgr_init.c, reu_mgr_alloc.c,
+ * reu_mgr_stats.c, reu_phys.c, reu_mgr_dma.c, reu_control_bank.c, and
+ * reu_control_registry.c. Keeping this translation unit disabled makes an
+ * accidental reintroduction of the obsolete $C600 mirror fail closed.
*/
+#if 0
+
#include "reu_mgr.h"
/* REU hardware registers */
@@ -213,3 +219,5 @@ void reu_dma_fetch(unsigned int c64_addr, unsigned char bank,
REU_LEN_HI = (unsigned char)(length >> 8);
REU_COMMAND = REU_CMD_FETCH;
}
+
+#endif /* retired legacy source */
diff --git a/src/lib/reu_mgr.h b/src/lib/reu_mgr.h
index 150cf4c..02fe5f6 100644
--- a/src/lib/reu_mgr.h
+++ b/src/lib/reu_mgr.h
@@ -1,6 +1,7 @@
/*
* reu_mgr.h - REU Memory Manager for Ready OS
- * Manages 256 REU banks (16MB) with allocation table at $C600
+ * Manages 256 REU banks (16MB) with its authoritative allocation table in the
+ * ReadyOS bank at REUCB_BANK_TYPE_OFF.
*/
#ifndef REU_MGR_H
@@ -21,28 +22,19 @@
#define REU_RB_CORE 14
#define REU_RB_CODE 15
-/* Memory-mapped system area ($C600-$C7FF, persists across app switches) */
-#define REU_ALLOC_TABLE ((unsigned char*)0xC600) /* 256 bytes, 1 per bank */
-#define REU_SYS_MAGIC ((unsigned char*)0xC700)
-#define REU_MAGIC_VALUE 0xA5
#define REU_TOTAL_BANKS 256
-/* Logical app snapshot tokens start at 1. Physical dynamic allocation starts
- * immediately after the ReadyOS global/control bank and launcher snapshot. */
+/* Logical app snapshot tokens start at 1. Physical Skip is the combined
+ * ReadyOS global/control bank and launcher snapshot; dynamic allocation starts
+ * at the immediately following physical bank. */
#define REU_FIRST_DYNAMIC 1
-/* Shim bitmap at $C836-$C838 (tracks which app banks are loaded) */
-#define SHIM_REU_BITMAP_LO ((unsigned char*)0xC836)
-#define SHIM_REU_BITMAP_HI ((unsigned char*)0xC837)
-#define SHIM_REU_BITMAP_XHI ((unsigned char*)0xC838)
-#define SHIM_REU_BANK_SKIP ((unsigned char*)0xC83B)
-
-#define REU_READYOS_GLOBAL_PHYSICAL() ((unsigned char)(*SHIM_REU_BANK_SKIP))
-#define REU_LAUNCHER_PHYSICAL() ((unsigned char)(*SHIM_REU_BANK_SKIP + 1u))
-#define REU_LOGICAL_TO_PHYSICAL(bank) \
- ((unsigned char)(*SHIM_REU_BANK_SKIP + \
- (((unsigned char)(bank) == 0u) ? 1u : (1u + (unsigned char)(bank)))))
-#define REU_FIRST_DYNAMIC_PHYSICAL() ((unsigned char)(*SHIM_REU_BANK_SKIP + 2u))
+/* $C83B contains the direct physical ReadyOS-bank number (Skip). */
+#define SHIM_READYOS_BANK ((unsigned char*)0xC83B)
+#define SHIM_REU_BANK_SKIP SHIM_READYOS_BANK /* deprecated source alias */
+#define REU_READYOS_GLOBAL_PHYSICAL() ((unsigned char)(*SHIM_READYOS_BANK))
+#define REU_LAUNCHER_PHYSICAL() REU_READYOS_GLOBAL_PHYSICAL()
+#define REU_FIRST_DYNAMIC_PHYSICAL() ((unsigned char)(*SHIM_READYOS_BANK + 1u))
/* Initialize REU manager (safe to call multiple times) */
void reu_mgr_init(void);
@@ -68,4 +60,11 @@ void reu_dma_stash(unsigned int c64_addr, unsigned char bank,
void reu_dma_fetch(unsigned int c64_addr, unsigned char bank,
unsigned int reu_offset, unsigned int length);
+/* ReadyOS-bank metadata access. These routines use the shim's resident
+ * one-byte scratch for byte operations, so callers do not need a BSS mirror. */
+unsigned char readyos_bank_read_byte(unsigned int offset);
+void readyos_bank_write_byte(unsigned int offset, unsigned char value);
+void readyos_bank_read(unsigned int offset, void *dst, unsigned int length);
+void readyos_bank_write(unsigned int offset, const void *src, unsigned int length);
+
#endif /* REU_MGR_H */
diff --git a/src/lib/reu_mgr_alloc.c b/src/lib/reu_mgr_alloc.c
index cb7213a..37906b1 100644
--- a/src/lib/reu_mgr_alloc.c
+++ b/src/lib/reu_mgr_alloc.c
@@ -1,45 +1,39 @@
-/*
- * reu_mgr_alloc.c - REU allocation/free helpers
- */
+/* reu_mgr_alloc.c - authoritative ReadyOS-bank allocation helpers */
#include "reu_mgr.h"
+#include "reu_control_bank.h"
static unsigned char reu_fixed_bank_type(unsigned char bank) {
- if (bank < *SHIM_REU_BANK_SKIP) {
- return REU_SKIPPED;
- }
if (bank == REU_READYOS_GLOBAL_PHYSICAL()) {
return REU_GLOBAL;
}
- if (bank == REU_LAUNCHER_PHYSICAL()) {
- return REU_LAUNCHER;
+ if (bank < REU_FIRST_DYNAMIC_PHYSICAL()) {
+ return REU_SKIPPED;
}
- return 0xFF;
+ return 0xFFu;
}
unsigned char reu_alloc_bank(unsigned char type) {
unsigned int bank;
- for (bank = REU_FIRST_DYNAMIC_PHYSICAL(); bank < REU_TOTAL_BANKS; ++bank) {
- if (reu_fixed_bank_type((unsigned char)bank) != 0xFF) {
+ /* $FF remains the legacy failure return, so the legacy allocator reserves
+ * physical bank 255. Token mappings themselves still represent all bytes. */
+ for (bank = REU_FIRST_DYNAMIC_PHYSICAL(); bank < 255u; ++bank) {
+ if (reu_fixed_bank_type((unsigned char)bank) != 0xFFu) {
continue;
}
- if (REU_ALLOC_TABLE[bank] == REU_FREE) {
- REU_ALLOC_TABLE[bank] = type;
+ if (readyos_bank_read_byte((unsigned int)(REUCB_BANK_TYPE_OFF + bank)) == REU_FREE) {
+ readyos_bank_write_byte((unsigned int)(REUCB_BANK_TYPE_OFF + bank), type);
return (unsigned char)bank;
}
}
-
- return 0xFF;
+ return 0xFFu;
}
void reu_free_bank(unsigned char bank) {
- unsigned char fixed_type = reu_fixed_bank_type(bank);
-
- if (fixed_type != 0xFF) {
- REU_ALLOC_TABLE[bank] = fixed_type;
- return;
- }
+ unsigned char fixed_type;
- REU_ALLOC_TABLE[bank] = REU_FREE;
+ fixed_type = reu_fixed_bank_type(bank);
+ readyos_bank_write_byte((unsigned int)(REUCB_BANK_TYPE_OFF + bank),
+ (fixed_type == 0xFFu) ? REU_FREE : fixed_type);
}
diff --git a/src/lib/reu_mgr_dma.c b/src/lib/reu_mgr_dma.c
index b56718c..30fd836 100644
--- a/src/lib/reu_mgr_dma.c
+++ b/src/lib/reu_mgr_dma.c
@@ -15,6 +15,7 @@
#define REU_CMD_STASH 0x90
#define REU_CMD_FETCH 0x91
+#define READYOS_BYTE_SCRATCH (*(volatile unsigned char*)0xC83D)
void reu_dma_stash(unsigned int c64_addr, unsigned char bank,
unsigned int reu_offset, unsigned int length) {
@@ -39,3 +40,21 @@ void reu_dma_fetch(unsigned int c64_addr, unsigned char bank,
REU_LEN_HI = (unsigned char)(length >> 8);
REU_COMMAND = REU_CMD_FETCH;
}
+
+unsigned char readyos_bank_read_byte(unsigned int offset) {
+ reu_dma_fetch(0xC83Du, REU_READYOS_GLOBAL_PHYSICAL(), offset, 1u);
+ return READYOS_BYTE_SCRATCH;
+}
+
+void readyos_bank_write_byte(unsigned int offset, unsigned char value) {
+ READYOS_BYTE_SCRATCH = value;
+ reu_dma_stash(0xC83Du, REU_READYOS_GLOBAL_PHYSICAL(), offset, 1u);
+}
+
+void readyos_bank_read(unsigned int offset, void *dst, unsigned int length) {
+ reu_dma_fetch((unsigned int)dst, REU_READYOS_GLOBAL_PHYSICAL(), offset, length);
+}
+
+void readyos_bank_write(unsigned int offset, const void *src, unsigned int length) {
+ reu_dma_stash((unsigned int)src, REU_READYOS_GLOBAL_PHYSICAL(), offset, length);
+}
diff --git a/src/lib/reu_mgr_init.c b/src/lib/reu_mgr_init.c
index 6c0cca0..4813f1d 100644
--- a/src/lib/reu_mgr_init.c
+++ b/src/lib/reu_mgr_init.c
@@ -1,70 +1,13 @@
/*
- * reu_mgr_init.c - REU manager initialization and shim bitmap sync
+ * reu_mgr_init.c - app-side ReadyOS-bank allocator initialization
+ *
+ * The launcher owns schema creation. Apps must never create or rebuild global
+ * state from a private RAM mirror; initialization is therefore intentionally a
+ * validation-only no-op. Allocation operations read the ReadyOS bank directly.
*/
#include "reu_mgr.h"
-static void reu_mark_bitmap_slot(unsigned char logical_bank, unsigned char is_loaded) {
- unsigned char phys;
- unsigned char type;
-
- phys = REU_LOGICAL_TO_PHYSICAL(logical_bank);
- type = REU_ALLOC_TABLE[phys];
- if (type == REU_UNAVAIL) {
- return;
- }
- if (is_loaded) {
- REU_ALLOC_TABLE[phys] = REU_APP_STATE;
- } else if (type == REU_RESERVED) {
- REU_ALLOC_TABLE[phys] = REU_FREE;
- }
-}
-
-static void reu_sync_from_bitmap(void) {
- unsigned char bitmap_lo = *SHIM_REU_BITMAP_LO;
- unsigned char bitmap_hi = *SHIM_REU_BITMAP_HI;
- unsigned char bitmap_xhi = *SHIM_REU_BITMAP_XHI;
- unsigned char bank;
- unsigned char mask;
- unsigned char skip = *SHIM_REU_BANK_SKIP;
-
- for (bank = 0; bank < skip; ++bank) {
- REU_ALLOC_TABLE[bank] = REU_SKIPPED;
- }
-
- REU_ALLOC_TABLE[REU_READYOS_GLOBAL_PHYSICAL()] = REU_GLOBAL;
- REU_ALLOC_TABLE[REU_LAUNCHER_PHYSICAL()] = REU_LAUNCHER;
-
- for (bank = 1; bank < 8; ++bank) {
- mask = (unsigned char)(1 << bank);
- reu_mark_bitmap_slot(bank, (unsigned char)(bitmap_lo & mask));
- }
-
- for (bank = 0; bank < 8; ++bank) {
- mask = (unsigned char)(1 << bank);
- reu_mark_bitmap_slot((unsigned char)(bank + 8),
- (unsigned char)(bitmap_hi & mask));
- }
-
- for (bank = 0; bank < 8; ++bank) {
- mask = (unsigned char)(1 << bank);
- reu_mark_bitmap_slot((unsigned char)(bank + 16),
- (unsigned char)(bitmap_xhi & mask));
- }
-}
-
void reu_mgr_init(void) {
- if (*REU_SYS_MAGIC == REU_MAGIC_VALUE) {
- reu_sync_from_bitmap();
- return;
- }
-
- {
- unsigned int i;
- for (i = 0; i < REU_TOTAL_BANKS; ++i) {
- REU_ALLOC_TABLE[i] = REU_FREE;
- }
- }
- *REU_SYS_MAGIC = REU_MAGIC_VALUE;
- reu_sync_from_bitmap();
+ /* Kept for source/ABI compatibility with existing apps. */
}
diff --git a/src/lib/reu_mgr_stats.c b/src/lib/reu_mgr_stats.c
index bddd27f..d9c8b31 100644
--- a/src/lib/reu_mgr_stats.c
+++ b/src/lib/reu_mgr_stats.c
@@ -1,38 +1,38 @@
-/*
- * reu_mgr_stats.c - REU manager query helpers
- * Split from core so apps that only use clipboard can avoid this code.
- */
+/* reu_mgr_stats.c - authoritative ReadyOS-bank allocation queries */
#include "reu_mgr.h"
+#include "reu_control_bank.h"
unsigned char reu_bank_type(unsigned char bank) {
- return REU_ALLOC_TABLE[bank];
+ return readyos_bank_read_byte((unsigned int)(REUCB_BANK_TYPE_OFF + bank));
}
unsigned char reu_count_free(void) {
unsigned int i;
- unsigned char count = 0;
-
- for (i = 0; i < REU_TOTAL_BANKS; ++i) {
- if (REU_ALLOC_TABLE[i] == REU_FREE) {
- ++count;
- if (count == 255) break;
+ unsigned char count;
+
+ count = 0u;
+ for (i = 0u; i < REU_TOTAL_BANKS; ++i) {
+ if (readyos_bank_read_byte((unsigned int)(REUCB_BANK_TYPE_OFF + i)) == REU_FREE) {
+ if (++count == 255u) {
+ break;
+ }
}
}
-
return count;
}
unsigned char reu_count_type(unsigned char type) {
unsigned int i;
- unsigned char count = 0;
-
- for (i = 0; i < REU_TOTAL_BANKS; ++i) {
- if (REU_ALLOC_TABLE[i] == type) {
- ++count;
- if (count == 255) break;
+ unsigned char count;
+
+ count = 0u;
+ for (i = 0u; i < REU_TOTAL_BANKS; ++i) {
+ if (readyos_bank_read_byte((unsigned int)(REUCB_BANK_TYPE_OFF + i)) == type) {
+ if (++count == 255u) {
+ break;
+ }
}
}
-
return count;
}
diff --git a/src/lib/reu_owned_alloc.c b/src/lib/reu_owned_alloc.c
index 0ea42cb..2025608 100644
--- a/src/lib/reu_owned_alloc.c
+++ b/src/lib/reu_owned_alloc.c
@@ -15,24 +15,16 @@ static unsigned int owned_rec_off(unsigned char rec_index) {
}
static unsigned char owned_current_app_id(void) {
- unsigned char i;
unsigned char logical;
- unsigned char control_bank;
+ unsigned char app_id;
logical = SHIM_CURRENT_BANK;
if (logical == 0u) {
return REUCB_NULL_REC;
}
- control_bank = REU_READYOS_GLOBAL_PHYSICAL();
- for (i = 0u; i < REUCB_APP_REG_COUNT; ++i) {
- reu_dma_fetch((unsigned int)owned_rec, control_bank,
- (unsigned int)(REUCB_APP_REG_OFF + i), 1u);
- if (owned_rec[0] == logical) {
- return i;
- }
- }
- return REUCB_NULL_REC;
+ app_id = readyos_bank_read_byte((unsigned int)(REUCB_TOKEN_APP_OFF + logical));
+ return (app_id < REUCB_APP_REG_COUNT) ? app_id : REUCB_NULL_REC;
}
static void owned_clear_record_for_bank(unsigned char bank) {
diff --git a/src/lib/reu_phys.c b/src/lib/reu_phys.c
index b5b5cc5..fb3073f 100644
--- a/src/lib/reu_phys.c
+++ b/src/lib/reu_phys.c
@@ -1,28 +1,16 @@
-/*
- * reu_phys.c - physical REU size probe and allocation-table policy
- */
+/* reu_phys.c - physical REU size policy stored in the ReadyOS bank */
#include "reu_phys.h"
+#include "reu_control_bank.h"
void reu_phys_apply_to_alloc_table(unsigned char encoded_count) {
- unsigned int bank;
-
- for (bank = 0u; bank < REU_TOTAL_BANKS; ++bank) {
- if (reu_phys_is_unavailable(encoded_count, (unsigned char)bank)) {
- REU_ALLOC_TABLE[bank] = REU_UNAVAIL;
- } else if (REU_ALLOC_TABLE[bank] == REU_UNAVAIL) {
- REU_ALLOC_TABLE[bank] = REU_FREE;
- }
- }
+ reu_control_bank_prepare(encoded_count);
}
unsigned char reu_phys_count_from_alloc_table(void) {
- unsigned int bank;
-
- for (bank = 0u; bank < REU_TOTAL_BANKS; ++bank) {
- if (REU_ALLOC_TABLE[bank] == REU_UNAVAIL) {
- return (unsigned char)bank;
- }
+ if (reu_control_bank_is_valid()) {
+ return readyos_bank_read_byte((unsigned int)(REUCB_HEADER_OFF +
+ REUCB_HEADER_PHYS_BANKS));
}
return REU_PHYS_COUNT_256;
}
diff --git a/src/lib/reu_phys_probe.c b/src/lib/reu_phys_probe.c
index 4980bd4..46a694d 100644
--- a/src/lib/reu_phys_probe.c
+++ b/src/lib/reu_phys_probe.c
@@ -26,7 +26,7 @@ unsigned char reu_phys_detect_bank_count(void) {
unsigned char got;
unsigned int bank;
- base_bank = *SHIM_REU_BANK_SKIP;
+ base_bank = REU_FIRST_DYNAMIC_PHYSICAL();
base_orig = reu_phys_fetch_probe_byte(base_bank);
reu_phys_stash_probe_byte(base_bank, 0x5Au);
diff --git a/src/lib/tui.c b/src/lib/tui.c
index 31936fe..da3bc87 100644
--- a/src/lib/tui.c
+++ b/src/lib/tui.c
@@ -1,10 +1,15 @@
-/*
+/* RETIRED LEGACY SOURCE -- intentionally preserved, never linked.
+ * The production TUI is split into operation-sized micromodules, including
+ * tui_readyos.c for direct ReadyOS-bank state access, to avoid app bloat.
+ *
* tui.c - TUI Library Implementation for Ready OS
* Text User Interface with PETSCII box drawing
*
* For Commodore 64, compiled with CC65
*/
+#if 0
+
#include "tui.h"
#include
#include
@@ -728,3 +733,5 @@ void tui_print_hex16(unsigned char x, unsigned char y, unsigned int value,
tui_putc(x + 3, y, tui_ascii_to_screen(hex[(value >> 4) & 0x0F]), color);
tui_putc(x + 4, y, tui_ascii_to_screen(hex[value & 0x0F]), color);
}
+
+#endif /* retired legacy source */
diff --git a/src/lib/tui.h b/src/lib/tui.h
index 8fc89db..446732d 100644
--- a/src/lib/tui.h
+++ b/src/lib/tui.h
@@ -85,14 +85,16 @@
#define TUI_MOD_CBM 0x02 /* Commodore key */
#define TUI_MOD_CTRL 0x04
-/* Shared global app hotkey slots in system RAM ($C7E0-$C7E8) */
+/* Shared global app hotkey slots in the ReadyOS bank. */
#define TUI_HOTKEY_SLOT_COUNT 9
#define TUI_HOTKEY_NONE 0
#define TUI_HOTKEY_BIND_ONLY 0xFE
#define TUI_HOTKEY_LAUNCHER 0xFF
-#define TUI_HOTKEY_BINDINGS ((unsigned char*)0xC7E0)
#define TUI_APP_BANK_MIN 1
-#define TUI_APP_BANK_MAX 223
+#define TUI_APP_BANK_MAX 64 /* launcher catalog capacity; tokens map explicitly */
+
+unsigned char tui_hotkey_get_binding(unsigned char slot_index);
+void tui_hotkey_set_binding(unsigned char slot_index, unsigned char token);
/* Keyboard auto-repeat policy */
#define TUI_KEYREPEAT_CURSOR KBREPEAT_CURSOR
diff --git a/src/lib/tui_hotkeys.c b/src/lib/tui_hotkeys.c
index 18567b2..22bc650 100644
--- a/src/lib/tui_hotkeys.c
+++ b/src/lib/tui_hotkeys.c
@@ -1,13 +1,12 @@
/*
- * tui_hotkeys.c - Shared direct app hotkeys backed by shim-safe RAM
+ * tui_hotkeys.c - Shared direct app hotkeys backed by the ReadyOS bank
*/
#include "tui.h"
+#include "reu_control_bank.h"
+#include "tui_readyos.h"
#define SHFLAG (*(unsigned char*)0x028D)
-#define SHIM_REU_BITMAP_LO ((unsigned char*)0xC836)
-#define SHIM_REU_BITMAP_HI ((unsigned char*)0xC837)
-#define SHIM_REU_BITMAP_XHI ((unsigned char*)0xC838)
#define APP_BANK_EDITOR TUI_APP_BANK_MIN
#define APP_BANK_MAX TUI_APP_BANK_MAX
@@ -85,16 +84,18 @@ static unsigned char hotkey_slot_from_unshifted(unsigned char key,
}
static unsigned char hotkey_bank_loaded(unsigned char bank) {
- if (bank < 8) {
- return (unsigned char)((*SHIM_REU_BITMAP_LO & (unsigned char)(1U << bank)) != 0);
- }
- if (bank < 16) {
- return (unsigned char)((*SHIM_REU_BITMAP_HI & (unsigned char)(1U << (bank - 8))) != 0);
- }
- if (bank < 24) {
- return (unsigned char)((*SHIM_REU_BITMAP_XHI & (unsigned char)(1U << (bank - 16))) != 0);
- }
- return 1;
+ return (unsigned char)(tui_readyos_read_byte(
+ (unsigned int)(REUCB_TOKEN_STATUS_OFF + bank)) & REUCB_TOKEN_LOADED);
+}
+
+unsigned char tui_hotkey_get_binding(unsigned char slot_index) {
+ if (slot_index >= TUI_HOTKEY_SLOT_COUNT) return TUI_HOTKEY_NONE;
+ return tui_readyos_read_byte((unsigned int)(REUCB_HOTKEY_OFF + slot_index));
+}
+
+void tui_hotkey_set_binding(unsigned char slot_index, unsigned char token) {
+ if (slot_index >= TUI_HOTKEY_SLOT_COUNT) return;
+ tui_readyos_write_byte((unsigned int)(REUCB_HOTKEY_OFF + slot_index), token);
}
unsigned char tui_get_modifiers(void) {
@@ -131,7 +132,7 @@ unsigned char tui_handle_global_hotkey(unsigned char key,
if (slot != 0) {
if (allow_bind && (modifiers & TUI_MOD_SHIFT) != 0) {
if (current_bank >= APP_BANK_EDITOR && current_bank <= APP_BANK_MAX) {
- TUI_HOTKEY_BINDINGS[(unsigned char)(slot - 1)] = current_bank;
+ tui_hotkey_set_binding((unsigned char)(slot - 1), current_bank);
}
return TUI_HOTKEY_BIND_ONLY;
}
@@ -141,12 +142,12 @@ unsigned char tui_handle_global_hotkey(unsigned char key,
return TUI_HOTKEY_NONE;
}
if (current_bank >= APP_BANK_EDITOR && current_bank <= APP_BANK_MAX) {
- TUI_HOTKEY_BINDINGS[(unsigned char)(slot - 1)] = current_bank;
+ tui_hotkey_set_binding((unsigned char)(slot - 1), current_bank);
}
return TUI_HOTKEY_BIND_ONLY;
}
- target = TUI_HOTKEY_BINDINGS[(unsigned char)(slot - 1)];
+ target = tui_hotkey_get_binding((unsigned char)(slot - 1));
if (target < APP_BANK_EDITOR || target > APP_BANK_MAX) {
return TUI_HOTKEY_NONE;
}
diff --git a/src/lib/tui_nav.c b/src/lib/tui_nav.c
index dc3e677..d651f0e 100644
--- a/src/lib/tui_nav.c
+++ b/src/lib/tui_nav.c
@@ -3,26 +3,17 @@
*/
#include "tui.h"
+#include "reu_control_bank.h"
+#include "tui_readyos.h"
#define SHIM_TARGET_BANK ((unsigned char*)0xC820)
-#define SHIM_REU_BITMAP_LO ((unsigned char*)0xC836)
-#define SHIM_REU_BITMAP_HI ((unsigned char*)0xC837)
-#define SHIM_REU_BITMAP_XHI ((unsigned char*)0xC838)
#define APP_BANK_EDITOR 1
-#define APP_BANK_MAX 23
+#define APP_BANK_MAX TUI_APP_BANK_MAX
static unsigned char tui_bank_loaded(unsigned char bank) {
- if (bank < 8) {
- return (unsigned char)((*SHIM_REU_BITMAP_LO & (unsigned char)(1U << bank)) != 0);
- }
- if (bank < 16) {
- return (unsigned char)((*SHIM_REU_BITMAP_HI & (unsigned char)(1U << (bank - 8))) != 0);
- }
- if (bank < 24) {
- return (unsigned char)((*SHIM_REU_BITMAP_XHI & (unsigned char)(1U << (bank - 16))) != 0);
- }
- return 0;
+ return (unsigned char)(tui_readyos_read_byte(
+ (unsigned int)(REUCB_TOKEN_STATUS_OFF + bank)) & REUCB_TOKEN_LOADED);
}
void tui_return_to_launcher(void) {
diff --git a/src/lib/tui_readyos.c b/src/lib/tui_readyos.c
new file mode 100644
index 0000000..8aa3cef
--- /dev/null
+++ b/src/lib/tui_readyos.c
@@ -0,0 +1,42 @@
+/*
+ * tui_readyos.c - no-BSS ReadyOS-bank byte DMA for lightweight TUI apps.
+ *
+ * Normal apps already link reu_mgr_dma.c and use the zero-frame aliases in
+ * tui_readyos_alias.s to avoid duplicating this register setup. Keep this
+ * standalone implementation for deliberately small apps that do not otherwise
+ * need the REU manager. tui_readyos_reu_mgr.c is the retained C reference.
+ */
+
+#include "tui_readyos.h"
+
+#define REU_COMMAND (*(unsigned char*)0xDF01)
+#define REU_C64_LO (*(unsigned char*)0xDF02)
+#define REU_C64_HI (*(unsigned char*)0xDF03)
+#define REU_REU_LO (*(unsigned char*)0xDF04)
+#define REU_REU_HI (*(unsigned char*)0xDF05)
+#define REU_REU_BANK (*(unsigned char*)0xDF06)
+#define REU_LEN_LO (*(unsigned char*)0xDF07)
+#define REU_LEN_HI (*(unsigned char*)0xDF08)
+#define READYOS_BANK (*(unsigned char*)0xC83B)
+#define READYOS_BYTE_SCRATCH (*(unsigned char*)0xC83D)
+
+static void tui_readyos_transfer(unsigned int offset, unsigned char command) {
+ REU_C64_LO = 0x3Du;
+ REU_C64_HI = 0xC8u;
+ REU_REU_LO = (unsigned char)offset;
+ REU_REU_HI = (unsigned char)(offset >> 8);
+ REU_REU_BANK = READYOS_BANK;
+ REU_LEN_LO = 1u;
+ REU_LEN_HI = 0u;
+ REU_COMMAND = command;
+}
+
+unsigned char tui_readyos_read_byte(unsigned int offset) {
+ tui_readyos_transfer(offset, 0x91u);
+ return READYOS_BYTE_SCRATCH;
+}
+
+void tui_readyos_write_byte(unsigned int offset, unsigned char value) {
+ READYOS_BYTE_SCRATCH = value;
+ tui_readyos_transfer(offset, 0x90u);
+}
diff --git a/src/lib/tui_readyos.h b/src/lib/tui_readyos.h
new file mode 100644
index 0000000..a72ff5e
--- /dev/null
+++ b/src/lib/tui_readyos.h
@@ -0,0 +1,9 @@
+/* tui_readyos.h - tiny shim-ABI ReadyOS-bank byte access for TUI modules */
+
+#ifndef TUI_READYOS_H
+#define TUI_READYOS_H
+
+unsigned char tui_readyos_read_byte(unsigned int offset);
+void tui_readyos_write_byte(unsigned int offset, unsigned char value);
+
+#endif
diff --git a/src/lib/tui_readyos_alias.s b/src/lib/tui_readyos_alias.s
new file mode 100644
index 0000000..a2162d8
--- /dev/null
+++ b/src/lib/tui_readyos_alias.s
@@ -0,0 +1,23 @@
+;
+; tui_readyos_alias.s - zero-frame ReadyOS-bank aliases for full REU clients.
+;
+; These entry points deliberately tail-jump to the canonical reu_mgr_dma
+; helpers. A tail jump preserves cc65's software-stack argument layout while
+; avoiding a second copy of the REU register-programming routines.
+;
+
+.import _readyos_bank_read_byte
+.import _readyos_bank_write_byte
+
+.export _tui_readyos_read_byte
+.export _tui_readyos_write_byte
+
+.segment "CODE"
+
+.proc _tui_readyos_read_byte
+ jmp _readyos_bank_read_byte
+.endproc
+
+.proc _tui_readyos_write_byte
+ jmp _readyos_bank_write_byte
+.endproc
diff --git a/src/lib/tui_readyos_reu_mgr.c b/src/lib/tui_readyos_reu_mgr.c
new file mode 100644
index 0000000..6990081
--- /dev/null
+++ b/src/lib/tui_readyos_reu_mgr.c
@@ -0,0 +1,19 @@
+/*
+ * tui_readyos_reu_mgr.c - safe C reference adapter retained for provenance.
+ *
+ * Production builds use tui_readyos_alias.s: its zero-frame tail jumps avoid
+ * duplicating DMA code without perturbing cc65's software-stack arguments.
+ * This C form remains a correct fallback/reference but is deliberately not
+ * linked because ordinary C calls cost more resident bytes.
+ */
+
+#include "tui_readyos.h"
+#include "reu_mgr.h"
+
+unsigned char tui_readyos_read_byte(unsigned int offset) {
+ return readyos_bank_read_byte(offset);
+}
+
+void tui_readyos_write_byte(unsigned int offset, unsigned char value) {
+ readyos_bank_write_byte(offset, value);
+}
diff --git a/src/shim/context.s b/src/shim/context.s
index 8f4ebae..a19ecd0 100644
--- a/src/shim/context.s
+++ b/src/shim/context.s
@@ -1,7 +1,9 @@
;
; context.s - Context Save/Restore for Ready OS
; Handles saving and restoring full app state via REU DMA
-; NOTE: Legacy shim module; production shim is generated from src/boot/boot_asm.s.
+; NOTE: Retired legacy module, intentionally not linked. The canonical shim
+; is src/boot/readyos_shim.inc. Constants below remain updated for archival
+; comparison and must not be mistaken for a second implementation.
;
.export _context_save, _context_restore
@@ -31,7 +33,7 @@ SCREEN_SIZE = 1000 ; 40x25 = 1000 bytes
COLOR_START = $D800
COLOR_SIZE = 1000
APP_START = $1000
-APP_END = $C600
+APP_END = $C800
APP_SIZE = $B600 ; 46,592 bytes ($1000-$C5FF)
; REU offsets for saved state (within app's 64KB bank)
diff --git a/src/shim/loader.s b/src/shim/loader.s
index f24c711..12ce668 100644
--- a/src/shim/loader.s
+++ b/src/shim/loader.s
@@ -1,7 +1,9 @@
;
; loader.s - Ready OS Loader Shim
; Resident at $0800-$0FFF, handles app loading and switching
-; NOTE: Legacy shim source; production shim is generated from src/boot/boot_asm.s.
+; RETIRED LEGACY SOURCE -- intentionally preserved, never assembled or linked.
+; Production uses src/boot/readyos_shim.inc from both boot implementations.
+; This file is archival and is disabled so it cannot become a second shim.
;
; This shim stays in memory and provides:
; - Load app from disk to $1000
@@ -10,6 +12,8 @@
; - Jump to app entry point
;
+.if 0
+
.export _shim_init
.export _shim_load_disk
.export _shim_load_reu
@@ -249,3 +253,5 @@ app_bank: .byte 0 ; REU bank for current app
app_size_lo: .byte 0 ; App size low byte
app_size_hi: .byte 0 ; App size high byte
app_loaded: .byte 0 ; 1 if app is loaded in RAM
+
+.endif ; retired legacy source
diff --git a/src/shim/syscalls.s b/src/shim/syscalls.s
index 26cdafb..f25e264 100644
--- a/src/shim/syscalls.s
+++ b/src/shim/syscalls.s
@@ -1,8 +1,12 @@
;
; syscalls.s - Ready OS Syscall Implementations
-; NOTE: Legacy shim module; production shim is generated from src/boot/boot_asm.s.
+; RETIRED LEGACY SOURCE -- intentionally preserved, never assembled or linked.
+; Production uses src/boot/readyos_shim.inc and focused C micromodules. This
+; file is archival and disabled so its obsolete syscall model cannot be used.
;
+.if 0
+
.export _sys_init_impl, _sys_suspend_impl, _sys_resume_impl, _sys_exit_impl
.export _sys_clip_copy_impl, _sys_clip_paste_impl
.export _sys_deeplink_impl, _sys_query_impl
@@ -11,7 +15,7 @@
.import _context_save, _context_restore
; System constants
-MAX_APPS = 24
+MAX_APPS = 64
; Memory layout constants
ZP_START = $00
@@ -486,3 +490,5 @@ dl_ptr: .word 0
; Imports
;-----------------------------------------------------------------------------
.import sp ; CC65 software stack pointer
+
+.endif ; retired legacy source
diff --git a/verify.py b/verify.py
index a78a927..0531169 100644
--- a/verify.py
+++ b/verify.py
@@ -6,9 +6,9 @@
- boot.prg structure and shim byte layout
- shim jump table / routine alignment / critical REU instruction sequences
- app PRG load addresses and binary extents
-- app linker map segment bounds against REU snapshot window ($1000-$C5FF)
-- region conflict checks across app/REU metadata/shim/I/O boundaries
-- app headroom warnings near the $C5FF snapshot ceiling
+- app linker map segment bounds against the `$1000-$C5FF` snapshot window
+- region conflict checks across app/shim/I/O boundaries
+- app headroom warnings near the `$C5FF` snapshot ceiling
"""
import argparse
@@ -44,6 +44,7 @@
("deminer", "deminer.prg"),
("cal26", "cal26.prg"),
("dizzy", "dizzy.prg"),
+ ("ucitest", "ucitest.prg"),
("readme", "readme.prg"),
("readyshell", "readyshell.prg"),
]
@@ -63,9 +64,8 @@
APP_SNAPSHOT_END = 0xC5FF # Shim stashes/fetches exactly $1000-$C5FF ($B600 bytes)
APP_SNAPSHOT_SIZE = APP_SNAPSHOT_END - APP_LOAD_START + 1
APP_LINKER_END = 0xC5FF # cfg/ready_app.cfg MAIN range upper bound
-REU_META_START = 0xC600 # reu_mgr alloc table area
-REU_META_END = 0xC7FF
-SHIM_START = 0xC800
+SHIM_START = 0xC600
+SHIM_ABI_START = 0xC800
SHIM_END = 0xC9FF
IO_START = 0xD000
APP_HEADROOM_WARN = 1024
@@ -164,9 +164,11 @@ def parse_launcher_runtime_contract(path):
with open(path, "r", encoding="utf-8", errors="replace") as f:
src = f.read()
- app_slot_capacity = int(
- re.search(r"#define\s+APP_SLOT_CAPACITY\s+(\d+)", src).group(1)
- )
+ capacities = [int(value) for value in
+ re.findall(r"#define\s+APP_SLOT_CAPACITY\s+(\d+)", src)]
+ if not capacities:
+ raise ValueError("APP_SLOT_CAPACITY definition not found")
+ app_slot_capacity = max(capacities)
max_apps_m = re.search(r"#define\s+MAX_APPS\s+\(APP_SLOT_CAPACITY\s*\+\s*1\)", src)
return {
@@ -338,9 +340,9 @@ def resolve_bank_max_token(path, token):
return {
"source_path": path,
"app_bank_max": resolve_bank_max_token(path, max_bank_m.group(1)),
- "uses_bitmap_lo": "SHIM_REU_BITMAP_LO" in src,
- "uses_bitmap_hi": "SHIM_REU_BITMAP_HI" in src,
- "uses_bitmap_xhi": "SHIM_REU_BITMAP_XHI" in src,
+ "uses_readyos_status": ("REUCB_TOKEN_STATUS_OFF" in src and
+ "tui_readyos_read_byte" in src),
+ "uses_retired_bitmap": "SHIM_REU_BITMAP_" in src,
"has_bank_loaded_helper": "hotkey_bank_loaded" in src or "tui_bank_loaded" in src,
}
@@ -552,9 +554,9 @@ def main():
return 1
shim = boot[offset:]
- all_ok &= check("Shim size", len(shim) == 512, f"{len(shim)} bytes (expect 512)")
- all_ok &= check("Shim is last payload block", offset + 512 == len(boot),
- f"shim_end=0x{offset + 512:04X}, file_len=0x{len(boot):04X}")
+ all_ok &= check("Shim ABI size", len(shim) == 512, f"{len(shim)} bytes (expect 512)")
+ all_ok &= check("Shim ABI is last payload block", offset + 512 == len(boot),
+ f"shim_abi_start=0x{offset:04X}, shim_end=0x{offset + 512:04X}, file_len=0x{len(boot):04X}")
boot_payload = len(boot) - 2
boot_end = boot_load_addr + boot_payload - 1
@@ -601,7 +603,7 @@ def main():
(0x09, [0x4C, 0x80, 0xC8], "JMP $C880 (preload)"),
(0x0C, [0x4C, 0x00, 0xC9], "JMP $C900 (return_to_launcher)"),
(0x0F, [0x4C, 0x40, 0xC9], "JMP $C940 (switch_app)"),
- (0x12, [0x4C, 0xC0, 0xC8], "JMP $C8C0 (stash_current)"),
+ (0x12, [0x4C, 0xFF, 0xC9], "JMP $C9FF (reserved no-op)"),
(0x15, [0x4C, 0xF0, 0xC8], "JMP $C8F0 (fetch_bank)"),
]
for off, expected, desc in jt_checks:
@@ -614,11 +616,11 @@ def main():
all_ok &= check("target_bank", shim[0x20] == 0x00, f"${shim[0x20]:02X} (expect $00)")
all_ok &= check("filename_len", shim[0x21] == 0x08, f"${shim[0x21]:02X} (expect $08)")
all_ok &= check("current_bank", shim[0x34] == 0x00, f"${shim[0x34]:02X} (expect $00)")
- all_ok &= check("reu_bitmap_lo", shim[0x36] == 0x00, f"${shim[0x36]:02X} (expect $00)")
- all_ok &= check("reu_bitmap_hi", shim[0x37] == 0x00, f"${shim[0x37]:02X} (expect $00)")
- all_ok &= check("reu_bitmap_xhi", shim[0x38] == 0x00, f"${shim[0x38]:02X} (expect $00)")
+ all_ok &= check("retired bitmap bytes reserved", shim[0x36:0x39] == bytes(3),
+ shim[0x36:0x39].hex(" "))
all_ok &= check("storage_drive", shim[0x39] == 0x08, f"${shim[0x39]:02X} (expect $08)")
- all_ok &= check("reu_bank_skip", shim[0x3B] <= 39, f"{shim[0x3B]} (expect 0..39)")
+ all_ok &= check("ReadyOS physical bank", shim[0x3B] <= 39,
+ f"{shim[0x3B]} (compiled Skip)")
# --- Routine Alignment ---
print("\n=== Routine Alignment ===")
@@ -632,59 +634,39 @@ def main():
(0x140, 0xAD, "switch_app", "LDA abs"),
(0x160, 0xC9, "reu_setup_logical", "CMP imm"),
(0x1A0, 0x8D, "reu_setup", "STA abs"),
- (0x1C0, 0xC9, "set_bitmap", "CMP imm"),
- (0x1E0, 0x48, "log_byte", "PHA"),
+ (0x1C0, 0x8D, "mark_loaded", "STA abs"),
+ (0x1FF, 0x60, "compatibility_noop", "RTS"),
]
for off, expected, name, desc in routines:
actual = shim[off]
- addr = SHIM_START + off
+ addr = SHIM_ABI_START + off
all_ok &= check(f"${addr:04X} {name}", actual == expected,
f"0x{actual:02X} (expect 0x{expected:02X} = {desc})")
# --- LOAD End Address Save ---
- print("\n=== LOAD End Address Save ($C8AC) ===")
- load_end_save = list(shim[0xAC:0xAC + 6])
- all_ok &= check("$C8AC STX/STY", load_end_save == [0x8E, 0x30, 0xC8, 0x8C, 0x31, 0xC8],
- f"{' '.join(f'{b:02X}' for b in load_end_save)} = STX $C830; STY $C831")
+ print("\n=== LOAD End Address Save ===")
+ load_end_pattern = bytes([0x8E, 0x30, 0xC8, 0x8C, 0x31, 0xC8])
+ load_end_at = shim.find(load_end_pattern, 0x80, 0xE0)
+ all_ok &= check("preload saves KERNAL end address", load_end_at >= 0,
+ f"shim offset ${load_end_at:03X}" if load_end_at >= 0 else "pattern missing")
# --- Critical Instruction Sequences ---
print("\n=== Critical REU Sequences ===")
reu = list(shim[0x1A0:0x1A0 + 3])
all_ok &= check("$C9A0 reu_setup", reu == [0x8D, 0x06, 0xDF],
f"{' '.join(f'{b:02X}' for b in reu)} = STA $DF06")
- reu_logical = list(shim[0x160:0x160 + 60])
- expected_logical = [
- 0xC9, 0x00, # CMP #0
- 0xD0, 0x09, # BNE lookup_app_bank
- 0xAD, 0x3B, 0xC8, # LDA $C83B
- 0x18, # CLC
- 0x69, 0x01, # ADC #$01
- 0x4C, 0xA0, 0xC9, # JMP reu_setup
- 0xAA, # TAX
- 0xA9, 0x3D, # LDA #<$C83D
- 0x8D, 0x02, 0xDF, # STA $DF02
- 0xA9, 0xC8, # LDA #>$C83D
- 0x8D, 0x03, 0xDF, # STA $DF03
- 0x8A, # TXA
- 0x8D, 0x04, 0xDF, # STA $DF04
- 0xA9, 0x2F, # LDA #$2F
- 0x8D, 0x05, 0xDF, # STA $DF05
- 0xAD, 0x3B, 0xC8, # LDA $C83B
- 0x8D, 0x06, 0xDF, # STA $DF06
- 0xA9, 0x01, # LDA #1
- 0x8D, 0x07, 0xDF, # STA $DF07
- 0xA9, 0x00, # LDA #0
- 0x8D, 0x08, 0xDF, # STA $DF08
- 0xA9, 0x91, # LDA #FETCH
- 0x8D, 0x01, 0xDF, # STA $DF01
- 0xAD, 0x3D, 0xC8, # LDA $C83D
- 0x4C, 0xA0, 0xC9, # JMP reu_setup
- ]
- all_ok &= check("$C960 logical setup", reu_logical == expected_logical,
- f"{' '.join(f'{b:02X}' for b in reu_logical)} = token 0 direct, nonzero tokens via bank0 $2F00 lookup")
- reu_len = list(shim[0x1A0 + 0x18:0x1A0 + 0x1D])
- all_ok &= check("$C9B5 transfer length", reu_len == [0xA9, 0xB6, 0x8D, 0x08, 0xDF],
- f"{' '.join(f'{b:02X}' for b in reu_len)} = LDA #$B6; STA $DF08")
+ reu_logical = shim[0x160:0x1A0]
+ token0_direct = bytes([0xC9, 0x00, 0xD0, 0x06, 0xAD, 0x3B, 0xC8,
+ 0x4C, 0xA0, 0xC9])
+ lookup_b740 = bytes([0x8A, 0x18, 0x69, 0x40, 0x8D, 0x04, 0xDF,
+ 0xA9, 0xB7, 0x69, 0x00, 0x8D, 0x05, 0xDF])
+ all_ok &= check("$C960 token 0 resolves directly to ReadyOS bank",
+ reu_logical.startswith(token0_direct))
+ all_ok &= check("$C960 nonzero tokens resolve through ReadyOS $B740",
+ lookup_b740 in reu_logical)
+ reu_len = bytes([0xA9, 0xB6, 0x8D, 0x08, 0xDF])
+ all_ok &= check("$C9A0 transfer length is $B600", reu_len in shim[0x1A0:0x1C0],
+ "LDA #$B6; STA $DF08")
stash = list(shim[0xE0:0xE0 + 3])
all_ok &= check("$C8E0 stash→reu_setup_logical", stash == [0x20, 0x60, 0xC9],
@@ -702,19 +684,18 @@ def main():
all_ok &= check("$C8F3 FETCH cmd", fetch_cmd == [0xA9, 0x91, 0x8D, 0x01, 0xDF],
"LDA #$91; STA $DF01")
- bitmap_guard = list(shim[0x1C0:0x1C0 + 4])
- all_ok &= check("$C9C0 bitmap bank guard", bitmap_guard == [0xC9, 0x18, 0xB0, 0x17],
- "CMP #$18; BCS done")
- bitmap_store = list(shim[0x1D5:0x1D5 + 6])
- all_ok &= check("$C9D5 bitmap indexed store", bitmap_store == [0x1D, 0x36, 0xC8, 0x9D, 0x36, 0xC8],
- "ORA $C836,X; STA $C836,X")
+ mark_loaded = shim[0x1C0:0x1FF]
+ status_b840 = bytes([0x18, 0x69, 0x40, 0x8D, 0x04, 0xDF,
+ 0xA9, 0xB8, 0x69, 0x00, 0x8D, 0x05, 0xDF])
+ all_ok &= check("$C9C0 commits valid/loaded/resumable status $07",
+ bytes([0xA9, 0x07, 0x8D, 0x3D, 0xC8]) in mark_loaded)
+ all_ok &= check("$C9C0 writes ReadyOS $B840 + token",
+ status_b840 in mark_loaded)
# --- Region Boundary Invariants ---
print("\n=== Region Boundary Invariants ===")
- all_ok &= check("App snapshot before REU metadata", APP_SNAPSHOT_END < REU_META_START,
- f"${APP_SNAPSHOT_END:04X} < ${REU_META_START:04X}")
- all_ok &= check("REU metadata before shim", REU_META_END < SHIM_START,
- f"${REU_META_END:04X} < ${SHIM_START:04X}")
+ all_ok &= check("App snapshot before shim", APP_SNAPSHOT_END < SHIM_START,
+ f"${APP_SNAPSHOT_END:04X} < ${SHIM_START:04X}")
all_ok &= check("Shim before I/O", SHIM_END < IO_START,
f"${SHIM_END:04X} < ${IO_START:04X}")
@@ -788,12 +769,9 @@ def main():
all_ok &= check(f"{app_name}.map runtime end<=linker", runtime_end <= APP_LINKER_END,
f"end=${runtime_end:04X}, linker_end=${APP_LINKER_END:04X}")
- overlap_reu_meta = intersects(runtime_start, runtime_end, REU_META_START, REU_META_END)
overlap_shim = intersects(runtime_start, runtime_end, SHIM_START, SHIM_END)
overlap_io = intersects(runtime_start, runtime_end, IO_START, 0xFFFF)
- all_ok &= check(f"{app_name}.map no overlap REU metadata", not overlap_reu_meta,
- f"${runtime_start:04X}-${runtime_end:04X} vs ${REU_META_START:04X}-${REU_META_END:04X}")
all_ok &= check(f"{app_name}.map no overlap shim", not overlap_shim,
f"${runtime_start:04X}-${runtime_end:04X} vs ${SHIM_START:04X}-${SHIM_END:04X}")
all_ok &= check(f"{app_name}.map no overlap I/O/ROM", not overlap_io,
@@ -953,8 +931,11 @@ def main():
except FileNotFoundError:
all_ok &= check("launcher source exists", False, "src/apps/launcher/launcher.c missing")
else:
- all_ok &= check("launcher patches load_disk device", "SHIM_LOAD_DISK_DEV_IMM" in launcher_src)
- all_ok &= check("launcher patches preload device", "SHIM_PRELOAD_DEV_IMM" in launcher_src)
+ all_ok &= check("launcher writes shim-global storage drive",
+ "set_shim_drive" in launcher_src and "SHIM_STORAGE_DRIVE" in launcher_src)
+ all_ok &= check("launcher does not patch shim instruction operands",
+ "SHIM_LOAD_DISK_DEV_IMM" not in launcher_src and
+ "SHIM_PRELOAD_DEV_IMM" not in launcher_src)
print("\n=== App Switch Contract (F2/F4) ===")
try:
@@ -968,11 +949,10 @@ def main():
else:
all_ok &= check("tui switch contract source exists", os.path.exists(tui_contract["source_path"]),
tui_contract["source_path"])
- all_ok &= check("APP_BANK_MAX", tui_contract["app_bank_max"] == 223,
- f'{tui_contract["app_bank_max"]} (expect 223)')
- all_ok &= check("tui checks bitmap low byte", tui_contract["uses_bitmap_lo"])
- all_ok &= check("tui checks bitmap high byte", tui_contract["uses_bitmap_hi"])
- all_ok &= check("tui checks bitmap xhi byte", tui_contract["uses_bitmap_xhi"])
+ all_ok &= check("APP_BANK_MAX", tui_contract["app_bank_max"] == 64,
+ f'{tui_contract["app_bank_max"]} (expect 64)')
+ all_ok &= check("tui checks ReadyOS token status", tui_contract["uses_readyos_status"])
+ all_ok &= check("tui ignores retired shim bitmap", not tui_contract["uses_retired_bitmap"])
all_ok &= check("tui has loaded-bank helper", tui_contract["has_bank_loaded_helper"])
# --- REU Allocation Contract ---
@@ -1007,9 +987,8 @@ def main():
highest_used = len(catalog_entries)
all_ok &= check("catalog no longer preallocates app-slot pool", highest_used <= 64,
f"{highest_used} catalog apps, dynamic snapshots assigned on load")
- if highest_used > 23:
- warn("catalog exceeds shim bitmap-visible token count",
- f"{highest_used} catalog apps rely on bank-0 loaded state above token 23")
+ all_ok &= check("catalog fits schema-v5 app registry", highest_used <= 64,
+ f"{highest_used}/64 app records")
# --- Warm Resume Contract ---
print("\n=== Warm Resume Contract ===")