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:

			<label> DEFL <value>

			instead of

				DEFL <label> <value>

			and the = directive is now an alias for DEFL instead of EQU.

	Fixed the RAM selector drop-downs on the debugger and memory dump windows
	not always reflecting a machine's changes when a peripheral with its own RAM
	(e.g. a Multiface) is hot-patched in or out.

	Physical joystick button presses would not be passed to the emulated
	joystick interface (e.g. Kempston Joystick interface) until the Spectrum
	had its ULA port read. This meant if there was a tight loop only reading
	the Kempston port with interrupts disabled (i.e. BASIC not reading the
	keyboard / ULA 50 times a second), the fire button would never be reported
	as pressed.	Thanks to XoRRoX for the report.

	The INT Vec. and WZ values on the Z80 Registers window were always shown
	in hex, regardless of the current setting. Thanks to XoRRoX for the report.

	Fixed the GUI's 'Mute' toolbar button becoming depressed after single stepping
	in the debugger. Thanks to XoRRoX for the report.


2.0.5 - 13.04.2023
------------------

Core Changes:

	The assembler can now produce .pok files directly using the new
	SAVEPOK and POKTRAINER directives. For example,	assembling:

		SAVEPOK		"test.pok"
		POKTRAINER	"Trainer One"
		ORG		0x8052
		jp		0xB701

		ORG 	0xB701
		ret

		POKTRAINER	"Trainer Two"
		ORG		0xC000
		ld		a,ixl
		ret

	...will product a file called test.pok that looks like this:

		NTrainer One
		M 8 32850 195 0
		M 8 32851 1 0
		M 8 32852 183 0
		Z 8 46849 201 0
		NTrainer Two
		M 8 49152 221 0
		M 8 49153 125 0
		Z 8 49154 201 0
		Y

	To fully demonstrate this new feature, I've included make_oink128.s
	in the Snapshots\s folder. This patches the original 48K Oink! release
	which was an annoying tape-multi load, into a everso-slightly-less-annoying
	128k version that loads	all the sub-games into RAM at once.

	Adding or removing most peripherals no longer requires the machine
	to be hard-reset.

	Added support for the Kempston '55' Joystick Interface, which is read
	using port 55 (A7=A6=A3 = 0).

	Added support for the Lex Van AY board for the Jupiter ACE, that
	appeared in ACE User 4 in 1983.

	Added the ability to breakpoint on a NMI being taken.

	Breakpoints with conditions that hit now additionally show the values of
	any symbols that took part in the condition.
	e.g. a breakpoint with a condition of "@addr<50000" might additionally
	show "@addr=49999".

CLI Changes:

	The --script option has been split into two: --prescript to run a Lua
	command before any specified file has been loaded, and --postscript
	to run afterwards.

	--tapelist now shows any additional information for a block, just as
	the GUI's Tape Browser does with view Additional Block Data enabled.

	Added --listdirectives to list the assembler's directives

	Added a --quiet option to turn off information log and user messages
	(warnings, errors and successes are always shown), enabling a cleaner
	output when used with --tapelist for example.

GUI Changes:

	Added the ability to configure the physical keyboard and joysticks
	as redefinable keys, using the name "COMCON" (as suggested by Luzie)
	as a big-up to the programmable joystick interface from back in the day.

	In addition, the COMCON settings are saved against a profile,
	so you can create different profiles for different games and select
	them as you need without having to create them from scratch each time.
	Each profile contains separate settings for the physical keyboard and
	controllers, so if you happen to use two controllers they can have
	different redefined keys assigned to them, too.

	Wait, there's more! Profiles can also be made to activate automatically
	for specific files, just as peripherals can be made to attach to them,
	so you could create a Mayhem profile and have it so it's selected
	whenever you load mayhem.szx. Not that you'd want to play Mayhem, but
	you get	the gist. The automatic profiles are selected on the Peripherals
	options page.

	Added an option to the debugger to display all video writes immediately on
	a breakpoint being hit (including single stepping, etc.) even if they've
	been made behind the TV's beam. This is useful for debugging code that
	writes to the display behind the beam to avoid flicker. Or maybe you'd
	just like to see how Uridium updates the screen?

	Added an option to the Options->General page to temporarily set the
	machine to unthrottled (i.e. maximum speed) when spooling, restoring
	the original speed when spooling has finished or has been cancelled.

	Added graphical indicators to the debugger and memory windows for
	Memory Read (cyan), Memory write (yellow), Memory read/write (green)
	breakpoints, in addition to the existing red ones for Opcode Read.

	Added a Lua bar to the messages window to allow you directly enter
	a Lua command, which can be useful for entering the odd script command
	rather than having to edit then run a snippet to do so. You can hide this
	new bar by selecting View -> Lua Bar.

	Added two new default snippets: Snippet #7 and #8 to reduce and increase
	respectively the speed of emulation. Existing installations of Inkspector
	can access these by resetting the snippets to the defaults
	(Snippets->Edit Snippets->Edit->Reset Snippets).

	The Machine->Hot Peripheral Patching sub-menu has been re-worked to show
	only peripherals compatible with the current machine as it was becoming
	too long.

	The absence of the D3DX9_43.DLL file (needed only by the screensaver)
	on the user's system no longer prevents the installer from proceeding.

	Greatly reduced the CPU usage when a physical controller is plugged in.

Bug Fixes:

	The debugger was not picking up on source symbol notification changes,
	meaning Refresh had to be manually selected after pressing its
	View Symbols or Source Listing toolbar buttons for them to take effect.
	This was broken in 2.0.4.

	Several controller issues that have just gone away as a result of
	re-writing the controller code for the COMCON keyboard and
	joystick support. For example, a long-standing issue with the physical
	controllers not working with keyboard-based joysticks
	(native cursor, AGF, Interface 2, etc.) has gone.

	Fixed an issue where the progress % value on the Tape Browser's
	status bar for some less common block types would remain at 0%.

	Fixed the maskable interrupt breakpoints not working.

	Fixed 'Find Memory' not always updating the debugger's disassembly
	window's address correctly when crossing RAM page boundaries on the
	16k/48k Spectrums when repeatedly pressing Find Next.

	Fixed nested IFs not always working correctly in the assembler.

	Fixed a crash that could occur in the assembler when specifying a
	zero byte instruction (e.g. DS 0) at address 65535.

	Unlike all the Sinclair models, the Jupiter ACE's cursor up key is
	Shift-6	(not Shift-7) and down is Shift-7 (not Shift-6), so I've
	corrected the cursor key mappings accordingly.

	Fixed a fairly rare dropping of spooled characters on the ZX81.

	Fixed some options on the GUI's ROM Management options page that
	should have taken effect immediately rather than after restarting
	Inkspector.

	Fixed some minor text colour issues on the debugger window when
	the emulator was running and opcodes were not being shown.

	Fixed the screensaver that was properly broken in 2.0.4 and crashed
	immediately when it ran :D I guess there's not too many people using
	the screensaver as I didn't hear anyone complaining :D
	It might be time to retire it...

	Restored the screensaver’s ability to remember the chosen
	allow-Spectrum-to-be-played-hotkey (default F1) on its configuration
	screen. It appears the relevent code was commented out early on in
	InkSpector 2.0 development!


2.0.4 - 31.12.2022
------------------

Core Changes:

	Added a feature called Spooling that types in the contents of the
	clipboard or an ASCII text file into the current machine. This works
	for all emulated machines and is accessible via the GUI's new
	Tools->Spool Clipboard and Spool File menu items or from script using
	inks.spool(path). Lines starting with # are ignored.

	Key Assist (which also powers the new Spooling feature) now
	automatically regulates the typing speed to avoid keypresses getting
	dropped as the edited line becomes longer and the emulated system takes
	longer to update and redraw it.

	Added ZX80 (.o, .80) and ZX81 (.p, .81, .p81) tape loader generation
	support to the assembler. There is also a new directive DEFNM
	- Define Native Message - that converts from ASCII to the target
	machine's character set to help make life a little easier.
	See snapshots\s\example_zx80.s and example_zx81.s for details.

	The data bus value used by the Jupiter ACE when calculating the IM2
	interrupt vector has changed from $FF to $20 as per the original
	hardware. The original valkyr.tap game (in addition to the version
	modified for emulators) now plays fine rather than crashing when the
	game starts.

	Added .tap load (including auto-load) and save support for the Jupiter
	ACE.

	Added emulation of the Big Mouth speech board designed by Martyn Davis
	for the Jupiter ACE.

	Added ZX 128 AY sound chip emulation for the Jupiter ACE, primarily so
	I can hear the music in the Old School Demo :)

	Add 'Cursor Joystick' support to the Jupiter ACE.

	Pressing TAB on the ZX81 with the keyboard in 'Native Cursor Keys' mode
	toggles [F]unction mode (as it already does [E] mode on the Spectrum).

	Improved the dumping of BASIC program lines that report themselves as
	0-length (usually as a form of protection), such as the one in
	Quazatron's loader.

	Added an option to only show the hidden floating point value of a number
	in a BASIC line if it differs from the text version that precedes it
	(i.e. when it appears an attempt to hide the true value has been made).
	For example, the line of BASIC in Quazatron's loader reads:

		0<<< 0-length line >>> CLEAR 00000[25000]: POKE 00000[23659],0:
			LOAD ""CODE : RANDOMIZE USR EXP 00.000000[10.435528]

		Note that POKE's second argument really is zero, so no actual
		value is shown in square brackets.

	Improved the heuristic that determines whether a line of BASIC is
	machine code or not to reduce the number of false positives, although
	it's still not perfect.

	Added system variables for the +2A and +3 Spectrums.

	Screenshot files (.scr and .mlt) are now classed as screenshots and no
	longer as snapshots. The most visible effect of this change is a new
	Recent Screenshots item on the GUI's File menu, and machine state is
	no longer dumped out (if so configured) after loading one.

	Added support for loading ZX32's .zxs snapshot files, including any
	embedded tape and disk images.

	Added textual bitwise operators to Inkspector's expression evaluator
	(i.e. in the debugger, calculator, and anywhere where values may be
	entered	as text) and assembler to complement the existing C-style ones:

		NOT (^), AND (&), OR (|) and XOR (^)

	Added a dereference operator * to the debugger's expression evaluator
	(not available in the assembler, but everywhere else) that evaluates
	to the 16-bit address pointed to by the argument. For example, while
	running a Spectrum:

		CHARS evaluates to $5C36
		*CHARS or *$5c36 evaluates to $3C00
		(i.e. the address CHARS	is pointing to)

		Put another way, it's equivalent to
		PEEK(<argument>) + 256 * PEEK(<argument>+1)

	Added a TAPELOADEREXEC directive to the assembler that specifies the
	BASIC line used to start the assembled program in the generated tape
	loader (i.e. whether to use PRINT USR, RANDOMISE USR or LET R=USR).
	See example.s for details.

	The assembler's SAVESNA (and SAVESNAP alias) and SAVETAP directives
	now behave as per SjASMPlus as not to make it unnecessarily difficult
	to switch between it and the Inkspector assembler. i.e. the optional
	second argument specifies the start address of the program. If this is
	not specified, the value specified by the END directive is used.
	See the updated	example.s for more details.

	Added batch_scr_to_gif.lua and batch_z80_to_szx.lua script files to the
	Snapshots\lua folder to demonstrate how to generate .gif screenshots
	from a folder full of snapshots and/or .scr and .mlt files, and convert
	a folder of .z80 snapshots to .szx files, respectively.

	Added the ability for the CLI and GUI to additionally send log messages
	to the Inkspector database's log table. The GUI additionally can clear
	them or export them to a text file. As a result, the screensaver no
	longer writes its messages to that table (not that anyone knew it did!),
	but it does keep its own option to write messages to a .txt file should
	screensaver logging be required (I doubt it!). This addition is really
	to help	with troubleshooting and isn't expected to be particularly
	exciting for anyone :)

	Changed the Fuller Box AY clock speed to 1.63819 MHz as per
	https://spectrumcomputing.co.uk/forums/viewtopic.php?p=91917#p91917

	Further hardening of some file loaders against malformed files following
	some ramping up of the fuzz testing done prior to a release.

	When writing out a .szx file containing a ZX Interface 1 block, the
	final byte of the ZXSTIF1 structure (chRomData[1]) is now omitted if
	there's	no custom IF1 ROM present, resulting in a 40 byte block. This
	is to appease Fuse, which, as of 1.6.0 at least, appears to assume
	ZXSTIF1 is 40 bytes long in such cases (ignoring the length in ZXSTBLOCK
	reporting 41), which prevents it from loading such files. Spectaculator
	8.0 also saves 40 byte ZXSTIF1 blocks when there's no custom IF1 ROM
	(although it does load the 41 byte versions fine), so this seems a
	reasonable change to make.

	When loading a tape image that requires LOAD ""CODE (and not LOAD "")
	into a 16K Spectrum with flash loading and auto loading enabled, a
	PAUSE 1 command is issued first. This kludge is to allow Pheenix to load
	successfully and not fall foul of its protection, which loads the value
	$1142 into FRAMES from the final block of the tape, then on start of the
	program it adds the value $EEBE to (FRAMES) and if the result is not
	zero, it assumes someone's been poking around and displays the screen
	wipe with the purple asterisks before resetting the machine. Previously
	on Inkspector, Pheenix always ended up with the value 1 in this specific
	scenario after adding those two values together, indicating FRAMES had
	been incremented between BASIC loading the final code block and launching
	the machine code program at 30105 (not 30121 as it would appear at first
	glance ;) Incidentally if you do start the program at 30121 you get the
	same result as if the FRAMES protection check had failed).
	The PAUSE 1 is used to sync the system as it uses a HALT to achieve the
	delay, which hopefully buys the system time (or at least puts it out of
	sync with an interrupt occurring), so FRAMES is not incremented	before
	the protection check is performed.
	That's enough about Pheenix for today.

	Added a breakpoint ROM/RAM page type of 'Any' which makes it a little
	easier to set up conditional breakpoints (particularly breaking on a
	read/write address range). Along with the rest of Inkspector, this is all
	being documented fully, but in the meantime this is an example how to set
	up a breakpoint on a memory write between addresses 52000 and 52100 using
	the GUI's "Add Breakpoint" menu items on the main or debugger windows:

		Breakpoint Type:	Memory Write
		Address: 		0	(this value doesn't actually matter when address mask is 0)
		Address Mask:		0	(so that all addresses are considered)
		ROM/RAM Pages:		Any
		Condition:		@addr >= 5200 && @addr <= 52100

	Additionally you can set Condition breakpoints that break whenever the specified
	condition becomes true, e.g. to break when HL becomes 49153:

		Breakpoint Type:	Condition
		Condition:		hl==49153

	Made further optimisations when Inkspector saves out the configuration.

	A fair bit of the usual tinkering throughout.

CLI Changes:

	Added --savegif that saves out a single frame (non-animated) .gif file
	from the current state of the machine, e.g.

		incli jsw.z80 --savegif		<- Creates jsw.gif from the snapshot

	Added --listconstants that lists all the Inkspector scripting constants.

GUI Changes:

	Added an option to specify the start-up machine. As with other
	configuration options, this is used by the CLI too.

	Added an option on the Tapes options page to specify the machine to be
	used for loading Spectrum tape images.

	The memory view window now allows the display to be updated while the
	machine is running (View->Update While Running), which makes the
	highlighted changed (tracked) bytes display much more useful. Also added
	menu items to clear changed bytes after 5 seconds and one to clear
	them all on demand.

	You can now create a breakpoint directly from the Tools->Add Breakpoint
	menu, (i.e. without having to open the debugger first). The debugger
	will open automatically when a breakpoint's hit.

	When viewing a system variable in a memory tab
	(View->System Variables->View->View In Memory Tab), if the variable is a
	pointer to an address, such as CHARS, the address used for the memory tab
	uses the new dereference operator (see above in Core Changes) unless CTRL
	is held down while clicking on the View In Memory menu item, in which case
	the address of the variable itself is used, as in previous versions.

	Added the ability to show BASIC runtime errors as meaningful pop-up
	messages on the ZX80 and ZX81, individually configurable on the
	ZX80,ZX81, Jupiter ACE options page.

	Performing "view BASIC Program" when the Jupiter ACE is running shows
	all the currently defined Forth words, similar to how its own VLIST
	command does, except words are grouped into whether they're defined
	in ROM or RAM.

	The debugger's View->View Symbols and View Source Code are now always
	enabled, regardless of the actual availability of such things. This
	makes it easier to use these features and fixes an issue where if the
	current ROM (e.g. 48K) does not have symbols or source available for it
	and the debugger is then switched, for example, to the Interface 1 and
	it does have such things available, the menu items would have remained
	disabled.

	The debugger's Add Breakpoint (CTRL-B) has been renamed
	"Add Breakpoint At Cursor" and its shortcut changed to CTRL-SHIFT-B.
	Add Breakpoint (CTRL-B) now adds a new breakpoint unassociated with
	the address at the cursor, making it equivalent to Add Breakpoint on the
	main window's Tools menu. This change also makes it slightly easier
	setting up more complicated breakpoints (see
	"Added a breakpoint ROM/RAM page type of 'Any'" in the core changes above).

	Added "Break On Branch" and "Break On No Branch" breakpoints to the
	debugger's Debug menu, which work on instructions that conditionally
	branch,	such as djnz, ret z, jr c, etc.

	Added debugger menu items to enable or disable all breakpoints.

	The debugger's list of breakpoints now displays breakpoint comments too.

	Added an option to generate an NMI (Machine->Generate an NMI)

	Performing a Copy on the messages window now copies all text if none is
	selected.

	The Z80 Registers window is now a regular tools window and no longer
	opened and closed by the debugger. It's opened from the main window's
	View menu (shortcut Alt-F). Added a Refresh (F5) menu command to refresh
	the values of the registers while the machine is running.

	Added a Tools->Assemble Clipboard Contents that assembles the text
	contents of the clipboard to the current machine. Unlike loading a
	.s or .asm file, the current machine's memory is not cleared before
	assembling over the top, so it may be useful for applying patches to
	games.

	Added a 'View->Show Headers' item to the Message window which allows
	the log line headers which show which bit of Inkspector code generated
	it (e.g. [MACH]) to be hidden. This can be useful when wishing to copy
	and paste the output of one of Inkspector's tools without timestamps
	(which may already be hidden) or headers getting in the way.

	Added options to the Advanced page to show the Inkspector version number
	and manifest version on the main window's title bar.

	Added --machine and --script command line options to match the CLI.

	Drastically reduced the time take to shutdown the GUI when the current
	machine has a large tape image loaded (e.g. a .wav file) and the shut
	down option to save the current machine state is enabled.

	Simplified the snippet editor colours by making all Lua and Inkspector
	function names blue, with Inkspector constants in blue italics.

	Added two new default snippets: Snippet #5 to toggle the global
	hex/decimal mode, and snippet #6 that demonstrates use of the in-line
	assembler. Existing installations of Inkspector can access these by
	resetting the snippets to the defaults (Snippets->Edit Snippets->
	Edit->Reset Snippets).

	Improved the handling of 'secret' filenames on the Microdrive Map
	and Microdrive Sector windows.

	Re-written the code that captures window sizes, positions and states
	(such as being maximised) to work more reliably.

Bug Fixes:

	When recording an RZX, the post-EI scenario (where normally a maskable
	interrupt wouldn't be taken, so the RZX frame is extended) is handled
	more reliably, and should fix an issue where the resulting recordings
	could lose sync at that point. After writing some test programs to
	assist fixing this, I discovered that all I needed to do to generate a
	post-EI frame was hold down DELETE in the 128k Spectrum's BASIC editor
	on an empty line until it repeatedly beeps.

	Fixed a long-standing issue when saving a .z80 snapshot when writing
	compressed versions of them. It was not honouring the rule about the
	first byte immediately following a single ED not taking part in a run.
	For example ED, 00 x 7 was being encoded as ED ED ED 07 00 and not
	ED 00 ED ED 06 00.

	Fixed an off-by-one error that could prevent the last few bytes of some
	Jupiter ACE .ace files from loading.

	The ETI Colourboard (Jupiter ACE) wasn't working correctly. The contrived
	test mode I had made it appear it was working. I have now verified it
	with the demo program supplied with the original ETI project.

	Fixed a problem with the assembler trying to apply indirect addressing
	to non-Z80 instructions such as DB, DW, preventing such lines as
	'DB (10+2)*2' from assembling.

	Fixed an issue with the assembler sometimes showing the wrong filename
	if it fails to resolve a forward reference.

	Fixed a crash if the MACRO and STRUCT directives were used without
	adding the name parameter.

	Fixed Key Assist typing TAB and _ incorrectly on the Spectrum,
	and / RND INKEY$ and PI on the ZX81.

	On the Spectrum, Key Assist now re-enables keywords after a colon in REM
	statements just as the BASIC editor does. e.g. REM : DEF FN a()=10

	The ZX80 Keyboard Assist code that was supposed to dismiss any "0/-2"
	style report message that may be active before inserting the requested
	key presses was not working properly.

	Added a workaround so that key assist on the ZX80 works immediately after
	a LOAD command. Previously it required a BASIC variable to be added or
	removed before it would work again. This was so the end of variables marker
	byte $80 was once again locatable via the E_LINE system variable - 1.
	Key Assist looks for its presence to verify the system is up and running.

	The detection of whether LOAD "" or LOAD ""CODE should be used to auto load
	a tape image could get the wrong result if there was a mix of TZX standard
	and turbo blocks present in the file. Thanks to TheShich for the report.

	Fixed an issue that prevented tapes requiring LOAD ""CODE from loading
	automatically on 128s and later (the code to navigate their system menus
	broke a couple of versions ago!).

	The Fuller Box joystick emulation was using active-high bits, not low. One
	reason (OK, excuse!) this went unnoticed for so long was that Imagine's
	Fuller joystick reading code (certainly in Arcadia and Zzoom) was correcting
	Inkspector's bug! :)

		From Arcadia:

			ld	bc,127
			in	a,(c)			; Read the Fuller Box's joystick
			bit	4,a			; Inkspector 2.0.3 and earlier return bit4 low
			jr	z,.active-high		; Looks like active-high - no need to flip the bits

			xor	255			; Flip the bits, making active-high
							; (we'll forgive them not using CPL here)
							; This is the path taken with Inkspector 2.0.4

		.active-high:

	Fixed an issue in the floating bus emulation where the calculation to
	determine which bit of the display was being read by the ULA went a
	little awry when the beam was in the lower parts of the screen. This
	was the reason the Ah Diddums! bear didn't have the bout of St. Vitus'
	dance he should have had when the Fuller Box, which steadies him, is
	absent.

	Fixed some system variables having incorrect details.

	When (the very slow) GDI+ render method was being used, the status bar
	updates could become intermittent.

	Restored the GUI's Tools->Stop Script functionality that was broken in 2.0.3.

	Fixed the debugger's breakpoint list not being rebuilt until the machine was
	paused, which could give the impression that breakpoints weren't being
	saved and restored correctly when switching between different machine types.

	Of all the text boxes on the Z80 registers window, only the PC box was being
	applied to the Z80 on pressing ENTER!

	Fixed a crash that could occur when loading a TZX file containing a
	nested loop (ironically, due to attempting to display some helpful
	information when encountering one).

	Fixed the superfluous spaces that were being inserted around some tokens
	when running View BASIC Program on the ZX80 and ZX81.

	Fixed a bug when determining the most common colour being displayed
	(the .scr and .mlt loaders set the border colour to it to complement
	the display) as it was only sampling the first 8 pixel lines of each
	third of the display memory, although this did seem to work pretty well
	in most cases!

	Fixed the Tape Browser's Save button that stopped lighting up in
	Inkspector 2.0.3. Thanks to PeterJ for the report.

	All of the text character columns on the Memory window are now always
	visible when View->Full Address is being used.

	When loading a .mdr Microdrive cartridge image file, it could take the
	trailing read/write flag from a byte somewhere before the end of image,
	causing the R/W flag to be set to the wrong value.

	The Microdrive cartridge checksum calculator could sometimes generate
	the wrong value, causing sectors in the Microdrive Cartridge Sector
	List window to be highlighted in red to indicate checksum error when
	they were actually OK. In addition, checksums are now coloured green
	when they pass.

	Fixed a bug with the Spectrum issue 2 emulation that prevented the
	Softlock release of Rasputin (which doesn't work on issue 3s) from
	being able to start the game.

	Fixed a regression introduced in 2.0.3 in the +2A/+3 memory contention
	timing handling when the Z80 was in a HALTed state. Running Hikaru /
	Intense's floating bus tester now shows the same results as on a real
	+3 again.

	Reverted the change made in 2.0.2 where the Spectrum 128's contention
	timings were changed to start from 14363 instead of 14361. They now
	start from 14361 again. This fixes an issue where the Castle Escape demo
	would not start the game on a 128K Spectrum (it was fine on other models)
	as it waited for a red attribute to appear on the floating bus that never
	arrived. The only down-side of this change is that the centre column of
	the display on the Shock megademo is 8 pixels to the left again.
	I'll take a look at this in a future version. Thanks to Craig Hackney
	for the report.

	When loading a tape image by passing it on the GUI's command line, the
	previously used machine was not selected first, so it would have been
	loaded into a Spectrum 48K regardless.

	Many additional pesky little buglettes fixed as a result of documenting
	Inkspector (I really am working on such a document!).


v2.0.3 - 07.02.2022
-------------------

Core Changes:

	Implemented two fairly recently discovered Z80 behaviours that are currently
	doing the rounds:

		The HALT instruction repeatedly reads the byte following the HALT
		instruction, not the HALT itself while in a halted state. This can
		make a detectable difference when the memory contention is different
		for the byte after the HALT. Thanks to ZJoyKiller and Tony Brewer for
		this information.

		The Z80 now modifies additional flags while executing a block instruction
		(LDIR, etc.) Thanks to David Banks, ZJoyKiller, Ped7g and Arjun Nair for
		the information.

		Thanks to Woody, Peter Helcmanovsky and Patrik Rak for their test programs
		used to	verify these changes.

	Added DK'Tronics 3 Channel Sound emulation.

	Added the ability to record animated GIF files. In the GUI there's a new
	Recordings options page where you can configure the frame rate, optimisations
	used to keep the GIF sizes to a minimum and whether to include a border.
	The recording is started using the new Tools->Record Animated GIF menu item.
	[GIF] appears on the right-hand side of the status bar when a GIF is being recorded.

	This functionality is also available in the CLI tool which makes it very easy to
	produce GIFs of tapes loading or RZXs being played at the command line, e.g.

		incli jetpac.tap --playtape --makegif	<- Creates jetpac.gif of the whole tape load

		incli commando.rzx --playrec --makegif	<- Creates commando.gif of the whole recording

		NB incli uses the same configuration as the Inkspector GUI, so you may
		configure the required GIF frame rate, etc, in the GUI on the Recordings
		options page before running incli. Similarly, you probably want to ensure that
		flash tape loading is disabled, for example, before creating a .gif from a
		a tape image otherwise it's not going to be very long or interesting!

	Added ROM and RAM mirroring to the ZX80 and ZX81. This fixes, on the ZX81 at
	least, Psion's 'Space Raiders and Bomber' behaving as though the movement keys
	were being held down due to some odd (protection?) code in those games reading
	memory from $3e80 and acting as though a key was pressed if not getting the
	expected result from the mirrored ROM access.

	Added ZX81 Chroma 81 emulation.

	Added support for writing ZX80 tape images in .o and .80 formats.

	Added support for writing ZX81 tape images in .p, .81 and .p81 formats.

	Added support for loading from ZX81 .p81 and .tzx (GDB / type 0x19 block) files,
	including being able to dump BASIC listings directly from these files.

	Add 'Cursor Joystick' support to the ZX80 and ZX81.

	Improvements to the machine state reporting (accessible via the inks.get_machine_state()
	script function or the GUI's Tools->View Machine State menu item / Alt-A)

	Made some small optimisations to the configuration read and writer.

	The ZX Interface 1 system variables are now available when it's present
	(including being displayed on the System Variables window).

	Auto-loaded tapes (where LOAD "" is typed in automatically) now play
	rather than sitting in pause mode when auto start stop tape playback
	is turned off.

	Added experimental code to detect and exclude BASIC lines that look as though
	they contain binary data such as machine code rather than a BASIC program.
	This new feature is on by default, but can be turned off on the Advanced option
	page if you find it's excluding regular BASIC lines containing many control
	codes, etc.

	The assembler now has a maximum nested include level of 30 files.

GUI Changes:

	Added a 'View->Show Timestamps' item to the Message window which allows
	the timestamps to be disabled.

	Breakpoints can now have comments assigned to them, which are displayed
	when they're hit to help identify them. Thanks to Andy Dansby for the
	suggestion.

	On the Tape Browser, you can go straight to recording a new tape by
	pressing the Record button without first having to press Create New Tape.

	Improved the Message window's performance when things get busy (e.g. when noisy
	diagnostic options are enabled)

	Holding down CTRL while selecting File->Load Last Auto-Save now saves the
	auto-saved image to %TEMP%\auto-save.ext (where ext is the appropriate extension
	for the machine being saved)

	Added a What's New? item on the Help menu to open up the whatsnew.txt file
	supplied with Inkspector as of this release (previously this information was
	buried inside Inkspector 2.txt).

CLI Changes:

	The CLI defaults to the same machine last used by the GUI. This makes it less
	frustrating when switching between the two. It may still be overriden with the
	--machine option.

	Added --makegif which records the whole session as an animated .gif. If no filename
	is given after --makegif, the name of the file loaded is used with a .gif
	extension.

	Added --playtape which plays the tape until either it comes to the end of the tape
	and stops, or it remains in pause mode for 5 (emulated, not real time) seconds.

Bug Fixes:

	The "...Show the Microdrive map too" option on the Interface 1 Options page didn't work!

	The Tape Browser window wasn't reopening when 'Automatically reopen active tool windows'
	was enabled.

	Fixed the log message 'This appears to be a .tzx file with an incorrect extension...' being
	shown when loading any .tzx file, which was introduced shortly before the 2.0.2 release.

	The screensaver was using the GUI's 'Additional Archive Folders' configuration settings
	when it should only have been using its own single archive folder setting.

	Snippets run by a breakpoint are no longer allowed to change the current machine. This
	change fixes a crash that could happen by attempting to do that.


v2.0.2 - 21.12.2021
-------------------

Core Changes:

	Changed the Spectrum 128's contention start from cycle 14361 (as most documents
	specify) to 14363. This fixes the centre column of the display on the Shock
	megademo being out of sync. Thanks to Rich Chandler for both the report and fix!

	Reduced the ZX Spectrum's bottom border height from 56 to 48 lines following
	a report from Rich Chandler.

	As this is becoming the R.C. release, add Boldfield Joystick Interface emulation
	for the Jupiter ACE, as per his new SpudACE release :)

	Added DK'Tronics Speech Synthesizer emulation.

	BASIC token expansion, as used by Keyboard Assist, is now disabled when entering
	quotation marks, and re-enabled	at the end of them. The backtick can now be used
	to change the current state of expansion within a quoted string (previously it
	was always off).

		PRINT "scr." -> PRINT "scr."
		PRINT "`scr." -> PRINT "SCREEN$ "

	In addition, the Spectrum's copyright symbol may now be specified with {C} and
	its pound sign with {UKP}. And this is how they appear in BASIC dumps, too.

	The tape generator now invokes the program using PRINT USR instead of RANDOMIZE USR
	so that if the program returns, the value of register pair BC will be printed out.

	Tape images whose contents look like .tzx files are now loaded as such, regardless
	of the actual file extension.

	Enhanced the logging system to capture entries early on in Inkspector's start-up
	before a means to display them is available.

	Upgraded to SQLite 3.37.0, Boost 1.78, Inno Setup 6.2.0

GUI Changes:

	Added a choice of CAPS and SYM SHIFT key mapping (Options->Keyboard and Joysticks),
	allowing CAPS SHIFT to be selected with the PC's left shift key and SYM SHIFT with the
	right shift key. This change also fixes a problem not allowing a '?' to be entered at
	the BASIC editor as it was previously being consumed by the CTRL-C copy screen shortcut.
	It now changes to ALT-CTRL-C when the CTRL key mapping is being used.

	Added an option to restore all tool windows on start-up (Options->Start-up and Shut Down).

	The RZX Verifier may be launched directly from the Search window with the currently selected
	file (File->Verify RZX File).

	The Options->Peripherals screen's Browse file selector now allows multiple snapshots
	to be selected at once, as requested by Pavero.

	Added a couple of extra escape points in the executor’s thread loop, which reduces
	- on average - the time taken for it (and therefore the Inkspector GUI) to close down,
	by up to a few milliseconds :)

	When the border size is changed to 'None', the border is no longer rendered internally,
	as it's not shown anyway!

Bug Fixes:

	Fixed numerous problems with the ROM and RAM drop-down selectors in the debugger.

	The Lua script functions inks.load(), inks.relative_to_script() and the file iterator
	dir() weren't handling UTF-8 characters properly.

	The assembler now guards against runaway macro recursion.

	The DI/Halt breakpoint now works correctly.

	Add a missing error string, which was the reason loading example_128k.s from within
	%ProgramFiles%\Inkland\InkSpector 2\Snapshots\s didn't show the actual error even
	though the tape generation had failed.


v2.0.1 - 28.05.2021
-------------------

Core Changes:

	Enhancements to the assembler. See the updated example.s for more details and examples:

		The SAVETAP directive can now save tape images as .tzx and .pzx in addition
		to .tap. As it's no longer .tap specific, a directive alias called SAVETAPE
		has been created.

		A TAPEINFO directive has been added to add information to .tzx and .pzx tape images.

		Added an IMPORT SYSVARS directive to import system variable names for the target
		machine (specified with DEVICE) as labels. Imported labels do not appear in any
		UNREFS report.

		Added a SETREGISTER directive to initialise a Z80 register to a specific value
		before snapshots are written out.

		SAVESYMBOLS, SAVELISTING, SAVEBIN and SAVEHEX now default to using
		<current-filename>.ext if no filename is specified, where ext is .sym, .lst,
		.bin and .hex respectively.

		Added an ALIGN directive.

	Ignore the block length value reported by a TZX block $2A ("Stop the tape in 48K mode") and
	always assume it's 0, as other emulators appear to do. This allows the "Amaurote3k+3_zx7rcs.tzx"
	tape image (and any	others there may be with non-zero length values) to load.

	The tape auto-loader now types LOAD ""CODE (i.e. the addition of CODE) if it appears
	to be a loader that doesn't	use the usual "Program:" file type as the first file,
	e.g. Pheenix

	The Interface 1 shadow ROM is now mirrored at $2000, as per:
	https://worldofspectrum.org/forums/discussion/34702/

	When dumping BASIC programs, unprintable characters are now shown as \nnn rather than ?
	and UDGs are shown as \A, \B, etc.

	Added a script that queues up multiple RZX recordings and plays them in sequence.
	It can be found in Snapshots\lua\queue_recordings.lua
	This was requested by Pavero:
	https://spectrumcomputing.co.uk/forums/viewtopic.php?p=52625#p52625

	Enable saving of .mlt screenshots for +2A and +3 machines and .sna snapshots for
	Spectrum 128s.

	Improved the source and symbols file functionality (currently used by the GUI's debugger):

		Inkspector assumed SjASMPlus .sym files were produced by its LABELSLIST directive, not its
		--sym command line option, but this understandably confused people when .sym files weren’t
		loading, so Inkspector now supports files produced by either method (Inkspector automatically
		detects).

		The symbols system now automatically imports the current machine's system variables and
		makes them available in the same way symbols loaded from files are. i.e. the numerous
		'Symbol' buttons on Inkspector windows are now always visible to allow selection of them
		(in addition to any symbol files loaded as before) and system variable names are shown in
		disassemblies and are highlighted on memory view windows. This feature may be disabled
		if necessary from the Debugger options page: "Expose the machine's system variables as
		symbols"

		Symbols and listing files are now loaded when loading tape images in addition to snapshots.

		Added support for loading .sym and .lst files from within a .zip file if the snapshot or
		tape file is itself in a .zip.

		Other general improvements including faster loading of source and symbol files and better
		cache handling.

	Upgraded to Lua 5.4.3, SQLite 3.35.5

	Made numerous small improvements to the performance of the core emulation code that
	together reduce the CLI's unthrottled playback time of my benchmark .rzx file from
	15 to 13 seconds. Every little helps!

GUI Changes:

	Added two display render methods selectable on the new Display options page:
	GDI+ and Direct 2D. Both offer smoothed displays but the Direct 2D is hardware
	accelerated, so is probably the better option, unless for some reason the Direct 2D
	option doesn't work on your system (the only reason GDI+ is supported, as it's slow).

	Added an Inkspector Search window (shortcut Alt+S) that quickly searches through your
	snapshot archive as configured in the new Options->Archives page, for files that match
	what is typed into the search bar. Double click a file or press the toolbar load button
	to load one. Holding down the CTRL key as you do so also closes the search window.
	File extensions	may be filtered by entering "ext:<extension>[,extension]"
	e.g. "manic ext:szx" to find all supported files containing the word "manic" with a file
	extension of szx, or "manic ext:szx,sna" to find ones with extensions of szx or sna.

	Added a calculator window (shortcut Alt+C) which uses the debugger's expression
	evaluator, giving you access to all available symbols.

	Added View->Block Data to the Tape Browser window to see the first 20 bytes of each block.

	Added a View->Additional Information to the Tape Browser which displays additional information
	available for some types of tape block (e.g. TZX Archive Info).
	"..." is shown at the end of lines when additional information is available.

	Added File->Load Memory to load a file directly into a machine's memory.

	File->Save Screenshot now supports saving images as .gif in addition to .png and .bmp.

	The View System Variables window remembers the last variable selected and auto-selects it on
	subsequent openings.

	Added a "Start Up" menu item and button to the Snippet Editor to quickly select the current
	snippet for running at start up, saving a trip to the Options->Startup and Shutdown page.

	The following keys are now mapped on all systems where available: , . / ; ' # - =

	The debugger can now show elapsed T-state counts at the start or end of an instruction.

	Added an option to the Debugger options page to show a message on the emulator window
	when a breakpoint is hit.

	Holding down the CTRL key while selecting any "Recent->" menu item copies the path to the
	clipboard instead of selecting it.

	Added ZX80 and ZX81 support to the Tools->View User Variables menu item and
	inks.expand_user_variables() script function.

	Changing settings in the Options screen relevant to the currently running machine now
	prompts the user to reset the machine for the changes to take effect.

	Made the following audio improvements:

		Added the ability to individually control the volumes of different audio devices.

		Reduced the audio latency.

		Corrected some audio clipping.

	Improved the performance of the message window by batching updates.

	Upgraded from wxWidgets 3.0.5 to 3.1.5 which does not suffer from the same
	issues as 3.1.3 (that the attempted upgrade in Inkspector 2.0.0.28 revealed).

	Numerous tweaks and changes throughout.

CLI Changes:

	Added --tapelist to list any loaded tape blocks

	Added --state to display the full machine state

	--play now shows the time taken to play the recording

Bug Fixes:

	Fixed the cassette player's auto-stop/start not pausing the tape when the EAR port is
	read by something previously determined not to be a tape loader, such as the ROM's
	keyboard reader. This fixes horizons.tap failing to load 'logo'screen$ (when flash
	loading is off) due to the PAUSE 250 immediately before the LOAD command, allowing
	the tape to continue playing during the PAUSE and resulting in missing the 'logo'
	header.

	Fixed the handling of TZX select blocks, which was treating the choice block offsets
	as absolute values and not relative offsets to the current tape block.

	The ZX Interface 2 was not being allowed to attach to a Spectrum 128 (only 16/48K)
	which in turn caused a crash when attempting to load Domin8tr1s. Both issues have
	been fixed.

	Spectrum 128s onwards were always displaying RAM page 5 when the disabled bit of
	port $7FFD was set, rather than using the display bit to decide as usual.
	This issue was also highlighted by Domin8tr1s!

	Fixed the debugger's single-step not executing an instruction if an interrupt was due.
	Thanks to djnzx48 for the report.

	Fixed a crash that could occur when single-stepping RZX recordings containing
	retriggered interrupts (e.g. boulderdash.rzx).

	Fixed several issues with "Symbol" selection buttons and menu items not being visible
	or enabled correctly.

	Fixed the flickering on the View System Variables window, caused by the rolling back
	to the earlier version of wxWidgets in 2.0.0.51.

	Changing the "Display values in hexadecimal" option on the debugger options page would
	not take effect on the Z80 Registers window immediately.

	Fixed a crash when passing the name of a .dsk or .mdr file on the GUI's command line.

	Fixed an issue with the Snippet code window loading non-ASCII characters incorrectly.

	Fixed the Machine->Hot Peripheral Patching->Cheetah SpecDrum menu item which did nothing! :)

	Fixed numerous display issues with filenames containing non-ASCII characters.

	Fixed the "Recent->" lists on the tool windows (e.g. Tape Browser) not being populated after
	being closed and re-opened.

	View User Variables now displays unprintable characters correctly, allowing all of Wudang's
	variables to be seen!

	Fixed the screensaver showing the bouncing "No valid scripts available!" message after
	playing back an .rzx recording that fails to play to completion.

	The assembler was writing incorrect values for local labels in symbol files (it was
	actually writing the value of the parent label)


v2.0.0.51 - 02.06.2020
----------------------

Common (GUI and CLI) Changes:

	Upgraded to Lua 5.4 RC4.

GUI Changes:

	Added a Help->Send An Email menu item that launches your default email app to send
	an email with the To and Subject lines pre-populated.

Bug Fixes:

	Reverted from wxWidgets 3.1.3 back to 3.0.5 which fixes the following:

		- The file preview display was being scaled incorrectly on high DPI systems
		- The debugger's peek disassembly tooltip window was generating unnecessary focus changes
		- Game controller inputs weren't coming through

	inks.load_from_archive() was not returning the result code.


v2.0.0.50 - 28.05.2020
----------------------

Common (GUI and CLI) Changes:

	ZX Spectrum +2A and +3 floating bus behaviour is now emulated.

	ZX80 and ZX81 tape images (.o, .80, .p and .81 files) are now handled as tape images
	rather than snapshots.

	Added BASIC listing dump support to the ZX80 and ZX81 and its tapes.

	Improved the spacing accuracy of BASIC listings

	Added more Lua inks.xxx() functions (these will be documented separately and soon!)

	Added a backtick (`) as a way to toggle token expansion and and off in key assist

	Added inks.get_recent(itemNum,[itemType]) to retrieve a file name from one of the recent
	items. 0 is the most recent, 1 the next, and so one. itemtype is one of the following
	strings: "snapshot" (the default), "tape", "script", "mdrv", "poke", "roll", "disk" or "source".

GUI Changes:

	Added native cursor key support to the Jupiter ACE, ZX80 and ZX81.

	Added Key Assist support to the Jupiter ACE, ZX80 and ZX81.

	Add a System Variables window (Tools->View System Variables) that shows system variables
	and their current values, which are updated automatically once a second.

	The system variable constants for the current machine are now available everywhere where
	an expression may be entered.

	Improved the full-screen view (it previously had small part of the display cropped when viewing
	with no border)

	Added a toolbar to the main and message windows.

	Added a Tools->Stop Script menu item that may be used to stop long-running scripts.

	Added a View->Raise Windows menu item and toolbar button to raise all open Inkspector
	windows to the top.

	Addded a Tools->View User Variables menu item, and exposed it via inks.expand_user_variables().
	Currently this works for ZX Spectrums only.

Bug Fixes:

	Fixed an issue displaying negative integers in the ZX81/Spectrum 5-byte number format.

	Modifying memory at the currently selected address using one of the right-button menu items
	(increment, decrement, poke, assemble) would not update the value at that address afterwards.

	Fixed the "Open disk control panel when a disk is accessed" option not working.


2.0.0.28 (Beta 1) - 12.05.2020
------------------------------

Common (GUI and CLI) Changes:

	The scripting framework has been re-written, with Lua being upgraded
	from 5.2 to the current 5.4 release candidate in the process.

	Inkspector now defines ten "snippets" which are Lua scripts, edited
	using the GUI's new Snippet Editor, and that may be run the following ways:

		1. Directly from within the Snippet Editor (Snippets->Edit Snippets)
		2. From the Snippets menu (shortcut keys Alt-1, Alt-2, etc.)
		3. By selecting one to be run on startup of Inkspector (Options->Startup)
		4. By selecting one to be run on a breakpoint hit within the debugger
		5. By using the CLI's --snippet option

		A few snippets are pre-defined as examples.

	Improved Currah uSpeech emulation in respect to ROM mirroring and blocking
	out the standard ROM when its own ROM is paged in. Intonation is now emulated too.

	Speech subtitling (Currah uSpeech and Fuller Orator) will automatically pause
	if the same allophone is played 10 times in succession, automatically resuming
	when a different allophone is played. This is to avoid the message window being
	flooded with "PA1" as the uSpeech ROM plays it incessantly.

	Added support for reading and writing .snx snapshots.

	Added support for reading and writing .mlt screen images.

	Added support for the Cheetah SpecDrum.

	InkSpector now has its own built-in macro assembler. It will attempt to assemble files
	that have either a .s or .asm extension. Two sample files, example.s and example_128k.s
	are supplied in the Snapshots\s folder that also serve as the assembler's
	documentation for now. The GUI can optionally load .s and .asm files for the
	file preview window too, but it is disabled by default. You may enable it on the
	"General" options page.

	To assemble using the CLI use the usual load file method:

		incli --load example.s

	The assembler also includes a .tap file generator that can automatically create
	a full .tap image (with optional loading screen) from the assembled output, including
	loading of 128K RAM pages.

	Emulation is paused and a message displayed should the Z80 execute 64K's worth
	of contiguous DD/FD opcode prefixes.

	The emulator core used by the GUI, CLI and the screensaver now uses UTF-8
	exclusively for messages and file paths internally. The only visible change
	is more consistent Unicode support throughout Inkspector.

	Many other minor tweaks and improvements.

GUI Changes:

	Added a snippet editor.

	On the General options page, a snippet may be selected to be run at start-up.

	The numerous placeholder toolbar button icons have been replaced with proper ones.

	Added support for physical joysticks.

	Added a navigation drop-down menu to the Navigate Backward debugger toolbar button.

	Added a Load Most Recent Tape Image (Shift-F9) and
	Load Most Recent Source File (Ctrl-F9) menu items.

	The message window now uses a fixed pitch font to make it more readable.

	Tape browser window updates (particularly block % updates) are now more efficient.
	You may only notice this change	on tape images containing thousands of small blocks,
	such as Rescate Atlantida.tzx

	The tape browser's File->Open menu item has been wired up.

	Added Tools->View In-Memory BASIC Program to the main window and
	Tools->View BASIC Program on the Tape Browser window which displays in
	the message window any BASIC programs present.

	The Tape Browser window can save out an individual tape block (Tools->Save Individual
	Tape Block). This currently works only for .tap blocks.

	Added an 'Advanced' page to Options, containing a 'show additional messages'
	option. This may be enabled to help diagnose issues with snapshots as it causes
	additional information about them to be displayed, mainly on the messages window,
	but also some of it on the file load/save preview window. Also added fine-grained
	diagnostic options that may produce a lot of information, so a warning is shown
	when Inkspector is started when one or more of them are enabled.

	The Key Assist dialog is disabled when an RZX recording is playing.

	Key Assist now also supports the Prototype ZX Spectrum ROM:
	http://www.computinghistory.org.uk/det/51620/Sinclair-ZX-Spectrum-Prototype

	The debugger breakpoint 'Comment' field has been replaced with 'Run Snippet'
	where you can now select one of the ten snippets to run when a breakpoint is hit.
	A new 'Never break' option has been added to the 'Break When...' drop-down list to
	allow the Lua commands to be executed without pausing execution and launching the
	debugger in the process.

	Once I've documented the Lua extensions, snippets will make sense :)

	Upgraded from wxWidgets 3.0.5 to 3.1.3
	Unfortunately this upgrade has also introduced a regression which causes the debugger
	peek disassembly tooltip to steal window focus when it appears, which manifests as
	the debugger's main window frame changing colour as focus changes. Hopefully this
	will be fixed in 3.1.4.

CLI Changes:

	Added a --dumpbasic option which will list a BASIC program stored within a snapshot
	or one or more tape image blocks.

Bug Fixes:

	A couple of tape block types (including PZX's PULS block) always showed 0% progress
	on the tape browser window.

	Fixed a problem with drag and dropping a .pok file onto the GUI that could cause
	an unhandled exeption to be reported.

	Fixed a crash that could occur when loading an .szx snapshot (including ones
	embedded within .rzx recordings) that references a tape image containing a drive
	letter than doesn't exist on the local machine.
	Thanks to Woody for unwittingly supplying an offending .rzx file!

	Fixed an issue with loading a snapshot with the debugger open, which could sometimes
	allow the machine to execute for a very short period before showing the first
	line of disassembly.

	Removed a harmless duplicate "Fuller Box present" message on the file preview dialog.

	Key Assist didn't work correctly when the Currah uSpeech unit was attached.

	Fixed the occasional allophone being dropped when the uSpeech or Orator were talking
	and the code wasn't querying the ready status before sending the allophone. This was
	most prominent at the start of Jungle Fever which proudly announced "Welcome to Jung Fever".

	The Spectrum's issue2/issue3 configuration setting wasn't being applied.

	Z80 opcode ed71 is now disassembled correctly as 'out (c),0' instead of 'out (c),f'

	The disassembler was skipping too many bytes following an undocumented instruction.

	Port writes to the 128K AY chip were being consumed even when the AY chip wasn't present
	(i.e. 48K machines) which manifested as flickering in the FPGA48all.tap tester as it
	eventually writes to port $8004! Thanks to azesmbog for reporting this. Similarly,
	reading the AY port when it wasn't present was returning $FF instead of reading the
	floating bus, which prevented 'Lord Bromley's Estate' from working.

	Fixed an issue with interrupt handling that caused minfo.tap ("INT time") and Woody's
	nointpfx.tap to fail.

	The 128K Spectrum was only holding the INT line low for 32 t-states, not 36.
	Thanks to Woody for diagnosing and reporting this! :)

	Improvements to accelerated tape loading compatibility.

	Fixed an issue that could allow AY chip tone counters to runaway, which resulted
	in some channels not sounding for a while. E.g. loading "Batman - The Movie.rzx"
	would result in the instruments appearing one by one when it first started to
	play the music on the menu. Thanks to Woody for the report.

	Fixed the Z80 snapshot reader wanting to select a Pentagon 128 for any unrecognised
	machine type, or machine type #3 when in a version 3 image (should be Spectrum 48K).
	This would result in a Spectrum 128 being selected, as the Pentagon isn't emulated.

	When the GUI's menu was active the machine was still running.


2.0.0.27 - First preview version - 13th October 2019
----------------------------------------------------

InkSpector has been re-written from the ground up and is now called Inkspector 2.
It is a separate program to Inkspector (1.0) and both may be installed on the same
machine without conflicts.

The GUI version is now the main focus of development, with another
new program 'incli' which is a command line headless version of the emulator
that may be used to convert between snapshot formats, disassemble directly
from snapshots, display snapshot and tape information, etc.
