(*
This file shows examples of the additions made to zeus-ish in v2.20..v2.22

If you want more sustantial files they're available at www.desdes.com


Timestamps
----------

Version 2.20 adds a predefine string variable "timestr" or "TIMESTR" which
contains the time/date at which assembly takes place (according to the local
clock) in a human-readible form. This can be used to add a timestamp to the
code as follows:

        db TIMESTR

This is not as useful as it might be - my development tools implant the
modification date in source files so that TIMESTR is only updated when the
files are edited. Assembling the same files repeatedly doesn't alter the
time implanted; it's hard to see how this functionallity could be duplicated
for zeusish - I can't use the dos filestamps because the files may be saved
before every assembly cycle and I can't assume my editor is being used...


New numeric functions
---------------------

Version 2.20 adds LOW, HIGH, WORD, ZEUSRAND

LOW returns the least significant byte, HIGH returns the next most significant byte.

They're useful for loading a 16-bit value into 8-bit registers.

WORD returns the least significant word (16-bits).

It's useful for loading a 16-bit value from a 32-bit value; perhaps when writing code
for a paged-memory design.

Fred    equ $12345678

        ld c,low Fred   ; c := $78
        ld b,high Fred  ; b := $56

        ld hl,word Fred ; hl := $5678


ZEUSRAND returns a 32-bit signed random number.

(From version v2.22 this uses the Mersenne Twister generator)

Note that using random numbers can introduce tricky problems - consider what happens
during multiple passes; does a single zeusrand statement always return the same value
on each pass? If it does not and this difference causes some labels to be moved, then
zeus may consider that the pass needs to be repeated and so on ad infinitum, or at least
until zeus gives up - a fatal assembly error.

However, I've thought about that and unless you go to some trouble the answer is yes,
any given zeusprint statement will return the same number on each pass of a single
assembly cycle - obviously each assembly cycle (each time you click assemble) may
produce a different value (it wouldn't be particularly random otherwise).

By way of example consider the following repulsive idea - suppose we want to randomly
move code about between different versions of an application, say for the purposes of
obsfucation. You might decide to plant a random number of bytes somewhere so that
everything gets moved about a bit during each development cycle. Something like this,
perhaps:

; Plant a random amount of random data...

mRandomSpace    macro(malign_size)
                  loop abs(ZEUSRAND) mod (malign_size+1)
                    db ZEUSRAND
                    lend
                  mend

So the idea is that invoking this macro plants a random number of random bytes.

                mRandomSpace(16) <- 0 .. 16 random bytes

                mRandomSpace(256) <- 0 .. 256 random bytes

And so on. Well, does this work? Yes, it does... Have fun ;)

If you want more deterministic randomness you can apply a fixed seed to zeusrand
as follows:

                zeusrand seedvalue

... where seedvalue is a 32-bit integer expression. This will cause subsequent
calls to zeusrand to return a fixed series of pseudo-random values.


Encrypted data
--------------

Version 2.20 adds a simple way to hide data from casual inspection; text strings
for example. Note that this is not intended for anything serious, it's just for
the purposes of obsfucation.

The two new statements are DBX (Define-Byte XOR'd) and DBXO (DBX Offset) and they
are used as follows:

To plant obscured data use dbx instead of db. The syntax is:

        dbx xor-value, data [,data]

Where xor-value is a byte that is to xor'd with the data. Eg:

        dbx $FF,"Hello!"

This puts 6 bytes in memory, where the bytes are the characters of the string
"Hello!" each xor'd with $FF.

Since xoring with a fixed value doesn't add much obscurity zeus allows you to have the
xor value change after every time it is used (after every byte) and zeus does this
by adding a fixed value to the xor value every time it is used. Normally this value
is zero, so that the xor is constant, but you can choose to set something other than
zero by using the dbxo statement. Eg:

        dbxo 1
        dbx $42,"Hello!"

This puts 6 bytes in memory, where the bytes are the characters of the string
"Hello!" with the first byte xor'd with $42, the second byte xor'd with $43 and so on.
I'd suggest using a dbxo value that is prime and in the range 17 .. 61, and deriving
a different starting XOR value from the data's address - that will be available to
whatever is decoding it.

Speaking of obsfucation, this macro can be useful. It acts like align but fills with
random bytes, so things aren't so obvious...

mAlignRandomFill macro(Alignment)

                while ( * mod Alignment) <> 0
                  db zeusrand
                  wend
                mend


See the example code at the end of this file for ideas...


New memory checksum functions
-----------------------------

Version 2.20 adds SUM_MEM and XOR_MEM

SUM_MEM and XOR_MEM are functions that will run through the Z80 code planted by zeus
and calculate a byte sum of a range of bytes, or the xor sum of a range of bytes.

These can be used to calculate the correct checksum for a block of memory so that the
code running can check for changes/errors.

Obviously these must be used with care - if the calculated result is planted as data
that lives in the range of memory being calculated it will alter the results of any
dynamic calculation made later. The obvious way to use these calculations is to include
the calculated bytes at the end of the range modified so that they, for example, make
checks over this larger range return zero.

eg:

CS_Start        equ *

                db "Put whatever you like here"
                dd " code or data"

                ; Add a byte which makes the block XOR to zero
                db XOR_MEM(CS_Start,* - CS_Start)

CS_Length       equ * - CS_Start

Now, if the application calculates the XOR of memory starting at CS_Start for CS_Length
bytes the result will be zero - the byte zeus calculated will cancel the rest out.

With a bit of thought it is possible to use these two functions to add three bytes to
any block of data so that both an XOR and a SUM of the total return zero; I leave this
as an exercise for the alert reader.


Scoping operator
----------------

Version 2.20 adds a new scoping operator "::" - prefixing a label with this causes zeus
to use the global symbol table for that symbol access regardless of the references location.

This has been added so that global symbols can be manipulated from inside procedures or
macros. Consider the following code:

Total = 0                               ; Init the total

Count           macro()                 ;
                  Total = Total+1       ; This doesn't work!
                mend                    ;

That looks like a simple macro which just adds one to the value Total every time it is
invoked - but it does not work. The problem is that the "Total=expression" does not
write a new value to the global variable "Total", what it does is declare a new local
variable "Total" inside the scope of the macro. This is probably not what the user
intended...

Total = 0                               ; Init the total

Count           macro()                 ;
                  ::Total = ::Total+1   ; This does work!
                mend                    ;

With the scoping operator :: prepended this now does what the user intended.

Note: Since zeus will look in the global symbol table for any symbols it doesn't find
in the local symbol table, the second scope override isn't strictly required. The
following will also work "::Total = Total+1" as long as there aren't any local labels
called "Total" declared in the macro.


Increased code memory
---------------------


Version 2.20 of zeus increases the code memory supported by zeus to $40000 (256K)
This may ease software development for systems which have paged memory. Then again,
it may not - unfortunately I haven't yet extended the szx output to support more than
64K; I don't have the file format documentation to hand.

Zeus can now use segments and/or displacements either from ORG statements or DISP
statements to place code in a larger space than 64K.

Note that you can save fragments of this large space in multiple file using multiple
output statements.
*)







; Example ZX Spectrum (48K) source to demonstrate DBX/DBXO/ZEUSRAND/ADD_MEM/XOR_MEM
;
; This shows how to use XOR_SUM and ADD_SUM so that changes to the
; code (loading errors or hacking, etc) can be detected.
;
; This just skims the surface of anti-piracy and anti-hacking concepts.
;

; Change this to suit your system - I note that Vista doesn't like changes to the root.
                output_szx "c:\temp\dbx.szx",0,Start       ; Generate code to test

; First turn the flow warning off so zeus doesn't care we appear to execute data
zoWarnFlow      = false                 ; We don't want to be bothered with 'em

; Set the encryption XOR step value
XOR_Inc         equ 37                  ; A reasonable value
                dbxo XOR_Inc            ; Tell Zeus

; Print control codes

cDel            equ $08                 ;
cCret           equ $0D                 ;
cCls            equ $0C                 ;
cClr            equ $1B                 ;
cHome           equ $0E                 ;

; Print colour select characters

cBlack          equ $00                 ;
cBlue           equ $01                 ;
cRed            equ $02                 ;
cMagenta        equ $03                 ;
cGreen          equ $04                 ;
cCyan           equ $05                 ;
cYellow         equ $06                 ;
cWhite          equ $07                 ;

                org $8000               ; Somewhere safe

Start           di                      ; Make sure we're not interrupted
                ld sp,0                 ; Set the stack to the top of memory

                ld a,cCls               ; Clear the screen
                call Print              ;

                ; Show some encrypted messages embedded in the code

                call PrintEncStrFollow  ; Print the encrypted string following this call
                dbx *,cCyan,"Hello! This was assembled at ",0

                call PrintEncStrFollow  ; Print the encrypted string following this call
                dbx *,cCret,TIMESTR,0

                call PrintEncStrFollow  ; Print the encrypted string following this call
                dbx *,cCret,cCret,cYellow,"If you look at the code you won't see",0

                call PrintEncStrFollow  ; Print the encrypted string following this call
                dbx *,cCret,cYellow,"any of this text...",0

                ; Now, print some encrypted data that lives elsewhere

                ld hl,szMsg1            ; Point at an encrypted string
                call PrintEncStr        ; And show it...

                ld hl,szMsg2            ; Point at an encrypted string
                call PrintEncStr        ; And show it...

                ld hl,szMsg3            ; Point at an encrypted string
                call PrintEncStr        ; And show it...

                ; Show the code length (changes randomly)

                ld hl,szLEN             ; "LENGTH = "
                call PrintEncStr        ;

                ld hl,CS_Length         ; Show the code length
                call PrintHex_HL        ;

                ; Show the checksum results

                ld hl,szXOR_CS          ; "XOR CS = "
                call PrintEncStr        ;

                ld hl,Start             ; XOR all the bytes together
                ld bc,CS_Length         ;
                call Calc_XOR_CS        ;
                call PrintHex_A         ; Show the result

                ld hl,szADD_CS          ; "ADD CS = "
                call PrintEncStr        ;

                ld hl,Start             ; XOR all the bytes together
                ld bc,CS_Length         ;
                call Calc_ADD_CS        ;
                call PrintHex_A         ; Show the result

                ; We're done...

                halt                    ; Stop all the excitement

; Add all the bytes of a block of memory

Calc_ADD_CS     xor a                   ; Clear the count

CAC_Lp          ld e,(hl)               ;
                add a,e                 ;

                cpi                     ; INC HL, DEC BC
                jp v CAC_Lp             ; Loop

                ret                     ; Done

; XOR all the bytes of a block of memory

Calc_XOR_CS     xor a                   ; Clear the count

CXC_Lp          ld e,(hl)               ;
                xor e                   ;

                cpi                     ; INC HL, DEC BC
                jp v CXC_Lp             ; Loop

                ret                     ; Done

; Data - the aligns are just here to make this obvious when you look at the Zeus Code tab
; so you can see how well obsfucated it is

                align 256

szMsg1          dbx *,cCret,cCret,cWhite,"If you look at the code you won't see",0
szMsg2          dbx *,cCret,cWhite,"this either.",0
szMsg3          dbx *,cCret,cCret,cGreen,"Exciting, isn't it? No? Oh well. Suit yourself...",0

szLEN           dbx *,cCret,cCret,cCyan,"Code length is ",0
szXOR_CS        dbx *,cCret,cCret,cCyan,"Memory XOR's to ",0
szADD_CS        dbx *,cCret,cCret,cCyan,"Memory ADD's to ",0

                align 256

(*
Now, notice that you can't easily do stuff like the following:

                call PrintEncStrFollow  ; Print the encrypted string following this call
                dbx *,cCyan,"Hello there!"
                dbx *,cCret,cYellow,"If you look at the code you won't see"
                dbx *,cCret,cYellow,"any of this text...",0

Why not? Well, because ALL the data has to be encoded by the SAME dbx statement if the
decryption process is going to work - each dbx statement above restarts with a new
XOR value. The print routine won't know this and so can't decode them correctly.
*)

; Print the zero-terminated encrypted string pointed to by HL

PrintEncStr     proc                    ;

                push hl,bc,af           ;

                ld b,l                  ; Get the low-byte of the address as the start XOR value

Loop            ld a,(hl)               ;
                inc hl                  ;

                xor b                   ; Apply the encryption
                jr z,Exit               ; If zero, we're done

                call Print              ;

                ld a,b                  ; Now we update the running XOR value
                add a,XOR_Inc           ;
                ld b,a                  ;

                jr Loop                 ;

Exit            pop af,bc,hl            ;
                retp                    ; (RET)

; Print an encrypted string at (HL)

PrintEncStrFollow proc                  ;

                ex (sp),hl              ;
                push af,bc              ;

                ld b,l                  ; Get the low-byte of the address as the start XOR value

Loop            ld a,(hl)               ;
                inc hl                  ;

                xor b                   ; Apply the encryption
                jr z,Exit               ; If zero, we're done

                call Print              ;

                ld a,b                  ; Now we update the running XOR value
                add a,XOR_Inc           ;
                ld b,a                  ;

                jr Loop                 ;

Exit            pop bc,af               ;
                ex (sp),hl              ;

                retp                    ; (RET)

; Print the contents of HL in hex

PrintHex_HL     ld a,h                  ;
                call PrintHex_A         ;

                ld a,l                  ;

                ; Print the contents of A in hex

PrintHex_A      call PH2                ;

PH2             rrca                    ;
                rrca                    ;
                rrca                    ;
                rrca                    ;

                push af                 ;

                and $0F                 ;

                add a,"0"               ;
                cp "9"+1                ;
                jr c,PH3                ;

                add a,"A"-("9"+1)       ;

PH3             call Print              ;

                pop af                  ;
                ret                     ;

; Print a space

Print_Sp        push af                 ; Save

                ld a,' '                ; Print a space
                call Print              ;

                pop af                  ; Done
                ret                     ;

; A print character routine. Proportionally spaced characters

Print           push ix,hl,de,bc,af     ; Save them

                cp cWhite+1             ;
                jr c,PrintColour        ;

                cp cCls                 ;
                jr z,PrintCls           ;

                cp cCret                ;
                jr z,PrintCret          ;

                cp cHome                ;
                jr z,PrintHome          ;

                ld h,PrintWidths/256    ;
                ld l,a                  ;

                ld a,(pCurX)            ;
                add a,(hl)              ;
                call c,PrintCret        ;

                call PrintOutChar       ;

                ld a,(pCurX)            ;
                add a,(hl)              ;
                ld (pCurX),a            ;

PrintExit       pop af,bc,de,hl,ix      ;
                ret                     ;

; Set a colour

PrintColour     cp 4                    ; Above green don't make them bright
                jr nc,PrintCol1         ;

                or $40                  ; Bright

PrintCol1       ld (CurCol),a           ;
                jr PrintExit            ;

; Carriage return

PrintCret       call PrintDoCret        ;
                jr PrintExit            ;

; Clear screen - this clears it slowly with a fade effect

PrintCls        ld e,$00                ;
                ld hl,$5800             ;
                ld bc,$02FF             ;

pC1             ld a,(hl)               ;
                and $07                 ;
                jr z,pC2                ;

                set 0,e                 ;
                dec (hl)                ;
pC2             cpi                     ;
                jp pe,pC1               ;

                call Delay              ;

                bit 0,e                 ;
                jr nz,PrintCls          ;

                ld hl,$4000             ;
                ld de,$4001             ;
                ld bc,$1800             ;

                xor a                   ;
                ld (hl),a               ;

                ldir                    ;

                ld a,(CurCol)           ;
                ld (hl),a               ;

                ld bc,$02FF             ;

                ldir                    ;

                xor a                   ;
                out ($FE),a             ;

PrintHome       xor a                   ;
                ld (pCurX),a            ;
                ld (ppCurY),a           ;

                ld a,cWhite             ;
                ld (CurCol),a           ;

                ld hl,$4000             ;
                ld (pCurY),hl           ;

                jr PrintExit            ;

; A suitable delay for the fade

Delay           push bc                 ;
                ld bc,1000              ;
Del1            cpi                     ;
                dec hl                  ;
                jp pe,Del1              ;
                pop bc                  ;
                ret                     ;

; Do the carriage return

PrintDoCret     ld a,(ppCurY)           ;
                inc a                   ;

PrintSetUpY     ld (ppCurY),a           ;

                and $1F                 ;

                push hl                 ;

                ld l,a                  ;
                ld h,$00                ;

                add hl,hl               ;

                ld de,YTable            ;
                add hl,de               ;

                ld a,(hl)               ;
                inc hl                  ;
                ld h,(hl)               ;
                ld l,a                  ;

                ld (pCurY),hl           ;

                xor a                   ;
                ld (pCurX),a            ;

                pop hl                  ;
                ret                     ;

; Output the character

PrintOutChar    bit 7,l                 ; characters $00..$7F only
                ret nz                  ;

                push hl                 ;

                ld h,0                  ;

                add hl,hl               ;
                add hl,hl               ;
                add hl,hl               ;

                ld de,PrintChars-256    ;
                add hl,de               ;

                push hl                 ;
                pop ix                  ;

                ld a,(pCurX)            ;

                rrca                    ;
                rrca                    ;
                rrca                    ;
                and $1F                 ;

                ld de,(pCurY)           ;

                or e                    ;
                ld e,a                  ;

                push de                 ;

                ld a,d                  ;
                rrca                    ;
                rrca                    ;
                rrca                    ;
                and $03                 ;
                or $58                  ;
                ld d,a                  ;

                ld a,(CurCol)           ;
                ld (de),a               ;
                inc de                  ;
                ld (de),a               ;

                pop de                  ;

                ld a,(pCurX)            ;
                and $07                 ;
                ld c,a                  ;

                ld b,$08                ;

OutCharL        ld h,(ix)               ;
                ld l,$00                ;

                ld a,c                  ;
                or a                    ;
                jr z,OCL1               ;

OCL2            srl h                   ;
                rr l                    ;
                dec a                   ;
                jr nz,OCL2              ;

OCL1            ld a,(de)               ;
                xor h                   ;
                ld (de),a               ;

                inc e                   ;

                ld a,(de)               ;
                xor l                   ;
                ld (de),a               ;

                dec e                   ;

                inc ix                  ;
                inc d                   ;

                djnz OutCharL           ;

                pop hl                  ;
                ret                     ;

; Screen addresses for the character rows

YTable          defw $4000,$4020,$4040,$4060    ;
                defw $4080,$40A0,$40C0,$40E0    ;
                defw $4800,$4820,$4840,$4860    ;
                defw $4880,$48A0,$48C0,$48E0    ;
                defw $5000,$5020,$5040,$5060    ;
                defw $5080,$50A0,$50C0,$50E0    ;
                defw 0,0,0,0,0,0,0,0            ; So running off the end isn't fatal

; Character set graphics

                mAlignRandomFill(256)           ; Put these on page boundaries

; These are left aligned bitmaps. The character widths follow afterwards.

PrintChars      dg --------
                dg --------
                dg --------
                dg --------
                dg --------
                dg --------
                dg --------
                dg --------

                dg #-------
                dg #-------
                dg #-------
                dg #-------
                dg #-------
                dg --------
                dg #-------
                dg --------

                dg #-#-----
                dg #-#-----
                dg #-#-----
                dg --------
                dg --------
                dg --------
                dg --------
                dg --------

                dg -#-#----
                dg -#-#----
                dg #####---
                dg -#-#----
                dg #####---
                dg -#-#----
                dg -#-#----
                dg --------

                dg --#-----
                dg -####---
                dg #-#-----
                dg -###----
                dg --#-#---
                dg ####----
                dg --#-----
                dg --------

                dg ##------
                dg ##--#---
                dg ---#----
                dg --#-----
                dg -#------
                dg #--##---
                dg ---##---
                dg --------

                dg -#------
                dg #-#-----
                dg #-#-----
                dg -#------
                dg #-#-#---
                dg #--#----
                dg -##-#---
                dg --------

                dg #-------
                dg #-------
                dg #-------
                dg --------
                dg --------
                dg --------
                dg --------
                dg --------

                dg --#-----
                dg -#------
                dg #-------
                dg #-------
                dg #-------
                dg -#------
                dg --#-----
                dg --------

                dg #-------
                dg -#------
                dg --#-----
                dg --#-----
                dg --#-----
                dg -#------
                dg #-------
                dg --------

                dg --#-----
                dg #-#-#---
                dg -###----
                dg --#-----
                dg -###----
                dg #-#-#---
                dg --#-----
                dg --------

                dg --------
                dg --#-----
                dg --#-----
                dg #####---
                dg --#-----
                dg --#-----
                dg --------
                dg --------

                dg --------
                dg --------
                dg --------
                dg --------
                dg -#------
                dg -#------
                dg #-------
                dg --------

                dg --------
                dg --------
                dg --------
                dg #####---
                dg --------
                dg --------
                dg --------
                dg --------

                dg --------
                dg --------
                dg --------
                dg --------
                dg --------
                dg --------
                dg #-------
                dg --------

                dg --------
                dg ----#---
                dg ---#----
                dg --#-----
                dg -#------
                dg #-------
                dg --------
                dg --------

                dg -###----
                dg #---#---
                dg #--##---
                dg #-#-#---
                dg ##--#---
                dg #---#---
                dg -###----
                dg --------

                dg --#-----
                dg -##-----
                dg --#-----
                dg --#-----
                dg --#-----
                dg --#-----
                dg -###----
                dg --------

                dg -###----
                dg #---#---
                dg ----#---
                dg --##----
                dg -#------
                dg #-------
                dg #####---
                dg --------

                dg #####---
                dg ----#---
                dg ---#----
                dg --##----
                dg ----#---
                dg #---#---
                dg -###----
                dg --------

                dg ---#----
                dg --##----
                dg -#-#----
                dg #--#----
                dg #####---
                dg ---#----
                dg ---#----
                dg --------

                dg #####---
                dg #-------
                dg ####----
                dg ----#---
                dg ----#---
                dg #---#---
                dg -###----
                dg --------

                dg --###---
                dg -#------
                dg #-------
                dg ####----
                dg #---#---
                dg #---#---
                dg -###----
                dg --------

                dg #####---
                dg ----#---
                dg ---#----
                dg --#-----
                dg -#------
                dg -#------
                dg -#------
                dg --------

                dg -###----
                dg #---#---
                dg #---#---
                dg -###----
                dg #---#---
                dg #---#---
                dg -###----
                dg --------

                dg -###----
                dg #---#---
                dg #---#---
                dg -####---
                dg ----#---
                dg ---#----
                dg ###-----
                dg --------

                dg --------
                dg --------
                dg #-------
                dg --------
                dg #-------
                dg --------
                dg --------
                dg --------

                dg --------
                dg --------
                dg -#------
                dg --------
                dg -#------
                dg -#------
                dg #-------
                dg --------

                dg ---#----
                dg --#-----
                dg -#------
                dg #-------
                dg -#------
                dg --#-----
                dg ---#----
                dg --------

                dg --------
                dg --------
                dg #####---
                dg --------
                dg #####---
                dg --------
                dg --------
                dg --------

                dg #-------
                dg -#------
                dg --#-----
                dg ---#----
                dg --#-----
                dg -#------
                dg #-------
                dg --------

                dg -###----
                dg #---#---
                dg ---#----
                dg --#-----
                dg --#-----
                dg --------
                dg --#-----
                dg --------

                dg -###----
                dg #---#---
                dg #-#-#---
                dg #-###---
                dg #-##----
                dg #-------
                dg -####---
                dg --------

                dg --#-----
                dg -#-#----
                dg #---#---
                dg #---#---
                dg #####---
                dg #---#---
                dg #---#---
                dg --------

                dg ####----
                dg #---#---
                dg #---#---
                dg ####----
                dg #---#---
                dg #---#---
                dg ####----
                dg --------

                dg -###----
                dg #---#---
                dg #-------
                dg #-------
                dg #-------
                dg #---#---
                dg -###----
                dg --------

                dg ####----
                dg #---#---
                dg #---#---
                dg #---#---
                dg #---#---
                dg #---#---
                dg ####----
                dg --------

                dg #####---
                dg #-------
                dg #-------
                dg ####----
                dg #-------
                dg #-------
                dg #####---
                dg --------

                dg #####---
                dg #-------
                dg #-------
                dg ####----
                dg #-------
                dg #-------
                dg #-------
                dg --------

                dg -####---
                dg #-------
                dg #-------
                dg #-------
                dg #--##---
                dg #---#---
                dg -####---
                dg --------

                dg #---#---
                dg #---#---
                dg #---#---
                dg #####---
                dg #---#---
                dg #---#---
                dg #---#---
                dg --------

                dg ###-----
                dg -#------
                dg -#------
                dg -#------
                dg -#------
                dg -#------
                dg ###-----
                dg --------

                dg ----#---
                dg ----#---
                dg ----#---
                dg ----#---
                dg ----#---
                dg #---#---
                dg -###----
                dg --------

                dg #---#---
                dg #--#----
                dg #-#-----
                dg ##------
                dg #-#-----
                dg #--#----
                dg #---#---
                dg --------

                dg #-------
                dg #-------
                dg #-------
                dg #-------
                dg #-------
                dg #-------
                dg #####---
                dg --------

                dg #---#---
                dg ##-##---
                dg #-#-#---
                dg #-#-#---
                dg #---#---
                dg #---#---
                dg #---#---
                dg --------

                dg #---#---
                dg #---#---
                dg ##--#---
                dg #-#-#---
                dg #--##---
                dg #---#---
                dg #---#---
                dg --------

                dg -###----
                dg #---#---
                dg #---#---
                dg #---#---
                dg #---#---
                dg #---#---
                dg -###----
                dg --------

                dg ####----
                dg #---#---
                dg #---#---
                dg ####----
                dg #-------
                dg #-------
                dg #-------
                dg --------

                dg -###----
                dg #---#---
                dg #---#---
                dg #---#---
                dg #-#-#---
                dg #--#----
                dg -##-#---
                dg --------

                dg ####----
                dg #---#---
                dg #---#---
                dg ####----
                dg #-#-----
                dg #--#----
                dg #---#---
                dg --------

                dg -###----
                dg #---#---
                dg #-------
                dg -###----
                dg ----#---
                dg #---#---
                dg -###----
                dg --------

                dg #####---
                dg --#-----
                dg --#-----
                dg --#-----
                dg --#-----
                dg --#-----
                dg --#-----
                dg --------

                dg #---#---
                dg #---#---
                dg #---#---
                dg #---#---
                dg #---#---
                dg #---#---
                dg -###----
                dg --------

                dg #---#---
                dg #---#---
                dg #---#---
                dg #---#---
                dg #---#---
                dg -#-#----
                dg --#-----
                dg --------

                dg #---#---
                dg #---#---
                dg #---#---
                dg #-#-#---
                dg #-#-#---
                dg ##-##---
                dg #---#---
                dg --------

                dg #---#---
                dg #---#---
                dg -#-#----
                dg --#-----
                dg -#-#----
                dg #---#---
                dg #---#---
                dg --------

                dg #---#---
                dg #---#---
                dg -#-#----
                dg --#-----
                dg --#-----
                dg --#-----
                dg --#-----
                dg --------

                dg #####---
                dg ----#---
                dg ---#----
                dg --#-----
                dg -#------
                dg #-------
                dg #####---
                dg --------

                dg #####---
                dg ##------
                dg ##------
                dg ##------
                dg ##------
                dg ##------
                dg #####---
                dg --------

                dg --------
                dg #-------
                dg -#------
                dg --#-----
                dg ---#----
                dg ----#---
                dg --------
                dg --------

                dg #####---
                dg ---##---
                dg ---##---
                dg ---##---
                dg ---##---
                dg ---##---
                dg #####---
                dg --------

                dg --#-----
                dg -###----
                dg #-#-#---
                dg --#-----
                dg --#-----
                dg --#-----
                dg --------
                dg --------

                dg --------
                dg --------
                dg --------
                dg --------
                dg --------
                dg --------
                dg #####---
                dg --------

                dg --------
                dg --------
                dg --------
                dg --------
                dg --------
                dg --------
                dg --------
                dg --------

                dg --------
                dg --------
                dg -##-#---
                dg #--##---
                dg #---#---
                dg #--##---
                dg -##-#---
                dg --------

                dg #-------
                dg #-------
                dg #-##----
                dg ##--#---
                dg #---#---
                dg ##--#---
                dg #-##----
                dg --------

                dg --------
                dg --------
                dg -####---
                dg #-------
                dg #-------
                dg #-------
                dg -####---
                dg --------

                dg ----#---
                dg ----#---
                dg -##-#---
                dg #--##---
                dg #---#---
                dg #--##---
                dg -##-#---
                dg --------

                dg --------
                dg --------
                dg -###----
                dg #---#---
                dg #####---
                dg #-------
                dg -###----
                dg --------

                dg --#-----
                dg -#------
                dg -#------
                dg ###-----
                dg -#------
                dg -#------
                dg -#------
                dg --------

                dg --------
                dg --------
                dg -####---
                dg #---#---
                dg #--##---
                dg -##-#---
                dg ----#---
                dg -###----

                dg #-------
                dg #-------
                dg ####----
                dg #---#---
                dg #---#---
                dg #---#---
                dg #---#---
                dg --------

                dg #-------
                dg --------
                dg #-------
                dg #-------
                dg #-------
                dg #-------
                dg #-------
                dg --------

                dg --------
                dg --#-----
                dg --------
                dg --#-----
                dg --#-----
                dg --#-----
                dg --#-----
                dg ##------

                dg #-------
                dg #-------
                dg #--#----
                dg #-#-----
                dg ###-----
                dg #--#----
                dg #---#---
                dg --------

                dg ##------
                dg -#------
                dg -#------
                dg -#------
                dg -#------
                dg -#------
                dg ###-----
                dg --------

                dg --------
                dg --------
                dg ##-#----
                dg #-#-#---
                dg #-#-#---
                dg #-#-#---
                dg #-#-#---
                dg --------

                dg --------
                dg --------
                dg ####----
                dg #---#---
                dg #---#---
                dg #---#---
                dg #---#---
                dg --------

                dg --------
                dg --------
                dg -###----
                dg #---#---
                dg #---#---
                dg #---#---
                dg -###----
                dg --------

                dg --------
                dg --------
                dg ####----
                dg #---#---
                dg #---#---
                dg ####----
                dg #-------
                dg #-------

                dg --------
                dg --------
                dg -####---
                dg #---#---
                dg #---#---
                dg -####---
                dg ----#---
                dg ----#---

                dg --------
                dg --------
                dg #-##----
                dg ##------
                dg #-------
                dg #-------
                dg #-------
                dg --------

                dg --------
                dg --------
                dg -####---
                dg #-------
                dg -###----
                dg ----#---
                dg ####----
                dg --------

                dg --------
                dg --#-----
                dg #####---
                dg --#-----
                dg --#-----
                dg --#-----
                dg ---##---
                dg --------

                dg --------
                dg --------
                dg #---#---
                dg #---#---
                dg #---#---
                dg #---#---
                dg -####---
                dg --------

                dg --------
                dg --------
                dg #---#---
                dg #---#---
                dg -#-#----
                dg -#-#----
                dg --#-----
                dg --------

                dg --------
                dg --------
                dg #---#---
                dg #---#---
                dg #---#---
                dg #-#-#---
                dg -#-#----
                dg --------

                dg --------
                dg --------
                dg #---#---
                dg -#-#----
                dg --#-----
                dg -#-#----
                dg #---#---
                dg --------

                dg --------
                dg --------
                dg #--#----
                dg #--#----
                dg #--#----
                dg ####----
                dg ---#----
                dg ###-----

                dg --------
                dg --------
                dg #####---
                dg ---#----
                dg --#-----
                dg -#------
                dg #####---
                dg --------

                dg --##----
                dg -#------
                dg -#------
                dg #-------
                dg -#------
                dg -#------
                dg --##----
                dg --------

                dg --------
                dg #-------
                dg #-------
                dg --------
                dg --------
                dg #-------
                dg #-------
                dg --------

                dg ##------
                dg --#-----
                dg --#-----
                dg ---#----
                dg --#-----
                dg --#-----
                dg ##------
                dg --------

                dg -#-#----
                dg --------
                dg -###----
                dg #---#---
                dg #####---
                dg #-------
                dg -###----
                dg --------

                dg --------
                dg --------
                dg ----#---
                dg -###----
                dg #-------
                dg --------
                dg --------
                dg --------

; Character widths

PrintWidths     db $07,$09,$09,$09,$09,$09,$09,$03
                db $05,$05,$05,$05,$03,$05,$05,$05
                db $05,$03,$05,$05,$05,$05,$09,$09
                db $07,$09,$07,$02,$05,$09,$07,$09
                db $06,$02,$04,$06,$06,$06,$06,$02
                db $04,$04,$06,$06,$03,$06,$02,$06
                db $06,$06,$06,$06,$06,$06,$06,$06
                db $06,$06,$02,$03,$05,$06,$05,$06
                db $06,$06,$06,$06,$06,$06,$06,$06
                db $06,$04,$06,$06,$06,$06,$06,$06
                db $06,$06,$06,$06,$06,$06,$06,$06
                db $06,$06,$06,$06,$06,$06,$06,$06
                db $06,$06,$06,$06,$06,$06,$04,$06
                db $06,$02,$04,$06,$04,$06,$06,$06
                db $06,$06,$05,$06,$06,$06,$06,$06
                db $06,$05,$06,$05,$02,$05,$06,$06
                db $03,$06,$0C,$12,$18,$1E,$24,$2A  ; Wide spaces $80..?
                db $30,$36,$3C,$42,$48,$06,$06,$06
                db $01,$02,$03,$04,$05,$06,$06,$06
                db $06,$06,$06,$06,$06,$06,$06,$06
                db $06,$06,$06,$06,$06,$06,$06,$06
                db $06,$06,$06,$06,$06,$06,$06,$06
                db $06,$06,$06,$06,$06,$06,$06,$06
                db $06,$06,$06,$06,$06,$06,$06,$06
                db $06,$06,$06,$06,$06,$06,$06,$06
                db $06,$06,$06,$06,$06,$06,$06,$06
                db $06,$06,$06,$06,$06,$06,$06,$06
                db $06,$06,$06,$06,$06,$06,$06,$06
                db $06,$06,$06,$06,$06,$06,$06,$06
                db $06,$06,$06,$06,$06,$06,$06,$06
                db $06,$06,$06,$06,$06,$06,$06,$06
                db $06,$06,$06,$06,$06,$06,$06,$06

; For fun, include some random bytes...

                align $400              ; So it shows up clearly on the Zeus Code tab

                db "Random block starts             "

                mRandomSpace(256)       ; Plant a random number of random bytes

                db "Random block ends"

; Now, we're going to add three bytes so that the XOR_SUM and ADD_SUMs are zero

; First, we plant a byte which makes the XOR CS (including it) zero
; To do that we just work out the XOR of every byte to here and plant that value

                db XOR_MEM(Start,* - Start)

; It may not be obvious but the SUM_MEM of any block with an XOR_SUM of zero must
; be even - since the LSB of the XOR CS is zero.
; This means we can do the following without having to divide an odd-number

; We now calculate the byte value we need to add to this block to make the SUM
; (including it) be zero.

SUM_Val         = 0 - SUM_MEM(Start,* - Start)

; We now plant that value as two equal bytes to make the ADD CS of all this zero
; We plant this as two halves so they cancel out when XOR'd and don't ruin the XOR CS

                db SUM_Val/2,SUM_Val/2

; Now if we XOR or ADD sum all the bytes between Start and here both should be zero.

CS_Length       equ * - Start           ; The number of bytes in the checked block

; Variables

pCurX           db 0            ; A logical X position
ppCurY          db 0            ; A logical Y position
pCurY           dw 0            ; The actual address
CurCol          db 0            ; The cursor colour

; A handy macro - acts like align but fills with random bytes

mAlignRandomFill macro(Alignment)               ; We're given the alignment required

                while ( * mod Alignment)        ; Loop while we're not aligned
                  db zeusrand                   ; Plant a random byte
                  wend                          ;
                mend

; Plant a random amount of random data...

mRandomSpace    macro(malign_size)
                  loop abs(ZEUSRAND) mod (malign_size+1)
                    db ZEUSRAND
                    lend
                  mend



