16 March 2019, 19:31 | #1 |
Registered User
Join Date: Oct 2017
Location: Sunderland, England
Posts: 2,702
|
Damn Interrupts
As part of Rygar I'm wanting to delve into an area that I know very little about.
I think I understand how the interrupts work but I just can't get them to fire. Taking the level 3 Vertical Blanking Interrupt as an example my understanding is that I should be able to write an interrupt service routine attached to VBR+$6c, within that routine I need to check if the VERTB is set within INTREQ and if it is then do whatever required... i need to ignore the other interrupts that are generated at this level which are COPER (Copper) and BLIT (Finished). Within my service routine i then need to acknowledge and unset the interrupt bit (i think). The code below is partially borrowed from elsewhere... but for the life of me I cannot get the service routine to fire and increment the Timer. Does anyone know what I'm missing here??? Code:
bsr InstallLevel3Int move.w #$c020,INTENA(a5) Code:
InstallLevel3Int: move.l a5,-(a7) ;--- get the vbr which is most probably somewhere in fast-ram lea getvbr(pc),a5 move.l $4.w,a6 jsr -30(a6) ; returns vbr in d0 lea vbroffset(pc),a0 move.l d0,(a0) ; store vbr ;--- you could store some old values here ;... ;--- register our own level 3 interrupt (vertical blanc and blitter) lea Level3Int(pc),a1 move.l a1,$6c(a0) move.l (a7)+,a5 rts ;--- get the vector base register getvbr: movec vbr,d0 ;dc.l $4e7a0801 ; this is the opcode for the above command rte vbroffset: dc.l 0 cnop 0,4 ;--- this is the actual interrupt code ; it could interrupt (!) your main-programm at anytime so better ; save the register states. this is what the push macro does (it uses movem.l). Level3Int: movem.l d0-d7/a0-a4,-(a7) move.w INTREQR(a5),d0 ; intreq-read btst #5,d0 ; Vertical Blank? bne .vertb bra .quitL3 .vertb lea Timer(pc),a0 addq.l #1,(a0) ; increase Timer by 1 lea VerticalBlank(pc),a0 move.w #-1,(a0) move.w #$4020,INTREQ(a5) ;0100000000100000 ; Clear vertical blank interupt. move.w #$4020,INTREQ(a5) bra.w .quitL3 .quitL3: movem.l (a7)+,d0-d7/a0-a4 nop rte ;--- this Timer is updated once a frame. ; there are 50 FPS on a PAL Amiga, so this variable has a resolution ; of 1/50 s ; or 20/1000 s ; or 20 ms Timer: dc.l 1 VerticalBlank: dc.w 0 Any help is really really really appreciated!!! Geezer |
16 March 2019, 20:05 | #2 |
68k
Join Date: Sep 2005
Location: Somewhere
Posts: 828
|
@mcgeezer What do you have in A0 when you set VERTB ? You should have VBR address here. Are you sure that you have VBR in A0 ? I ask because I see that VBR is in D0. Please add at least following line to your code
Code:
move.l d0,(a0) ; store vbr move.l d0,a0 ; vbr --> a0 Cheers |
16 March 2019, 20:08 | #3 | |
Registered User
Join Date: Oct 2017
Location: Sunderland, England
Posts: 2,702
|
Quote:
Working great now! Geezer |
|
16 March 2019, 20:12 | #4 |
68k
Join Date: Sep 2005
Location: Somewhere
Posts: 828
|
@mcgeezer Great. But You can check also Level3Int. It works but I am not sure if is correct.
|
16 March 2019, 20:21 | #5 | |
Registered User
Join Date: Oct 2017
Location: Sunderland, England
Posts: 2,702
|
Quote:
Geezer Edit... Here is now my Interrupt Service Routine on Level 3. Part of this is to ensure that the 2nd button code works on all Amiga 1200's/CD32. In the Vertical Blank routine I'm writing to POTGO, then in my copper routine at line 64 I'm causing the button state to be read. This is the first time I've done stuff like this and it seems I'm getting the hang of it finally. Code:
Level3Int: movem.l d0-d7/a0-a4,-(a7) move.w INTREQR(a5),d0 ; intreq-read btst #5,d0 ; Vertical Blank? bne.s .vertb btst #4,d0 ; Copper bne.s .copper bra.s .quitL3 .vertb: lea VerticalBlank(pc),a0 move.w #-1,(a0) move.w #$ff00,POTGO(a5) ; Reset POTGO bsr UPDATE_TIMER bsr CYCLE_COLOURS moveq #8,d0 bsr UPDATE_ROUND_GUIDE move.w #$4020,INTREQ(a5) ;0100000000100000 ; Clear vertical blank interupt. move.w #$4020,INTREQ(a5) bra.w .quitL3 .copper: bsr BTN_DETECT move.w #$4010,INTREQ(a5) ;0100000000100000 ; Clear copper interupt. move.w #$4010,INTREQ(a5) bra.w .quitL3 nop .quitL3: movem.l (a7)+,d0-d7/a0-a4 nop rte Last edited by mcgeezer; 16 March 2019 at 20:36. |
|
16 March 2019, 20:43 | #6 | |
Registered User
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 55
Posts: 1,975
|
Quote:
This code dont looks good for me: Level3Int: movem.l d0-d7/a0-a4,-(a7) move.w INTREQR(a5),d0 ; intreq-read |
|
16 March 2019, 20:44 | #7 |
Registered User
Join Date: Oct 2017
Location: Sunderland, England
Posts: 2,702
|
|
17 March 2019, 00:12 | #8 |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,474
|
I'm a bit tipsy but I try
If you disable system IRQ you don't need to split IRQ3 in VBI and Copper parts. And a simple init for POTGO suffice. You can do: Code:
bsr InstallLevel3Int move.w #$ff00,POTGO(a5) ; Reset POTGO move.w #$c020,INTENA(a5) (In Copper IRQ fork you test only joy/buttons state?) [Anyway.. if you want to activate Copper IRQ you need to write #$c030,INTENA(a5)] Another thing: do you stop IRQs during the loading phase? Because if not, then a5/a6 need to be saved. To clean the IRQ only clear the interested bit (so move.w #$20,INTREQ(a5)suffice) and nopis unnecessary. Optimized routine: Code:
Level3Int: movem.l d0-d7/a0-a6,-(a7) lea $dff000,a5 ;a6? lea VerticalBlank(pc),a0 st (a0) ; do you check for EQ? bsr BTN_DETECT bsr UPDATE_TIMER bsr CYCLE_COLOURS moveq #8,d0 bsr UPDATE_ROUND_GUIDE moveq #$20,d0 move.w d0,INTREQ(a5) move.w d0,INTREQ(a5) movem.l (a7)+,d0-d7/a0-a6 rte Last edited by ross; 17 March 2019 at 00:39. Reason: added lea custom,a5 |
17 March 2019, 12:49 | #9 |
Registered User
Join Date: Oct 2017
Location: Sunderland, England
Posts: 2,702
|
Thanks Ross, I have fixed up the saved registers.
My understanding was that if I wanted to support CD32 pads I would need to write #$ff00 to POTGO at the vertical blank and then read the button inputs from POTGOR at least 4 scan lines later. I have probably mis-understood due to the various postings about this. It will all come out in play testing anyways. Graeme |
17 March 2019, 15:28 | #10 |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,474
|
It depends.
CD32 pad have two working mode: "CD32 mode" and "normal mode". If you want basic CD32 pad support (only the red/blue buttons as 1st and 2nd joy buttons) aka "normal mode" this init should suffice. /Tech mode on Pin 5 (MMB) = 1 = output, I/O data = 0 (gnd) -> pad to "CD32 mode", shift register enabled*. Pin 5 = 0 = input or data = 1 (5v) -> "normal mode", red and blue buttons -> 2 buttons joystick. This is what I've understood from the mess laying around But I've never owned a joypad... *you need a proper routine to read all the buttons state All the delay / capacitors stuff is for when you use POT in analog mode (bit 0 = 1) /off jotd has a ready auto-recognition routine that uses different code depending on what is connected. And a full "CD32 mode" support. Toni to confirm/correct me and/or give you more details |
24 March 2019, 16:50 | #11 | |
WinUAE developer
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,515
|
Don't do it. Sooner or later you make some optimized routine that temporarily uses all address registers which in worst case works just fine until (much) later something else changes timing just enough to break it randomly without any clue..
Quote:
Capacitors are always connected but they only cause max few tens of microsecond delays when reading buttons using POTGOR bits. No problems as long as you don't do something weird like toggling POTGO data out/in bits and then immediately attempt to read button state Pot line caps is also the reason why CD32 pad routines have delays (usually by reading CIA register which always takes at least 1 E-clock cycle = ~710KHz) btw, it is much simpler to read POTGOR first, then set it to $ff00. This way you guarantee there is always more than enough time before next read. This is how KS ROM does it too. (But remember to ignore results of first read..) |
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
A cautionary tale: trying to be 'too smart' with interrupts | roondar | Coders. Asm / Hardware | 28 | 28 November 2018 17:54 |
How does Paula handle pending interrupts? | bloodline | Coders. Asm / Hardware | 6 | 21 January 2018 15:45 |
CIA interrupts... | bloodline | Coders. System | 6 | 18 January 2018 10:33 |
Interrupts and Multitasking: Examples? | tygre | Coders. General | 13 | 22 December 2015 04:56 |
Advice on interrupts and jumps | alexh | Coders. General | 11 | 20 May 2008 09:42 |
|
|