Z80, pushing registers (was Re: Z80 ... thanks) 
Author Message
 Z80, pushing registers (was Re: Z80 ... thanks)

[I have cross-posted this to alt.lang.asm (about time they had
some Z80 traffic!), and directed follow-ups there.]


Quote:

>     yeah all but the one I wanted to push ... the SP register.
>   If you can come up with a good swap inside the CPU that I don't
>   see I'd be glad to hear about it ... I'm using this wonder of
>   wonders ...

>     ld (temp),sp     [ 20 T-states ]
>     ld ix,(temp)     [ 20 T-states ]

        ld ix,0    ; 14 T-states
        add ix,sp  ; 15 T-states

There is no direct "ld hl,sp" (or whatever) command, unfortunately.

Pushing the SP always sounds rather silly to me... the minute you push it,
it would be out of date :-)  I do, however, know why you want to do
so - I have done so myself in the past.

--



Thu, 30 Dec 1993 21:01:32 GMT  
 Z80, pushing registers (was Re: Z80 ... thanks)

Instead of using:

ld ix,0
add ix,sp

to get SP into a register, you'd be better off using...

ld hl,0 MCycles: 3 TStates: 10
add hl,sp MCycles: 3 TStates: 11

More effecient, after all...
--

=B(0/1/2/3) f- t w- c- d- s++(+) m e++ r(-) p k(+) <--My BearCode, if you care=
=My thoughts, my posts, my ideas, my responsibility.  Nobody else's, so there!=
=So, how many Transverse System Engineers DOES it take to change a lightbulb??=



Fri, 31 Dec 1993 03:06:25 GMT  
 Z80, pushing registers (was Re: Z80 ... thanks)

[This is no longer an issue of computer folklore, so I have deleted
alt.folklore.computers from the newsgroups line.  As I said before,
alt.lang.asm could do with some Z80 traffic....]


Quote:

> Instead of using:

> ld ix,0              [ 14 T-states]
> add ix,sp            [ 15 T-states]

> to get SP into a register, you'd be better off using...

> ld hl,0 MCycles: 3 TStates: 10
> add hl,sp MCycles: 3 TStates: 11

> More effecient, after all...

Of course it is more efficient - the IX register does have a high
overhead.  Most of the Z80 special (ie, extra to 8080) commands a pretty
expensive.

However, I think you are missing the point - there is a reason for using
IX in the example given:


Quote:

>     yeah all but the one I wanted to push ... the SP register.
>   If you can come up with a good swap inside the CPU that I don't
>   see I'd be glad to hear about it ... I'm using this wonder of
>   wonders ...

>     ld (temp),sp     [ 20 T-states ]
>     ld ix,(temp)     [ 20 T-states ]

Typically the reason for loading the SP into IX, is so that you can
reference variables on the stack.  Ie, you push some stuff onto the
stack, and then you can read directly from there.  It makes a nice
temporary store.  It just doesn't work the same with HL..... :-(

Anyway, I find a little strange that there is a "ld sp,ix" (and so on)
instruction, but not a "ld ix,sp" instruction.  I guess they ran out of
microcode space...

--



Fri, 31 Dec 1993 08:59:42 GMT  
 Z80, pushing registers (was Re: Z80 ... thanks)

Quote:
>ld hl,0 MCycles: 3 TStates: 10
>add hl,sp MCycles: 3 TStates: 11

To push SP, the general (8080) solution is

        PUSH H
        LXI H,0
        DAD S
        XTHL

According to my leaky memory.  No better Z-80 ways to do it, but the
best solution depends a lot on circumstances.

+----------------+
! II      CCCCCC !  Jim Cathey
! II  SSSSCC     !  ISC-Bunker Ramo
! II      CC     !  TAF-C8;  Spokane, WA  99220

! II      CCCCCC !  (509) 927-5757
+----------------+
                        "With e{*filter*}ment like this, who is needing{*filter*}s?"



Sun, 02 Jan 1994 07:45:43 GMT  
 Z80, pushing registers (was Re: Z80 ... thanks)
Quote:


> (Ewen McNeill) writes:
> > Pushing the SP always sounds rather silly to me... the minute you push it,
> > it would be out of date :-)  I do, however, know why you want to do
> > so - I have done so myself in the past.

> I can't think of any situation in which one would want to push the
> stack pointer onto the stack, especially if one is saving all registers
> in preparation to messing them all up. This must be some evil trick that
> I've never heard of (so it should be interesting :-)
> Please would someone enlighten me?

It is a semi-common trick on Z80s -- you load the stack pointer into one
of the index registers (IX or IY), and then you can index data on the
stack.  Just before you do this you push some interesting data onto the
stack.  This then gives you array-type access to the data on the stack,
giving you some pretty easy to allocate temporary storage.  Lots of C
compilers (for instance) on the Z80 use this method to get at
parameters passed (pushed onto the stack when passed, and then read
directly).

It is not so much pushing the stack pointer that is the important part;
more that he wanted to get the stack pointer into IX.  One way (if it
was possible) would be to push SP, and then pop it into something else.
Alas this is not possible, nor is ld <register>,SP (the reverse can be
done though :-)

--



Sun, 02 Jan 1994 06:11:56 GMT  
 Z80, pushing registers (was Re: Z80 ... thanks)

Quote:

> >It is a semi-common trick on Z80s -- you load the stack pointer into one
> >of the index registers (IX or IY), and then you can index data on the
> >stack.

> The Small C compiler uses HL, and does an:

>    ld      hl,offset
>    add     hl,sp
>    ld      a,(hl)

> sort of thing to access parameters on the stack. This compiler originally
> generated 8080 code, however. It would seem that the +127/-128 type limit
> on the offset to IX & IY would limit how much automatic storage you could
> have, whereas using HL and the add avoids this problem.

It depends on what you have on the stack whether the limit would be a
problem. For instance, arrays of memory are typically not (never?!) passed
by value - they are passed by reference.  A pointer only takes 2 bytes
on the stack (on your average Z80).  Besides, you don't normally want to
store _that_ much on the stack... the stack area is often small.  Heap
space, with a pointer on the stack, is usually better.

For a C compiler, generating Z80 code (as opposed to 8080 code) it would
be better to use IX (or IY) for a couple of reasons:
  you don't have to mess around with your main registers (IX/IY not used
   for much else anyway)
  you only have to do the load/add once, which means the overhead
   disappears, even with the extra time taken with ld r,(ix)
   instructions.

The real problem with using HL is that you often want to use HL in the
following statements as well (eg ADD HL,DE) so you are forever recalculating
the stack value.

A really _smart_ compiler would notice how much was on the stack and
generate appropriate code... :-)

Quote:


> | ...!chinet!servalan!epmooch!ben         |CNEWSMUSTDIECNEWSMUSTDIECNEWSM|

--



Mon, 03 Jan 1994 08:54:44 GMT  
 Z80, pushing registers (was Re: Z80 ... thanks)
Quote:

>Anyway, I find a little strange that there is a "ld sp,ix" (and so on)
>instruction, but not a "ld ix,sp" instruction.  

I have noch docs handy but i remember from my early days in
asm - hacking that the Z80 has many more instructions than described
in the manuals. Since there was no 'illegal instruction exception',
anybody could try the holes in the decoder and test the results.

Good ole Z80 days...

Greets,
        Andreas

--

Keyboarderror or no Keyboard present. Press any key to continue...



Sun, 02 Jan 1994 19:41:34 GMT  
 Z80, pushing registers (was Re: Z80 ... thanks)


Quote:

>>Anyway, I find a little strange that there is a "ld sp,ix" (and so on)
>>instruction, but not a "ld ix,sp" instruction.  
> I have noch docs handy but i remember from my early days in
> asm - hacking that the Z80 has many more instructions than described
> in the manuals. Since there was no 'illegal instruction exception',
> anybody could try the holes in the decoder and test the results.

There were about 120 instructions more than documented. Most of them
dealt with the 'halves' of the IX and IY register seperately. This proved
that the design of the Z80 was more regular than the highly irregular
instruction set itself would suggest. In fact, if you had an instruction
xx H,yy (xx L,yy) there would be an instruction xx IXH,yy (xx IXL,yy)
and mutatis mutandis for IYH, IYL.
Note that I write this in the past tense. My only Z80 (kept in an
Exidy Sorcerer) has gone the way of all silicon ... :-(
--

Toon Moene, SARA - Amsterdam (NL)

Note:   Because I'll switch jobs to the Royal Dutch Meteorological Institute
        (climate modelling), this mailbox will destroy itself on August 16th.



Tue, 04 Jan 1994 22:19:25 GMT  
 Z80, pushing registers (was Re: Z80 ... thanks)

Quote:

>There were about 120 instructions more than documented. Most of them
>dealt with the 'halves' of the IX and IY register seperately. This proved
>that the design of the Z80 was more regular than the highly irregular
>instruction set itself would suggest. In fact, if you had an instruction
>xx H,yy (xx L,yy) there would be an instruction xx IXH,yy (xx IXL,yy)
>and mutatis mutandis for IYH, IYL.

The 8080 chip used only single-byte opcodes.  It's operands could
be zero, one, or two immediate bytes.  Everything was fully decoded
and relatively orthogonal.  One instruction which was missing was
MOV M,M, or 76h, which was the HLT instruction.

The gaps in the 8080 instruction set became Z-80 extensions.  08, 10,
18, 20, 28, 30 and 38 became one of the register set exchanges, DJNZ,
the 8-bit relative absolute branch, and the four conditional 8-bit
relative branches.

There was one other oddball single-byte opcode, 0d9h, which was
the other register set exchange (one exchanged A & Flags with
A' & Flags', the other one exchanged the regular registers.)

CB became a special prefix with a second byte of additional
instruction decoding.  This formed the BIT, SET, RES bit
operations, and the additional shift and rotate instructions.

ED was another opcode extender, which gave access to various
stuff like SDED, LDED, SBCD, LBCD, DSBB, etc.  (I use the
TDL-type 8080 mnemonic extensions.  Those of us already
programming those chips were reluctant to switch to Zilog's
goofy new mnemonics.)

DD and FD were the index register prefixes, which only had an
effect on instructions which referenced the H or L registers,
or the HL pair, or the psuedo-register M, which referred to
the byte at (HL).

If you prefixed these instructions with DD, the X register would
substitute for HL, and FD caused Y to be used.  If it was
an "M" reference, an additional byte of instruction would be
fetched which became an additional offset to the index register.

It was possible to use the DD and FD prefixes on other Z-80
extended instructions, too, which could result in a 4-byte
instruction.

The instructions mentioned above which accessed only the high
or low bytes of X or Y could be easily generated with an
assembler by doing:

       db      0ddh     ; generate X register op
       mov     h,a      ;  move a into the high byte of X

etc.

I still have Z-80s that work, by the way.  It was a fine old part!



Fri, 07 Jan 1994 15:45:42 GMT  
 
 [ 13 post ] 

 Relevant Pages 

1. I need Z80 and Z80-CTC and Z80-PIO

2. Z80 subroutine for A/D Conversion (CTC)

3. Z80 ASM Question

4. OT: Z80 opcode question

5. Z80 Forth Performance

6. Z80 hForth -- just ported to ZMASM

7. Looking for Clyde Philips Jr. - FORTH/Z80 programmer

8. Camel80 / Z80 mnemonic question

9. FORTH for the Z80

10. Z80 Floating Point

11. Z80 Fossils and rambling notions

12. Z80 Fossils ...

 

 
Powered by phpBB® Forum Software