On 23 Feb 2009 at 11:22, les at
frii.com wrote:
Does the 8080 decrement the sp before it pushes the
return address, or
after. If its after, that code would of course not work. I can't
remember which order that happens in, although I suspect that it
decrements before pushing.
Decrement, then store, for both bytes.
Another possibility (seems more likely) is that the
loading of the stack
pointer is not finished before the next instruction is executed. I am
trying to remember which register was used for the sp in the emulation
mode. (I think it may be BP????) In this case, as long as some
instruction gets executed between lxi sp,xxxx and the first push/pop/call,
it may not show up.
In emulation mode (V20) BP = (8080) SP. But I don't follow your
logic on how to avoid it. Why JRT chose to code things that way,
I'll never know, but it worked on 8080, 8085 and Z80 and not on V20,
so it's a bug. And a bug in commercial (i.e. you paid money for it)
software.
In any case, this seems like a rare issue, as most
programs (thats a
big undefensable statement) would set the sp when they start, and then
leave it alone.
But there was no published document from Intel (or Zilog) that said
that one *had* to do things that way. As a matter of fact, if one
anticipates lots of interrupt activity, it's prudent to change to a
system stack (later versions of DOS do it) for interrupt servicing.
A more common-sense implementation would be to have the CPU
automatically use an alternate stack register for saving CPU state as
a result of interrupt (some microprocessors do, but not Intel, at
least in real mode).
Related, I found a bug in Spellstar for DOS. It
worked fine on an 8088 or
80286, but crashed on a 386 (it could have been a 486).
This little piece of self modifying code worked great
until the
instruction queue in the cpu became large enough that the jump instruction
was already in the pipeline before it was modified with the desired
address.
The instruction prefetch queue issue was well documented in the 386,
as was the use of an unconditional jump to void the queue. Although
it's lousy practice to use self-modifying code, I don't blame
MicroPro for it--they wrote their code to an earlier processor.
And it may just have been a relic of translated 8080 code from the
original Spellstar--sometimes writing good tight 8080 code wasn't
possible without self-modifying code (not enough registers)--and in
other cases, it was unavoidable (e.g. IN and OUT where the port is
determined at run time).
But claiming backward compatibility is a different game. Unless
something is 100% backward-compatible with the original, you'd best
not advertise it as being backward-compatible at all, unless you like
answering support calls.
To be sure, there are many instruction curiosities in the x86 family.
For example, it's permissible to do a MOV CS,something in the
8086/8088, but not in the 80C86/80C88 (or the V20/V30).
Cheers,
Chuck