assemblycpu-registersz80

Z80 assembly using alternative registers


I tried to write bubble sort for z80 assembly and I found that I need using alternative registers. But the recommended syntax (B′) not work and raise errors. How can I use those registers?


Solution

  • There are no instructions to use the shadow registers directly.
    Instead there is an instruction EXX to exchange the normal registers with the shadow registers.

    Give yourself to the dark side
    If you plan to use the shadow registers outside an interrupt handler1 you must also disable interrupts for the duration of using the shadow registers.

    Example:

    di           ;disable interrupts
    exx          ;exchange registers BC,DE,HL with BC',DE',and HL'
    ld b,8       ;do stuff with the shadow registers
    ....
    exx          ;put the normal registers in charge
    ei           ;re-enable interrupts
    

    1)Only applies if your system uses the shadow regs in the interrupt handler.

    Warning
    Do not do lengthy calculations with interrupts disabled, or your system will not be able to react to the external inputs that the interrupt handler processes.

    There is also a shadow register for AF: AF'.
    You access this like so:

    ex af,af'    ;exchange af with its shadow register.
    

    Note that even though ex does not affect the flags per se, ex af,af' will exchange the flags register with its shadow.

    For more info see: http://z80-heaven.wikidot.com/instructions-set

    Note that bubble sort sucks as an algorithm and it ought to be banned.
    Please implement insertion sort instead.

    Use the stack Luke
    If you do do lengthy processing, then you cannot use the shadow registers and must use the stack instead using push and pop.

    ld b,8              ;normal processing
    push bc              ;save bc for later
    ld b,9              ;extended processing
    ... do stuff with bc
    pop bc               ;throw away the extended bc and restore the old bc.
    

    …No. There is another.
    If the stack does not cut it for you, you'll have to store values in memory using ld.

    ld b,8               ;do stuff with bc
    ld (1000),bc         ;store bc for later
    ld b,9               ;do other stuff
    .....
    ld (1002),bc         ;store the extended bc
    ld bc,(1000)         ;restore the saved bc
    ....                 ;continue processing.
    

    The nice thing about addressing memory directly is that you don't have to throw values away; the disadvantage is that it runs a bit slower than the stack.