Interrupt friendly IKBD routine?

All 680x0 related coding posts in this section please.

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

Zamuel_a
Atari God
Atari God
Posts: 1234
Joined: Wed Dec 19, 2007 8:36 pm
Location: Sweden

Interrupt friendly IKBD routine?

Postby Zamuel_a » Tue Feb 19, 2013 9:40 am

I have a small problem with the IKBD routine in my Pacmania game. It seems to interfere with the top border removal routine. If I disable the IKBD during the removal it works, but if I do alot of movements with the joystick or keys it hangs and it won't take any more joystick or keyboard commands. If I pull the coord to the keyboard and insert again it helps sometimes. Doing that will ofcourse empty the IKBD buffer, but it seems like something else on the computer side also happen because after doing that I don't need much at all to make it hang again. I haven't digged into the original IKBD routine from the ST version of Pacmania so much, but I guess it's a rather general routine. Once I did a simple keyboard handler myself that use it's own buffer and I was only polling the keyboard with move.b $fffc02,d0 . This worked more or less ok, but didn't handle multiple keystrokes at once so good so you had to release the first button before you pressed the second one, which ofcourse isn't so good in a game, but I never got that version to hang even that I disabled the IKBD during time critical code.
ST / STFM / STE / Mega STE / Falcon / TT030 / Portfolio / 2600 / 7800 / Jaguar / 600xl / 130xe

User avatar
shoggoth
Nature
Nature
Posts: 952
Joined: Tue Aug 01, 2006 9:21 am
Location: Halmstad, Sweden
Contact:

Re: Interrupt friendly IKBD routine?

Postby shoggoth » Tue Feb 19, 2013 9:45 am

What if you only enable the IKBD interrupt for, say, 150 scanlines mid-screen?
Ain't no space like PeP-space.

Zamuel_a
Atari God
Atari God
Posts: 1234
Joined: Wed Dec 19, 2007 8:36 pm
Location: Sweden

Re: Interrupt friendly IKBD routine?

Postby Zamuel_a » Tue Feb 19, 2013 11:00 am

What if you only enable the IKBD interrupt for, say, 150 scanlines mid-screen?


That is more or less what I was doing. I turn it on after the top border is opened and turn it off before the bottom border is opened. It seems to work with normal game play, but if I move the joystick as fast as I can in all kinds of directions or press alots of keys, then it hangs.
ST / STFM / STE / Mega STE / Falcon / TT030 / Portfolio / 2600 / 7800 / Jaguar / 600xl / 130xe

Zamuel_a
Atari God
Atari God
Posts: 1234
Joined: Wed Dec 19, 2007 8:36 pm
Location: Sweden

Re: Interrupt friendly IKBD routine?

Postby Zamuel_a » Tue Feb 19, 2013 3:24 pm

Reading the scancodes from $fffc02 is easy to do, but one problem is that you only get one code at a time, so if you hold two buttons pressed, you will not detect it. I tried to have a table that for each scancode position I set a ONE if the button was pressed and a ZERO if I detected the break code for that button. This works if I only press one button at a time, but the problem is if I for example press X to make Pacman go right and after that press Z to go left without releasing X first. What I think happenes is that it detects X without any problems and set a ONE in that position in my table. After that it detects the Z and set that one to ONE, and if I then release X while I hold Z down I will miss the Z break code since I only detect one thing at a time by reading $fffc02 so the program will think both X and Z are pressed and it will stay like this until I press X again and release it without holding anything else down.
Maybe there is a good solution to solve this since it feels like a polling method is much better than using interrupts if the timing is critical.
ST / STFM / STE / Mega STE / Falcon / TT030 / Portfolio / 2600 / 7800 / Jaguar / 600xl / 130xe

mc6809e
Captain Atari
Captain Atari
Posts: 159
Joined: Sun Jan 29, 2012 10:22 pm

Re: Interrupt friendly IKBD routine?

Postby mc6809e » Tue Feb 19, 2013 4:44 pm

Zamuel_a wrote:
What if you only enable the IKBD interrupt for, say, 150 scanlines mid-screen?


That is more or less what I was doing. I turn it on after the top border is opened and turn it off before the bottom border is opened. It seems to work with normal game play, but if I move the joystick as fast as I can in all kinds of directions or press alots of keys, then it hangs.


The IKBD can send close to 700 bytes/second to the ACIA and a new scanline occurs 15625 times/second. In the worst case then you only have about 22 scanlines between interrupts. There are at least 42 scanlines after the bottom border before you get to the top border so you're potentially missing interrupts during that time.

Zamuel_a
Atari God
Atari God
Posts: 1234
Joined: Wed Dec 19, 2007 8:36 pm
Location: Sweden

Re: Interrupt friendly IKBD routine?

Postby Zamuel_a » Tue Feb 19, 2013 9:53 pm

I don't care so much if I loose packages. The problem is that the IKBD get's stucked in some strange way so after I enable it again it sends garbage or whatever. It only happenes if I move the joystick or press alots of keys at once for a while.

Another thing that happens if I move the joystick or press keys alot when I switch screen, the screen get's corrupt so I get 16 extra pixels on the left side (the STE 16 pixel trick), but it's only with 1-2 bitplanes so the screen get's corrupt. I know I have had this problem before when I did rasters or overscan or other time sensitive code. Is there a way to prevent this? Or get out from it when it happenes? I usually have to restart the computer since even in GEM the display is shifted a couple of bitplanes to the left.
ST / STFM / STE / Mega STE / Falcon / TT030 / Portfolio / 2600 / 7800 / Jaguar / 600xl / 130xe

Ato
Captain Atari
Captain Atari
Posts: 300
Joined: Tue Aug 10, 2010 3:27 am
Location: Duisburg, Germany

Re: Interrupt friendly IKBD routine?

Postby Ato » Tue Feb 19, 2013 11:32 pm

Zamuel_a wrote:I tried to have a table that for each scancode position I set a ONE if the button was pressed and a ZERO if I detected the break code for that button.
[...]
and set a ONE in that position in my table. After that it detects the Z and set that one to ONE
[...]


Perhaps try to not use a boolean but an integer which gets incremented every time a (random) key has been pressed. Then, as soon as a key gets released, decrement the value. By that you'll always be able to keep track if there is still any key being pressed or if all keys have been released (value = 0 again).

Or am I just silly and totally missing the point? :lol:

Hth. Cheers,
T.

Zamuel_a
Atari God
Atari God
Posts: 1234
Joined: Wed Dec 19, 2007 8:36 pm
Location: Sweden

Re: Interrupt friendly IKBD routine?

Postby Zamuel_a » Wed Feb 20, 2013 7:01 am

well, I don't know if that would help. I have a table for all keys so I can treat everything in parallel, but it seems like I miss some data if I just poll the IKBD, but nevermind. I will not use that technic in the game anyway. The original code (with interrupts) works better so I will keep it. What I had needed is a way to reset the IKBD or something similar to empty the internal buffer after I have enabled it again during the next frame. It seems like if the buffer get's full, then it hangs. I know there is a reset command, but that restarts the IKBD and that can't be fast enough to do once each frame I guess.
ST / STFM / STE / Mega STE / Falcon / TT030 / Portfolio / 2600 / 7800 / Jaguar / 600xl / 130xe

User avatar
simonsunnyboy
Moderator
Moderator
Posts: 5032
Joined: Wed Oct 23, 2002 4:36 pm
Location: Friedrichshafen, Germany
Contact:

Re: Interrupt friendly IKBD routine?

Postby simonsunnyboy » Wed Feb 20, 2013 4:46 pm

Have you considered polling the IKBD buffer contents during your synccode sequence?
E.q. read the buffer to prevent it from overflowing, and processing the data a few scanlines later in a delayed fashion?

If all fails, you could use Tobe's custom IKBD routine (might break emulators!) which sends smaller and more efficient data packages.
Simon Sunnyboy/Paradize - http://paradize.atari.org/

Stay cool, stay Atari!

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

Zamuel_a
Atari God
Atari God
Posts: 1234
Joined: Wed Dec 19, 2007 8:36 pm
Location: Sweden

Re: Interrupt friendly IKBD routine?

Postby Zamuel_a » Wed Feb 20, 2013 5:16 pm

Have you considered polling the IKBD buffer contents during your synccode sequence?


I tried something like that, but didn't get it to work.

I checked if fffc00 was 1 and if it was, I read fffc02 and looped this until fffc00 was 0, but it hanged in the loop all the time so that didn't work. I think fffc00 should be 1 if the buffer have data and 0 if not?
ST / STFM / STE / Mega STE / Falcon / TT030 / Portfolio / 2600 / 7800 / Jaguar / 600xl / 130xe

User avatar
npomarede
Atari God
Atari God
Posts: 1260
Joined: Sat Dec 01, 2007 7:38 pm
Location: France

Re: Interrupt friendly IKBD routine?

Postby npomarede » Wed Feb 20, 2013 10:24 pm

Zamuel_a wrote:
Have you considered polling the IKBD buffer contents during your synccode sequence?


I tried something like that, but didn't get it to work.

I checked if fffc00 was 1 and if it was, I read fffc02 and looped this until fffc00 was 0, but it hanged in the loop all the time so that didn't work. I think fffc00 should be 1 if the buffer have data and 0 if not?

Hello
polling correctly should not give the result/lock you get.
You should not compare with 1, because there're other bits in fffc00 that can be set ; you should test only bit 0 of fffc00 (RDRF) :

Code: Select all

 btst #0,$fffc00
 beq.s no_byte
 move.b $fffc02,d0
 move.b d0,(a0)+
no_byte


with a0 pointing to a large enough buffer(you can get approx ~17 bytes from the IKBD per 50 Hz VBL)

Doing this regularly (at least every 20 scanlines) should be enough to get all bytes sent by the ikbd, with whatever timer you use at the same time to remove top border. You can then process later the buffer in a0.

Nicolas

Zamuel_a
Atari God
Atari God
Posts: 1234
Joined: Wed Dec 19, 2007 8:36 pm
Location: Sweden

Re: Interrupt friendly IKBD routine?

Postby Zamuel_a » Wed Feb 20, 2013 11:05 pm

I don't have an interrupt that runs every 20 lines so will be tricky to do it. I think I will stay with the current version since it work's rather good. Sometime I get the screen to jump for 1 VBL, but it's not to bad. If I turn off the IKBD during the sensitive part were I remove the top border it works even better. It's just that it sometimes hangs if I move the joystick really fast in all directions. Now this is not a situation that should occure if you play the game as it is intended so maybe this doesn't matter so much :wink:
ST / STFM / STE / Mega STE / Falcon / TT030 / Portfolio / 2600 / 7800 / Jaguar / 600xl / 130xe

User avatar
npomarede
Atari God
Atari God
Posts: 1260
Joined: Sat Dec 01, 2007 7:38 pm
Location: France

Re: Interrupt friendly IKBD routine?

Postby npomarede » Thu Feb 21, 2013 9:22 am

Zamuel_a wrote:I don't have an interrupt that runs every 20 lines so will be tricky to do it. I think I will stay with the current version since it work's rather good. Sometime I get the screen to jump for 1 VBL, but it's not to bad. If I turn off the IKBD during the sensitive part were I remove the top border it works even better. It's just that it sometimes hangs if I move the joystick really fast in all directions. Now this is not a situation that should occure if you play the game as it is intended so maybe this doesn't matter so much :wink:

You don't need to have an interrupt every 20 lines :
- during the time critical part (border removal), use "move 2700,sr" and poll fffc00/fffc02 while waiting for the position to remove top border
- during the rest of the VBL, use the MFP interrupt for the IKBD.

This way, you can handle even fast joystick changes.

I don't think turning off/on keyboard reporting is a good idea.

Nicolas

Zamuel_a
Atari God
Atari God
Posts: 1234
Joined: Wed Dec 19, 2007 8:36 pm
Location: Sweden

Re: Interrupt friendly IKBD routine?

Postby Zamuel_a » Thu Feb 21, 2013 9:49 am

I don't wait for the time to open the top border. I use Timer A to control that and Timer B for the bottom border. Inside the Timer A and B routine, Timer A is setup during the VBL and I tried to disable interrupts here to, but didn't see any difference. I think that the problem occures if the IKBD interrupt happenes just before the VBL so it get's delayed and then the timing for Timer A get's wrong.

It is abit strange because I thought that writing $2700 so SR should disable all interrupts but something automatically turns them on again? I tried to write $2700 in the VBL and there is no other writes to SR in the code, but anyway I don't see any difference. Timer A and B and VBL triggers normally. Only the IKBD seems to behave alittle different from it.

It had been much easier if the IKBD could store everything and then you just read the buffer from it once each VBL at a time you want it to. You can't press to many keys each VBL so that the IKBD buffer can get full anyway so this should be possible, but maybe the IKBD has to be reprogrammed first.
ST / STFM / STE / Mega STE / Falcon / TT030 / Portfolio / 2600 / 7800 / Jaguar / 600xl / 130xe

User avatar
npomarede
Atari God
Atari God
Posts: 1260
Joined: Sat Dec 01, 2007 7:38 pm
Location: France

Re: Interrupt friendly IKBD routine?

Postby npomarede » Thu Feb 21, 2013 10:02 am

Zamuel_a wrote:I don't wait for the time to open the top border. I use Timer A to control that and Timer B for the bottom border. Inside the Timer A and B routine, Timer A is setup during the VBL and I tried to disable interrupts here to, but didn't see any difference. I think that the problem occures if the IKBD interrupt happenes just before the VBL so it get's delayed and then the timing for Timer A get's wrong.

It is abit strange because I thought that writing $2700 so SR should disable all interrupts but something automatically turns them on again? I tried to write $2700 in the VBL and there is no other writes to SR in the code, but anyway I don't see any difference. Timer A and B and VBL triggers normally. Only the IKBD seems to behave alittle different from it.

It had been much easier if the IKBD could store everything and then you just read the buffer from it once each VBL at a time you want it to. You can't press to many keys each VBL so that the IKBD buffer can get full anyway so this should be possible, but maybe the IKBD has to be reprogrammed first.


ikbd interrupt could delay the VBL, that's why you must be sure that the timer A is started approximatively always at the same time. One possibility is to start the timer A on the previous VBL, while you remove the bottom border (and you're already synchronised with the video counter).
Another possibility is to use HBL interrupt to count 32 lines after the start of the VBL (but as it will trigger 32 times, it will cost you more CPU).

If you don't want the VBL to be delayed too much by the IKBD interrupt, do a "move 2300,sr" at the start of the ikbd interrupt ; this way the VBL will be able to start with minimal delay and you timer A should work better.

Note that if you write 2700 in SR during the VBL, the RTE at the end of the VBL will restore the previous value of SR. So if your MFP interrupts happen after the end of the VBL, it's normal they're processed.

Nicolas

Zamuel_a
Atari God
Atari God
Posts: 1234
Joined: Wed Dec 19, 2007 8:36 pm
Location: Sweden

Re: Interrupt friendly IKBD routine?

Postby Zamuel_a » Thu Feb 21, 2013 11:30 am

Note that if you write 2700 in SR during the VBL, the RTE at the end of the VBL will restore the previous value of SR. So if your MFP interrupts happen after the end of the VBL, it's normal they're processed.


Ah ofcourse. This is what happens. I can try "move 2300,sr" to see if it helps.

Is there a list somethere about the 8 different interuppt levels so it's easy to see how to enable / disable them. I have searched for it, but can't find it anywere.

I tried this code, since I was curious, but it didn't work at all

Code: Select all

   lea   keyboard_buffer,a0

aa1   btst   #0,$fffc00
   beq.s   aa2

   move.b   $fffc02,d0
   btst   #7,d0         ;check if it's a press or release
   bne.s   brkcode   
   and.l   #127,d0
   move.b   #1,(a0,d0)      
   bra.s   aa1

brkcode   and.l   #127,d0
   move.b   #0,(a0,d0)      
   bra.s   aa1
   
aa2   rts


I check the keyboard for data and if it's a press or release key, I update the key position in a table and it works if I remove the two lines dealing with fffc00 and replace the bra.s aa1 to rts, but I can ofcourse only treat one key at a time. With the code above nothing happenes and I don't detect anything, so fffc00 is always zero.
ST / STFM / STE / Mega STE / Falcon / TT030 / Portfolio / 2600 / 7800 / Jaguar / 600xl / 130xe

User avatar
npomarede
Atari God
Atari God
Posts: 1260
Joined: Sat Dec 01, 2007 7:38 pm
Location: France

Re: Interrupt friendly IKBD routine?

Postby npomarede » Thu Feb 21, 2013 1:00 pm

The problem with your code is that it works only for keys, not for mouse/joystick packets.
Before testing for bit 7, you should check if d0 is between $f6 and $ff ; those are special codes from the ikbd and you need to read a specific number of bytes after those to get a complete packet.
If you don't do this, you will get out of sync with the ikbd and interpret bad bytes (unless you completely disable mouse/joystick report in the ikbd or you tell the ikbd to report joystick as keys)

See http://www.kernel.org/doc/Documentation/input/atarikbd.txt for example for a description of all the packets.
This adds a little more complexity than just changing (a0,d0) directly, but it's required if you want to handle things correctly.

Apart from that, I think your code should work.

Nicolas

User avatar
npomarede
Atari God
Atari God
Posts: 1260
Joined: Sat Dec 01, 2007 7:38 pm
Location: France

Re: Interrupt friendly IKBD routine?

Postby npomarede » Thu Feb 21, 2013 1:07 pm

Zamuel_a wrote:Is there a list somethere about the 8 different interuppt levels so it's easy to see how to enable / disable them. I have searched for it, but can't find it anywere.


On ST, you only have 3 levels : 2 (HBL), 4 (VBL) and 6 (MFP).
So the meaningful values for SR would be 2100 (hbl+vbl+mfp), 2300 (vbl+mfp), 2500 (mfp only) and 2700 (nothing)

Zamuel_a
Atari God
Atari God
Posts: 1234
Joined: Wed Dec 19, 2007 8:36 pm
Location: Sweden

Re: Interrupt friendly IKBD routine?

Postby Zamuel_a » Thu Feb 21, 2013 3:05 pm

Yes I know I don't care about the mouse or joystick here. This was just an example and a quick way to see if it could work, but it doesn't. If I remove the check at fffc00 it works so fffc00 is useless here.
ST / STFM / STE / Mega STE / Falcon / TT030 / Portfolio / 2600 / 7800 / Jaguar / 600xl / 130xe

stevebagey
Atarian
Atarian
Posts: 1
Joined: Wed Aug 22, 2012 10:56 pm

Re: Interrupt friendly IKBD routine?

Postby stevebagey » Fri Feb 22, 2013 11:01 am

Zamuel_a wrote:
I tried this code, since I was curious, but it didn't work at all

Code: Select all

   lea   keyboard_buffer,a0

aa1   btst   #0,$fffc00
   beq.s   aa2



That code will read a word from $fffffc00 not a byte which means the IKBD status will be in the most significant byte, not the LSB (at least that's what happens on my Falcon). Try a btst.b #0,$fffc00 instead.

Steve

User avatar
npomarede
Atari God
Atari God
Posts: 1260
Joined: Sat Dec 01, 2007 7:38 pm
Location: France

Re: Interrupt friendly IKBD routine?

Postby npomarede » Fri Feb 22, 2013 1:19 pm

stevebagey wrote:
That code will read a word from $fffffc00 not a byte which means the IKBD status will be in the most significant byte, not the LSB (at least that's what happens on my Falcon). Try a btst.b #0,$fffc00 instead.

Steve

That's maybe because your assembler is producing 68030 code.
On 68000, when using btst on a memory location, bit number is modulo 8 and the access is a byte. So I don't think that's the cause of the problem for zamuel_a

Nicolas

Ato
Captain Atari
Captain Atari
Posts: 300
Joined: Tue Aug 10, 2010 3:27 am
Location: Duisburg, Germany

Re: Interrupt friendly IKBD routine?

Postby Ato » Tue Mar 05, 2013 9:22 pm

npomarede wrote:That's maybe because your assembler is producing 68030 code.
On 68000, when using btst on a memory location, bit number is modulo 8 and the access is a byte.


According to "M68000 FAMILY PROGRAMMER’S REFERENCE MANUAL", ch. 3.1.5 Bit Manipulation Instructions, all M68k CPUs have 8 bit operands when accessing memory:
[...]Register operands are 32 bits long, and memory operands are 8 bits long.[...]


Cheers,
T.

danorf
Atari maniac
Atari maniac
Posts: 78
Joined: Tue Feb 12, 2013 1:18 pm
Location: Behind a computer

Re: Interrupt friendly IKBD routine?

Postby danorf » Wed Mar 06, 2013 9:37 am

Have you already read : viewtopic.php?f=16&t=5297 ? And more precisely files in HD6301-v2.ZIP ?

As I understand it, on real hardware it could perhaps solve your problem.

Downside would be that you have to test if your code runs on real hardware or emulator (don't know if possible with all emulators, but I remember than some of them have cookies or other tricks to identify them) and have two IKBD routs, one for each case (or rely on emulators coders to correctly emulate your code :mrgreen: ).


Social Media

     

Return to “680x0”

Who is online

Users browsing this forum: No registered users and 4 guests