bugbiter Posted August 4, 2015 Share Posted August 4, 2015 I can't believe I am not able to solve this myself... Until now in assembly, I always read the keycode in CH myself if I was using keyboard keys in my programs. After mastering disk i/O with IOCB I thought, hell, that's easy! What an elegant OS our Atari has! Now I tried to use the keyboard 'the proper way' , reading a key via CIO. I came across that small routine: 00010 ------------------------------00020 * READ CHAR FROM KEYBOARD *00030 * CHAR WILL BE IN THE *00040 * <A> REGISTER *00050 * <X>,<Y> will be destroyed *00060 ------------------------------00070 *00080 GETKEY LDA $E425 GET ADRESS-VECTOR00090 PHA FROM ROM HANDLER TAB00100 LDA $E424 PLACE ADDRESS AS00110 PHA RETURN ADDRESS TO STACK00120 RTS JUMP TO ROM-ROUTINE00130 * But It doesn't work, I just get EOLs all the time. Maybe I have to open a channel first? I always thought the keyboard handler is resident, so there should be always an open keyboard channel set by the OS, but which one? when I use .IOCB command in Altirra's debugger to check IOCB status, no K: channel seems to be open. (my code runs from 'compile and run' in WUDSN) So how do I open a channel for "K:" ? I can't find an example anywhere about how to do it properly. Do I have to use a specific channel number? Do I have to use open for read or write? Which IOCB registers do I have to set and how? This should be such a simple task, it's embarrassing... Quote Link to comment Share on other sites More sharing options...
phaeron Posted August 5, 2015 Share Posted August 5, 2015 (edited) The E:, S:, and K: handlers in the OS are all the same module internally and cross-call between each other. K: doesn't need to be open because E: directly calls into the keyboard routines. The problem is that the K: handler is checking bit 0 of ICAX1Z to see if should respond in forced read mode. CIO normally copies ICAX1,X to ICAX1Z before invoking the device handler, but since you are bypassing CIO you'll need to set up it up yourself by setting ICAX1Z=$04. Interestingly, while this behavior is documented for E:, it doesn't seem to be documented for K:. The OS manual says that there are no device dependent bits in ICAX1, even though both OS-B and the XL/XE OS check ICAX1Z in K: GET BYTE. If you want to do it the fully correct way, you'll have to open K: through an IOCB. Set X=IOCB*16, i.e. $10 for IOCB #1, ICBAL,X and ICBAH,X to point to the filename ('K', $9B), ICAX1,X to the mode ($04 for read), and ICCMD,X to the OPEN command ($03). JSR CIOV with X=$10 to open the IOCB and check the N flag for an error. To read a byte, do a zero byte read with ICCMD,X=$07, ICBLL,X=0, ICBLH,X=0, X=IOCB*16, JSR CIOV and receive the byte in the A register. Close the IOCB with ICCMD,X=$0C, X=IOCB*16, JSR CIOV. Edited August 5, 2015 by phaeron 1 1 Quote Link to comment Share on other sites More sharing options...
bugbiter Posted August 5, 2015 Author Share Posted August 5, 2015 Thanks, phaeron for that thorough and detailed explanation. Quote Link to comment Share on other sites More sharing options...
Rybags Posted August 5, 2015 Share Posted August 5, 2015 A trick if you want to continue processing and not be held up waiting for a key - check the CH variable ($2FC, 764 dec) - only do the CIO call if the value is < $C0. That will ignore situations of no keypress or SHIFT + CONTROL + key (which generate keyclick but don't return anything). There are some "null" keypresses though that fall into the $80 - $BF scan code range. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.