zeusemulate "48k" /* This file shows and example of the additions made to zeus-ish in v2.80 If you want more sustantial files they're available at www.desdes.com Profiling ---------- Version 2.80 enables some profiling options. These are intended to show how many times each piece of code is called, or how many T-States it takes. Profiling can be used to check code coverage and for performance optimisation. Make sure the "T-States" checkbox down below near the bottom of the screen is not checked. Now right-click on the source code and select "Toggle Profile" to make the profile field visible in the margin Now click on the "Assemble" button and then press and hold F7... You should be single-stepping in the source, with the profile field in the margin showing how many times the instructions on each line of source are executed. The "Profiled time" edit box shows the total number of instructions executed. If the "T-States" box is checked the totals will be the number of T-States used. You can tell Zeus to profile on a byte by byte basis by surrounding the code you wish to profile by "profile = true" and "profile = false", or you can tell Zeus to profile a block of memory using "profile start,length", ie, "profile 0,65536" will profile everything. If you use the block profile options you should put them at the end of the source file, or bytes written later will override the blocks. Whenever the emulator is running the profile counts update in real-time, so click "Assemble then Emulate" and then click back on the Zeus(Assembler) tab to get back to the editor, then press F7. This will probably take you to the "Halt" source line. Press F8 to let the emulator run while watching the source, you should see the counter update... */ ; 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 "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 ; Tell Zeus we want to profile this piece of code profile = true 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 ; 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