Chuck Guzis wrote:
On 8/8/2006 at 3:35 PM Don wrote:
Having B appear on the address bus is a nice way
of combining
an IN and OUT instruction into a single operation. I often
exploit this when decoding key matrixes, etc. (i.e. set
B to whatever you want to appear on the row drivers, C to
the IO address for the "keyboard" and do an IN A,C)
Yes! I prefer to think of it as a 16-bit port address. But the idea's the
It is. I just like using half of *that* address space (for the
keypad) as an output port. Just like partially decoding
addresses instead of *fully* decoding them.
same, instead of latching an index value into a
register file on a device,
one can simply use the value of the B register as the index and do away wit
hthe latch entirely, saving valuable time.
Well, you still need a set of buffers. But, buffers are cheaper
and don't ALSO require a separate I/O address decode (to LATCH
the data).
So, you can:
LD B,0xFF
LD C,KEYPAD_PORT
IN A,C
JR Z,NO_KEYSDOWN
LD B,0x01
LOOP: IN A,(C)
JR NZ,KEYS_IN_THIS_ROW_DOWN
RLC B
JP LOOP
Note the unconditional JP used instead of JR since it
is faster (the conditional JP/JR are the same speed so
use the JR's since they are smaller)
Also note that IN A,(C) doesn't require a subsequent
operation to set the condition codes as *it* does
(whereas IN A,(###) would not).
The tiny buglet in the code is left as an exercise for
the reader :>
The NSC800 has a configuration port at 0bbh, which can
be modified with the
register-indirect form of the OUT instruction, but not the immediate-port
form.