Jump to content
IGNORED

Hooking into keyboard interrupt


Recommended Posts

I was playing around with this code from DERE Atari, which hooks into IRQs and prevents the user from typing control key combinations and disables BREAK key. The article says it would work with revision B OS as well as the older one. I am trying this code on a 130XE and having no luck getting the CONTROL KEY part working (lines 300-360), BREAK key disabling part works fine. Can anyone confirm that the code is correct and if so what could be the reason for it not working as expected. When I say not working I mean CONTROL KEY combinations still work like usual after the code is loaded and run.

10 POKMSK =    0010
20 KBCODE =    $D209
30 VKEYBD =    $0208
40 IRQEN  =    $D20E
45 IRQST  =    IRQEN
46 VMIRQ  =    $0216
60        *=   $600
80 START  SEI             ;   DISABLE IRQS
90        LDA  VMIRQ      ; REPLACE THE IRQ VECTOR
0100      STA  NBRK+1     ;WITH OUR OWN
0110      LDA  VMIRQ+1    ; ALL IRQS WILL
0120      STA  NBRK+2     ; GO TO NBRK
0130      LDA  #IRQ&255
0140      STA  VMIRQ
0150      LDA  #IRQ/256
0160      STA  VMIRQ+1
0170      CLI             ; ENABLE IRQS
0200      LDA  VKEYBD     ; POINT KEY IRQ TO
0210      STA  JUMP+1     ; REP
0220      LDA  VKEYBD+1
0230      STA  JUMP+2
0240      LDA  #REP&255   ; VECTOR KEY IRQ
0250      STA  VKEYBD     ; LOW BYTE OF VECTOR
0260      LDA  #REP/256
0270      STA  VKEYBD+1
0280      RTS

0290      *=$639
0300 REP  LDA  KBCODE ; ALL KEY IRQS COME HERE
0310      AND  #$80   ; CHECK IF CONTROL HIT
0320      BEQ  JUMP   ;IF NOT HIT THEN GO
0330      PLA         ; ELSE IGNORE CONTROL KEY
0340      RTI
0360 JUMP JMP JUMP    ;THIS CALLS THE OLD KEY IRQ
0375 IRQ  PHA         ; ALL IRQS COME HERE
0380      LDA  IRQST  ; CHECK IF [BREAK]
0390      BPL  BREAK  ; IF [BREAK] IRQ,BRANCH
0405      PLA         ; ELSE CALL OLD IRQ VECTOR
0410 NBRK JMP  NBRK   ; CALL OLD IRQ VECTOR
0430 BREAK LDA  #$7F  ; HERE IF [BREAK]
0440      STA  IRQST  ; SHOW NO [BREAK]
0450      LDA  POKMSK
0460      STA  IRQEN
0462      PLA
0464      RTI ; RETURN AS IF NO [BREAK]
0470      *=  $02E2
0480      .WORD START
Edited by atari8warez
Link to comment
Share on other sites

BREAK key is a seperate IRQ type and can simply be disabled via the high bit of IRQEN.

 

But, IIRC the early OS-A doesn't have a Break key IRQ - would need to look at that OS to see how it's processed.

 

For normal keys, yes you could simply mask out the bit relating to the CTRL key. The XL/later key IRQ is somewhat more complex than the one used in the 400/800 though.

Also there's the repeat logic - that's handled in part by the IRQ but largely by the Stage 2 VBlank. A potential problem is that the repeat function might get confused.

 

Possible scenarios:

- CTRL key masked as if never pressed and normal key generated. Repeat probably wouldn't work since the VBlank routine sees CTRL pressed and doesn't process it as a held key.

- CTRL key masked and entire keystroke ignorred. Repeat won't work, but no problem as key ignored anyway.

 

Re processing all this stuff - you'd probably be better off using the keyboard IRQ rather than the Immediate vector.

If it's the case you want to just ignore CTRL-key combinations then you can just return from the interrupt, for "valid" keys just continue by jumping to the system-provided routine.

Link to comment
Share on other sites

 

Re processing all this stuff - you'd probably be better off using the keyboard IRQ rather than the Immediate vector.

If it's the case you want to just ignore CTRL-key combinations then you can just return from the interrupt, for "valid" keys just continue by jumping to the system-provided routine.

 

Above code is replacing the keyboard IRQ vector with its own and when a key is pressed it is supposed to retrieve the KBCODE, AND it with $80 to check for the CONTROL bit and if it is set, simply RTI and ignore/skip the rest of the keyboard handler, otherwise jump to the regular keyboard handler vector.

 

When I run the code on the XE it seems that lines (300-360) aren't actually executed, I've inserted some noise making code in those lines to see if the keyboard interrupt is captured as it is supposed to be, but no noise is ever heard, so even though the vector is modified (verified with DDT) the machine seems to somehow ignore the custom processing.

 

I will try that on my 800 to see what happens there.

Link to comment
Share on other sites

Not sure which DOS is in use or whether this is an INIT segment of a much larger file, but if it's stand-alone, SDX will run the set-up routine twice: once as an INIT segment, and then again as a RUN segment, because SDX always ends up jumping to the first byte of code if no other RUN address is supplied. The net result of this is that the keyboard IRQ ends up in an endless loop, since the second time START is vectored, (JUMP+1) ends up containing REP. Changing $02E2 to $02E0 fixes that, but it's probably by the by anyway.

 

Other than that, everything works as intended on an XE, with CTRL keys properly blocked (although LDA KBCODE / BPL JUMP will save a couple of bytes). Ensure there are no type-ahead buffers already active, which might be continually resetting the keyboard IRQ.

Edited by flashjazzcat
Link to comment
Share on other sites

Not sure which DOS is in use or whether this is an INIT segment of a much larger file, but if it's stand-alone, SDX will run the set-up routine twice: once as an INIT segment, and then again as a RUN segment, because SDX always ends up jumping to the first byte of code if no other RUN address is supplied. The net result of this is that the keyboard IRQ ends up in an endless loop, since the second time START is vectored, (JUMP+1) ends up containing REP. Changing $02E2 to $02E0 fixes that, but it's probably by the by anyway.

 

Other than that, everything works as intended on an XE, with CTRL keys properly blocked (although LDA KBCODE / BPL JUMP will save a couple of bytes). Ensure there are no type-ahead buffers already active, which might be continually resetting the keyboard IRQ.

 

I tried this with both SDX and DOS 2.5 on a 600XL, 130XE (both machines with mods) and just today with my 800 (no mods) using DOS 2.5. The result is the same all over. The program loads and acts as if nothing is happening, keys with CTRL pressed still show control characters (are not ignored). With SDX if i use KEY ON the keyboard locks-up (as expected and indicated in the SDX manual) otherwise the program loads but does not seem to do what it is supposed to do.

 

One thing I noticed is that the system keyboard interrupt vector is initialized to $BEB2 on my 800 (memory examination with DDT), in contrast to that Mapping the Atari says that the value for VKEYBD is initialized to $FFBE and that the vector has not been changed in "B" version of the OS, yet I have a different value there!!.

 

I am completely lost at this stage, this shouldn't be really that complicated. I checked my code with DDT and the vectors are replaced properly once the program loads and runs :?

Edited by atari8warez
Link to comment
Share on other sites

One thing I noticed is that the system keyboard interrupt vector is initialized to $BEB2 on my 800 (memory examination with DDT), in contrast to that Mapping the Atari says that the value for VKEYBD is initialized to $FFBE and that the vector has not been changed in "B" version of the OS, yet I have a different value there!!.

$BEB2 is in the cartridge space, so I suspect this is actually DDT's keyboard IRQ, used to trap hot-key entry into DDT itself. The 800 OS doesn't start until $E000, so Mapping is probably accurate there.

  • Like 1
Link to comment
Share on other sites

Hmmm, changing the INIT address to RUN address made the difference. The code now runs properly and indeed blocks the control characters. I think both segments needed to be loaded before the code is ran. Thank you John for the suggestion, I've never paid attention what kind of address was used (run vs init).

Link to comment
Share on other sites

$BEB2 is in the cartridge space, so I suspect this is actually DDT's keyboard IRQ, used to trap hot-key entry into DDT itself. The 800 OS doesn't start until $E000, so Mapping is probably accurate there.

 

Yes, it looks like it is Mac/65 keyboard IRQ vector. I compile the code into memory with Mac/65 and then enter DDT, run the code from DDT, examine $208 and I can see my own interrupt routine's vector in there, then I exit DDT and drop back to Mac/65, try typing some control characters and they are not blocked, so i re-enter DDT examine $208 again and I see that the vector changed back to $BEB2. So i presume then when Mac/65 is re-entered the keyboard IRQ vector is re-initialized back to it's own vector address.

Edited by atari8warez
Link to comment
Share on other sites

Yes, the DDT manual describes various "gotchas" regarding manipulation of the keyboard IRQ vector.

 

Always pays to read the manuals, which is something I normally do, but obviously not this time

 

Edit: Checking the manual reveals that back in the day I have actually read the "gotchas" section (yellow highlights on critical points at page 38), I guess 30 years were enough to cloud my memory and make me forget all of these fine points. :)

Edited by atari8warez
Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...