Date : Sun, 30 Nov 2003 14:35:40 +0000 (GMT)
From : jim <jim@...>
Subject: Re: Puzzling out the OSBYTE 121 and f0cc
On Sat, 29 Nov 2003, BBC Micro wrote:
> Still puzzling through the code at f0cc.
Now where did I put that OS disassembly? ... Oh man, that one's a doozy.
> I know the OSBYTE 121 will return the negative key value if it is
> currently pressed but I can't tie up the description with the code
> walkthrough.
The description in the "Guide to BBC ROMs" isn't very clear, quite
possibly because the authors didn't understand the routine very well
themselves.
> I can see that it is cheking the keyboard interrupts
> to see if the key is currently pressed but I can't see
> where a successful match is falling out the loop...
>
> What is at (01DF) as (02DF) is the keyboard hold?
Nothing. The 02DF in the book is a typo, it should be 01DF.
> "X determines the key to be detected and also
> determines the range of keys to be scanned" I'm not
> entirely sure about the "also" part...
It doesn't really mean "also" ... it just means that X is either a key
number or a lower bound depending on whether it is positive or negative.
> The loop points are f0e3 and f103 but I can't make out
> what they are doing...
The beeb keyboard is somewhat ideosyncratic and was never very thoroughly
documented as far as I can make out. It appears to the processor as an
8x10 grid, the internal key number just being the address as sent to the
decode circuitry on the keyboard. It has 2 modes of operation, selected by
bit 3 of the addressable latch on the system VIA (the AUG calls this
"write enable"). If this bit is 1 we're in auto-scan mode and an interrupt
will be raised when a key goes down. Otherwise we're in addressable mode
(I just made that term up, btw). You know all this but it's as well to
recap.
The loop at &f0e3 looks much like a column scan of the keyboard. I don't
actually know this for sure, but if we postulate that, when the keyboard
is in addressable mode, it will raise an interrupt whenever an address is
written to it if any key on that column is currently down, then the code
starts to make sense. We set the DDR to write to the keyboard, enable key
addressing, then make sure we only get interrupts from the column we're
actually interested in by addressing a nonexistant column and clearing the
keyboard IRQ. Then we perform the actual scan of the column, and if no key
is pressed continue the loop at &f123 which is its normal termination
condition. I don't know why this business of going back to auto-scan and
enabling interrupts, but I suspect it's just to stop the keyboard scan
routine from stealing a key down event from the normal keyboard driver.
If a keypress is detected, we fall through to &f103 with the column number
in X. This is the row scan within the column, hence the 'adc #&10' ...
we're looping on the top nybble of the key address. We skip any key below
the start value which we stored earlier, and any key which isn't actually
pressed. The non-OSBYTE version of the routine (carry clear) will also
only acknowledge a keypress that isn't already in the rollover buffer. (In
this case Y will presumably be set to &ec/&ed by the caller). If a valid
key was found after all that, we break out to &f127, otherwise we carry on
with the scan. &f127 puts the key number in X and tidies up.
If no key was found we get to the end of the loop with &ff in X.
Incidentally it looks as if you have an earlier edition of the AUG than I
do. The third edition does not have the paragraph about the key in &ee
being ignored, which looking at the code is in fact wrong: that check
isn't performed during a user call of the routine.
jim
--
http://madeira.physiol.ucl.ac.uk/people/jim/
- Bill Stickers is innocent!