![]() |
![]() |
#1 |
This cat is no more
Join Date: Dec 2004
Location: FRANCE
Age: 52
Posts: 8,389
|
is it possible to emulate keypresses from software?
Hi,
Well I guess not, but maybe I'm wrong... |
![]() |
![]() |
#2 |
Registered User
Join Date: Jan 2002
Location: Germany
Posts: 7,035
|
Sure it is possible. How do you think that keyboard drivers would work, for example for USB keyboards?
Check input.device / IND_WRITEEVENT Of course this only works with AmigaOS programs, not with games which access the hardware directly. |
![]() |
![]() |
#3 |
BoingBagged
Join Date: Aug 2007
Location: The South of nowhere
Age: 46
Posts: 2,358
|
|
![]() |
![]() |
#4 |
This cat is no more
Join Date: Dec 2004
Location: FRANCE
Age: 52
Posts: 8,389
|
thanks, but I meant in a non os friendly environment (games)
|
![]() |
![]() |
#5 |
son of 68k
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,365
|
Why can't you just locate where the program is accessing the keyboard and put a patch there ?
|
![]() |
![]() |
#6 |
WinUAE developer
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,575
|
Not tested idea:
Disable interrupts Write very small value to CIA-A timer A. Set CIA serial port to output mode (Set bit 7 of CRA) Start timer (which does nothing yet because output mode is active) Write keycode you want to inject in SDR. (Serial port transmit starts, transmit rate = timer A) Wait a bit to guarantee end of transmit. (Don't touch ICR!) Restore timer A if needed. Enable interrupts Unfortunately simply writing keycode to CIA serial port register is not enough because it does not generate any interrupts and there is no other way to generate SP (serial port) interrupt than a) using serial port in output mode and transmitting data to keyboard (which keyboard ignores, output mode is normally used only for keyboard handshake). Uses small timer value (I guess 1 is smallest possible) to make serial port transmit as fast as possible. All this complexity to get SP interrupt request bit set... (Which most keyboard interrupt handlers check before reading SDR) |
![]() |
![]() |
#7 |
This cat is no more
Join Date: Dec 2004
Location: FRANCE
Age: 52
Posts: 8,389
|
@meynaf: yeah, but I want to make a generic handler, not rewrite all patches done for games (it's for a possible cd32 loader project using whdload slaves & RN CD loader)
@Tony: I was waiting for an answer from the Boss ![]() Well this should be tested on a real amiga as well! WinUAE could just be nice and work, whereas the real thing wouldn't. BTW how the handler distriguishes between timer interrupts and keyboard interrupts? |
![]() |
![]() |
#8 |
WinUAE developer
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,575
|
No, it should generate correct keyboard serial port interrupt, SP flag in CIA ICR should become activated (unfortunately it can't be set by CPU write, like INTREQ can be both set and cleared with CPU write).
Check HRM CIA chatper, it has short serial port output mode description. (Timer A = CIA serial port baud rate generator in output mode, in input mode it is not used by serial port) I'll do real hardware test later. |
![]() |
![]() |
#9 |
Registered User
Join Date: Jan 2002
Location: Germany
Posts: 7,035
|
This is a nice experiment, but it has no practical use. You can only inject one key code before the game starts. Once the game has taken over the system, there is no multitasking any more and no way for your program to get control. You can only hope that the game does not overwrite the interrupt vector and that your interrupt routine is regularly called. But it surely does not make a generic handler.
|
![]() |
![]() |
#10 |
son of 68k
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,365
|
Good remark !
Either it's an environment where the OS still runs (in that case using input.device is the solution) or it's an "OS kill" environment - and then no interrupt survives... Why wanting to force games to detect fake keypresses anyway ? |
![]() |
![]() |
#11 |
WinUAE developer
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,575
|
I think the point is to allow generic injection of keycodes without knowing how the game/demo reads them = you already have some control of running code (for example via some other patch, probably has something to do with JST
![]() |
![]() |
![]() |
#12 |
son of 68k
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,365
|
This does not answer the question : why wanting to inject key codes ?
I would understand the need to inject joystick changes - to emulate it with the keyboard, for example. But inject key codes ? ![]() |
![]() |
![]() |
#13 |
WinUAE developer
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,575
|
I am not OP but one possibility that makes sense is running games that need keyboard on CD32 or CDTV using joypad to send key codes.
EDIT: Why does it need some purpose? Weird and possibly pointless "classic" Amiga stuff is fun. |
![]() |
![]() |
#14 |
son of 68k
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,365
|
It's often easier to find a solution when the exact purpose is known.
|
![]() |
![]() |
#15 |
This cat is no more
Join Date: Dec 2004
Location: FRANCE
Age: 52
Posts: 8,389
|
you're both right.
In that case, it's to be able to reuse somehow whdload slaves with a kind of JST/Whdload on CD32 to send keypresses from the extra joypad buttons. If it cannot be done, then all slaves which need extra keys will need to be patched manually as we happen to do. |
![]() |
![]() |
#16 |
WinUAE developer
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,575
|
It seems to work. Test code below (Injects keys a, b and c). Real A1200 confirmed. (Also work in UAE)
Code:
move.l 4.w,a6 lea keycodes(pc),a4 l6 ; Disable interrupts jsr -$78(a6) ; Timer value = 10 (Just randonly chosen value) move.b #10,$bfe401 move.b #0,$bfe501 ; OUTMODE and START move.b #$41,$bfee01 l1 ; Write keycode move.b (a4)+,$bfec01 ; Delay until keycode transmit is complete ; (Can't poll CIA interrupt register because it also clears it) moveq #10-1,d2 l4 move.w $dff006,d0 clr.b d0 l3 move.w $dff006,d1 clr.b d1 cmp.w d0,d1 beq.s l3 dbf d2,l4 ; Stop timer bclr #0,$bfee01 ; Enable interrupts jsr -$7e(a6) ; Wait until keyboard interrupt ; handler has handled the keycode ; = outmode was cleared. l5 btst #6,$bfee01 bne.s l5 cmp.b #$ff,(a4) bne.s l6 rts keycodes dc.b ~($20<<1+0),~($20<<1+1) ;A press,A relase dc.b ~($35<<1+0),~($35<<1+1) ;B dc.b ~($33<<1+0),~($33<<1+1) ;C dc.b $ff |
![]() |
![]() |
#17 |
This cat is no more
Join Date: Dec 2004
Location: FRANCE
Age: 52
Posts: 8,389
|
Excellent! Thanks for the code
|
![]() |
![]() |
#18 |
This cat is no more
Join Date: Dec 2004
Location: FRANCE
Age: 52
Posts: 8,389
|
Toni, this code works very well, but on some games which already use CIA timer A it has some bad side effects.
For instance, in Fire & Ice, if we send key presses like that, the music is frozen. I tried (and failed) to store the previous values of the timers. Maybe some stuff is write only or whatever, because it doesn't work, like at all (crashes winuae!!) note that I'm not disabling the interrupts at all in this code. Code:
send_key_event ; Disable interrupts: no need here: we are in VBL movem.w d3-D5,-(a7) ;; JOTD changes to stop timer & save values (doesn't work!!) move.b $bfee01,d5 ; save CIAACRA value bclr #0,$bfee01 ; stop timer move.b $bfe401,d3 move.b $bfe501,d4 ;; end of JOTD changes ; Timer value = 10 (Just randonly chosen value) move.b #10,$bfe401 move.b #0,$bfe501 ; OUTMODE and START move.b #$41,$bfee01 l1 ; Write keycode (keypress only) rol.b #1,d0 not.b d0 move.b d0,$bfec01 ; Delay until keycode transmit is complete ; (Can't poll CIA interrupt register because it also clears it) moveq #10-1,d2 l4 move.w $dff006,d0 clr.b d0 l3 move.w $dff006,d1 clr.b d1 cmp.w d0,d1 beq.s l3 dbf d2,l4 ; Stop timer bclr #0,$bfee01 ;; JOTD changes to put previous values in timer & control regs move.b d3,$bfe401 move.b d4,$bfe501 move.b d5,$bfee01 movem.w (a7)+,d3-D5 rts |
![]() |
![]() |
#19 |
Going nowhere
Join Date: Oct 2001
Location: United Kingdom
Age: 50
Posts: 9,020
|
Can you not simply do a selectable option at the start where user selects Timer A or Timer B operation?
|
![]() |
![]() |
#20 |
This cat is no more
Join Date: Dec 2004
Location: FRANCE
Age: 52
Posts: 8,389
|
Pretty good idea actually ! I'd prefer a generic solution but if it's not possible, I'll go for that instead. Brilliant.
|
![]() |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
Send keypresses from external program to WinUAE? | bazizten | support.WinUAE | 2 | 24 June 2012 18:05 |
How do I emulate AKIRA? | JimboKudo | New to Emulation or Amiga scene | 4 | 16 August 2007 18:54 |
How to emulate blank discs? | nathan Summers | New to Emulation or Amiga scene | 4 | 07 September 2006 11:28 |
can i emulate workbench? | cyclone | New to Emulation or Amiga scene | 5 | 16 June 2005 20:00 |
Ok who uses xbox to emulate the Amiga !!! | synchro | Amiga scene | 23 | 08 January 2005 15:02 |
|
|