03 November 2023, 15:48 | #1 |
Registered User
Join Date: Mar 2018
Location: Rome
Posts: 173
|
playing with keyboard interrupts
I'm trying to create a simple keyboard interrupt demo.
The code is the following, much similar to AsmOne NonSystemStartup except that wants to enable inter. level 2 PORTS of INTENA instead of VBLANK Code:
************************************************* * * * System OFF with PORTS Interrupt * * * ************************************************* OldOpenLibrary = -408 CloseLibrary = -414 ; A = AGNUS, D = DENISE, P = PAULA ;DMACON 096 W A D P DMA control write (clear or set) ;DMACONR 002 R A P DMA control (and blitter status) read DMASET= %1000001110000000 ($8380) ; fedcba9876543210 ; f: Set/Clear control bit ; e: Blitter busy status bit (read only) ; d: Blotter logic zero status bit (read only) ; c: X ; b: X ; a: Blitter DMA priority (blitter nasty) ; 9: Enable all DMA below ; 8: Bitplane DMA enable ; 7: Copper DMA enable ; 6: Blitter DMA enable ; 5: Sprite DMA enable ; 4: Disk DMA enable ; 3: Audio channel 3 DMA enable ; 2: Audio channel 2 DMA enable ; 1: Audio channel 1 DMA enable ; 0: Audio channel 0 DMA enable ;INTENA 09A W P Interrupt enable bits (clear or set bits) ;INTENAR 01C R P Interrupt enable bits (read) INTENA= %1100000000001000 ($C008) ; fedcba9876543210 ; f: Set/Clear control bit ; e: Master interrupt ; d: External interrupt ; c: Disk sync register ( DSKSYNC ) matches disk data ; b: Serial port receive buffer full ; a: Audio channel 3 block finished ; 9: Audio channel 2 block finished ; 8: Audio channel 1 block finished ; 7: Audio channel 0 block finished ; 6: Blitter finished ; 5: Start of vertical blank ; 4: Copper ; 3: I/O ports and timers ; 2: Reserved for software -initalited interrupt ; 1: Disk block finished ; 0: Serial port transmit buffere empty START: ;--- Store Old Register Settings --- MOVEM.L D0-D7/A0-A6,-(SP) MOVE.L $4.W,A6 LEA GFXNAME(PC),A1 JSR OldOpenLibrary(A6) ; load graphics library MOVE.L D0,A1 MOVE.L 38(A1),OldCopper ; store old copper 1 JSR CloseLibrary(A6) ; close graphics library LEA $DFF000,A6 MOVE.W $1C(A6),OldIntena ; store old INTENA (INTENAR) MOVE.W $02(A6),OldDma ; store old DMACON (DMACONR) ;--- Disable Intena/Intreq/Dmacon --- MOVE.L #$7FFF7FFF,$9A(A6) ; disable INTENA/INTREQ MOVE.W #$7FFF, $96(A6) ; disable DMACON ;--- Set Register Settings --- BSR WAITVB ; Wait for VBLANK MOVE.W #DMASET,$96(A6) ; set bits of DMACON state MOVE.L #COPPERLIST, $80(A6) ; set custom COPPERLIST ;--- Program Interrupt --- MOVE.L $68.W,OldInter ; store old INTER PTR MOVE.L #INTER,$68.W : set interrupt pointer MOVE.W #INTENA,$9A(A6) ; set bit of INTENA LEFTMOUSE BTST #6,$BFE001 BNE.S LEFTMOUSE **** EXIT - RESTORE OLD REG SETTINGS **** LEA $DFF000,A6 MOVE.W #$7FFF,$9A(A6) ; disable interrupts BSR.S WAITVB MOVE.W #$7FFF,$96(A6) ; disable DMA MOVE.W OldDma(PC),D0 OR.W #$8000,D0 ; set bits of DMACON state MOVE.W D0,$96(A6) ; restore original DMACON MOVE.L OldCopper,$80(A6) ; restore original COPPERLIST CLR.W $88(A6) ; activate original COPPERLIST MOVE.L OldInter(PC),$68.W ; restore inter pointer MOVE.W #$7FFF,$9C(A6) ; clear requests MOVE.W OldIntena(PC),D0 OR.W #$C000,D0 ; set bits of INTENA state MOVE.W D0,$9A(A6) ; restore original INTENA MOVEM.L (SP)+,D0-D7/A0-A6 RTS WAITVB: TST.B $DFF005 BEQ.B WAITVB .LOOP TST.B $DFF005 BNE.S .LOOP RTS INTER: MOVEM.L D0-D7/A0-A6,-(SP) LEA $DFF000,A6 LEA $BFE001,A5 MOVEQ #$08,D0 ; check if is it level 2 interrupt MOVE.W $1E(A6),D1 AND.W D0,D1 BEQ.B EXIT_INTER MOVE.B $0D00(A5),D1 ; check if SP cause interrupt AND.B D0,D1 BEQ.B EXIT_INTER MOVE.B $0C00(A5),D0 ; read a byte from CIAA serial data register connected to keyboard into d0 NOT.B D0 ; negate a byte in d0 ROR.B #1,D0 ; rotate right 1 bit CMP.B #$59,D0 ; compare F10 key value with d0 BNE.S WAIT ; if not F10 pressed - goto exit BCHG #1,(A5) ; Test bit and change. Bit 1 is power LED WAIT MOVEQ #3-1,D1 ; handshake .WAIT1 MOVE.B $06(A6),D0 .WAIT2 CMP.B $06(A6),D0 BEQ.B .WAIT2 DBF D1,.WAIT1 EXIT_INTER: MOVE.W #$4008,$9C(A6) ; clear interrupt request MOVEM.L (SP)+,D0-D7/A0-A6 RTE GFXNAME: DC.B 'graphics.library',0 EVEN OldCopper: DC.L 0 OldIntena: DC.W 0 OldDma: DC.W 0 OldInter: DC.L 0 SECTION Copper,DATA_C COPPERLIST: DC.L $01800000 DC.L $01820FFF END PS The code for the handshake wait, is it correct? |
03 November 2023, 17:39 | #2 |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,475
|
There is no handshake with the keyboard (SPMODE pulse).
This the reason why at exit the full keyboard buffer is flushed. |
03 November 2023, 22:12 | #3 |
Registered User
Join Date: Jun 2016
Location: europe
Posts: 1,039
|
Yep, you should do something like bset #6,$e00(a5) before WAIT, and then bclr #6,$e00(a5) before EXIT_INTER (after the wait dbf loop).
Also, your copper list isn't terminated with DC.L $fffffffe. |
03 November 2023, 23:48 | #4 | |
Registered User
Join Date: Mar 2018
Location: Rome
Posts: 173
|
Quote:
Code:
INTER: MOVEM.L D0-D7/A0-A6,-(SP) LEA $DFF000,A6 ; base custom register in A6 LEA $BFE001,A5 ; base CIAA register in A5 MOVEQ #$08,D0 MOVE.W $1E(A6),D1 ; check if is it level 2 interrupt AND.W D0,D1 BEQ.B END_INTER MOVE.B $0D00(A5),D1 ; check if SP cause interrupt AND.B D0,D1 ; read from CIAA icr BEQ.B END_INTER MOVE.B $0C00(A5),D0 ; read a byte from CIAA sdr register NOT.B D0 ; negate a byte in D0 ROR.B #1,D0 ; rotate right 1 bit CMP.B #$59,D0 ; compare F10 key value with d0 BNE.S NOTF10 ; if not F10 pressed - goto exit BCHG #1,(A5) ; Test bit and change. ; Bit 1 is power LED NOTF10: OR.B #$40,$0E00(A5) ; CIAA cra - SPMODE output MOVEQ #4-1,D1 ; wait 4 raster lines (at least 90us) .WAITLINES ; for the handshake MOVE.B $06(A6),D0 ; some Amiga keyboards (i.e. A1200) .CHECKLINE ; requires more time than others CMP.B $06(A6),D0 BEQ.B .CHECKLINE DBF D1,.WAITLINES AND.B #$BF,$0E00(A5) ; CIAA cra - SPMODE input END_INTER MOVE.W #$4008,$9C(A6) ; clear interrupt request MOVEM.L (SP)+,D0-D7/A0-A6 RTE |
|
08 November 2023, 12:54 | #5 |
Registered User
Join Date: Mar 2018
Location: Rome
Posts: 173
|
Hi there, I'm trying to attach an interrupt to an already existent one.
In order to do this I avoid touching cia icr so that existent keys continue to work. Now I want a key that if pressed do some stuff and then I want to redirect the keyboard to a specific key so I can simulate the press of it. Is it possible in theory to do this without messin all up? |
08 November 2023, 15:58 | #6 |
Registered User
Join Date: Jan 2019
Location: Germany
Posts: 3,233
|
Certainly. It is all the input.device. You receive keys over the IDCMP of your window (that is the recommended way) or a custom input even thandler (then global through all the system) and can add an input even there that emulates a pressed key.
|
08 November 2023, 17:54 | #7 |
Registered User
Join Date: Mar 2018
Location: Rome
Posts: 173
|
Ok, do you know any sources to learn how to use input.device properly?
Many assembler books do not cover sys libraries afaik |
08 November 2023, 22:47 | #8 |
Registered User
Join Date: Jan 2019
Location: Germany
Posts: 3,233
|
|
09 November 2023, 10:58 | #9 |
Registered User
Join Date: Mar 2018
Location: Rome
Posts: 173
|
Thanks a lot
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Interrupts interrupting interrupts | deimos | Coders. Asm / Hardware | 21 | 19 January 2022 17:05 |
Interrupts? | oRBIT | Coders. Asm / Hardware | 2 | 09 April 2021 15:50 |
CIA interrupts... | bloodline | Coders. System | 6 | 18 January 2018 10:33 |
LIVE keyboard playing of the classic Hybris Amiga tune :) | TorbenLarsen | Retrogaming General Discussion | 10 | 19 December 2012 22:11 |
Playing without joystick using keyboard | _ThEcRoW | project.WHDLoad | 12 | 28 April 2006 16:09 |
|
|