Changelog
All notable changes to ZX-M8XXX are documented in this file.
v0.9.27
- Port Trace Filter: Whitelist filter for trace logging and Port I/O log
- When empty, all ports are traced (default behavior); when ports are specified, only matching ports are recorded
- Applies to both runtime trace port ops and standalone Port I/O log
- Mask-based matching using same
parsePortSpecformat as breakpoints:FE,7FFD,FE&FF - UI: Port filter row in Trace panel with add/remove/clear controls and filter list
- Filter state (
portTraceFilters) persisted in project save/load
- Fix: Port I/O Export button no longer opens save dialog twice
- Multi-Drive Support: BetaDisk 4 drives (A-D) + FDC 2 drives (A-B) + simultaneous tape
- BetaDisk per-drive state (
loaders.js):drives[]array with per-drivediskData,diskType, andheadTrack- WD1793 track register remains shared (real hardware behavior); physical head position tracked per drive
loadDisk(data, type, driveIndex)— load into specific driveejectDisk(driveIndex)/hasDisk(driveIndex)/hasAnyDisk()— per-drive managementcreateBlankDisk(label, driveIndex)— blank formatted disk in specific drive
- FDC per-drive updates (
fdc.js):ejectDisk(driveIndex), drive number in activity callback - Tape + Disk coexistence (
spectrum.js): Loading tape no longer ejects disk and vice versa- Separate state:
loadedTape,loadedBetaDisks[4],loadedFDCDisks[2] - Separate file listings per controller:
loadedBetaDiskFiles[4],loadedFDCDiskFiles[2] clearTape()/clearDisk(driveIndex, type)for selective clearing
- Separate state:
- Drive selector UI (
index.html): Dropdown to choose target drive (A-D) when loading disk images - Per-drive catalog tabs: Dynamic drive sub-tabs in Settings → Media disk catalog
- Simple labels (
A:,B:, etc.) when one controller is active - Prefixed labels (
3DOS:A,3DOS:B,TRD:A,TRD:B) when both FDC and Beta Disk have disks simultaneously - Each tab shows only its controller’s catalog content
- Simple labels (
- Disk activity indicator: Drive letter prefix (e.g.,
A:T00:S01:A), tooltip lists all loaded drives - Auto-load gating: Only triggers when loading into drive A (index 0)
- Project save/load v2:
mediaVersion: 2format stores tape + per-drive Beta Disk + per-drive FDC disk- Backward compatible with old single-media project format
- BetaDisk per-drive state (
v0.9.26
- Scorpion ZS 256 Support: New machine type — Soviet clone with 256KB RAM
- New “scorpion” option in machine selector dropdown (group: Scorpion)
- 256KB RAM (16 × 16KB pages), 4 ROM banks in
scorpion.rom(64KB) - ROM layout: ROM0=128 BASIC, ROM1=48 BASIC, ROM2=Service Monitor, ROM3=TR-DOS
- Pentagon-compatible ULA timing (224 T/line × 320 lines = 71680 T/frame, no contention)
- AY clock: 1.75 MHz (Pentagon standard)
- Port 0x7FFD: standard 128K paging (RAM pages 0-7, ROM 0/1, screen bank, paging lock)
- Port 0x1FFD (exact match): bit 0 = RAM page 0 over ROM, bit 1 = Service Monitor ROM select, bit 4 = RAM page high bit (+8)
- 3-way ROM selection (per FUSE): 1FFD bit 1 set → ROM 2 (Service Monitor); unset → 7FFD bit 4 selects ROM 0/1
- Built-in TR-DOS: ROM bank 3 loaded into Beta Disk ROMCS (
trdosInRom: true) — no separatetrdos.romrequired - Beta Disk interface enabled by default (same as Pentagon)
- SZX machine ID: 8, Z80 hardware mode: 9 (same as Pentagon)
- SZX snapshots save/load all 16 RAM pages + port 0x1FFD state
- SNA load preserves Scorpion machine type when already selected
- Auto-loads from
roms/scorpion.romon startup - ROM dialog with scorpion.rom button and status indicator
- Test runner: Scorpion and Pentagon 1024 support: Both machines now available as test targets
- Added
scorpionandpentagon1024to test runnerswitchMachine()mapping - Previously fell through to 48K default silently
- Added
- Fix SZX snapshot Pentagon 1024: Save/load now preserves full paging state
- Port 0x7FFD reconstruction includes extended bits 6-7 (RAM bank bits 3-4) and bit 5 (1MB mode)
- Port 0xEFF7 saved in SPCR byte 3 and restored on load
- RAM page count no longer capped at 16 — all 64 pages saved/loaded correctly
- Fix SZX snapshot +3 paging: Port 0x1FFD now restored for +3 (not just +2A)
- Changed
machineType === '+2a'check topagingModel === '+2a'which covers both +2A and +3
- Changed
- Fix SNA load Pentagon 1024: Machine type preserved when loading 128K SNA snapshots
- Previously dropped to generic 128K; now stays on Pentagon 1024 (same as Pentagon and Scorpion)
- Fix getFullState() Pentagon 1024: State dump now includes portEFF7, pentagon1024Mode, and ramInRomMode
- Extract shared constants (
constants.js): Magic numbers replaced with named constants- Port addresses:
PORT_7FFD,PORT_1FFD,PORT_EFF7,PORT_ULAPLUS_*,PORT_WD_* - Port decode masks:
DECODE_128K_MASK,DECODE_PLUS2A_MASK,DECODE_AY_MASK, etc. - Paging bit masks:
P7FFD_RAM_MASK,P7FFD_SCREEN_BIT,P7FFD_ROM_BIT,P7FFD_LOCK_BIT - SNA format sizes:
SNA_48K_SIZE,SNA_128K_SIZE,SNA_128K_MIN,PAGE_SIZE - Screen memory:
SCREEN_ATTR,SCREEN_END,BANK_MASK
- Port addresses:
v0.9.25
- Explorer: DSK file support: Tools → Explorer now parses and displays DSK disk images
- Shows disk geometry (format, tracks, sides, sectors, block size, reserved tracks)
- +3DOS boot sector parsing: reads disk specification with checksum validation
- CP/M directory listing with precise file sizes from +3DOS headers
- File types (BASIC/CODE) with load addresses and autostart line numbers
- Full filenames with extensions (e.g.
SCREEN.BIN,GAME.CODE) - BASIC program decoding: click a BASIC file to see decoded listing
- Boot sector disassembly: Disasm tab shows boot loader code at $FE10
- Boot sector hex dump: Hex tab shows full boot sector from $FE00
- File content access: click a file for hex dump or disassembly
- Screen preview for files matching known screen sizes (6912, 6144, etc.)
- DSK files accessible inside ZIP archives (auto-drill and click)
- Fix: DSK Explorer crash on non-standard disk formats (“source array is too long”)
- Disks with large sectors (e.g. 4096 bytes) caused fractional
sectorsPerBlock, leading to undersized buffer in_readDirectoryand overflow inTypedArray.set() _readDirectoryrewritten to use byte-count loop, handles any sector sizelistFiles/readFileDatanow use boot track geometry consistently for block-to-sector mapping
- Disks with large sectors (e.g. 4096 bytes) caused fractional
- Fix: DSK loading crash on non-CP/M disks (e.g. copy-protected games like Hostages)
listFiles()wrapped in try/catch in bothloadDSKImage()and Explorer- Non-filesystem disks load and auto-boot correctly; Explorer shows geometry without file list
v0.9.24
- FDC Read Track command (0x02): Implement Read Track for copy-protected games (e.g. Batman)
- Reads all sectors on current track in physical order, ignoring sector IDs
- Previously unrecognized command caused FDC desync — game sent 9-byte command but FDC returned invalid result after byte 1, leaving subsequent bytes misinterpreted
- FDC Scan commands (0x11/0x19/0x1D): Accept all 9 command bytes (stub returning scan-not-satisfied)
- Prevents same desync issue as Read Track for any game using Scan Equal/Low/High
- Fix FDC drive select masking: Only bit 0 decoded on +3 hardware (drives 0/2 map to same physical drive)
- Batman’s bootstrap uses drive=2 in FDC commands; previously treated as non-existent drive
- Fix FDC Read/Write Data physical track lookup: Use drive head position, not logical cylinder from command
- Copy-protected disks have non-matching physical/logical track numbers (e.g. physical track 38, C=0x12 in sector headers)
- Previously read data from wrong physical tracks, causing garbage on screen
- Fix FDC Read Data R > EOT handling: Always read at least sector R regardless of EOT value
- On real µPD765, sector R is always read; EOT only controls when to stop reading additional sectors
- Games with non-standard sector layouts (R=0x0B, EOT=0x09) hung waiting for data that was never provided
- Fix FDC CRC-error noise destroying game data: Only randomize CRC-error sectors where stored data fully covers the declared size
- Oversized sectors (e.g. N=6, 8192 declared, 6144 actual) have CRC errors because declared size exceeds stored data — their content is valid game data, not noise
- Previously ALL CRC-error sectors had bytes 256+ randomized, destroying valid data (e.g. Robocop 2)
- Now:
sec.data.length >= sectorDataSize→ randomize (genuine CRC corruption, e.g. Target Renegade protection);sec.data.length < sectorDataSize→ pass through as-is
- Fix +3 DSK auto-load: Use Amstrad menu Enter key injection (like +2/+2A tape) instead of raw PC=0 boot — ROM’s “Loader” option now properly detects disk and boots the game
v0.9.23
- ZX Spectrum +3 Support: First-class machine type with built-in floppy disk controller
- New “+3” option in machine selector dropdown
- +3 ROM section in ROM dialog (
plus3.rom, 64KB — 4 ROM banks) - Auto-loads from
roms/plus3.romon startup - Same memory banking as +2A (
pagingModel: '+2a', port 0x1FFD special paging) - Z80 snapshot hwMode 7 maps to +3; SZX machineId 5 maps to +3
is128kCompat()helper updated to include +3
- µPD765 FDC Emulation (
fdc.js): Floppy disk controller for ZX Spectrum +3- Full state machine: idle → command → execution → result phases
- 11 commands: Specify, Sense Drive Status, Read/Write Data, Recalibrate, Sense Interrupt Status, Read ID, Write/Read Deleted Data, Format Track, Seek
- MSR (Main Status Register) with RQM, DIO, NDMA, CB bits
- Port 0x2FFD (MSR read), 0x3FFD (data read/write), motor via 0x1FFD bit 3
- 4 drives supported, instant-completion model (same approach as BetaDisk WD1793)
- Disk activity indicator shows FDC operations
- DSK Disk Format Support: Standard and extended CPC DSK format
DSKLoader.parse()handles both “MV - CPC” standard and “EXTENDED CPC DSK” formatsDSKImageclass for in-memory disk with read/write sector operations- CP/M-style directory listing in Settings → Media → Disk tab
.dskfiles recognized in file picker, ZIP browser, and drag-and-drop
- Auto Load for +3 DSK: Boots +3 from disk automatically when Auto Load is enabled
bootPlus3Disk()resets machine, preserves disk, sets motor on, boots from ROM- Amstrad menu handling: +3 added to Amstrad menu detection
- Fix: Beta Disk auto-paging on +2A used hardcoded ROM bank 1
updateBetaDiskPaging()andbootTrdos()now useprofile.basicRomBank(bank 3 for +2A)
- Fix: FDC port reads (0x2FFD, 0x3FFD) were overwritten by floating bus handler
- FDC reads were outside the port dispatch if/else chain; floating bus
elseclause overwrote results with garbage - Moved FDC reads into the if/else chain to prevent fallthrough
- FDC reads were outside the port dispatch if/else chain; floating bus
- Fix: FDC Read/Write Data correctly buffers sectors from R to EOT
- +3 ROM sets EOT=R for single-sector reads (buffers 1 sector), custom game loaders set EOT > R for multi-sector reads
- Previously single-sector-only buffering broke custom loaders that expect multi-sector transfers (e.g. Venom Strikes Back, Target Renegade)
- Fix: FDC data commands returned normal termination (ST0=0x00) instead of abnormal
- +3 ROM expects ST0 bits 7:6 = 01 (abnormal) and ST1 bit 7 = EN (end of track) because TC is never asserted
- Without these flags, +3DOS treated successful reads as errors
- Fix: FDC MSR missing drive busy bits and EXM flag
- Added drive busy bits (MSR bits 0-3), set by Seek/Recalibrate, cleared by Sense Interrupt Status
- EXM bit (bit 5) correctly set during execution phase for non-DMA mode
- Fix: FDC Sense Drive Status returned wrong flags for missing drives
- No disk now returns WP=1 (write protected) + RDY=0 (not ready), matching +3 ROM’s drive detection logic
- Fix: FDC CM (Control Mark) flag in ST2 was inverted for Read Deleted Data
- CM should be set when actual data mark type doesn’t match command expectation
- Read Data + deleted mark → CM=1; Read Deleted Data + normal mark → CM=1
- Fix: Extended DSK parser returned empty sector data when
actualLen=0- In extended CPC DSK format,
actualLen=0means use default size from N (size code), not 0 bytes - Affected games using non-standard formats (e.g. Target Renegade: 1024-byte sectors, deleted data marks)
- In extended CPC DSK format,
- Fix: FDC Read Data/Read Deleted Data discarded DSK sector error flags (ST1/ST2)
- DSK files store per-sector ST1/ST2 for copy protection (CRC errors, missing marks, etc.)
- FDC now passes through DSK error flags (DE, DD, MA, MD) merged with computed flags (EN, CM)
- Fixes copy-protected games that check for specific error signatures (e.g. Target Renegade reads sector 2 expecting ST1=0x20 DE + ST2=0x20 DD)
- Fix: EDSK weak/random sector support for copy protection (Speedlock +3)
- Sectors with
actualSize > nominalSize(exact multiple) contain multiple data copies - At parse time, copies are compared byte-by-byte to build a weak byte map
- On each FDC read, weak byte positions are randomized (FUSE approach)
- Fixes Speedlock-protected games that read a sector multiple times and expect different data (e.g. Target Renegade)
- Sectors with
- Fix: FDC SK (Skip Deleted) flag parsed but never used in Read Data/Read Deleted Data
- SK=1 now skips sectors whose mark type doesn’t match the command
- SK=0 reads mismatched sectors but sets CM flag and terminates after the sector
- Per-sector DDAM check via DSK ST2 bit 6 (Deleted Data Address Mark indicator)
- Fix: FDC EN (End of Track) flag unconditionally set in ST1
- EN should only be set when all R→EOT sectors were read without early termination
- Not set when terminated by CM (mark mismatch) or CRC error (DE flag)
- Fix: +2A/+3 memory contention used wrong delay pattern
- 48K/128K/+2 use pattern (6,5,4,3,2,1,0,0); +2A/+3 use (7,6,5,4,3,2,1,0)
- Added profile-driven
contentionPatternproperty ('65432100'vs'76543210') - Precomputed contention delay lookup table replaces Swan formula
- Reference: FUSE
contend_delay_76543210for +3, sinclair.wiki.zxnet.co.uk contention tables
- Fix: +2A/+3 incorrectly applied IO contention
- The Amstrad 40077 gate array only contends on MREQ, not during IO operations
- Added
hasIOContentionprofile flag;applyIOTimingsreturns 0 when false - Reference: sinclair.wiki.zxnet.co.uk/wiki/Contended_I/O (“no contention occurs” on +3)
- Fix: +2A/+3 incorrectly applied internal cycle contention
- Non-MREQ cycles (DJNZ, JR internal waits) should not be contended on +2A/+3
- Added
hasInternalContentionprofile flag;contendInternalskips delays when false - Reference: FUSE
contend_delay_no_mreq = spectrum_contend_delay_nonefor +3
v0.9.22
- Machine Profile System: Configurable machine definitions replacing hardcoded type checks
- Pentagon 1024 Support: Extended memory banking (64 RAM pages) via port 0xEFF7
v0.9.21
- ZX Spectrum +2A Support: First-class machine type (without floppy)
- New “+2A” option in machine selector dropdown
- +2A ROM section in ROM dialog (
plus2a.rom, 64KB — 4 ROM banks) - Auto-loads from
roms/plus2a.romon startup - Port 0x1FFD handling: special all-RAM paging modes (4 configurations)
- ROM bank selection via combined 0x7FFD bit 4 and 0x1FFD bit 2
- +2A contention: banks 4,5,6,7 (differs from 128K/+2 which uses 1,3,5,7)
- Same ULA timing as 128K (228 T/line, 311 lines, 70908 T/frame)
- Z80 snapshot hwMode 13 maps to +2A; SZX machineId 4 maps to +2A
- SZX snapshot preserves port 0x1FFD value in SPCR chunk
- +3/+3e SZX snapshots treated as +2A (hardware-identical minus floppy)
- Tape trap uses ROM bank 3 for 48K BASIC (not bank 1 like 128K)
is128kCompat()helper updated to include +2A
- Auto Load for Amstrad menu (+2/+2A): Press Enter to select “Tape Loader” (default menu item) which runs LOAD “” automatically — no key typing needed
- SCL boot injection: Boot file injection (Settings → Media → Boot File) now works for SCL files
- SCL converted to TRD format before boot injection via
betaDisk.sclToTrd() - Ensures “Add boot” / “Replace boot” modes apply to both TRD and SCL disk images
- SCL converted to TRD format before boot injection via
- Test runner +2A support: Test suite correctly loads TAP files on +2A machines
- Mirrors main auto-load approach: waits for Amstrad menu, presses Enter for Tape Loader
- Machine alias
plus2amapped to+2ain test runner’sswitchMachine()
- Test runner TRD/SCL disk support: Tests can now boot from disk images
- New
diskRunfield in tests.json: program name to run (e.g."game") or"boot"for boot file - Boots TR-DOS via
bootTrdos(), waits for prompt, typesRUN "filename"and Enter - Works with TRD and SCL files (SCL converted to TRD automatically)
- New
v0.9.20
- ZX Spectrum +2 Support: First-class machine type with dedicated ROM
- New “+2” option in machine selector dropdown
- +2 ROM section in ROM dialog (
plus2.rom, 32KB) - Auto-loads from
roms/plus2.romon startup - ROM dialog reopens with Close button when switching to a machine with missing ROM
- Identical hardware to 128K (same ULA timing, contention, AY, memory banking) — only ROM differs
is128kCompat()helper function for 128K-compatible hardware checks- Z80 snapshot hwMode 12 maps to +2; SZX machineId 3 maps to +2
- Z80/SZX export writes correct machine identifiers for +2
- SNA load preserves +2 machine type when already selected
- Tape trap ROM bank check includes +2
v0.9.19
- Auto Load: Automatic load-and-run for tape and disk files
- New “Auto Load” checkbox in Settings → Media (enabled by default)
- TAP/TZX: Resets machine, types
LOAD ""(128K: selects BASIC from menu first) - TRD/SCL: Boots into TR-DOS automatically
- Pure turbo TZX (no standard blocks): Switches to real-time mode automatically
- setTimeout-based key injection using
ula.keyDown()/ula.keyUp() - Cancels cleanly on machine change, reset, or new file load
- Setting saved/restored in project files
- TZX Turbo Block Handoff: Flash load to real-time turbo transition
- Dual tape system:
tapeLoader(standard blocks only) +tapePlayer(all blocks) standardBlockMapmaps flash-loaded block indices to full tape positions- After flash-loading standard blocks, turbo blocks auto-start via
_turboBlockPendingflag - Auto-start triggers in
portRead()when custom loader reads port 0xFE - Critical
PC >= 0x4000guard prevents false trigger from ROM keyboard scan
- Dual tape system:
- Tape Block Catalog: Block listing in Settings → Media
- Shows all TZX/TAP blocks with type labels (Standard, Turbo, Pure Tone, etc.)
- Displays block sizes and current playback position
- Fix: Disk auto-load (TRD/SCL) crashed on Pentagon instead of booting TR-DOS
bootTrdos()was manually constructing system variables and jumping to wrong entry point (0x3D13)- Rewritten to use FUSE-style approach: reset machine, select ROM bank 1, page in TR-DOS ROM, boot from address 0
- TR-DOS ROM runs its own initialization from address 0, properly setting up all system variables and workspace
- Fix: Beta Disk auto-paging only worked on Pentagon, not on 48K/128K with Beta Disk enabled
- Main loop gated
updateBetaDiskPaging()byisPentagoninstead of_betaDiskPagingEnabled
- Main loop gated
- Fix: Loading TRD/SCL on machine without Beta Disk no longer forces switch to Pentagon
- Now shows warning message instead of automatically changing machine type
v0.9.18
- Fix: Screen flicker in double-buffered games (e.g., Cubix) on 128K/Pentagon
- Deferred paper rendering was incorrectly triggered by simple double-buffering (1 bank swap per frame)
- Deferred mode reads screen RAM at end-of-frame, which shows the cleared back buffer instead of the completed display
- Now only defers for scroll17-style effects (many rapid bank alternations per frame)
- Normal scanline rendering correctly handles double-buffering by reading the active bank at each line’s execution time
- Fix: SZX snapshots inside ZIP archives were not recognized
findAllSpectrum()in ZIP loader was missing.szxfrom the supported extension list
- Fix: SZX save wrote wrong machine ID for Pentagon (saved as 128K instead of Pentagon)
- Caused machine type mismatch on load, leading to ULA dimension errors (IndexSizeError)
- Pentagon machine ID is now correctly written as 7 in SZX header
v0.9.17
- Fix: Debugger “Go to address” navigation error (navHistory not defined)
- Fix: Beam mode rendering improvements for multicolor programs after snapshot load
- Fix: Beam mode now preserves last complete frame as background (not overwritten when stepping)
- Fix: “No Bitmap” overlay mode now respects multicolor (per-scanline attributes)
- Improve: Beam mode previous frame is darker (50%) for better contrast with current colored region
v0.9.16
v0.9.15
- Test Suite Enhancements: Extended automated test capabilities
- Added RZX file support for input recording playback tests
- Added SZX snapshot format support
- New multicolor rendering tests (Shock megademo, Nirvana+ effects)
- New RZX playback tests to verify recording compatibility
- Test categories: Filter tests by type (All/CPU/Video/ULA+/Multicolor/RZX)
- Category tabs with test counts above test list
- Select-all checkbox now only affects visible (filtered) tests
- Fixed ROM corruption when tests load snapshots that change machine type
- Fixed RZX playback in test runner (frame counter wasn’t advancing in headless mode)
- Fixed ULA+ palette bleeding between tests (now reset before each test)
- RZX Playback Fix: Fixed RZX playback failing when loaded from different machine type
- Loading 48K RZX while in Pentagon or 128K mode now works correctly
- ROM is now properly reloaded when machine type changes during snapshot loading
- Previously, wrong ROM was used causing execution to diverge (e.g., RET returning to wrong address)
- RZX UI Fix: RZX controls now properly clear when loading other files
- Stop button and progress indicator no longer remain visible after loading snapshot/tape
- Loading Fix: Fixed black screen when loading snapshot while RZX is playing
- Emulation now properly restarts after ROM reload on machine type change
- Code Cleanup: Removed excessive debug logging
- Removed Z80 Loader debug messages
- Removed RZX initial state dump
v0.9.14
- Info Tab Reorganization: Restructured Info tab with sub-tabs for better organization
- I/O sub-tab: Keyboard layout, ports (keyboard, Kempston, ULAplus, AY-3-8910), colors
- Timings sub-tab: Frame timing, border sizes, memory map, RAM banks, contention patterns, Pentagon differences
- Opcodes sub-tab: Z80 instruction set reference (moved from main tabs)
- Tools Tab: New consolidated Tools tab with sub-tabs
- Explorer sub-tab: File structure viewer (TAP, TZX, SNA, Z80, etc.)
- Compare sub-tab: Snapshot and binary comparison tool
- Tests sub-tab: Emulator regression tests (moved from main tabs)
- Export sub-tab: Screenshot, frame export, PSG capture, RZX recording, ASM export options
- Settings Tab Reorganization: Split Settings tab into sub-tabs
- Display sub-tab: Border size, palette, zoom, overlay, fullscreen mode, late timings, ULA+
- Input sub-tab: Kempston joystick/mouse, gamepad, Beta Disk
- Media sub-tab: Flash load, tape controls, blank disk, boot file
- Audio sub-tab: Sound, AY in 48K, volume, stereo mode
- ULAplus Support: Extended palette mode for 64 colors
- Ports $BF3B (register select) and $FF3B (data)
- 64-color palette using GRB 332 format (4 CLUTs × 16 colors)
- Real-time palette preview in Settings → Display
- Enable/disable via checkbox, persisted to localStorage
- HAM256 raster effects: Full support for mid-frame palette changes
- Tracks palette writes with T-state timing
- Group-based palette lookup (12 groups × 64 entries per frame)
- Works on 48K, 128K, and Pentagon machines
- ULAplus state properly managed on machine switch (checkbox preserved, palette reset)
- SCR Export with ULAplus: Export screen with extended palette
- Standard SCR: 6912 bytes (bitmap + attributes)
- ULAplus SCR: 6976 bytes (+ 64-byte palette appended)
- Auto-detects if game has modified ULAplus palette
- Compatible with ZX-Paintbrush and other editors
- Export Improvements:
- Added PNG format to export format selector
- Export button uses selected format (PNG, SCR, BSC, etc.)
- SCR export reads raw screen memory for accurate ULAplus data
- Game Browser Improvements:
- Fixed pagination (client-side, fetches up to 100 results)
- Added placeholder with diagonal lines for games without screenshots
- Scroll to top when changing pages
v0.9.13
- Game Browser: Added online game search powered by Spectrum Computing (ZXDB)
- Access via Load → Web in toolbar
- Search games by title with screenshots and details
- Uses ZXInfo API (api.zxinfo.dk) - the largest ZX Spectrum database
- Direct download links for TAP, TZX, Z80, SNA files
- Results sorted alphabetically by title
- Zero dependencies - works directly from browser
- Quicksave/Quickload: Save and restore game state instantly
- F2 = Quicksave (saves to browser localStorage)
- F5 = Quickload (restores saved state)
- Also accessible via Save/Load dropdowns
- Uses SZX format for full state preservation
- UI Improvements: Consolidated toolbar for cleaner interface
- Load dropdown: File, Web, Project, Quick (F5)
- Save dropdown: SNA, Z80, SZX, Project, Quick (F2)
- Help and theme buttons moved next to Save dropdown
- App name/version moved to Help button tooltip
- Reduced toolbar width, no more overlapping with tabs
- Info Tab: Added input port reference
- Keyboard port (#FE) with all half-row addresses and key bits
- Kempston joystick port (#1F) with direction/fire bits
- Kempston mouse ports (#FBDF, #FFDF, #FADF)
- Input state summary: keyboard active-low (0=pressed), joystick active-high (1=pressed)
- RZX Recording: Fixed RZX export to work with other emulators (Spectaculator, EmuZWin)
- Recording now starts after interrupt fires, not at frame boundary
- Uses SZX snapshot format (preserves CPU halted state)
- Keyboard scan inputs now correctly captured in frame 0
- Most recordings work; some games with unusual timing (e.g., Batty) may still fail
- RZX Loading Fix: Show snapshot screen when RZX is loaded in paused state
- Canvas was cleared by updateCanvasSize() after snapshot rendering
- Border color from snapshot now correctly displayed
- RZX Explorer Fix: Fixed Z80 screen preview showing random blocks
- Z80 format always stores screen in page 8 (both 48K and 128K)
- Was incorrectly looking for page 5 in 128K mode
- UI Fix: Can now start new RZX recording after exporting
- Recording button was disabled after export due to stale playback state
- Code Cleanup: Removed excessive RZX debug logging
v0.9.12
- RZX Playback Improvements: Improved RZX replay compatibility
- Fixed Z80 loader not recognizing +3, +2, +2A machine types (hwMode 7, 12, 13)
- Fixed Z80 loader not recognizing Pentagon (hwMode 9) in V2 format snapshots
- Fixed ROM not loaded when switching from 48K to 128K/Pentagon (ROM bank 1 was empty)
- Some recordings still have issues due to emulator-specific behavior differences
- Disassembler Fixes: Fixed several bugs in disassembler and trace-to-file export
- Export Enhancement: Added option to collapse multiple lines of block operations (LDIR, LDDR, etc.)
- Reduces output size for repeated block instruction sequences
- Multicolor Fix: Fixed Shock megademo multicolor rendering bug
- Issue was caused by previous screen bank switching optimization
- Snapshot Loading Fix: Fixed frozen display/no sound when loading SZX/Z80/SNA snapshots
- Root cause: paging lock from previous program blocked port 7FFD writes
- All loaders now reset
pagingDisabledbefore restoring paging state - Also reset frame timing and ULA deferred rendering state
- UI Improvements:
- Removed redundant “Running/Stopped” status label (button text shows state)
- Fixed RZX status layout shifts when frame counter digits change
- Removed RZX debug overlay (keypress display in bottom-right corner)
- Code Cleanup: Removed excessive console logging throughout codebase
- Debug logs now controlled by flags (debugContention, debugInterrupts, etc.)
v0.9.11
- Fullscreen Mode: Added fullscreen support for the emulator canvas
- Fullscreen button (⛶) in the control bar, or press F11
- ESC key exits fullscreen
- Three display modes:
- Crisp: Integer scaling for perfectly sharp pixels (default)
- Fit: Maximum scale with aspect ratio preserved
- Stretch: Fill entire screen
- Setting saved to localStorage
- Disassembler Fix: Fixed incorrect mnemonic for indexed load instructions
LD L,(IX+d)was incorrectly shown asLD IXL,(IX+d)LD H,(IX+d)was incorrectly shown asLD IXH,(IX+d)- Same fix applied for IY variants
- IXH/IXL substitution now only applies when not using indexed memory addressing
- Displacement now shown in hex (e.g.
IX+31hinstead ofIX+49for 0x31)
- Trace Recording Fix: Fixed incorrect disassembly for self-modifying code
- Instructions that write to their own address (e.g.
LD (94AEh),IXat 94AF) were traced incorrectly - Now captures instruction bytes BEFORE execution, not after memory modification
- Instructions that write to their own address (e.g.
- RZX Playback Fix: Fixed DDCB/FDCB M1 cycle counting
- DDCB/FDCB instructions now correctly count as 2 M1 cycles, not 3
- R register now increments correctly (2 times per instruction)
- Fixes potential RZX playback desync for recordings using indexed bit operations
- RZX Playback Fix: Fixed screen rendering artifacts during RZX playback
- T-states now reset at frame start during RZX playback
- Fixes “line by line” progressive rendering artifact where parts of screen weren’t rendered
- RZX frames end by instruction count, not T-states, causing scanline calculation drift
v0.9.10
- Performance Optimization: Fixed severe slowdown with screen bank switching effects
- Demos using 128K screen bank switching (Echologia, etc.) now run at full speed
- Optimized
renderDeferredPaper()from per-pixel to per-column rendering (~100x faster) - Pre-cached RAM bank lookups to avoid repeated function calls
v0.9.9
- Hobeta Boot Support: Boot file injection now accepts Hobeta files
- Supports Hobeta files (typically .$b or .$c)
- Boot source can be TRD disk or standalone Hobeta file
- UI shows file type label: “(TRD)” or “(Hobeta)”
v0.9.8
- Boot TRD Injection: Automatically add boot loader to TRD disk images
- Settings → Media → Boot File: select a TRD or Hobeta file containing a boot loader
- Three modes: No change, Add boot (if missing), Replace boot
- Boot file is injected when loading TRD images based on selected mode
- Smart replace: reuses old boot’s disk location when new boot fits
- Error popups when disk is full or boot cannot be added
- TR-DOS Boot Loaders Fix: Fixed boot loaders showing empty disk
- TR-DOS ROM flag was not being updated after ROM load
- Boot loaders now properly read disk catalog via TR-DOS ROM
- Extended Mode Characters: Fixed typing of
[ ] { } ~ | \characters- These characters require Extended Mode on Spectrum (Caps+Symbol, then Symbol+letter)
- Emulator now automatically simulates the two-step key sequence
- Works in both 48K and 128K BASIC modes
v0.9.7
- Keyboard Remapping: Changed modifier key assignments
- Ctrl → Caps Shift (was Shift)
- Alt → Symbol Shift (was Ctrl)
- PC Shift now free for regular shifted characters (!@#$%^&*etc)
- Non-English Keyboard Fix: Keyboard now works with any layout (Russian, German, etc.)
- Uses
e.code(physical key position) instead of deprecatede.keyCode - Keys mapped by QWERTY physical layout, independent of active language
- Uses
- SCA Type 1 Export: Added payload type 1 support for multicolor animations
- Type 0: Full 6912-byte SCR frames (unchanged)
- Type 1: 8-byte fill pattern + 768-byte attributes per frame (smaller files)
- Fill pattern options: 53c (AA 55), 127c (DD 77), Vertical 4x8, Horizontal 8x4, Custom
- Automatic pattern detection from captured screen bitmap
- User prompt when pattern cannot be auto-detected
v0.9.6
- SCA Export Fix: Fixed SCA animation export version field (was 0, now 1)
- Exported .sca files now compatible with other viewers
v0.9.5
- Code Folding: Collapse/expand subroutines and custom blocks in disassembly
- Click fold toggle (▾/▸) on subroutine headers to collapse/expand
- Collapsed view shows summary: “(N bytes, M instructions)”
- User-defined fold blocks via right-click → “Create fold block…”
- Fold markers for user blocks displayed in magenta
- “Collapse all folds” / “Expand all folds” in context menu
- Auto-expand when PC enters a collapsed region
- Fold state saved in projects and localStorage
- Works in both main and right panel disassembly views
v0.9.4
- TZX Tape Loading: Full TZX file format support with variable speed blocks
- Standard speed data blocks (0x10) - same as TAP
- Turbo speed data blocks (0x11) - custom pilot/sync/data timing
- Pure tone blocks (0x12) - single frequency pulses
- Pulse sequence blocks (0x13) - arbitrary pulse arrays
- Pure data blocks (0x14) - data without pilot/sync
- Pause/Stop blocks (0x20) - silence between blocks
- Loop blocks (0x24/0x25) - multi-load support
- TZX files work in both flash load and real-time modes
- Unified block format for TAP/TZX playback
- TZXLoader Class: New parser for TZX format in loaders.js
- Magic byte detection (“ZXTape!” + 0x1A)
- Converts TZX blocks to unified format for TapePlayer
- ZIP archive support for TZX files
v0.9.3
- Real-Time Tape Loading: Optional cycle-accurate tape playback with border stripes and sound
- New “Flash Load” checkbox toggles between instant (ROM trap) and real-time modes
- Real-time mode shows authentic border loading stripes during tape playback
- Tape audio emulation with “Tape Sound” checkbox to enable/disable loading sounds
- Play/Stop/Rewind controls for manual tape control in real-time mode
- Tape position indicator shows current block and progress
- Standard tape timing: pilot (2168T), sync (667T/735T), zero (855T), one (1710T)
- Both settings saved/loaded with projects
- TapePlayer Class: New tape playback engine with accurate timing
- State machine: pilot → sync1 → sync2 → data → pause → next block
- Edge transition recording for audio generation with T-state precision
- Proper header (8063 pulses) and data block (3223 pulses) pilot lengths
v0.9.2
- PSG Export: Record AY chip output to PSG file format
- Start/Stop recording in Settings → AY Capture section
- “Changed only” option exports only modified registers (smaller files)
- “Get Player” downloads ready-to-assemble Z80 player source
- Real-time frame/write counter during recording
- Sound Fix for 128K: Fixed AY sound not working after machine type switch
ayEnabledflag now correctly updates insetMachineType()
- Audio Context Improvements: Better browser autoplay policy handling
- Audio init triggers on both click and keydown events
- Persistent resume handlers for stricter browsers
- Default Settings Changes:
- Default zoom changed to x1 (was x2)
- Late Timings disabled by default (was enabled)
v0.9.1
- 48K Border Timing Fix: Memory-location-aware I/O timing for OUT (n),A
- Contended memory ($4000-$7FFF): ioOffset=11 (fixes Aquaplane)
- Non-contended memory ($8000+): ioOffset=8 (fixes Venom)
- OUT (C),r unchanged at ioOffset=9 (ULA48 continues to pass)
- All border timing tests now pass: Aquaplane, ULA48, Venom, P128, Comet
v0.9.0
- 128K Border Timing Fix: Instruction-specific I/O timing for accurate border effects
- OUT (C),r (12T): ioOffset=13 for ULA128-style timing tests
- OUT (n),A (11T): ioOffset=9 for Shock-style multicolor demos
- Both ULA128 test and Shock megademo now display correctly on 128K
- 128K Multicolor Timing: Refined attribute timing calculations
- TOP_LEFT_PIXEL_TSTATE=14364 (documented value) now used consistently
- Border and paper rendering aligned (BORDER_TIMING_OFFSET=0)
- mc128kOffset tuning parameter for fine-grained control
v0.8.9
- Multicolor Support: T-state accurate attribute tracking for Nirvana+ and similar engines
- Attribute writes ($5800-$5AFF) now tracked with precise T-state timing
- Rendering uses correct attribute value at each column’s ULA scan time
- Shock megademo, Nirvana+ games now display correctly
- PUSH Contention Timing: Fixed 1T internal cycle before memory writes
- PUSH writes now contended at T+5 and T+8, not T+4 and T+7
- Critical for multicolor engines that use PUSH for rapid attribute updates
- Interrupt Timing: Fixed contention for interrupt/NMI handling
- IM1/IM2: 7T acknowledge cycle before push (no internal cycle)
- NMI: 5T acknowledge cycle before push
- Interrupt push correctly skips the 1T internal cycle
- Beta Disk for 48K/128K: TR-DOS interface now available on all machine types
- New “Beta Disk (TR-DOS)” checkbox in Settings → Input section
- Allows loading TRD/SCL disk images on 48K and 128K machines
- Requires trdos.rom to be loaded; always enabled for Pentagon
v0.8.8
- Filename Display Fix: Test runner now updates filename in status bar when loading files
- Previously, running tests would leave stale filename from previous manual load
- Both
loadTestFileandloadExtractedFilenow update the display
- Border Timing Improvements: Instruction-specific timing for 48K border effects
- OUT (C),r (12T) uses ioOffset=9, OUT (n),A (11T) uses ioOffset=8
- Fixes Comet and similar demos that use OUT (C),r for border effects
- ULA48, Comet, Venom border tests now pass
v0.8.7
- Port 0xFE Emulation Fix: Fixed IN instruction tests (Raxoft z80test)
- EAR input (bit 6) now LOW when no tape (Issue 2/3 ULA behavior)
- Bits 5,7 now consistently HIGH for port 0xFE reads
- Floating bus still available via other port reads
- ULA Timing Improvements: Fixed early/late timing for 48K and 128K
- Settings preserved when loading files (only projects change settings)
- 48K: Early timing (14336T) now default and matches ULA48 test
- 128K: Late timing (14361T) matches ULA128 test
v0.8.6
- AudioWorklet Migration: Replaced deprecated ScriptProcessorNode with modern AudioWorklet API
- New
audio-processor.jsruns on dedicated audio thread - Lower latency, no UI jank during audio processing
- Supported in all modern browsers (Chrome 66+, Firefox 76+, Safari 14.1+)
- New
- Code Cleanup: Removed debug logging from console
v0.8.5
- Gamepad Calibration: Configure any USB/Bluetooth gamepad
- Click “Calibrate” button next to Gamepad checkbox
- Assign Up/Down/Left/Right/Fire by moving stick or pressing buttons
- Extended buttons (C, A, Start) for Sega-style games
- Mapping saved to localStorage and project files
- Explorer BASIC: USR VAL “number” addresses now clickable
- Supports quoted numbers:
USR VAL "24064" - Supports scientific notation:
USR VAL "2.4064E4" - Also works with PEEK VAL and POKE VAL
- Supports quoted numbers:
- Performance: Audio disabled at speeds > 200% to reduce CPU usage
- Numpad Kempston: Fixed cross-platform compatibility
- Uses
e.codeinstead of deprecatede.keyCode - Up/Down now work consistently on all keyboards
- Uses
- Console: Removed verbose SCL/TRD conversion debug messages
v0.8.4
- Kempston Mouse: Full mouse emulation with pointer lock
- Click screen or 🖱️ button to capture mouse, Escape to release
- Ports: FADF (buttons), FBDF (X), FFDF (Y)
- Optional wheel support on bits 7:4 of button port
- Extended Kempston Joystick: Sega Genesis/Mega Drive gamepad compatible
- Bit 5: C button ([ key)
- Bit 6: A button (] key)
- Bit 7: Start button (\ key)
- Hardware Gamepad Support: USB/Bluetooth controllers via Gamepad API
- D-pad and analog stick for directions
- Standard button mapping (A=Fire, B/X=Extended buttons, Start)
- Auto-detection with status display
- Per-Panel Navigation: Left and right disasm panels have independent history
- ◀/▶ buttons navigate within each panel
- Clicking CALL/JP targets navigates in the same panel
v0.8.3
- Snapshot Saving Formats: Added Z80 and SZX snapshot saving
- Save dropdown replaces Save button - select SNA/Z80/SZX format
- Z80 v3 format (48K, 128K, Pentagon) - uncompressed for maximum compatibility
- SZX format with zlib compression (48K, 128K, Pentagon)
- Pentagon snapshots use hardware mode 9 in Z80 format
v0.8.2
- Calculator in Right Panel: Moved calculator from tab to right panel dropdown
- Available as third option alongside Memory and Disasm
- Bits panel spans full width below calculator and history
- History preserved when switching between panel types
- Numeric system dropdown disabled when formula is present (prevents conversion errors)
- UI Improvements:
- Reduced panel heights for better fit on smaller monitors
- Fixed dropdown styling in dark mode
- Compact calculator layout with optimized spacing
v0.8.1
- Configurable Debug Panels: Left and right panels can independently show disasm or memory dump
- Panel type selector dropdown in each panel header
- All panel combinations supported: disasm+memory, disasm+disasm, memory+memory, memory+disasm
- Step controls appear in disasm panels, search controls in memory panels
- Bookmark emojis indicate panel type (🔍 disasm, 📦 memory)
- Improved Context Menu Navigation: Unified navigation across all panels
- “Address XXXX” header shows target address
- Explicit “Disasm left/right” and “Memory left/right” options
- Right-click on memory address column now works
- Hover underline on memory addresses
- UI Improvements:
- Fixed panel height alignment in portrait and landscape modes
- Fixed search mode sync between independent memory panels
- Region coloring in left memory panel matches right panel
- Consistent lowercase menu item text
v0.8.0
- Subroutine Detection: Mark and display subroutines in disassembly
- Manual marking via right-click context menu
- Auto-detection during Auto-Map Apply (CALL instruction targets)
- IDA-style separator display with subroutine name
- End marker after RET instruction (“; end of sub_XXXX”)
- Saved in projects and localStorage per file
- Explorer Tab: New Explorer tab for analyzing ZX Spectrum files without loading into emulator
- Supports TAP, SNA, Z80, TRD, SCL, SZX, RZX, and ZIP formats
- File Info sub-tab: File structure, blocks, registers, disk catalogs
- BASIC sub-tab: Decode and display BASIC programs with syntax highlighting
- Disasm sub-tab: Z80 disassembly with ROM routine labels
- Hex Dump sub-tab: Raw hex view with ASCII column
- Screen preview for snapshots and graphics files
- Click on TRD/SCL BASIC files to decode, CODE files to disassemble
- Click USR addresses in BASIC to jump to disassembly view
- Blank lines after flow control instructions (JP, JR, CALL, RET, RST, DJNZ, HALT)
- Copy-friendly text format for disassembly and hex dump
- TR-DOS BASIC decoder with correct PROG address (0x5D3B)
- Code Refactoring: Removed duplicate functions, shared flow-break detection
- Bug Fixes:
- Fixed DJNZ not showing blank line in debugger disassembly
- Fixed text selection in Explorer outputs
v0.7.1
- Compare Tool: New Compare tab for comparing snapshots and binary files
- Compare two snapshot files (.SNA or .Z80, 48K or 128K)
- Compare two raw binary files byte-by-byte
- Compare snapshot against current emulator state
- Side-by-side hex dump with ASCII representation
- Register comparison with main and alternate registers side-by-side
- Differences highlighted in red with marker
- Exclude screen memory option ($4000-$5AFF and 128K shadow screen)
- Pagination for large differences (50 blocks per page)
- Cross-format comparison (e.g., .SNA vs .Z80)
- Export ASM: Enhanced disassembly export from Memory Map
- Uses memory regions to determine code vs data
- Code regions disassembled as Z80 instructions
- DB/DW/Text/Graphics regions exported with appropriate directives
- Includes labels and CPU state in header
- Addr+Bytes option for address and hex byte comments
- Screen memory exported as INCBIN directive
v0.7.0
- Automated Test Suite: New Tests tab for regression testing with native Spectrum programs
- Define tests in
tests.jsonwith machine type, timing settings, and screenshot steps - Multi-step tests with key press simulation between screens
- Absolute frame numbering (frame count from test start, not relative to previous step)
- Screenshot comparison against reference PNG images
- Preview mode for calibrating frame numbers with Pause/Resume
- Screenshot button to capture reference images during preview
- Copy Frame# button to clipboard for easy test configuration
- Full border mode support for accurate border rendering in tests
- Step progress shown during test runs (e.g., “Test 1/10: z80ccf (3/8)”)
- Frame number displayed on mismatch detection
- Author and source URL fields in tests.json for attribution
- Time elapsed and average FPS shown in test summary
- Define tests in
- Test Key Simulation: Flexible key press format for test automation
- Single keys:
ENTER,SPACE,a,1 - Simultaneous keys:
SHIFT+a,CTRL+p(Symbol Shift) - Key sequences with delays:
ENTER,500ms,SPACE - Special keys:
UP,DOWN,LEFT,RIGHT
- Single keys:
- Bug Fixes:
- Fixed preview state not resetting after errors (preview button would stop working)
- Fixed duplicate element ID for screenshot buttons
- Removed excessive debug logging from browser console
v0.6.5
- AY-3-8910 Sound: Full PSG emulation with Web Audio API output
- 3 tone generators with 12-bit period counters
- Noise generator with 17-bit LFSR
- Envelope generator with all 16 shapes
- Stereo modes: Mono, ABC (A-left, B-center, C-right), ACB
- Volume control and mute button
- State saved/restored in projects
- Register logging for future PSG export
- Works on 128K, Pentagon, and optionally 48K
- Z80 Q Factor: Implemented undocumented Q register for accurate CCF/SCF behavior
- Q register tracks whether previous instruction modified flags
- CCF/SCF bits 3,5 computed as
((Q ^ F) | A) & 0x28 - Block instructions (LDIR/LDDR/CPIR/CPDR) set Y/X from PC when repeating
- I/O block instructions (INIR/INDR/OTIR/OTDR) have additional PF/HF modifications
- Passes all z80ccf tests including edge cases (LDIR->NOP’, INIR->NOP’, etc.)
- Z80 HALT Fix: Corrected HALT behavior to match real hardware
- PC points to HALT instruction itself (traditional behavior)
- During HALT NOP cycles, CPU reads from PC+1 (next instruction), not HALT itself
- When interrupt fires, PC is incremented to point to next instruction
- Proper memory reads during HALT cycles for accurate contention timing
- Late Timing Option: Configurable early/late interrupt timing
- INT now fires at frame END (T=tstatesPerFrame), matching real hardware
- Early timing: INT recognized at frame end
- Late timing: INT recognized 4 T-states after frame end
- INT pulse duration: 32 T-states (48K) or 36 T-states (128K/Pentagon)
- Models cold/warm ULA behavior (real hardware drifts over time)
- Fixed: INT now stays pending until IFF1 is true (EI works correctly)
- Fixed: Proper EI delay handling (INT not recognized immediately after EI)
- Checkbox in Settings → Timing
- Saved in projects and localStorage
- Floating Bus Emulation: Basic floating bus support for 48K
- Returns video memory data during ULA active display
- Returns 0xFF during border/retrace periods
- Helps with timing-sensitive tests and some copy protection
v0.6.4
- SCL Disk Image Fix: Fixed SCL→TRD conversion for proper file loading
- Corrected logical track/sector calculation (16 sectors per logical track)
- Fixed directory entries to use 0-based sectors matching TRD format
- Files now start at logical track 1 (physical track 0, side 1)
- Data offsets now match real TRD disk layout
- Pentagon Beta Disk Fix: Fixed “RUN USR 0” hang in Basic 128
- TR-DOS auto-paging now only activates when ROM 1 (48K BASIC) is selected
- Prevents spurious TR-DOS activation when running 128K editor code
- Explicit TR-DOS activation when booting via menu
- Z80 MEMPTR Fix: Fixed undocumented MEMPTR behavior for block I/O instructions
- INIR, INDR, OTIR, OTDR now set MEMPTR = PC + 1 when repeating (B ≠ 0)
- Passes z80memptr test v1.2a (INIR->NOP’, INDR->NOP’ tests)
v0.6.3
- Graphics Viewer UI Improvements:
-
Reorganized layout: Canvas Address+Navigation+Settings Comment+Actions - Navigation buttons, Width/Height spinners, checkboxes, zoom, and preview all in one column
- Radio buttons (zoom x1/x2/x3) moved below checkboxes
- Added tooltips to all GFX controls and buttons
- Renamed “→Mem” button to “→Memdump”
- Adjusted canvas sizing for portrait mode
-
- Programmer Calculator Improvements:
- Fixed Enter key to update display with result (not just history)
- Disable unavailable digit buttons based on numeric system (hex/dec/oct/bin)
- Visual styling for disabled buttons (grayed out)
- Keyboard input validation for current base
- UI Polish:
- Renamed tabs: Debug / ASM / Opcodes / GFX / Info / Settings / Calc
- Landscape mode: shifted app name, Help, and theme buttons right
- Graphics dump canvas width reduced to 24 columns
v0.6.2
- Text Scanner Tool: Search memory for human-readable text strings
- Dictionary mode with ~120 common game/computer words (SCORE, LIVES, GAME OVER, etc.)
- Custom search mode for specific text
- ROM scan option to include ROM area (0000-3FFF)
- All banks option to scan all 8 RAM banks in 128K mode (not just mapped memory)
- Supports null-terminated and bit7-terminated strings
- Case-insensitive dictionary matching
- Pagination with configurable results per page (10/25/50/100/All)
- Click result to navigate to memory address
- Memory Dump Tooltip Enhancement:
- Now shows ASCII character for printable bytes (32-126)
- Shows
'X'+$80notation for characters with bit 7 set
v0.6.1
- Drag & Drop for Assembler: Drag .asm or .zip files directly onto editor
- Separate drop zones: assembler tab for sources, emulator area for ROM/snapshots
- Visual feedback (cyan border) when dragging over editor
- File Replace Dialog: Smart handling of duplicate filenames
- When dropping a file that exists in project, choose to replace or add as new
- Prevents duplicate tabs for same file
- Properly refreshes editor with new content after replace
- TAP File Fix: Corrected BASIC block param2 (program length) in TAP headers
- BASIC blocks now have correct header structure matching sjasmplus.exe output
- UI Improvements:
- Fixed defines dropdown colors in dark theme
- Increased assembler output panel height
- “Assembling…” message shown immediately when compiling
v0.6.0
- Integrated Z80 Assembler: sjasmplus-compatible assembler with syntax highlighting
- Full instruction set support including undocumented opcodes
- Directives: ORG, EQU, DEFINE, INCLUDE, INCBIN, DB, DW, DS, BLOCK, ALIGN
- Macros, local labels, temporary labels, structs
- Expressions with arithmetic, bitwise, and logical operators
- Multi-file Projects: Virtual File System (VFS) for assembly projects
- Load ZIP files containing multiple .asm source files
- File tabs with modification indicators
- Main file detection and selection
- INCLUDE directive resolves files from VFS
- Assembler Search/Replace: Full search and replace functionality
- Ctrl+F: Open find bar
- Ctrl+R or Ctrl+H: Open find/replace bar
- F3/Shift+F3: Find next/previous
- Case-sensitive option
- Replace one or replace all
- Search All Files: Search across all project files in VFS
- “All Files” button in search bar searches all .asm files
- Results show filename, line number, and highlighted match
- Click result to jump to file and line (opens tab if needed)
- Output File Generation: SAVEBIN, SAVESNA, SAVETAP, EMPTYTAP directives
- Generated files listed in output with size and MD5 hash
- Download button to save output files (single file or ZIP archive)
- Multiple SAVETAP commands to same file produce single TAP with multiple blocks
- MD5 Checksum Verification: Verify generated file integrity
- Add
; md5: hashcomment to SAVE directives for automatic verification - MD5CHECK macro support for associating hashes with files
- Output shows MD5 OK or MD5 MISMATCH with expected hash
- Add
- Command-Line Defines: Pass defines for conditional assembly (IFDEF/IFNDEF)
- Defines input field:
DEBUG,VERSION=5,BUILD=$100 @definemarkers in source: add; @define NAMEin first 50 lines- Dropdown appears for detected @define markers (Ctrl+click for multiple)
- Defines input field:
- Debug Button: Inject code and start debugging at entry point
- Entry point priority: SAVESNA address > single ORG > prompt if multiple ORGs
- Assembler Tests: Comprehensive test suite (asm-test.html)
- Tests for instructions, directives, labels, expressions, macros, conditionals
- Assembler UI improvements:
- Removed redundant Save button (Export covers it)
- Smart button states: Inject disabled until successful assembly, Assemble disabled when nothing to compile
-
Reordered toolbar: Files ▼ Assemble Inject Debug Clear New Load Export Download - Files dropdown shows directory path and sorts by dir/filename
- Files button always visible but disabled when ≤1 file
- Main file label colored red for visibility
- Assembly status shown in Output textarea with success/error styling
- “Show compiled” checkbox to toggle hex dump display
- Main file moved to top when loading ZIP projects
- Error reporting: Assembly errors now correctly show file and line number
- Removed localStorage saving of assembler source (use project save/load instead)
- Removed debug logging for cleaner console output
v0.5.8
- Memory Watches: New Watches tab for monitoring up to 10 memory addresses
- Displays 8 bytes per watch with hex dump and ASCII representation
- Shows label names when watch address matches a defined label
- Paged address support (e.g.,
5:C000reads directly from RAM bank 5) - Changed bytes highlighted during stepping
- Watches persisted to localStorage and saved in projects
- UI reorganization:
- Moved Overlay mode, Zoom controls to Settings/Display
- Moved Screenshot/Export to Settings/Export
- Moved Tests link to Settings/Tools
- Help button positioned near theme button
- Reduced screen container padding for compact layout
- New palettes: Added Linear, SpecEmu, SpecEmu (green), SpecEmu (grey), Spectaculator b/w
- Invert display: Checkbox in Settings/Display to invert screen colors
v0.5.7
- Frame Export enhancements:
- SCR export format (256x192 screen only, 6912 bytes)
- BSC export format (screen + border data for rainbow effects, 11136 bytes)
- SCA export format (animation with header + delay table + SCR frames)
- Single file export when Max frames = 1 (no ZIP wrapper)
- Export filename based on loaded game name (e.g.,
gamename.tap_0000.scr) - Format auto-selects correct capture size (SCR/SCA=screen only, BSC=full border)
- Compact UI: Format and Max controls on same row
- BSC format fixes: Correct border data extraction with proper screen position calculation
v0.5.6
- Settings tab: New tab with Input and Display settings
- Palette support: 15 color palettes including Default, ATM-Turbo, Pulsar, Spectaculator, Mars, Ocean, Grey
- Palette selection persisted to localStorage
- Disassembler fixes: Fixed ED-prefixed instructions showing extra spurious instructions
- Redundant prefixes (DD DD, FD FD, ED ED, ED CB) now correctly shown as DEFB
v0.5.5
- Undocumented flags: Added ‘x’ (bit 3) and ‘y’ (bit 5) flags to the flags display
- EXA/EXX buttons: Quick register swap buttons in the IX/IY register row
- Editable T-states: Click to edit current T-state counter value
- Keyboard image: Added ZX Spectrum keyboard layout image to Info tab
- Fixed register editing: contentEditable approach prevents UI shifting
- Fixed keyboard capture during register editing
- Input length limits based on register size (4 chars for 16-bit, 2 for 8-bit, etc.)
v0.5.4
- Editable registers: Click on any register value (AF, BC, DE, HL, IX, IY, SP, PC, I, R) to edit
- Inline editing with hex/decimal input, Enter to confirm, Escape to cancel
- Editable I, R, IM registers and IFF1/IFF2 interrupt flags
- Clickable flags: Click individual CPU flags (S, Z, H, P/V, N, C) to toggle them
- 128K paging controls: Edit RAM bank (C000), screen bank, ROM bank, and paging lock
- Alternate registers (AF’, BC’, DE’, HL’) also editable
- Register editing disabled when viewing trace history
v0.5.3
- 128K I/O contention emulation based on Swan emulator algorithm
- Port contention patterns: C:1,C:3 for contended high byte ($40-$7F), N:1,C:3 for ULA ports
- Contention check with
& 0x87mask ensures accurate per-line timing - Fixed ULA timing lacing/interlacing issue in 128K mode
- All ULA timing tests now pass: 48K, 128K, and Pentagon
- Chained prefix support: DD DD, DD FD, FD DD, DD ED correctly handled
- Z80 emulator processes chained prefixes with correct timing (4T per prefix)
- Disassembler shows redundant prefixes as separate NOP instructions
- Added chained prefix tests to system test suite
v0.5.2
- Pixel-perfect Pentagon timing calibrated against ULA timing test
- Pentagon line composition: 32 (H-blank) + 36 (left border) + 128 (screen) + 28 (right border) = 224 T-states
- Pentagon frame: 16 (V-blank) + 64 (top border) + 192 (screen) + 48 (bottom border) = 320 lines
- Theme persistence across emulator and test pages via localStorage
- Unified font sizes and styling across all test pages
v0.5.1
- Pixel-perfect 128K border timing with ULA rendering offset for right border
- Overlay mode cycling button: None → Grid → Box → Screen → Reveal
- Grid overlay: 8x8 grid, thirds/quarters dividers, 256x192 boundary lines in borders
- Box overlay: Yellow rectangle around 256x192 paper area
- Screen overlay: Border-only mode (hides paper, shows timing stripes)
- Reveal overlay: Semi-transparent paper showing border underneath
- Overlay lines render at 1px regardless of zoom level
- I/O contention for port operations in 128K mode
v0.5.0
- Pixel-perfect border timing for 48K multicolor effects
- Timing now uses pixel units (7MHz) for sub-T-state precision
- ULA contention: per-line delay during screen drawing (32 T-states for 48K, 36 for 128K)
- Single global beam sync offset (no per-line adjustments)
- Border color recorded at correct point in OUT instruction cycle
- Accurate 50 FPS frame timing using requestAnimationFrame
- Machine-specific timing parameters (48K/128K/Pentagon)
- Contention checkbox enabled by default
v0.4.78
- Fixed: Pentagon 128K menu navigation causing reset
- Fixed: TR-DOS ROM now separate from Pentagon ROM (pentagon.rom contains 128K BASIC + 48K BASIC, NOT TR-DOS)
- Added separate trdos.rom loading (16KB TR-DOS 5.03/5.04t required for disk support)
- Implemented automatic Beta Disk ROM paging (3D00-3DFF trigger)
- TR-DOS ROM pages in when CPU fetches from 3D00-3DFF
- TR-DOS ROM pages out when CPU enters RAM (>=4000h)
- TR-DOS trap handler now checks trdosActive flag before triggering
- Fixed: WD1793 Type III commands (Read/Write Track) now signal completion properly
- Fixed: TRD/SCL loading no longer shows file selection dialog - disk inserts directly
- Fixed: Ctrl+number keys now work for Symbol Shift symbols (underscore, etc.)
- Added: Keyboard help with full Symbol Shift combinations table
v0.4.77
- Beta Disk interface emulation (WD1793 floppy controller)
- Full TR-DOS ROM support - uses actual TR-DOS for disk operations
- Auto-switch to Pentagon mode when loading TRD/SCL (if Pentagon ROM available)
- “Boot TR-DOS” button for direct access to TR-DOS command prompt
- Proper disk I/O via emulated WD1793 ports (#1F, #3F, #5F, #7F, #FF)
- SCL to TRD conversion for Beta Disk compatibility
v0.4.76
- TRD/SCL: TR-DOS trap handler for disk operations
- TRD/SCL: Boot files highlighted in selection dialog
- TRD/SCL: CODE files load directly into memory at specified address
- TRD/SCL: Improved messages (not TAP-style LOAD instructions)
- Fixed ZIP extraction buffer slice bug (central directory parsing)
v0.4.75
- TRD/SCL disk image support (TR-DOS format)
- File browser shows disk contents with type, address, and size
- Files converted to TAP format for instant loading
- Nested disk images in ZIP archives supported
- Project files now store original TAP/TRD/SCL for multi-file programs
- Tape position preserved in project files
v0.4.74
- Export All Sprites: Export all marked graphics regions to single ASM file
- Region width/height stored with graphics regions for accurate export
- Memory Map: Scale with ticks and 128K multi-bank view
- Click on graphics viewer to show address popup
v0.4.73
- Graphics Viewer: New tab for sprite search and memory visualization
- Continuous memory dump rendered as graphics (EmuzWin-style)
- Adjustable sprite width (1-32 bytes) and height (1-64 lines)
- Main dump: sprite width x 288 lines, small preview with context
- Red rectangle highlights current sprite selection
- Navigation: byte, line, row (8 lines), sprite, page (24 rows)
- Min/max buttons for width, +/-8 buttons for height (snap to 8-line boundary)
- Mouse wheel scrolling through memory
- Mark selected sprite as Graphics region
- Jump to disassembly or memory view from selected sprite
- Grid overlay and invert display options
v0.4.72
- Operand Formatting: Right-click on disassembly to change operand display
- Format options: Hex (FFh), Decimal (255), Binary (%11111111), Char (‘A’)
- Formats persist per instruction address in project save/load
- Syntax highlighting: registers (gold), numbers (green), chars (purple), binary (blue)
v0.4.71
- Memory Heatmap: Visualize execution/read/write access frequency
- Toggle between Regions and Heatmap views in Memory Map dialog
- RGB color intensity shows access patterns (B=execute, G=read, R=write)
- Log-scale normalization for better visualization of hot spots
- Tooltip shows exact access counts per address
v0.4.70
- Unified Breakpoint System: Single panel for all trigger types
- Trigger types: Exec, Read, Write, R/W, Port IN, Port OUT, Port I/O
- Enable/disable triggers without removing them
- Conditions now support
val(memory/port value) andportkeywords - Hit counters for each trigger
- Backward compatible with old project files
v0.4.69
- Execution Trace: Record last 10,000 instructions with full register state
- Trace navigation: Step back/forward through execution history (Alt+Left/Right)
- Trace list panel showing recent instructions with registers
- Click status counter to show/hide trace list
v0.4.68
- Undo/Redo: Revert changes to labels, regions, comments, bookmarks (Ctrl+Z/Y)
- Pattern Search: Wildcard support with ? for any byte (e.g., “CD ? 00”)
- Undo/redo buttons added to toolbar
v0.4.67
- Tools panel: Consolidated POKE search, Auto-Map, and XRefs into unified panel
- Step buttons moved into disasm panel for compact layout
- Version display moved to status line
- Navigation history fix when navigating from memory map
- Improved landscape mode layout and alignment
v0.4.66
- Tabbed interface: Debugger and Opcodes tabs with responsive layout
- Z80 opcodes reference with byte values, flags, cycles
- Sorted by mnemonic, undocumented instructions marked
- Search and category filter for opcodes
v0.4.65
- Cross-references (XRefs): Track where addresses are referenced from
- Hover over operand addresses to see xref tooltip
v0.4.64
- Bookmarks: Quick navigation for disassembly and memory views
v0.4.63
- RZX playback (partial)
- Auto memory mapping
v0.4.62
- Data region rendering (DB/DW/Text as assembler syntax)
- Export with regions (sjasmplus compatible)
v0.4.61
- Project save/load
- Memory region marking
- Theme toggle
v0.4.60
- Labels with persistent storage
- Conditional breakpoints
- Memory diff and POKE search