/* This is a simple demonstration file for the Zeus assembler. If you want more sustantial files they're available at www.desdes.com Extra 16-bit load 'instructions'... To make some 16-bit operations look nicer in the source Zeus provides some pseudo-ops that generate pairs of 8-bit instructions. For example, the Z80 does not have a "LD HL,DE" instruction. Normally you'd have to do this with a pair of instructions in the source, but Zeus will allow you to type "LD HL,DE" and will generate the pair of instructions for you. Now, there are things you need to be aware of when doing this - it doesn't improve code efficiency, it just looks neater. Also, you might assume that the operation is atomic, ie, happens indivisibly, but that isn't true - an interrupt might occur between the two loads, for example. If you are writing code where this might be an issue (it almost never is) then I suggest you use the "STRICT" option, this disables all the extensions. Some people just detest this sort of pseudo-operation; I'm sympathetic, but too lazy to type more than I need when programming ;) Let's have some examples: Note - with versions of Zeus later then, um, 1.5 this code will generate lots of warnings because Zeus doesn't like the idea of the z80 running through those align statements. Just ignore the warnings, or turn them off on the config tab... */ org 0 ld bc,de ; This generates the same code as... ld bc,hl ; This generates the same code as... ld bc,ix ; This generates the same code as... ld bc,iy ; This generates the same code as... align 16 ; Make it easier to check (look at the code) ; The bytes should be identical vertically ld b,d:ld c,e ; ... this ld b,h:ld c,l ; ... this ld b,ixh:ld c,ixl ; ... this ld b,iyh:ld c,iyl ; ... this align 64 ; Make it easier to check (look at the code) ld de,bc ; This generates the same code as... ld de,hl ; This generates the same code as... ld de,ix ; This generates the same code as... ld de,iy ; This generates the same code as... align 16 ; Make it easier to check (look at the code) ld d,b:ld e,c ; ... this ld d,h:ld e,l ; ... this ld d,ixh:ld e,ixl ; ... this ld d,iyh:ld e,iyl ; ... this align 64 ; Make it easier to check (look at the code) ld hl,bc ; This generates the same code as... ld hl,de ; This generates the same code as... align 16 ; Make it easier to check (look at the code) ld h,b:ld l,c ; ... this ld h,d:ld l,e ; ... this /* Note that you can't do a LD HL,IX because of the way the Z80 uses prefix bytes to address IX... I choose not to support it rather than do the PUSH HL:POP IX because that assumes you have a safe stack, and it's also ssllooww... Now, they're simple enough, but the extra 16-bit 'instructions' that make most sense are the ones involved with loads to/from the index registers. These are nice because (a) they save a lot of typing and (b) they remove unsightly expressions. Eg, ld hl,(ix) replaces ld l,(ix):ld h,(ix+1) and ld hl,(ix+dpNext) replaces ld l,(ix+dpNext):ld h,(ix+dpNext+1), assuming the labels used exist, of course. NOTE - Zeus assumes that your 16-bit variables are stored in memory low byte at the lowest address, as god himself intended, and Zeus loads the low byte first in this implementation. Forbidden Planet made extensive use of these 16-bit loads and the source suffers from their omission. So at some point I'll restore the original source. Let's have some examples. I'll also use a structure to illustrate the process. */ struct dpNext ds 2 ; Point at the next thing dX ds 2 ; X,Y,Z as 16-bit variables dY ds 2 ; dZ ds 2 ; send org $100 ld bc,(ix+dX) ; Typical code ld de,(ix+dY) ; ld hl,(ix+dZ) ; align 32 ld c,(ix+dX) ; This is what it replaces ld b,(ix+dX+1) ; ld e,(ix+dY) ; ld d,(ix+dY+1) ; ld l,(ix+dZ) ; ld h,(ix+dZ+1) ; align $80 ld (iy+dX),bc ; Typical code ld (iy+dY),de ; ld (iy+dZ),hl ; align 32 ld (iy+dX),c ; This is what it replaces ld (iy+dX+1),b ; ld (iy+dY),e ; ld (iy+dY+1),d ; ld (iy+dZ),l ; ld (iy+dZ+1),h ;