Zeus-ish Z80 cross assembler

It's all the fault of She Who Must Be Obeyed...

"I've been converting some of my old games files"
  "Uh-huh"
"Recovered them for some old floppies"
  "Uh-huh"
"Bloody hard work, I might add..."
  "Yep"
"Not helped by the rotten tools I had to use"
  "Uh huh"
"Frankly I could have written a better assembler in the time I wasted"
  "I should hope so"
"From scratch, I'm talking about the whole bloody thing!"
  "Surprised you didn't. Anything on the TV?"
"The useless one I had to use doesn't even know all the instructions!"
  "Strictly come dancing is on, do you want to watch that?"
"Neurgh! Right! I'll do it... I'll show 'em!"
  "That's nice dear... What's an assembler?"

So, as you can see I had no alternative whatsoever to writing this... Gah.

Long time (fifteen years) since I've written a Z80 assembler, back then it took
two days to do in 80x86 assembler, so I'm assuming it'll be a doddle in Delphi...

Session 1 started 22:22 4/Oct/2008
 - Start with symbol table and evaluator from the FPGA risc assembler
   They'll need modifying but that can wait. The symbol table is naive but works

 - Implemented ds
 - Implemented align
 - Implemented db,dw,dl
 - Implemented fixed opcodes
 - Implemented INC/DEC
 - Implemented JP/CALL/RET
 - Implemented just about everything except the ROT/BIT/LD set
Session 1 ends 05:11 5/Oct/2008

Session 2 started 13:19 5/Oct/2008
 - Start with ROT, they're easy.
 - Note! Z80 documentation on web is wrong, "RR" missing. Called "RL" again
 - Implemented ROT 13:38
 - Implemented STRICT and EXTENDED 13:44
 - Cleaned up editor exit behaviour with clean files
 - Implemented BIT 14:00 (Oh gawd, only the LD set left)
 - Note! Z80 documentation on web is wrong, "LD A,R LD R,A" missing.
 - Implemented LD A,[full set] 14:51
 - Implemented LD [8-bit reg],[full set] 15:09
 - Implemented LD [16-bit reg],[full set] 15:41
 - Note! Correctly handles indirect addressing issue ld a,(4*5)+1 is not ld a,(n)
 - Note! Zeus has extra 16-bit loads, eg, ld hl,de... This doesn't yet
 - All Z80 instructions full implemented. 16:21

 - Now we need to bring the evaluator up to scratch.
 - Added support for $hex, #hex, and either . $ or * for PC 16:34
 - Added &,| and ^ as aliases for and, or and xor 16:40
 - Added single character string literals to evaluator 16:45

 - Assembles Forbidden Planet 16:51
   Sluggish though, FP (14,400 lines) takes almost a second <grin>
   I'd guess from previous assemblers that a hashed symbol-table would
   speed this up by a factor of ten or so... Not really bothered.
   [Turns out it's much faster except for the long time Delphi's memo takes
    just to provide the text in the first place...]

Session 2 ends 16:58 5/Oct/2008

Session 3 started 21:20 5/Oct/2008
  - Ported my binary -> szx file convert routines and added them.

  FP didn't run. A binary comparison of the output with it assembled by my dev
  tools showed JR displacements weren't calculated correctly. Forgot you had
  to store the PC at the start of the instruction so it didn't change
  as bytes were planted. Doh! Still, it has been 15 years since I last wrote
  a Z80 assembler... I've said that already, haven't I? Evidence of senility...

  Now generates same bytes as my development assembler. Project finished?
  So, it took about 11 hours to write a complete and useable Z80 assembler.
  Life in the olde dog yet...

  - Added a QAD find function to editor 22:07

Session 3 ended 22:52 5/Oct/2008


- Added some backward compatibility stuff for Spectrum Zeus.
  '!' for OR (Note - v1.1 revises this and makes ! and NOT behave as logical nots)
  'ENT' is ignored.

Well, that's as much as I can be bothered to write for now.  All that needs
adding to the assembler is conditional assembly and some looping structures.
That's about an hour's work. I might add a real editor at some point, but not now.

7 Oct 2008
  - Felt frisky after a successful day at work, so I've added some of Zeus's
    extentions for compatibility.
  - DEFM aliases DEFB
  - // comments
  - Added support for variables as well as labels
  - Added predefined true/false/version labels
  - Filtered out CamelCase from internal tokens so they can be used as labels
  - Added displacement support, both as "DISP" and as "ORG ADDR,DISP"
  - Added struct/send for declaring structures
  - Added import_bin for importing raw data
  - Added more documentation files
  - Added jump to error line if error message clicked on in report window
  - Added loop/lend
  - Added repeat/until
  - Added while/wend
  - Added if/elseif/else/endif

Released as V1.1 (zeusver = 1)

I wanted to call it SPASM, but that's been taken. I've called it Zeus, which is
a little unfair to the real Zeus (part of my in-house development tools) but he'll
just have to live with it.


Dedicated to all those Z80 instructions lost in action. You will not be
forgotten...


[later]

From starting out as an amusing diversion this has developed into an interesting
tool... I'm now trying out ideas (mostly implementation details) I'll use in my
next generation of development tool assemblers.

7 Oct 2008
  - Added a hashed symbol-table (virtually the same as Zeus-2 had in 1984) and
    revised token handling to use it... Much faster passes.
  - Added support for Zeus's 16-bit load set.

Released as V1.2 (zeusver = 2)

10 Oct 2008
  - Added the Diana disassembler.
  - Added support for multiple files (syntax -> include "c:\fred.asm")
  - Added support for exporting symbol tables (syntax -> export_sym "c:\fred.txt" [, numeric options]

See examples for more details.

Released as V1.3 (zeusver = 3)

13 Oct 2008
  - Added proc/endp to provide local labels. (see zeus_ex-macros.asm)
  - Added parameterless macros. (see zeus_ex-macros.asm)

Released as V1.4 (zeusver = 4)

13 Oct 2008 (later)
  - Added flow control checking (noflow - see zeus_ex_macros.asm)
  - Changed local label format and added global access to local labels
  - Added segments (see zeus_ex_segments.asm)

Released as V1.5 (zeusver = 5)

16 Oct 2008
  - New expression evaluator supports strings and floats
  - Added various string and numeric functions
  - Changed symbol table reporting options

Released as V1.6 (zeusver = 6)

16 Oct 2008 (later)
  - Fixed a bug (had to have one sooner or later) in multiple source handling.

Released as V1.61 (zeusver = 7)

18 Oct 2008
  - Added full support for macro parameters
  - Removed curly-braces comment style.
    I'm sorry if anyone has used these extensively, but I intend to use these as code block delimiters

Released as V1.7 (zeusver = 8)

19 Oct 2008
  - Added support for '==' and ':='
  - Removed a couple of debugging calls and changes I'd forgotten to disable

Released as V1.71 (zeusver = 8)

20 Oct 2008
  - Improved macro handling when macros are passed as parameters to macros
  - Added '\' as a string to token conversion operator. Allows calculated instructions, etc.

Released as V1.8 (zeusver = 9)

20 Oct 2008 (later)
  - Looking at producing a command line version. More of a PITA than it should be...
  - Added support for multi-line expressions inside brackets. See zeus_ex_macro.

Released as V1.81 (zeusver = 9)

23 Oct 2008
  - Created a command-line only version for use with other editors. (zcl.exe)
  - Extended output options to support hex files and multiple file writes

Released as V1.9 (zeusver = 10)

24 Oct 2008
  - Tidied up command line version.
  - Added support for roman numerals. Use zero-R as a prefix (i.e. 0rMMVIII) and zeusprintroman
    At last the wait is over - a Z80 assembler that understands roman notation!
    "Vos quod regam orbis terrarum!!!!!" - Nero.
    "Haud incultus hex!" - crem.

Released as v1.91 (zeusver = 10)

25 Oct 2008
  - Saves screen position

Released as v1.92 (zeusver = 10)

26 Oct 2008
  - Added syntax highlighting editor. Very experimental.
    The editor is a sub-set of the one used in the real Zeus.
    This implementation has always been a pain in the arse, so I expect trouble...
    Use the config tab to enable it.

Released as v2.00 (zeusver = 10)

29 Oct 2008
  - Added horizontal scroll bar to Diana definition window

Released as v2.01 (zeusver = 10)

 6 Nov 2008
  - Added various option variables.
  - Added DG pseudo-op for graphical character definition
  - Added a couple of options to Diana. See the help text.

Released as v2.10 (zeusver = 11)

7 Dec 2008
  - Added DF and DEFF which plant IEEE 32-bit floating-point values.
    Note that these are not compatible with ZX Spectrum floating point values.
    (I would support ZX format as well but I can't find a definition of it on t'web).

  - Added TIMESTR
    plants the time of assembly - eg "db TIMESTR"

  - Added LOW
    returns the low 8-bits of a value - eg "db low $1278 ; plants $78"
  - Added HIGH
    returns the high 8-bits of a value (shifted right) - eg "db high  $1278 ; plants $12"
  - Added WORD
    returns the low 16-bits of a value - eg "dw word $12345678 ; plants $5678"
    (For historical reasons these functions do not require brackets).
  - Added ZEUSRAND
    returns a 32-bit random number

  - Added SUM_MEM
    calculates the byte sum of an area of memory - eg SUM_MEM(Start,Length)
  - Added XOR_MEM
    calculates the byte xor sum of an area of memory - eg XOR_MEM(Start,Length)
    (Both used to calculate the correct values of simple CRC's for blocks of memory)

  - Added DBX and DBXO
    These allow simple encryption (obsfucation, really) of data.
    DBX takes a byte xor value followed by the same parameters as a DB statement.
    It then plants the bytes xor'd with that first value.

    By default DBX xor's each byte with the same value. If you want zeus can change
    that xor value dynamically by adding a value to it after every byte.
    Use DBXO to set this increment.

  - Added :: Scope selector
    used inside procedures/macros as a prefix to force a symbol to use the global symbol table
    eg "::Fred = ::Fred+1"

  - Increased code memory size to 256K
    To support paged memory designs. The sxz output routines don't support this directly yet.

  - Changed hex code display to eliminate redundant lines (lines that are all zeros)
    With 256K of memory it was taking too long to display the code ;)

    Note that you will need to delete the z80.tok file in order for Zeus to update it
    if you want Zeus to include these new tokens in the syntax highlighting.

Released as v2.20 (zeusver = 12)

8 Dec 2008
  - Changed file routines so that they will create paths if they don't already exist.

Released as v2.21 (zeusver = 12)

9 Dec 2008
  - Changed zeusrand to use Mersenne Twister algorythmn - Delphi's was a joke.
    Zeus now reseeds the MT algorythmn before each pass.
    use "zeusrand [value]" to reseed with a constant value.

Released as v2.22 (zeusver = 13)

9 Dec 2008
  - Revised pass control scheme. Don't know what I was thinking of when I wrote it...
  - Revised text extraction from syntax highlighting editor.

Released as v2.30 (zeusver = 14)

12 Dec 2008
  - Bug the third :( When I increased memory size I screwed up "import_bin"... Now fixed

Released as v2.31 (zeusver = 15)

6 Feb 2009
  - Extended "import_bin" to support loading parts of binary files.
    (e.g. import_bin "filepath", memory address, length to read, offset into file)
    It also now supports loading to default PC address
    (e.g. import_bin "filepath")

Released as v2.32 (zeusver = 16)

16 Sept 2009
  - Added "TextTidy" option to the edit menu. Just does some simple text reformatting.
    It usually improves the look of badly formatted source code, but it's easily fooled so
    I suggest comparing the code generated before and after use to be sure it hasn't
    altered the source's meaning.

Released as v2.33 (zeusver = 16)

30 Sept 2009
  - Added backup file options. (See editor options in config tab)
  - Bug-fix. Unary operators applied to string constants were ignored.

Released as v2.34 (zeusver = 17)

26 Aug 2010
  - Added SETRADIX pseudo-op to define the radix of numbers with leading zeros
   This is to aid compatibility with Grahams M80 sources

Released as v2.40 (zeusver = 18)

30 Aug 2010
  - Added code display option to editor (right-click on an editor)

Released as v2.41 (zeusver = 18)

30 Aug 2010
  - Added binary comparison option to zeus
   This is complicated and needs an example source written

Released as v2.50 (zeusver = 19)

17 May 2011
  - Changed pass end detection logic
  - Added output_db and output_unit filetypes

Released as v2.51 (zeusver = 20)

17 May 2011
  - Cured a bug with undefined label reporting
  - Cured a bug with saving the flow warning option

Released as v2.52

20 May 2011
  - Added a version of the Delphi Spec spectrum emulator, written by Chris Cowley.
    This does not handle memory contention but is very useful for debugging code,
    detecting logical errors, memory access errors and so forth.

Released as v2.60 (zeusver = 21)

27 May 2011
  - Improved the emulator
  - Added "emulate_spectrum" pseudo-op

Released as v2.61 (zeusver = 22)

29 May 2011
  - Added breakpoints to my editor windows

Released as v2.62 (zeusver = 22)

30 May 2011
  - Improved a few bits and pieces

Released as v2.63 (zeusver = 22)

2 June 2011
  - Fixed a bug where Zeus didn't fault ld ixl,l and similar illegal loads.
  - Adding the option to single-step the emulator in the editor
    F7 = step, F8 = run, F9 = stop
    Some register inspection works (F7 + hover the cursor over a register)

Released as v2.64 (zeusver = 23)

9 June 2011
  - Fixed the memory display (was using alt-BC and alt_DE register values, doh!)
  - Rather more register/memory inspection works (F7 + hover the cursor over a register
    or memory address, ie, (ix+dWhatever) or the fred bit of ld a,(fred)

Released as v2.65 (zeusver = 23)

29 Feb 2012
  - Adding some half-assed support for different models of Spectrum

Released as v2.70 (zeusver = 24)

26 Mar 2012
  - Removed a bug in the Z80 emulator's parity handling (there wasn't any) - my fault.
  - Changed Spectrum emulation, joystick behaviour mainly.

Released as v2.71 (zeusver = 25)

27 Mar 2012
  - Added simple compression option for tape-loaders.

Released as v2.72 (zeusver = 26)

27 Mar 2012
  - Updated compression option

Released as v2.73 (zeusver = 27)

10 Jul 2014
  - Added roman, morse, bitmap and invbitmap functions

Released as v2.74 (zeusver = 28)

30 Sept 2014
  - Changed import_bin file handling to make it more civilised
    Filenames with no path will now be assumed to come from the same directory as the main sourcefile

Released as v2.75 (zeusver = 29)

1 Oct 2014
  - Removed a bug which prevented the use of labels in nested macros

12 Dec 2014
  - Added FOR/TO/STEP/NEXT, TOSTR, TOHEX, LABEL
    LABEL has three uses:
    LABEL(name) defines a label from a string and gives it the current address as a value
    LABEL(name,val) defines a label from a string and gives it the value Val
    LABEL(name) in expressions returns the value of a label given as a string
    these are mainly intended for automatic code generation in macros/loops.

  - Added HX,LX,HY,LY as aliases for IXH etc, DUP/EDUP for LOOP/LEND
    these can save some editing when working with sources for other assemblers.

  - I have changed the string slicing so that the index can optionally start from 0
    set this with "zoStringIndexFromZero"

  - Enabled some of the the profile timing in the free version.
    You can mark code to be profiled like this:
    PROFILE = true
    nop                 ; This will be counted (NOP takes 4 bytes)
    PROFILE = false

    Or you can mark blocks of memory like this:
    PROFILE Start,Length
    Usually you'd do that at the end of the source-file or it will be overwritten as code is dumped

    If you want to see the profile data on a line by line basis you need to use the syntax highlighting
    editor and right-click to toggle profiling. It will update live if you want (F7/F8)

    You can elect to profile the number of TStates or the number of times an instruction is executed.

Released as v2.80 (zeusver = 31)

  - Enabled the SWITCH,CASE,ENDCASE,ENDSWITCH,DEFAULT in the free version.
  - Enabled OPTIONSIZE and OPTIONLIST in the free version.

Released as v2.81 (zeusver = 32)

1 Jan 2015
  - Various bits of tidying up in the emulator.
    Added stack display. Removed unnecessary analog joystick panel (just use the screen window)
    Register values can now be edited (stop the emulation, change value and hit return)
    PC cursor keys now emulated.

  - Removed support for non-syntax highlighting editor, too many options need it.

Released as v2.82 (zeusver = 32)

3 Jan 2015
  - Added the rescale menu option and the notes tab.

Released as v2.83 (zeusver = 32)

25 Feb 2015
  - Increased the number of include files allowed from 32 to 255.

Released as v2.84 (zeusver = 33)

26 Feb 2015
  - Local paths on include files are now supported. (Mutters darkly about bugs in other people's code)

Released as v2.85 (zeusver = 34)

25 Mar 2015
  - Added support for saving 128K szx files.
    If you set [emulate_spectrum "128K"] and then use output_szx it will save 128K .szx files.
    If you set [emulate_spectrum "3"] and then use output_szx it will save Model 3 .szx files.

    How Zeus's memory maps into the blocks isn't straightforward. It maps like this:

    For all the Spectrum models the memory from $4000 .. $FFFF is mapped as follows.
    Zeus address..... Memory Page
    00000 - 03FFF -> Not stored in the file
    04000 - 07FFF -> Page 5
    08000 - 0BFFF -> Page 2
    0C000 - 0FFFF -> Page 0

    For the 128K and Model 3 Spectrums there are extra blocks mapped as follows.
    10000 - 13FFF -> Page 1
    14000 - 17FFF -> Page 3
    18000 - 1BFFF -> Page 4
    1C000 - 1FFFF -> Page 6
    20000 - 23FFF -> Page 7

Released as v2.86 (zeusver = 35)

12 Oct 2015
  - Relaxed requirement to have "A," on 8-bit add,adc,sbc instructions. (Unless STRICT)
    So as well as "ADD A,B" Zeus will accept "ADD B", for example.

  - Some changes to give Zeus compatibility with Pasmo sources, as far as seems reasonable.
    The biggest issue was their differing operator precedence rules. There's now a flag in
    Zeus to support low priority logical operators if they really must. [mutter]

Released as v3.00 (zeusver = 36)

23 Nov 2015
  - Replaced the Spectrum emulator with one that correctly emulates the Z80 flags, understands
    memory contention and has cycle-accurate timing... Delphi Spec was extremely useful but
    I've always wanted an emulator that could handle border timing graphics; having invented
    them with Tony (the space-invader figure that lurks in the border during High Score display
    in Dark Star) it always nagged at me that the emulator in Zeus couldn't display them... so
    I finally bit the bullet and wrote one... urgh... I'd say I'm grateful to all the people who've
    put information out on the web, much of which is entirely accurate, about the Spectrum hardware,
    except that without them I probably wouldn't have bothered doing this at all and saved myself
    several hours of farting about.

    The new emulator should also handle "bi-colour" mode software that dynamically changes the
    pixel/attribute data in real-time.

    LIMITATIONS - tested with a 48K Spectrum. Should support 128K accurately. Doesn't attempt to
    accurately support anything else.


  - Added output_tzx so that Zeus can directly generate TZX tape files. (48K only at the moment)

    Usage:

    There are three separate modes:

    (0) To generate a "CODE" block for storing binary data:

    output_tzx "pc filename","tape filename","comment",Start,Length

    Where "pc filename" is the name to be used for the file, "tape filename" is the name to be
    put in the tzx file for the code block, "comment" is any comment required in the file, Start
    is the address in memory of the first byte and Length is the number of bytes.

    eg:

    output_tzx "darkstar.tzx","","",$8000,$4000
    output_tzx "darkstar.tzx","beefburger","not the original",$8000,$4000

    (1) Zeus can also automatically generate a "PROGRAM" block containing a tape loader, and add the
    code as a data block after it... this uses a loader like the ones I used to use in the 80's
    that load the screen at the same time as they load the data.

    output_tzx "pc filename","tape filename","comment",Start,Length,1,ExecuteAddr
    or it supports some options, mainly you can change the border colours
    output_tzx "pc filename","tape filename","comment",Start,Length,1,ExecuteAddr,Options

    To use this loader sensibly you should have a loading screen loaded in memory at $4000 .. $5AFF
    for it to use... how Zeus chooses to load the screen depends on how much of it contains visible
    pixels; if entire lines of pixels are $00 Zeus will not load them.

    For example, if you have an assembler source for a game that starts at $8000, is $2000 bytes
    long and you have a loading screen for it in a file called "screen.scr" then Zeus can generate
    a tzx file with a nice loading screen using the commands:

    import_bin "screen.scr",$4000 ; This gets the loading screen and puts it in memory in place
    output_tzx "game.tzx","mygame","(c) Etc",$8000,$2000,1,$8000 ; Generate the tzx file
    where the 1 indicates this is the required TZX format.

    To load a program generated using Zeus use LOAD "" on your Spectrum or emulator.

    The "Options" optional parameter allows you to set the colours used while the loader is operating.
    Options is a 32-bit value containing six 4-bit fields. These are as follows:

    Bits    | 31 .. 24  | 23 .. 20 | 19 .. 16 | 15 .. 12 | 11 ..  8 |  7 ..  4 |  3 ..  0 |
    Effect  | Loader Opt| Line INC | Line XOR | Loader A | Loader B | Leader A | Leader B |

    Where Leader A and B are the colours used while reading the tape leader, Loader A and B are the
    colours used while reading the data, and the loader colours are modified at the end of each
    video line by the Line XOR and Line INC values... the XOR and INC values interact with each
    other... if you don't want the border flashing on each bit-cycle make the A and B values the
    same. For example these colours are particularly repulsive.

    output_tzx "tony","tony","Hideous!",$7F00,$4000,1,$7F00,$00123456

    The most significant byte is reserved for other loader options to be added in future. Set it
    to zero for the moment.

    (2) Zeus can also put the code it generates inside a REM statement and save this as a BASIC
    programme that automatically runs the code.

    During tape loading the REM statement code is placed in memory at address $5BC0, so if you
    assemble and save code starting at that address it is run there. Otherwise Zeus prepends a
    chunk of code at the start of the REM to move your code into the required position.

    output_tzx "pc filename","tape filename","comment",Start,Length,2,ExecuteAddr
    where the 2 indicates this is the required TZX format.


  - The profile times are now shown as ccccc , ttttt, where ccccc is the T-State count in the
    current video frame when this line was last executed, and ttttt is the total time spent in
    it. The time in the frame is useful when writing code that dynamically alters the border
    or attributes.
    In CP/M emulation there's no concept of video frames so this doesn't apply.

  - Removed support for (* comment *) comments... Too much source code has (* or *) in it.

    I dithered about this, since it breaks compatibility, but too many old files have stuff like
    "org (* or blah de bloody blah)" in them, and it gets annoying having Zeus treat it as comments.

  - Changed the way Zeus supports local labels in nested structures.

    Shouldn't be a concern to anyone unless they're doing something narsty with macros. Zeus is
    more forgiving about some things than it used to be.

  - Added MULTIPASS support...

    Do not confuse MULTIPASS with the normal run of the mill multiple passes that Zeus performs
    anyway... consider a source that has options, so that the user can choose to generate different
    versions of it. Before MULTIPASS the user would have to edit the source to set the options
    required, assemble the source, change the options, assemble the source, etc, etc, for each
    set of options. What MULTIPASS allows is the assembler to automatically run several times with
    different options. I will provide example source code at some point.

  - Added support for emulating a simple Z80 machine, with 64K RAM + CF card interface and serial port.
    This is capable of running the software for a number of simple Z80 machines, notably that of
    Grant Searle's CP/M project (with the UART code modified)...

    I will provide example files for running/debugging CP/M on this hardware.
    See www.desdes.com/products/oldfiles...

  - Added "import_hex" for importing hex files.

    import_hex "fred.hex",StartAddr,Length

    Unlike binary files, hex files contain addresses for the data they contain. StartAddr will only
    work correctly if the first address mentioned in the file is the lowest address in the file, ie,
    has the smallest value. This may not always be the case... import_hex will deduce the format of the
    hex file if it can and copes with most standard 8-bit hex files (Intel, S-Record, etc).

    Unlike binary files Zeus provides no support for offsetting into hex files, sorry.

  - Lots of other changes I have forgotten or don't feel like sharing ;)

Released as v3.10 (zeusver = 37)

12 Dec 2015
  - Added NASCOM 2 emulation. See the usual place for support files...
    The NASCOM keyboard is mapped onto the PC keys as well as reasonably possible.
    The "Nascom.zip" file contains several games including The Keys of Kraal, they all run well.
    The "Upload File" buttons will upload "*.CAS" files to the NASCOM during emulation.

  - Added MEM_ROM to allow areas of memory to be set as ROM, they cannot then be changed by executing code.

  - Added an option (See config tab) to allow some of the memory flags to be displayed on the Zeus Code tab.
    This now updates the code tab whenever it's opened, bit slower but more useful.

Released as v3.11 (zeusver = 37)

12 Dec 2015
  - Widened the borders in the Spectrum emulator.
  - Stopped the assembler resetting the editor back to the start of the first source.

Released as v3.12 (zeusver = 38)

15 Dec 2015
  - Added homebrew emulation.
    A right bugger, actually, trying to get the LED brightnesses more or less right.

Released as v3.20 (zeusver = 39)

17 Dec 2015
  - Added ULA+ support and changed ':' handling for increased compatibility with neolithic source syntax

Released as v3.30 (zeusver = 40)

23 Dec 2015
  - Added support for emulating the Membership Card Z80 project
    The OS can be found in membership.zip, assemble and emulate membership.asm to see it operating.

    There are instructions in their PDF file in the zip.

Released as v3.31 (zeusver = 40)

23 Dec 2015
  - Added support for the membership card serial port. Click on the terminal window in the emulator2 tab
    while it's running.

Released as v3.32 (zeusver = 41)

23 Dec 2015
  - Added support for formatted strings. So you can optionally use stuff like "Hello\r\n"
    The syntax highlighting fails for some obscure cases, an example is "\" "
    I need to rip that rancid code out and rewrite it.

  - Changed 48K Spectrum emulation to start code as if loaded from tape, with
    the interrupt running and so on.

  - Added "xl", "xh", "yl", "yh" as aliases for the extended register set "ixl" etc...
    So that's IXL, LX and XL now... how many variants of names for these are there?
    [historical note - Zeus-2 was the first Z80 assembler to support the extended
     registers and we defined them as IXL, IXH and so on. That used to be the standard,
     but lots of things about Z80 history seem to have been forgotten...]

18 May 2016
  - Added template file for 48K Spectrum coding. (file menu New)
    Changed Zeus code tab behaviour to show the rom.
    I'm going to alter the whole way this displays when I get a moment or two.

  - Enabled GIF file generation in ZX Spectrum mode. See emulator tab.

Released as v3.33 (zeusver = 42)

20 May 2016
  - Enabled GIF generation in ULA+ mode (oops) and NASCOM-2 mode.

Released as v3.34 (zeusver = 42)

31 May 2016
  - Changed profiling instruction counting so ix/iy instructions count as 1 per execution.
  - Changed TextTidy option (improved tidying for *really* vile sources)
  - Added "TextUglify" for those strange people who prefer tabs after mnemonics.
  - Added some notes.
  - Changed ZeusEmulate_PC to Zeus_PC, Zeus_SP to Zeus_SP,EmulateStartInCycle to Zeus_Cycle
  - Changed editor focusing code and profile update timing.
  - Increased Spectrum FAST mode to 30MHz...

Released as v3.35 (zeusver = 43)
