2.0.6 - 17.12.2024 ------------------ Core Changes: Emulate the Z80 NMOS bug where, when executing LD A,R or LD A,I when an interrupt is taken, the parity flag is reset instead of reflecting the value of IFF2. Emulate ZjoyKiLer's newly discovered effects of the Z80's INIR/INDR/OTIR/OTDR instructions on MEMPTR, as per: https://spectrumcomputing.co.uk/forums/viewtopic.php?f=23&t=10555&sid=56f5663db83649db579966cd5c349715 Emulate the "Floating" AY chip register. https://worldofspectrum.org/forums/discussion/23327/floating-ay-registers As per the actual hardware, the Spectrum beeper is now slightly louder when the MIC bit is set in conjunction with the speaker bit. This also fixes the missing speech in Cobra's Arc. When reading the Jupiter ACE's keyboard and cassette input port, the top two (unused) bits now return 0, not 1, as per the real hardware. This fixes John Kennedy's Frogger, which previously could not start the game and would remain in attract mode even when pressing ENTER as prompted. Thanks to Richard Chandler and Kevin Palser. Added the ability to show Jupiter ACE system runtime errors as meaningful pop-up messages (as is currently available for the ZX80 and ZX81) instead of just numbers as shown by the Jupiter's system, configurable on the ZX80,ZX81, Jupiter ACE options page. Added Jupiter ACE .tap and .ace file generation support to the assembler. See snapshots\s\example_ace.s for details. Added read/write support for EightyOne's .z81 ZX80 and ZX81 snapshot format. This also means that the Start-up and Shut Down option to load any automatically saved machine state now also works for the ZX80 and ZX81, which was one of the reasons for adding this feature. Added emulation of the QS Character Generator component of the Chroma 81 for the ZX81, as well as adding new menu entries at the bottom of the Machine menu to enable and disable it (as well as the Colour Board component). Added emulation of the BI-PAK ZON X-81 sound card for the ZX81. Added emulation of the Mikro-Gen Analogue Joystick interface for the ZX81 (accessed via memory address $3E80). Added emulation of the Mikro-Gen Digital Joystick interface for the ZX81 (port $DF). Added emulation of the Zebra Systems Ltd. Joystick interface for the ZX81 (port $1D). Added emulation of the Cheetah Sweet Talker and Datel Vox Box speech synthesis units for the Spectrum. These are both slightly unusual in that they halt the Z80 while an allophone is playing, so the Spectrum cannot do anything else while they are talking. Added emulation of A. T and Y Computing's Spec-Mate back-up interface for the Spectrum (note you can press Z to exit its screenless interface - it has no visible menu system or such - it uses the display border to indicate the mode it's in). Loading a .mdr Microdrive cartridge image file now attempts to auto-load it by auto-typing "RUN" to start the Interface 1's autorun mechanism. The type of machine used to do this with is configurable with "Load Microdrive Cartridge Using" on the ZX Interface 1 options page. The .wav file cassette image loader has been rewritten. It now additionally supports stereo, 16-bit and A-law encoded files. This change also fixes a bug where .wav files containing a LIST block may not have loaded, depending on where in the file it appeared. Added the ability to record audio to a .wav file. From the GUI: Tools->Record Audio. With the CLI: incli --recaudio filename.wav which records audio for the session, e.g. incli aufmonty.rzx --recaudio auf.wav --playrecording Added support for digit separators in the expression evaluator for all number bases, which takes effect in the assembler, debugger and anywhere else an expression can be entered in Inkspector, e.g. 1'000'000+9'999 Added support for being able to list BASIC from PZX tape image DATA blocks e.g. incli --listbasic chronos.pzx The expected data size of a file within a tape image, taken from the header, is now shown in the Tape Browser. Added @tapeblock, @tapeplaying, @tapepaused and @tapestopped pseudo variables allowing the tape's state to be used in breakpoint conditions, and queried elsewhere in expressions. See the new documentation for details. Added @beamx and @beamy pseudo variables, allowing the CRT's current display position to be queried. These are particularly useful when added to the Watch window. Note at present only the Spectrum models return meaningful values. Other models return -1. Added @border pseudo variable to report the border colour (or -1 if the current system has no border). Added @ram_page to query the current system's RAM paged in. Added @totalts that returns the total elapsed t-state count of the running system. 0-length blocks encountered when parsing a .tap file no longer cause the parser to stop processing the image, allowing such files to be examined in their entirety past such blocks. Added a DC directive to the assembler that works as DB except when used with a string, the final byte has the top bit set. dc "Hello" ; The final byte is "o" + 128 dc 0 ; Byte is 0, not 0+128, because it's not a string The assembler now includes in the .sym files each expanded member of a variable that's an instance of a STRUCT, which also means they're now available to the debugger and the new Watch window, etc. e.g. Added new assembler directive MEMCOPYMODE to control how the assembler writes its generated data to memory. See the new documentation for details. Added a TAPEPROGNAME assembler directive to allow the name of the first file in the generated tape image to override the default. The default assembler TARGET is no longer a Spectrum 48k but the current model being emulated. This makes it easier to load a .s source file over the top of a running game that's running on a different model (otherwise a new instance of a Spectrum 48k would be created, clobbering the current machine and its running game). See snapshots\s\ghostbusters_screen_update.s as an example of such a .s source patch file. When an assembler ASSERT command fails, the values used within the expression are displayed to make it easier to see how the assertion failed, e.g. ASSERT symbols referenced: $=32825,.loop=32793 C:\temp\m.s(245) : ASSERT failed: (($ - .loop) / 2) == 15 Improved the assembler's .sym file generation by also including all STRUCTS, their members and total sizes. Added protection against malformed TZX tape images where there's endless JUMP and CALL loops. Thanks to Woody for the report and test files. Additional hardening of some file loaders against malformed files. .zip files with filenames containing non-ASCII characters can now be loaded. Made the .pok file loader tolerant of trailing spaces on a line. Thanks to Xorrox for the heads up. Added the ability to save the screen of the current machine to a text file. This works for all emulated machines. From the GUI: File -> Save Screen As Text Edit -> Copy Display As Text Hold down CTRL to include line numbers. From script: -- Save the contents of the screen as a text file result = inks.save_screen_as_text(path) -- Retrieve the contents of the screen as rows of text screen = inks.get_screen_as_text() for k,v in ipairs(screen) do print(k,v) end Added an assembler directive BREAK that instructs Inkspector to breakpoint in the generated code, or in the generated snapshot (breakpoints are made to persist in snapshot files by the use of a new auxiliary snapshot XML file). For example, in its simplest form with no additional parameters, this example instructs the debugger to break at the specified line: ORG $8000 go: BREAK ret END go This will cause the debugger to break when the instruction at $8000 is executed. In addition, you can use all the options that are available in the GUI’s Edit Breakpoint dialog window. For example using the conditional breakpoints in conjunction with pseudo variables (ones starting with @), to make the debugger break if the Spectrum’s border turns green: ORG $8000 go: BREAK CONDITION @border==4 ld a,4 out ($fe),a ; Debugger will break here ret END go If you want to catch writes to memory, you can do that too: ORG $8000 BREAK WRITE,ADDRESS go, LENGTH 1000 ; 1000 = number of bytes to monitor so, between “go” and “go”+999 inclusive. go: ld hl,0 ld de,go-200 ld bc,1000 ; The debugger will break at the point the memory at $8000 is written to ldir END go If you wish to break when a specific value is written (or read) the VALUE option allows you specify it: ORG $8000 BREAK WRITE,ADDRESS livesLeft, VALUE 4 ; Stop when 4 is written to livesLeft go: ld hl,livesLeft dec (hl) jr nz,go ret livesLeft db 8 END go One more example before I end up duplicating the entire documentation here. ORG $8000 go: ld a,200 .lp:inc a BREAK NO_BRANCH jr nz,.lp ; Breakpoint will fire when the jump is not taken. i.e. when the zero flag is set in this case END go All breakpoints requested by BREAK directives are created in the machine that receives the assembled code so they take effect in the debugger immediately, as you would expect. For cases where BREAK is used and at least one of the assembler’s output is a snapshot file, a snapshot auxiliary file is created in the same directory as the snapshot file. This is to allow the breakpoints to persist after Inkspector is closed down, and automatically loaded and applied the next time the snapshot is loaded. To be able to do this, auxiliary snapshot files have the same name as the snapshot, but with .aux.xml added. For example if the assembler generated c:\temp\myprog.szx, it would also create c:\temp\myprog.szx.aux.xml. As well as the list of breakpoints, it may also in future contain additional information to expand the abilities of existing snapshot formats such as adding support for hardware not supported by their original specifications. If the BREAK directives are removed or commented out and the code assembled again, the snapshot auxiliary files will be deleted so that old breakpoints are no longer applied when Inkspector loads the snapshot. Since BREAK breakpoints for snapshots are applied using auxiliary files, the assembled output, and therefore the snapshot file itself, is not modified by the use of BREAK and so may be used to distribute a program or game without issue (i.e. no opcodes or such are injected into the assembled code by the BREAK directive). NB for the auxiliary files to be written, deleted or loaded with a snapshot, auxiliary snapshot file support must first be enabled in Inkspector. This is done on the GUI’s Assembler options page by enabling “Use snapshot auxiliary files”. For full details on the BREAK directive and auxiliary files, see the documentation. Countless tweaks and other small improvements have been made throughout. GUI Changes: Added a Watch window (shortcut Alt-W) that allows one or more expressions to be watched. Expressions may override the current global Inkspector view-as-hex setting by adding a comma and a letter. For example, using hl as the value to be watched: hl <- Watches the value of HL as either decimal or hexadecimal depending on the current global view-as-hex setting. hl,b <- Watches the value of HL as binary hl,d <- Watches the value of HL as decimal hl,x <- Watches the value of HL as hexadecimal hl,e <- Watches the value of HL as a pointer to a string (use E for native - not ASCII - format string) hl,t <- Watches the value of HL as a pointer to a string terminated with bit 7 set (use T for native format string) hl,z <- Watches the value of HL as a pointer to a string terminated with a 0 byte (use Z for native format string) hl,sN <- Watches the value of HL as a pointer to a string of N bytes (use SN for native format string) hl,AN <- Watches the value of HL as a pointer to a BCD number N bytes in length And since you can watch any valid expression, pseudo variables may be used: @beamx,d <- The x coordinate of the display beam See the new documentation for the full list of formatting and type options. Added the option to view native character sets on the Memory window with View->View Native Character Set. For example, when disabled, entering *D_FILE as the memory address while a ZX80 is running with "HELLO" displayed top left of the screen would show "v-*114" on the right hand side of the window as it interprets the characters as ASCII. Selecting View Native Character Set would show ".HELLO" as they would be interpreted as ZX80 characters. This works for the ZX81 too which also has its own non-ASCII character set. Added File->Save Screenshot (with flashing) that saves the current screen to a .gif file, with the additional feature that if the current machine is a Spectrum and there's at least one flashing attribute on display, a 2-frame animated .gif is written out to preserve the flashing effect. Added Edit->Copy On-Screen Disassembly to the debugger, which does exactly what it says on the tin: copying the on-screen disassembly to the clipboard as text using the current layout. Added File->Save Selected File As to the Microdrive Map window, which allows the currently selected file on the Microdrive cartridge to be saved out individually to a file. Added .mdr support to the Load/Save File Preview display, which shows the list of files it contains, along with the BASIC and variable listings for each if so configured on the Options -> General screen. The previous also attempts to autorun the cartridge file. The Microdrive Map window now shows the currently selected filename as a string of hexadecimal bytes to be able to distinguish, for example, between a file called COPY (i.e. the bytes for ASCII values of C,O,P,Y) and one called COPY (i.e. the token 255). Added View BASIC Programs and Check Cartridge For Errors to the Microdrive Control Window's Tools menu. Holding down CTRL while clicking on a hyperlink address in the debugger now opens up a memory window for that address. Holding down CTRL while double-clicking a breakpoint on the debugger navigates to the breakpoint's address (saves having to open the breakpoint editor window then pressing the 'Go To' button). Added a Lucky Dip toolbar button and menu item to Inkspector Search to randomly select a file from the current selection. Added a Save All toolbar button and menu item to the Snippet Editor that forces changes to all snippets to be saved to disk. Previously, it was necessary to either run the snippet or close the Snippet Editor to do this. Changed the "ROMnn" part of the address on the debugger when "Show Full Address" is enabled, to something more meaningful. e.g. ROM00 is now SPEC, ROM08 is now ZX81, etc. Basically anything that doesn't start with "RAM..." is a ROM. Added a Scale Display 400% and Set Custom Display Scale menu items to the new Display menu which now contains all display-related menu items as the View menu was becoming a bit too long. Re-worked the Create Microdrive Cartridge window, so you can select how the cartridge is formatted (including new options to have the FORMAT command auto-typed for you) and whether you want the CAT command auto-typed once formatting is complete. Also new cartridge images don't have to have a filename assigned to them immediately (just as creating new +3 disk images don't). Added a File->Recent Microdrive Cartridges menu. The numeric keypad keys are now mapped to the emulated machine's 0-9 keys. Thanks to sn3j for the suggestion. Improvements and minor optimisations to the audio handling of muting and unmuting, particularly the auto-muting when single stepping in the debugger. Also the audio stream no longer starts playing until Inkspector has completed its start-up tasks, which fixes the short burst of audio that can be heard when the debugger window has been opened automatically (thus pausing the machine) because it was open in a previous session. CLI Changes: Added --flashgif which works with the existing --savegif command and makes it behave as per the new File -> Save Screenshot (with flashing) feature as described above. Added --timeout value, which abandons any on-going operation after the specified number of emulated seconds (when value is positive) or emulated frames (when the value is negative). This can be useful to save the state of the machine at a certain point, for example, to save the flashing Manic Miner loading screen to a GIF file: incli manic.tap --playtape --savegif --flashgif --timeout 25 Which is equivalent to the following, specifying the timeout value as a negative number of frames: incli manic.tap --playtape --savegif --flashgif --timeout -1250 Rationalised the names of command line options that produce a listing, so now: --list -> --listlua --tapelist -> --listtape --basiclist -> --listbasic --basicvars -> --listbasicvars --sysvars -> --listsysvars --listbasic now also shows variables defined in addition to the BASIC program. This also works when listing from tape and Microdrive images (--listbasic can now list from loaded Microdrive cartridges too). Added --listmdrvcart to list the contents of a Microdrive cartridge image file, e.g. incli --listmdrvcart chuckie_egg.mdr When using the --listtape option to list a tape's block list, bad block entries (usually bad checksums) are highlighted in red, just as they are in the GUI's Tape Browser. Added --listdblog that dumps to the screen any log entries stored in the database. Bug Fixes: Fixed a rare, long-standing issue that could prevent a breakpoint from hitting. Fixed an issue where if the GUI was launched with a relative (i.e. not fully qualified) filename on the command line, Inkspector would probably report that it could not be found. Fixed a problem that prevented Microdrive cartridges formatting correctly when using the FORMAT command (cartridges quick-formatted by Inkspector were fine). Fix a fairly obscure bug that could occur during spooling of commands when a BASIC error is encountered that was raised by the Interface 1 using its own internal error codes (which are stored in the Spectrum's ERR_NR system variable as though it used the standard error code values). e.g. spooling FORMAT "m";1;"" now correctly reports spooling has been stopped due to an 'Invalid filename' error rather than 'Variable not found'. When writing a .z80 snapshot, the two bytes at offsets 61 and 62 were always set to 0, indicating RAM is present at address ranges 0-8191 and 8192-16383, which is incorrect (unless the machine happens to be a +2A/+3 in all-RAM mode). The values are now set as per the specs. The "subtitles" for the SP0256AL2 speech chip (Currah uSpeech, etc.) were being shown only intermittently on the message window when audio was muted. The GUI's Disk Control window could allow you to Revert changes when there wasn't a disk image file to revert to. The memory window's "Update While Running" option could work inconsistently unless the "Follow" checkbox was checked. The RZX Studio wouldn't allow the user to save out the very first part of a recording as an individual snapshot via Tools->Save As Snapshot. The default keyboard controller type is once again Native Cursor Keys, after becoming 'None' following the keyboard and joystick controller changes in 2.0.5. Thanks to sn3j for the report. The GUI's Assembler dialog was not handling instructions that use relative displacements (JR, DJNZ, etc.) correctly. Note this bug only affected this dialog window and did not affect the assembler when used elsewhere such as when assembling .s and .asm files. Several assembler fixes: Local labels within a STRUCT should have been disallowed. INCLUDE directives are now shown in listing files. DEFINE and DEFL allowed invalid label characters to be used in the identifier names. String identifiers are now handled properly, e.g. DEFINE MyName "Marky" DB MyName If an error occurred within a macro, the line number indicating where it was invoked from could be incorrect. To be more compatible with other assemblers, the DEFL directive now uses the format of: