atari8warez Posted May 16, 2014 Share Posted May 16, 2014 (edited) 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 May 16, 2014 by atari8warez Quote Link to comment Share on other sites More sharing options...
Rybags Posted May 16, 2014 Share Posted May 16, 2014 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. Quote Link to comment Share on other sites More sharing options...
Rybags Posted May 16, 2014 Share Posted May 16, 2014 Just checked - yes, OS-A processes the Break key within the Immediate IRQ code, no vector provided. Quote Link to comment Share on other sites More sharing options...
atari8warez Posted May 16, 2014 Author Share Posted May 16, 2014 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. Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted May 16, 2014 Share Posted May 16, 2014 (edited) 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 May 16, 2014 by flashjazzcat Quote Link to comment Share on other sites More sharing options...
atari8warez Posted May 16, 2014 Author Share Posted May 16, 2014 (edited) 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 May 16, 2014 by atari8warez Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted May 16, 2014 Share Posted May 16, 2014 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. 1 Quote Link to comment Share on other sites More sharing options...
atari8warez Posted May 16, 2014 Author Share Posted May 16, 2014 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). Quote Link to comment Share on other sites More sharing options...
atari8warez Posted May 17, 2014 Author Share Posted May 17, 2014 (edited) $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 May 17, 2014 by atari8warez Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted May 17, 2014 Share Posted May 17, 2014 That concurs with the docs, so puzzle solved. Quote Link to comment Share on other sites More sharing options...
atari8warez Posted May 17, 2014 Author Share Posted May 17, 2014 That concurs with the docs, so puzzle solved. What!... is all that in the user manual already? lol Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted May 18, 2014 Share Posted May 18, 2014 Yes, the DDT manual describes various "gotchas" regarding manipulation of the keyboard IRQ vector. Quote Link to comment Share on other sites More sharing options...
atari8warez Posted May 19, 2014 Author Share Posted May 19, 2014 (edited) 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 May 19, 2014 by atari8warez 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.