Execute an interrupt routine each time a key is pressed zx81

ZX80, ZX 81, ZX Spectrum, TS2068 and other clones
Post Reply
zx81ultra
Member
Posts: 36
Joined: Thu Feb 13, 2020 1:56 am

Execute an interrupt routine each time a key is pressed zx81

Post by zx81ultra »

Hello,

Is it possible to execute an interrupt service routine each time a key is pressed on the zx81 ?

I'm thinking on a ISR that saves the pressed key on a buffer that is later consumed inside the game loop.

Thank you.
stefano
Well known member
Posts: 1534
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

..a sort of single key buffer?
Or, which is the benefit you'd expect in having an interrupt driven trigger rather than calling in_inkey from your program loop?
zx81ultra
Member
Posts: 36
Joined: Thu Feb 13, 2020 1:56 am

Post by zx81ultra »

I need to be able to process a rapid series of key presses (single key) that are basically the cursor keys.
Sometimes the keys are ignored, I guess that's because the action is inside the game logic at that moment, so I was thinking on key buffering.

I know I have enough cpu time left, there's a msleep(25) at the end of the loop otherwise things get too fast. This raises another question, will an interrupt work with msleep ?

Maybe there are other clever workarounds instead of interrupts, idk. BTW, this a game using pseudo high res :)

Thank you !
zx81ultra
Member
Posts: 36
Joined: Thu Feb 13, 2020 1:56 am

Post by zx81ultra »

In the meantime I implemented a key buffering solution that I think emulates in some degree the functionality of an interrupt service routine.

It's not very elegant but now the responsiveness of the keys used on my game is a lot better.

Here's the source in case anyone finds it useful :

Code: Select all

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <input.h>
#include <zx81.h>

#define MAX_KEY_BUF  2

// keyboard buffering
int KeyBuf[MAX_KEY_BUF], Key, LastKey;
unsigned char KeyBufOut, KeyBufIn, KeyReady;

void CheckKeyPress(void)
{
if((Key = in_Inkey())) 
  { if(LastKey != Key) // ignore if it's the same key
      { LastKey = Key;
        
        KeyBuf[KeyBufIn] = Key; // save pressed key
        if(++KeyBufIn == MAX_KEY_BUF) // buffer capacity
          KeyBufIn = 0; // overwrite previous keys
        
        if(KeyReady < MAX_KEY_BUF) 
          ++KeyReady; // key is available to be consummed
      }
    Key = 0; 
  }
} /*** CheckKeyPress ***/


void ReadKeyBuf(void)
{
if(KeyReady) // key available
  { Key = KeyBuf[KeyBufOut]; // reads key
    if(++KeyBufOut == MAX_KEY_BUF) // buffer capacity
      KeyBufOut = 0;
    --KeyReady;
  }
} /*** ReadKeyBuf ***/


void main(void)  
{
KeyBufOut = 0;
KeyBufIn = 0;
KeyReady = 0;
LastKey = 0;

GameLoop:

CheckKeyPress();
ReadKeyBuf(); // retrieves Key from buffer if available

switch(Key)
  {
    ...
    ...
  }

...code
CheckKeyPress();

...code
CheckKeyPress();

...code
CheckKeyPress();

...code
CheckKeyPress();

goto GameLoop;
}
Post Reply