IKBD buffer overflow with interrupt disabled

GFA, ASM, STOS, ...

Moderators: simonsunnyboy, Mug UK, Zorro 2, exxos, Moderator Team

IKBD buffer overflow with interrupt disabled

Postby simonsunnyboy » Sat Jul 07, 2012 3:08 pm

Hello together,

in normal operation with the IKBD interrupt active, I suppose the IKBD buffer never becomes full because the ISR empties the buffer.
How does it react if I disable the normal IKBD interrupt and start polling the IKBD buffer myself?

My polling interval is hopefully long (e.q. once per VBL so it won't disturb rasters) etc.

Are there large risks of data loss for usual game stuff such as polling both joysticks and maybe a couple of keys?

I don't think the problem is enormous as lots people have used the following scheme in the past

Code: Select all
mainloop:
<<<>long code>>
cmpi.b #57,$fffffc02
bne mainloop


OTOH there my be applications with a lot more input events than a demo screen waiting just for a press of SPACE.

So can anyone enlighten me here?

Regards,
ssb
Simon Sunnyboy/Paradize - http://paradize.atari.org/ - STOT: http://www.npoi.de/stot/

Stay cool, stay Atari!

1x2600jr, 1x1040STFm, 1x1040STE 4MB+TOS2.06+SatanDisk, 1xF030 14MB+FPU+NetUS-Bee

Jabber: simonsunnyboy@atari-jabber.org
User avatar
simonsunnyboy
Moderator
Moderator
 
Posts: 4329
Joined: Wed Oct 23, 2002 4:36 pm
Location: Friedrichshafen, Germany

Re: IKBD buffer overflow with interrupt disabled

Postby simonsunnyboy » Sat Jul 07, 2012 5:27 pm

I started coding a small statemachine with C and upon first try I seem to get very few packets for mouse moves. Is this normal?

Incomplete C sketch is as follows:

Code: Select all
/**
 * @file smplikbd.c
 * Simple IKBD handler for Atari ST/STE/TT/Falcon 030
 * @author Simon Sunnyboy / Paradize <marndt@asmsoftware.de>
 * @copyright http://paradize.atari.org/
 */

#include <stdbool.h>
#include <tos.h>

typedef unsigned char BYTE;

/* memory mapped I/O registers */
static volatile BYTE* const IKBD_CTL  = (BYTE *)(0xFFFFFC00UL);
static volatile BYTE* const IKBD_DATA = (BYTE *)(0xFFFFFC02UL);
static volatile BYTE* const IREB      = (BYTE *)(0xFFFFFA09UL);
static volatile BYTE* const IRMB      = (BYTE *)(0xFFFFFA15UL);

/* module internal variables: */
static BYTE old_irmb,old_ireb;

static BYTE keytbl[128];
static BYTE joystate[1];
static BYTE mousex,mousey,mousek;

#define MASK_IKBD_ISR 0x40

#define RDRF 0x01 /* RX bit within IKBD_CTL */
#define TDRE 0x02 /* RX bit within IKBD_CTL */

#define IKBD_KEY_PRESSED     (BYTE)(0xff)
#define IKBD_KEY_UNDEFINED   (BYTE)(0x80)
#define IKBD_KEY_RELEASED    (BYTE)(0x00)

void SimpleIKBD_Install()
{
   old_ireb = *IREB;
   old_irmb = *IRMB;
   *IREB    = (*IREB & (~MASK_IKBD_ISR));
   *IRMB    = (*IRMB & (~MASK_IKBD_ISR));
   return;
}

void SimpleIKBD_Uninstall()
{
   *IREB = old_ireb;
   *IRMB = old_irmb;  /* reactivate IKBD in Interrupt Mask B*/

   return;
}

void SimpleIKBD_HandleCyclic()
{
   BYTE code;
   static unsigned short col = 0x0F0;
   /* recv bytes from IKBD: */
   while(*IKBD_CTL & RDRF)
   {
      code = *IKBD_DATA;

      if(code == 0xFF) /* joystick 1 packet? */
      {
         while(!(*IKBD_CTL & RDRF)); /* wait for joystick data */
         joystate[1] = *IKBD_DATA;
      }
      else if(code == 0xFE) /* joystick 0 packet? */
      {
         while(!(*IKBD_CTL & RDRF)); /* wait for joystick data */
         joystate[0] = *IKBD_DATA;
      }
      else if((code >= 0xF8)&&(code <= 0xFB)) /* mouse packet? */
      {
         mousek = (code & 0xFC);
         while(!(*IKBD_CTL & RDRF)); /* wait for x data */
         mousex = *IKBD_DATA; /* relative information */
         while(!(*IKBD_CTL & RDRF)); /* wait for y data */
         mousey = *IKBD_DATA; /* relative information */

         Bconout(2,'*');
      }
      else if(code & 0x80) /* key release */
      {
         keytbl[(code & 0x7F)] = IKBD_KEY_RELEASED;
      }
      else  /* key press */
      {
         keytbl[(code & 0x7F)] = IKBD_KEY_PRESSED;
      }

   }
   return;
}
Simon Sunnyboy/Paradize - http://paradize.atari.org/ - STOT: http://www.npoi.de/stot/

Stay cool, stay Atari!

1x2600jr, 1x1040STFm, 1x1040STE 4MB+TOS2.06+SatanDisk, 1xF030 14MB+FPU+NetUS-Bee

Jabber: simonsunnyboy@atari-jabber.org
User avatar
simonsunnyboy
Moderator
Moderator
 
Posts: 4329
Joined: Wed Oct 23, 2002 4:36 pm
Location: Friedrichshafen, Germany

Re: IKBD buffer overflow with interrupt disabled

Postby Dio » Sat Jul 07, 2012 5:36 pm

Once per VBL is not sufficient. The keyboard transmit rate is 7.8kbps at roughly 11 bits per character, so it can transmit one character roughly every 1.5ms. If you're polling, and want to avoid lost data, you need to check at least this often.

In addition, your poll above is highly fragile, because you're comparing an exact value, and if the overflow bit happens to become set at the ACIA the routine will always branch.

If you want to go with this kind of mechanism, you can pause and resume the data transfer for set intervals. Or disable the mouse and joystick, although very occasionally you will still lose data. Generally, when people do this, they're only looking for 'a key was pressed' and so the exact data returned isn't relevant.

The second routine above might be losing mouse messages due to not polling for the duration of Bconout - I'm not sure if that takes long enough to be a problem (it certainly is it if scrolls the screen, but in non-scrolling cases I'd expect it to be OK...).

Generally, polling is fragile, which is why it's done by interrupt by default.
Dio
Captain Atari
Captain Atari
 
Posts: 452
Joined: Thu Feb 28, 2008 3:51 pm

Re: IKBD buffer overflow with interrupt disabled

Postby simonsunnyboy » Sat Jul 07, 2012 5:44 pm

Comparing an exact value is necessary to determine the packet or key event. The idea is to get stable input information afterall and not a generic "something happened" event.

How do games with lots of Timer B handle the issue then? For me I have the feeling, any IKBD interrupt, even a small non-TOS one, still takes cycles to offset timers and thus makes rasters jitter.
Simon Sunnyboy/Paradize - http://paradize.atari.org/ - STOT: http://www.npoi.de/stot/

Stay cool, stay Atari!

1x2600jr, 1x1040STFm, 1x1040STE 4MB+TOS2.06+SatanDisk, 1xF030 14MB+FPU+NetUS-Bee

Jabber: simonsunnyboy@atari-jabber.org
User avatar
simonsunnyboy
Moderator
Moderator
 
Posts: 4329
Joined: Wed Oct 23, 2002 4:36 pm
Location: Friedrichshafen, Germany

Re: IKBD buffer overflow with interrupt disabled

Postby Klapauzius » Sat Jul 07, 2012 5:50 pm

simonsunnyboy wrote:How do games with lots of Timer B handle the issue then? For me I have the feeling, any IKBD interrupt, even a small non-TOS one, still takes cycles to offset timers and thus makes rasters jitter.


Just put a "move #$2500,sr" as the first thing in your ikbd interrupt routine and you should be fine with rasters.
http://www.klapauzius.net
http://dbug.kicks-ass.net/klaz

The tears are welling in my eyes again, I need twenty big buckets to catch them in, twenty pretty girls to carry them down, twenty deep holes to bury them in.
User avatar
Klapauzius
The Klaz
The Klaz
 
Posts: 4300
Joined: Sun Jul 04, 2004 7:55 am
Location: Bavaria

Re: IKBD buffer overflow with interrupt disabled

Postby simonsunnyboy » Sat Jul 07, 2012 5:54 pm

Sorry for sounding dumb, I never understood the bit settings for those instructions setting the sr. I have seen values $2700 $2500 and $2500 by now....

If this really helps it would be a real helper for me as I already have a working IKBD ISR subsystem (but not stabilized against more interruptions ofcourse)
Simon Sunnyboy/Paradize - http://paradize.atari.org/ - STOT: http://www.npoi.de/stot/

Stay cool, stay Atari!

1x2600jr, 1x1040STFm, 1x1040STE 4MB+TOS2.06+SatanDisk, 1xF030 14MB+FPU+NetUS-Bee

Jabber: simonsunnyboy@atari-jabber.org
User avatar
simonsunnyboy
Moderator
Moderator
 
Posts: 4329
Joined: Wed Oct 23, 2002 4:36 pm
Location: Friedrichshafen, Germany

Re: IKBD buffer overflow with interrupt disabled

Postby Klapauzius » Sat Jul 07, 2012 6:00 pm

useful values for the IPL/sr - all in supervisor mode:

$2100: allows HBL, VBL, MFP
$2300: allows VBL, MFP
$2500: allows MFP only

After the ikbd interrupt has been triggered the sr will have an IPL of 6 (for example sr = $2600), which means no other MFP interrupts will happen as long as the ikbd interrupt routine runs.
http://www.klapauzius.net
http://dbug.kicks-ass.net/klaz

The tears are welling in my eyes again, I need twenty big buckets to catch them in, twenty pretty girls to carry them down, twenty deep holes to bury them in.
User avatar
Klapauzius
The Klaz
The Klaz
 
Posts: 4300
Joined: Sun Jul 04, 2004 7:55 am
Location: Bavaria

Re: IKBD buffer overflow with interrupt disabled

Postby simonsunnyboy » Sat Jul 07, 2012 6:05 pm

So immediately setting it back to $2500 may allow pending MFP interrupts like the Timer B to fire inbetween?

Thanks for the explanation, I admit that I tended to simply use the interrupts as a given setup for now and i did not attempt to really fiddle a lot with the priority settings.
Simon Sunnyboy/Paradize - http://paradize.atari.org/ - STOT: http://www.npoi.de/stot/

Stay cool, stay Atari!

1x2600jr, 1x1040STFm, 1x1040STE 4MB+TOS2.06+SatanDisk, 1xF030 14MB+FPU+NetUS-Bee

Jabber: simonsunnyboy@atari-jabber.org
User avatar
simonsunnyboy
Moderator
Moderator
 
Posts: 4329
Joined: Wed Oct 23, 2002 4:36 pm
Location: Friedrichshafen, Germany

Re: IKBD buffer overflow with interrupt disabled

Postby Dio » Sat Jul 07, 2012 8:13 pm

Yes - the Timer B is higher priority than the ACIAs so as long as the MFP is in SEI mode the ACIA can't interrupt a Timer B routine.
Dio
Captain Atari
Captain Atari
 
Posts: 452
Joined: Thu Feb 28, 2008 3:51 pm

Re: IKBD buffer overflow with interrupt disabled

Postby simonsunnyboy » Wed Jul 11, 2012 4:12 pm

I'm still not fully satisfied here. How do games with sync code handle the issue? Lethal Xcess and Enchanted Land come to mind.
Or are those games not completely made with sync code and still have flexible timing gaps where asynchronous interrupts may disrupt the timing?

Sorry for being too curious but being unable to debug the issue for myself to see :(
Simon Sunnyboy/Paradize - http://paradize.atari.org/ - STOT: http://www.npoi.de/stot/

Stay cool, stay Atari!

1x2600jr, 1x1040STFm, 1x1040STE 4MB+TOS2.06+SatanDisk, 1xF030 14MB+FPU+NetUS-Bee

Jabber: simonsunnyboy@atari-jabber.org
User avatar
simonsunnyboy
Moderator
Moderator
 
Posts: 4329
Joined: Wed Oct 23, 2002 4:36 pm
Location: Friedrichshafen, Germany

Re: IKBD buffer overflow with interrupt disabled

Postby troed » Wed Jul 11, 2012 5:21 pm

simonsunnyboy wrote:I'm still not fully satisfied here. How do games with sync code handle the issue? Lethal Xcess and Enchanted Land come to mind.
Or are those games not completely made with sync code and still have flexible timing gaps where asynchronous interrupts may disrupt the timing?

Sorry for being too curious but being unable to debug the issue for myself to see :(


The latter. Sync scrolling consumes a few scanlines where the lockdown is tight, the rest is perfectly interruptable. You're probably thinking of fullscreens, and yes, due to having to open the left and right borders on _every_ scanlines those indeed are problematic. You'll find that very few demos do open every single line, most leave a few at the bottom to do non-synclocked stuff.
User avatar
troed
Captain Atari
Captain Atari
 
Posts: 373
Joined: Mon Apr 30, 2012 6:20 pm
Location: Sweden

Re: IKBD buffer overflow with interrupt disabled

Postby simonsunnyboy » Wed Jul 11, 2012 6:28 pm

Thanks for making clear!

But leaving only a few scanlines left per VBL, does this mean there is more time to process the IKBD data than doing it during the VBL?
Otoh I just have to accept that it magically seems to work somehow.
Simon Sunnyboy/Paradize - http://paradize.atari.org/ - STOT: http://www.npoi.de/stot/

Stay cool, stay Atari!

1x2600jr, 1x1040STFm, 1x1040STE 4MB+TOS2.06+SatanDisk, 1xF030 14MB+FPU+NetUS-Bee

Jabber: simonsunnyboy@atari-jabber.org
User avatar
simonsunnyboy
Moderator
Moderator
 
Posts: 4329
Joined: Wed Oct 23, 2002 4:36 pm
Location: Friedrichshafen, Germany

Re: IKBD buffer overflow with interrupt disabled

Postby Dio » Wed Jul 11, 2012 8:58 pm

1.5ms is 23 video lines, and sync-scrolling consumes a lot less than that. So you can happily disable interrupts for 20 lines plus without any risk of missing an interrupt.
Dio
Captain Atari
Captain Atari
 
Posts: 452
Joined: Thu Feb 28, 2008 3:51 pm


Return to Coding

Who is online

Users browsing this forum: CommonCrawl [Bot] and 0 guests