Home > Back-end >  Load value of register in 2 by 2 bytes to another register
Load value of register in 2 by 2 bytes to another register

Time:09-03

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
  • Related