English Amiga Board


Go Back   English Amiga Board > Coders > Coders. General > Coders. Tutorials

 
 
Thread Tools
Old 21 December 2011, 00:24   #1
jman
Registered User
 
Join Date: Nov 2010
Location: Italy
Posts: 303
[REQ:ASM] Reading a keystroke

Hello,

I'd like to read a keystroke, then based on what is pressed do <this> or <that>.
I'd like to do this in the most smooth way possible, thus using input.device

I've mumbled over the documentation and this post but I don't have clear what is needed to do. Basically I have to:
- CreateMsgPort()
- CreateIORequest()
- OpenDevice()
- SendIO() ? DoIO() ?

and then? Do I have to prepare an InputEvent struct?

Attached a tentative code snippet...

Thanks
Attached Files
File Type: s input.s (952 Bytes, 183 views)
jman is offline  
AdSense AdSense  
Old 21 December 2011, 22:02   #2
Leffmann

 
Join Date: Jul 2008
Location: Sweden
Posts: 2,025
First, there are a few bugs in your code, f.ex you're doing "move.l name, a0" in a few places when you probably meant to do "lea name, a0" to get its address in memory, etc.

Do you want to wait until a keyboard event occurs, or do you want to check the current state of the keyboard? If you want to wait for an event then add an input handler through input.device using the IND_ADDHANDLER and IND_REMHANDLER commands and go through all incoming events. If you want to check the current state of the keyboard then send KBD_READMATRIX to keyboard.device instead. You can find thorough examples of this in the RKM Devices.
Leffmann is offline  
Old 21 December 2011, 23:29   #3
jman
Registered User
 
Join Date: Nov 2010
Location: Italy
Posts: 303
Yes, basically I want to have a "listener" and note down the keys that are sent.

I'll look further into it, thanks.
jman is offline  
Old 22 December 2011, 21:31   #4
Leffmann

 
Join Date: Jul 2008
Location: Sweden
Posts: 2,025
Here's an example:

Code:
             include  exec/io.i
             include  exec/nodes.i
             include  exec/tasks.i
             include  exec/interrupts.i
             include  devices/input.i
             include  devices/inputevent.i

             macro    call
              xref    _LVO\1
              jsr     _LVO\1(a6)
             endm


             section  code

             move.l   4, a6
             call     CreateMsgPort
             move.l   d0, a5            ; a5 = MsgPort

             move.l   a5, a0
             move.l   #IOSTD_SIZE, d0
             call     CreateIORequest
             move.l   d0, a4            ; a4 = IOStdReq

             lea      inputdevice, a0
             moveq    #0, d0
             move.l   a4, a1
             clr.l    d1
             call     OpenDevice

             sub      #IS_SIZE, sp
             move.l   sp, a3            ; a3 = Interrupt

             ; set up our input handler

             sub.l    a1, a1
             call     FindTask
             move.l   d0, IS_DATA(a3)
             move.l   #handlercode, IS_CODE(a3)
             move.b   #127, LN+LN_PRI(a3)
             move.l   #handlername, LN+LN_NAME(a3)

             ; add it to the chain of handlers

             move.l   a3, IO_DATA(a4)
             move.w   #IND_ADDHANDLER, IO_COMMAND(a4)
             move.l   a4, a1
             call     DoIO

             ; put our task to sleep until we get the ABORT signal

             move.l   #SIGF_ABORT, d0
             call     Wait

             ; remove the handler and clean up

             move.l   a3, IO_DATA(a4)
             move.w   #IND_REMHANDLER, IO_COMMAND(a4)
             move.l   a4, a1
             call     DoIO

             add      #IS_SIZE, sp

             move.l   a4, a1
             call     CloseDevice
             move.l   a4, a0
             call     DeleteIORequest
             move.l   a5, a0
             call     DeleteMsgPort

             moveq    #0, d0
             rts



             ; the input handler receives a linked list of events in A0
             ; and must return the new list in D0. register A1 will
             ; contain the IS_DATA field of the Interrupt structure

handlercode  move.l   a0, d0

             ; check if we have pressed the escape key

.check       cmp.b    #IECLASS_RAWKEY, ie_Class(a0)
             bne      .next
             cmp.w    #69, ie_Code(a0)
             bne      .next

             ; null this event so they keypress isn't seen by the system

             move.b   #IECLASS_NULL, ie_Class(a0)

             ; signal ABORT to our task. (A1 already points to our task)

             movem.l  d0/a6, -(sp)
             move.l   4, a6
             move.l   #SIGF_ABORT, d0
             call     Signal
             movem.l  (sp)+, d0/a6
             rts

             ; check the next event in this list

.next        move.l    ie_NextEvent(a0), a0
             move.l    a0, d1
             bne       .check
             rts



handlername  dc.b      "test input handler", 0
inputdevice  dc.b      "input.device", 0
Leffmann is offline  
Old 23 December 2011, 00:13   #5
jman
Registered User
 
Join Date: Nov 2010
Location: Italy
Posts: 303
Uhm ... very interesting. Also, very clean and instructive code.

So, what I really need is a callback that handles the events and let me choose those interesting from those uninteresting.
With such a handler I can read all events passing through the device, correct?

Also, I think I see why I need such a listener: it wouldn't be possible to simply perfom a SendIO() with a CMD_READ set at IO_COMMAND offset of my IoStdReq. I would probably end up getting ... random data, I'd say, right? Not the input event I want, maybe I could intercept a mouse movement or whatever is passing through the input.device in that moment. right?

Maybe the CMD_READ is more targeted to reading from a serial interface?

Thanks for clarifying these points :-)
jman is offline  
Old 23 December 2011, 03:28   #6
Leffmann

 
Join Date: Jul 2008
Location: Sweden
Posts: 2,025
Quote:
Originally Posted by jman View Post
So, what I really need is a callback that handles the events and let me choose those interesting from those uninteresting.
With such a handler I can read all events passing through the device, correct?
Yes all input events will pass through your handler.

Quote:
Originally Posted by jman
Also, I think I see why I need such a listener: it wouldn't be possible to simply perfom a SendIO() with a CMD_READ set at IO_COMMAND offset of my IoStdReq. I would probably end up getting ... random data, I'd say, right? Not the input event I want, maybe I could intercept a mouse movement or whatever is passing through the input.device in that moment. right?

Maybe the CMD_READ is more targeted to reading from a serial interface?

Thanks for clarifying these points :-)
CMD_READ is one of several commands that need to be supported by all devices, and a must for storage devices like trackdisk.device etc., but I don't think it has any effect when sent to input.device. It's not mentioned in the reference material for input.device at least.

There are other methods of getting input events and data from the keyboard that might be better depending on what kind of program you're writing, but this method works for everything and should handle external HIDs such as USB keyboards without any extra code.
Leffmann is offline  
Old 08 August 2012, 19:47   #7
Foul
Registered User

Foul's Avatar
 
Join Date: Jun 2009
Location: Perigueux/France
Age: 43
Posts: 1,264
Send a message via ICQ to Foul Send a message via MSN to Foul Send a message via Skype™ to Foul
Similar request :

i want, per exemple, when F1 is pressed to jump to a sub-routine.

is there simple way to do that ? i was thinking :

wait_F1:
cmp.b #$keycode,$bfec01
beq main

edit: just found by pure hazard F1 is $5F

None rawkey codes are corresponding : http://www.whdload.de/docs/en/rawkey.html


Last edited by Foul; 08 August 2012 at 23:22.
Foul is offline  
Old 09 August 2012, 01:22   #8
Leffmann

 
Join Date: Jul 2008
Location: Sweden
Posts: 2,025
It's a bit more complicated than that. I've started writing a tutorial on the standard keyboard, joystick and mouse hardware, input routines are done but I need to write a demo program that puts it all together and shows how it works first. I'll try to finish it soon.
Leffmann is offline  
Old 09 August 2012, 01:31   #9
Foul
Registered User

Foul's Avatar
 
Join Date: Jun 2009
Location: Perigueux/France
Age: 43
Posts: 1,264
Send a message via ICQ to Foul Send a message via MSN to Foul Send a message via Skype™ to Foul
ok excellent

Nothing Hurry, i'm just learning some asm codes writting little progs for my own usage
Foul is offline  
Old 09 August 2012, 02:24   #10
Codetapper
2 contact me: email only!

Codetapper's Avatar
 
Join Date: May 2001
Location: Auckland / New Zealand
Posts: 3,135
Quote:
Originally Posted by Foul View Post
Similar request :

i want, per exemple, when F1 is pressed to jump to a sub-routine.

is there simple way to do that ? i was thinking :

wait_F1:
cmp.b #$keycode,$bfec01
beq main

edit: just found by pure hazard F1 is $5F

None rawkey codes are corresponding : http://www.whdload.de/docs/en/rawkey.html

The rawkey codes are different from the code returned from $bfec01. You need to do the following:

Code:
        move.b  $bfec01,d0      ;Get 'encoded' key that pressed
        ror.b   #1,d0
        not.b   d0
        move.b  d0,_KeyPressed  ;Store rawkey that was pressed

        cmp.b   #$50,d0	        ;Check for $50 = F1
        beq     _F1Pressed
        cmp.b   #$51,d0	        ;Check for $51 = F2
        beq     _F2Pressed
        ...
But it's a bit more complicated than that, as you have to acknowledge the keypress etc. There's a routine called _SetupKeyboard in keyboard.s in the WHDLoad development kit which has a complete keyboard routine in it. That'd be a good place to look, but it does hit the hardware rather than using intuition etc.
Codetapper is offline  
Old 09 August 2012, 09:26   #11
Foul
Registered User

Foul's Avatar
 
Join Date: Jun 2009
Location: Perigueux/France
Age: 43
Posts: 1,264
Send a message via ICQ to Foul Send a message via MSN to Foul Send a message via Skype™ to Foul
Good to know !
Foul is offline  
AdSense AdSense  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
[REQ:ASM] Sprite collisions basics jman Coders. Tutorials 5 03 September 2011 01:07
[REQ:ASM] Loading a static image and its palette jman Coders. Tutorials 3 04 June 2011 15:08
[REQ:ASM] Assembling and running jman Coders. Tutorials 9 07 May 2011 19:39
REQ:ASM getting elapsed time on A1200 jman Coders. Tutorials 18 11 January 2011 23:24
REQ:ASM How to use buffers jman Coders. Tutorials 7 01 December 2010 02:41

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 14:10.


Powered by vBulletin® Version 3.8.8 Beta 1
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Page generated in 0.16026 seconds with 13 queries