+slx Posted September 25, 2017 Share Posted September 25, 2017 I am trying to read the keyboard in order to implement a pause routine in a patched version of Shamus. I read all I could find about SKSTAT and KBCODE but it doesn't really work as expected. I do not use system VBI routines. I tried to load SKSTAT during VBI, AND $04 and act on the results of that, i.e. interpreting anything not zero as a keypress. I then check for a specific KBCODE (Space) to enter the pause routine. After a little delay I check for SKSTAT and KBCODE again to end the pause when it is pressed again. That works as well but the game only stays "unpaused" when I keep the space bar pressed. then SKSTAT seems to remain "latched" as the game will end the pause but jump right back unless that key is held. My understanding is that SKSTAT bit 2 should revert to zero if no key is depressed. In reality it seems to remain set (always?) and as KBCODE does not change when a key is released the next VBI jumps right back into the pause routine. My code is below. Any ideas what I did wrong? (The "PAUSECTR" and countdown from 4 in the PAUSING routine were intended to make sure the key is really depressed for a little while. The behaviour of the routine doesn't change when I leave them out, so I assume I am doing something wrong with SKSTAT.) XITVBV equ $E462 NMIEN equ $D40E DLISTL equ $D402 DLISTH equ $D403 KBCODE equ $D209 SKSTAT equ $D20F SKCTL equ SKSTAT AUDF1 equ $D200 HITCLR equ $D01E CHECKKEYS LDA SKSTAT ;this is where VVBLKI points AND #$04 BEQ EXIT LDA KBCODE CMP #$21 BNE EXIT0 INC PAUSECTR LDA PAUSECTR CMP #$04 BNE EXIT2 PAUSE LDA #$00 STA NMIEN ;no more VBIs while pausing STA PAUSECTR LDA <PAUSEDLIST ;change to dedicated display list STA DLISTL LDA >PAUSEDLIST STA DLISTH LDA #$00 LDY #$03 KILLAUDIO STA AUDF1,Y DEY BPL KILLAUDIO PAUSING LDX #$04 KEYPRESSED LDA SKSTAT AND #$04 BNE PAUSING LDA KBCODE CMP #$21 BNE PAUSING DEX BEQ ENDPAUSE BNE KEYPRESSED ENDPAUSE LDA #$B8 STA DLISTL LDA #$35 STA DLISTH LDA #$C0 STA NMIEN STA HITCLR EXIT0 LDA #$00 EXIT STA PAUSECTR EXIT2 JMP XITVBV PAUSECTR .BY $00 Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted September 25, 2017 Share Posted September 25, 2017 SKSTAT bit 2 goes to 0 on a keystroke, not 1. So: LDA SKSTAT AND #$04 BNE EXIT ...and so on. 2 Quote Link to comment Share on other sites More sharing options...
+therealbountybob Posted September 25, 2017 Share Posted September 25, 2017 probably not much help but on my games I only use CH ($02FC = Last Key Pressed) if it's 21 (space) I pause and set CH to 255 (clear the key) then I test for it not being 255 then I exit pause and set it back to 255 1 Quote Link to comment Share on other sites More sharing options...
Rybags Posted September 25, 2017 Share Posted September 25, 2017 I think Jon nailed it - with the dark theme and that striped colour for the listings it makes the [ code ] sections almost impossible to read. 2 Quote Link to comment Share on other sites More sharing options...
+slx Posted September 25, 2017 Author Share Posted September 25, 2017 probably not much help but on my games I only use CH ($02FC = Last Key Pressed) if it's 21 (space) I pause and set CH to 255 (clear the key) then I test for it not being 255 then I exit pause and set it back to 255 That's what I was used to from BASIC and Action! but I think those only work when using system VBLANK which Shamus doesn't (and it would write all over the game code if I'd enable it). Quote Link to comment Share on other sites More sharing options...
+slx Posted September 26, 2017 Author Share Posted September 26, 2017 (edited) I tried changing this from VBI based to keyboard interrupt based code but still face the same problem. CHECKKEYS PHA TXA PHA TYA PHA LDA #$00 STA NMIEN STA IRQEN LDA <PAUSEDLIST STA DLISTL LDA >PAUSEDLIST STA DLISTH LDA #$00 LDY #$03 KILLAUDIO STA AUDF1,Y DEY BPL KILLAUDIO PAUSING LDA TRIG0 BNE PAUSING ENDPAUSE LDA #$B8 STA DLISTL LDA #$35 STA DLISTH LDA #$C0 STA NMIEN STA HITCLR LDA #$40 STA IRQEN LDX #$05 JSR WAIT1 EXIT ; PLA TAY PLA TAX PLA CLI RTI While I can enter the pause routine and exit it using the fire button, the interrupt will fire again immediately. Is there anything else I need to do to reset the keyboard interrupt? As no other IRQs are required I run this directly through VIMIRQ at $217/8, not through VKEYBD. Edited September 26, 2017 by slx Quote Link to comment Share on other sites More sharing options...
Rybags Posted September 27, 2017 Share Posted September 27, 2017 I'd get rid of the CLI before RTI - the RTI pulls P off the stack so it's not needed. By storing 00 in IRQEN that clears the keyboard IRQ. It could be the case that you're suffering a debounce IRQ, though I think that while the key IRQ is disabled they shouldn't be able to become pending (need to read Altirra HW reference to clarify there). The other precaution for your coding - not a good idea to store into the DLIST address pointers direct in Antic just any old time. On real hardware you'd probably get occasional glitches. In emulation I think the KB IRQ will always occur at the same place (?) so such things mightn't become apparent. Quote Link to comment Share on other sites More sharing options...
+slx Posted September 27, 2017 Author Share Posted September 27, 2017 I'd get rid of the CLI before RTI - the RTI pulls P off the stack so it's not needed.Thanks, didn't think of that. By storing 00 in IRQEN that clears the keyboard IRQ. It could be the case that you're suffering a debounce IRQ, though I think that while the key IRQ is disabled they shouldn't be able to become pending (need to read Altirra HW reference to clarify there).I do store $00 to IRQEN (line 17 above) but nevertheless the IRQ keeps firing again a bit after the reset and RTI. Not tested on real hardware yet. (Or did you mean that the $40 to IRQEN is a problem - I would not know how to re-enable keyboard IRQs otherwise, however?) The other precaution for your coding - not a good idea to store into the DLIST address pointers direct in Antic just any old time. On real hardware you'd probably get occasional glitches. In emulation I think the KB IRQ will always occur at the same place (?) so such things mightn't become apparent.I do that because system VBI routines are not in use and IIRC I would need those not to write to ANTIC directly. Is there an inherent problem to writing to ANTIC or just the risk of writing only half the address and be interrupted by a VBI? As I understand the system this would cause a corrupted display, i.e. some flicker when restoring from the pause screen to the game screen for one frame which seems tolerable. Quote Link to comment Share on other sites More sharing options...
Rybags Posted September 28, 2017 Share Posted September 28, 2017 Just writing the DList address to Antic anytime has potential for screen corruption or unwanted behaviour. Think the case of 3 x 8 blank lines then 24 text/coloured mode as many games use. Write the DList address when it's halfway down the screen - Antic will process the blank lines then you'll get part of the window displayed for the remainder of the frame. The Jump + wait for VBlank won't be processed. Without VBlank storing the shadow register the DList will continue to run into the next frame. So next frame you'll get second half of the window shown right at the top of the active display. JVB will be read and you'll get a large blank portion for the remainder of frame. Then next frame, things back to normal. At best you get that sort of glitch. At worst unwanted program behaviour or even a crash if there's DLIs active and they go out of sequence or some are missed. Also, PM graphics won't be affected but will be out of place relative to the playfield. Potential for unwanted collisions. Best practice with storing that DList pointer for pause/resume would be to wait on VCOUNT <4 or >128. 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.