I am learning Z80 assembly programming for the Amstrad CPC, and then I need to get the address from a list of two byte hex values, but for the moment I know how to get 1 by 1 byte (using 'A' register).
I have a "table" of addresses named 'map' that stores random video memory addresses.
for example:
map:
dw #C630, #C6E8, #C73D, #C78F
;;for C630 address is 4007
;;for C6e8 address is 4009
;;for C73D address is 400B
;;for C78F address is 400D
I could access It with index register instructions (ix or iy) but while I'm learning more, I undestand that index registers can pushed and popped or load 'A' register whith only 1 byte, not 2 bytes as I need.
My question is: there is some method to get the 2 bytes address (4007) and load the COMPLETE ADDRESS (4007) in a register and then load the COMPLETE VALUE (C630) of this address and not only 1 by 1 byte using 'A' register?
Something like if this Z80 instruction exists:
ld hl,(ix)
CodePudding user response:
You urgently need to obtain a programmer's manual for the Z80 that includes a detailed chapter on its instructions. Use your web search skills to find one.
There are instructions do implement this.
For example you can read a 16 bit value from an absolute address:
ld hl,($4007)
If you have the address in a register pair, unfortunately there is not single instruction to read a 16 bit value via this "pointer". But you can do it in a few instructions:
ld hl,$4007
; hl now has $4007
ld e,(hl)
inc hl
ld d,(hl)
; optionally, if needed to restore the original address:
dec hl
; alternatively, if needed to advance to the next address:
inc hl
BTW, experienced Z80 programmer try to avoid using IX and IY because of the worse performance compared to HL (1 more M1 cycle, 1 more M2 cycle, and some clocks for addition per load operation, as well as 2 more bytes per instruction). For example, you could write:
ld l,(ix) ; actually "ld l,(ix 0)" that is sometimes clearer
ld h,(ix 1)
But this will "cost" 38 clocks and 6 bytes, while the former example needs 26 clocks and 4 bytes.
If you need a real lot of loading and do not need the stack for processing, you can abuse the stack pointer. I found this trick in a Gameboy game. Its processor is quite similar to the Z80 but lacks the repeated load instructions like ldir
.
; don't forget to save the SP somewhere else, if necessary...
ld sp,$4007
pop hl
;...
; restore the SP
CodePudding user response:
I try this and It works for me:
ld hl,map
ld e,(hl)
inc hl
ld d,(hl)
inc hl
push hl ;then popped in a loop
ex de,hl
ld (hl),#ff
map:
dw #C630, #C6E8, #C73D, #C78F