Roy J. Tellason wrote:
On Tuesday 04 April 2006 09:08 am, Don Y wrote:
Roy J. Tellason wrote:
On Monday 03 April 2006 12:57 am, Don Y wrote:
I think the real reason (?) goes to a difference
in cultures between
register rich and register poor machines IN THAT TIMEFRAME.
I think you're
probably right...
E.g., if you are writing code for a 68xx, you
have little choice
but to do everything in memory addressing. Whereas if you are
using 8080/8085/Z80 et al., you just get used to *keeping* things
in registers (I can recall spending lots of time evaluating
which arguments I would put in which registers so I could
*keep* them there -- or somewhere else in the register set -- for
the duration of the algorithm... XCHG being a favorite tool
in those cases!)
Yeah. Though XTHL was another one...
As was PCHL. But,
XCHG was lots of bang for the buck (4 clocks?)
Yes. And I often wished that they'd had one that would work with BC, as
well... :-)
The typical usage was HL & DE for source/destination pointers
and BC as length/byte count. So, you could
LXI H,...
LXI D,...
...
DAD B ;HL points to something
XCHG ;save HL in DE, get at contents of DE
DAD B ;DE points to similar "thing"
...
Moving to
something like a 99000 can be terribly distressing
for the register rich crowd to become accustomed to! ;)
I found, though, when I
was doing some z80 stuff a while back that most
of the time I'd use one pair for an address pointer and maybe one other
besides the accumulator and that was it, over 90% of the time.
Z80 is a different
beast from the 808[05]. You write code differently for
it because it has a much richer instruction set.
But I never used most of that stuff. Never got around to doing anything with
the index registers, the alternate set, or a lot of those "specials" that
Alternate register set was ideal for interrupt service (assuming
IRQs aren't nested *or* you restrict the alt registers for use by
a single IRQ that can never interrupt itself). Consider the
cost of saving all of that state and restoring it before RETI
and you can see how quickly you can save a lot of time!
were added. I kinda liked relative jumps, though,
since it made it way
easier to do relocatable code and plus they were a byte smaller. :-)
A favorite trick was to finish a product. Then grep for all
CALLs. Sort this list to come up with the N most common CALLs,
and then assign those to the "unused" RST's. You could often
save 500 bytes of code with that 10 minute exercise...
But, if you
are doing things like adding an 8 digit BCD number to another 8
digit BCD number, you quickly discover that you need a lot of registers (two
pointers for the two arguments -- assuming the destination is one
of these as well, a "digit counter", the accumulator and, of course, the
carry).
I suppose. I guess it all depends on what you want to do...
Oh, and
the little monitor program that I was playing with didn't push a
parameter on to the stack, it put it inline, right after the call to
some subroutine -- the called code would pick it up and use it and adjust
the stack pointer to just past it for the return. :-)
Yes, a favorite trick for
"printing" strings, etc.
CALL OUTPUT
DB 'Hello, World!'
<insert next instruction here>
Just so.
We would often develop our own interpreters to make some of this
stuff more efficient to code. This would get coded in-line
with appropriate macros. For example:
STATE IDLE
ON '0' THRU '9' GOTO IDLE EXECUTING Accumulate_Digit
ON BARCODE GOTO TEST EXECUTING Clear_and_Read_then_Test
ON CLEAR GOTO IDLE EXECUTING Clear_Accumlator
ON ENTER GOTO TEST EXECUTING Test_Value
ENDSTATE
STATE TEST
ON GOODVALUE GOTO ACCEPT EXECUTING Process_Value
ON BADVALUE GOTO REJECT EXECUTING Signal_Error
ENDSTATE
So, with ~25 bytes, I can code a numeric data entry routine
(trivial example) in a way that actually is reasonably easy
to read.
I have to dig out that code, anyhow, there were a
few little tricks in
there that I think I want to use again. Like funneling everything
through a dispatch table, so that un-programmed EPROM showing up as
"FFFF" in some entries would be handled automatically ("CRASH!" :-),
ferinstance.
Or, using INR M to 'test' flags.
Yep!
THogh this caused all sorts of problems when I got my first
ICE! :-( (think about it :> )
Sometimes I like the absolutely minimalist approach to
things, too. One of
these days I'm gonna dig that code out, burn it, and see how small a z80
box I can build that'll still prove useful for all sorts of things. I sure
have enough of those parts on hand here...
I have a tiny multitasking executive that runs in a handful of
bytes. Slick as snot -- if you adopt its coding style.