01 August 2009, 13:02 | #1 |
WinUAE developer
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,574
|
Quest for emulating Rampage/TEK.
"Everyone" knows that Rampage/TEK still crashes after few parts in emulation.
Problem is simple, demo does following: start blit (blit that has free cycles, CPU does not stop) move.l #vector3,$6c enable blitter interrupt (move.w #$c040,INTENA) (other level 3 interrupts are disabled, vertb is not used in this or any previous parts, demo uses copper to trigger level 1 interrupt, not level 3 like normally) self-modifying code, modify vector3 blitter parameters rts vector3: move.l #0,A-channel move.l #0,C-channel move.l #0,D-channel <other blitter register> move.w #$4040,INTREQ move.l #vector3b,$6c move.w #0,BLTSIZE rte vector3b: ... Fun things happen if INTREQ already have blitter interrupt request bit set. Interrupt starts instantly after writing to INTENA. Nice 128K blit (D=A^C) starts that clears first 128K of chip ram -> not good Above is what happens in emulation. (yes, demo does work on real A500) Your task, if you accept it, is to check if INTREQ blitter interrupt bit is set before above code is executed. (My Action Replay 3 is dead) and also explain what is really happening (I must be really desperate, I guess..) I'll post exact address of above routine tomorrow (I am not at home and forgot to take my notes with me..) but good place to check is when screen starts moving down revealing "landscape". If you enter debugger at this point, you can use following workaround: type "W dff09c 4040" to clear the intreq bit. (first 4 is only to force it to be word sized write..) I am running out of ideas (I can't find any code that could reset the intreq bit), perhaps there is some weird hardware feature, but I can't find anything wierd on my real A500.. btw, expect some more undocumented feature posts soon.. |
02 August 2009, 13:04 | #2 |
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
|
Interesting
It seems the blitter interrupt request bit is set just before the "The Electronic Knights" text fades up and remains set through the demo, and is last set by a blit started just before the blue Rampage logo fades up, but I guess you knew that already. I can't find any code either that is supposed to clear it. My first thought was that maybe the real hardware doesn't set request bits for interrupts that aren't enabled in INTENA in the first place. I've never bothered to check this myself. This should fix the demo, but is this correct hardware behaviour? And is there any code out there that relies on the state of INTREQR bits but ignores the equivalent bits in INTENA? Maybe I'm simply forgetting something here. |
02 August 2009, 13:13 | #3 | |
WinUAE developer
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,574
|
and here is source (I have partial sources for debugging purposes)
address: 0x00038C12 Code:
ls_wbb btst #14,2(a6) bne.b ls_wbb move.l lsc_doub4(a0),$54(a6) ; BLTD move.l #$01000000,$40(a6) ; BLTCON clr.w $66(a6) ; DMOD move.l #-1,$44(a6) ; MASK move.w d0,$58(a6) ; STROBE lea ls_fill(pc),a1 move.l a1,$6c.w move.w #$c040,$9a(a6) sub.w #1<<6,d0 move.w d0,ls_fill4+2-ls_fill(a1) move.l lsc_doub2(a0),d1 moveq #0,d2 move.w lsc_width(a0),d2 add.l d1,d2 move.l d1,ls_fill1+2-ls_fill(a1) move.l d2,ls_fill2+2-ls_fill(a1) move.l d2,ls_fill3+2-ls_fill(a1) rts ls_fill ls_fill1 move.l #0,$dff04c ls_fill2 move.l #0,$dff050 ls_fill3 move.l #0,$dff054 clr.l $dff062 move.l #$0d3c0000,$dff040 move.w #$4040,$dff09c ls_fill4 move.w #0,$dff058 ls_fill5 move.l #fv_loesch,$6c.w rte Quote:
|
|
02 August 2009, 13:55 | #4 |
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
|
But wait what are you saying here, will real hardware set bits in INTREQ even if they are not enabled in INTENA?
|
02 August 2009, 13:59 | #5 |
WinUAE developer
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,574
|
|
02 August 2009, 14:06 | #6 |
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
|
Keep us posted
|
02 August 2009, 14:11 | #7 |
Registered User
Join Date: Jun 2008
Location: somewhere else
Posts: 524
|
Isn't it because the interrupt doesn't start before the blitter have finished it's clearing operation ?
|
02 August 2009, 14:13 | #8 |
WinUAE developer
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,574
|
|
02 August 2009, 14:27 | #9 |
Registered User
Join Date: Jun 2008
Location: somewhere else
Posts: 524
|
What blit, the clearing one ?
The rkm mentions that the blitter interrupt flag is set at the end of each blit. Writing to INTENA have no immediate effect while the clearing blit above isn't finished yet and the interrupt is only generated when it is then the code above and it's behaviour on a real a500 makes sense. Last edited by hitchhikr; 02 August 2009 at 14:56. |
02 August 2009, 14:44 | #10 |
WinUAE developer
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,574
|
|
02 August 2009, 14:58 | #11 |
WinUAE developer
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,574
|
Blitter interrupt is separate line from Agnus to Paula (also level 2/6 CIA interrupts), all other interrupts are completely handled inside Paula. Perhaps this difference means something..
|
02 August 2009, 15:13 | #12 |
Registered User
Join Date: Jun 2008
Location: somewhere else
Posts: 524
|
For me that piece of code is clear, the blitter sends a notification to the 68000 as soon as it's work is done, the 68000 then checks if the blitter interrupt bit has been enabled or not (it was via the move.w #$c040,$9a(a6)) and enters the vector at $6c.w.
Writing to the INTENA doesn't trigger the interrupt right away since there's a blit job using the free cycles running in the background, the interrupt may even be triggered after the rts (or whenever the blitter allows it after completion of it's job), the bit is cleared (via move.w #$4040,$dff09c) to stop the interruption. I assume that fv_loesch contains another move.w #$4040,$dff09c to stop the interrupt request which is triggered at the end of the blit job located inside the interrupt. Did you try to modify the emulator so that intreq bit is cleared at each blitter job start and set when the job is finished or checking the blitter busy flag when a writing to the INTENA occurs ? During the writing to the INTENA the interrupt is only triggered if the blitter isn't busy. At the end of a blit job the interrupt is only triggered if the INTENA bit is enabled. Last edited by hitchhikr; 02 August 2009 at 15:24. |
02 August 2009, 15:50 | #13 |
WinUAE developer
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,574
|
Good theory but I can't duplicate this. Cleared INTENA, wrote 8040 to INTREQ, started similar clear blit, wrote C040 to INTENA, interrupt still happens instantly, not after blit has finished.
|
02 August 2009, 17:24 | #14 |
WinUAE developer
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,574
|
Can anyone with AR2/3 set breakpoint at 0x38C9E (set it when screen starts moving down), wait for breakpoint, disassemble from 0x38C68.
Do you see: move.l #x,$dff04c move.l #x,$dff050 move.l #x,$dff054 clr.l $dff062 move.l #$0d3c0000,$dff040 moe.w #$4040,$dff09c move.w #x,$dff058 .. Are x's zero or non-zero? I just noticed this demo part works fine even if first clear blit is completely skipped (memory is already zero) so perhaps interrupt works as documented but blitter stops early enough and does not clear any exception vectors. |
02 August 2009, 17:34 | #15 |
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
|
There is a non working version of the demo around, so I uploaded a working DMS of it to the zone for anyone who wants.
|
02 August 2009, 18:10 | #16 |
Registered User
Join Date: Jun 2008
Location: somewhere else
Posts: 524
|
Ok, take a look a this: http://pagesperso-orange.fr/franck.c...mp/testint.zip
That one will display red/yellow color if the interrupt is occuring right away or a green one if it's delayed. Writing 8040 in INTREQ does make the interrupt starts right away indeed but the exe still works perfectly on the A500 and crash in WinUAE if cycle exact is enabled (but works if the option is disabled), so the code which is executed right away is: Code:
move.l #0, $dff04c move.l #0, $dff050 move.l #0, $dff054 clr.l $dff062 move.l #$0d3c0000, $dff040 move.w #$4040, $dff09c move.w #0, $dff058 On the A500 the color is yellow which means that the int is triggered one time with all values empty, it should make the machine to crash but it doesn't. If i remove the clearing blit job it crashes on the A500 which means that the blit job which is located within the interrupt isn't triggered or is somehow nullified when the blitter is still clearing. When a blitter interrupt is triggered there may be some fail safe to check if the blitter is running or not if it is then no operation occur (if there's a waitblit after the clearing like in testint2 then the machine crashes). This behaviour only occurs when using blitter int as this will produce a crash: Code:
move.w #$8040, $9c(a6) move.l #100*64+20, d0 move.l #$60000, d1 move.l d1, $54(a6) clr.w $66(a6) move.l #-1, $44(a6) move.l #$1000000, $40(a6) move.w d0, $58(a6) ls_fill1: move.l #0, $dff04c ls_fill2: move.l #0, $dff050 ls_fill3: move.l #0, $dff054 clr.l $dff062 move.l #$0d3c0000, $dff040 move.w #$4040, $dff09c ls_fill4: move.w #0, $dff058 |
02 August 2009, 19:29 | #17 |
WinUAE developer
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,574
|
Thanks, I can confirm this. There are really weird things happening...
Blitter gets totally confused when channel mode=1 gets switched to D while blit is already active. I checked the cycle diagrams with logic analyzer: Clear blit, -D-D-D-D... write 0x?D?? to DFF040 and cycle diagram changes to officially non-existing BACBACBAC. (correct channel combination should have been ABD) I don't know how to explain this without knowing blitter internals but this does explain why memory is not corrupted (=demo does not crash), blitter only reads, it never writes anything... EDIT: I didn't notice this because I did 2 mistakes, I didn't check it with LA and I had blitter nasty set = "BAC" does not have any free cycles -> CPU stopped before write to BLTSIZE, writing to BLTSIZE when blitter is idle -> blitter resets cycle diagram, blitter writes again.. |
03 August 2009, 09:14 | #18 |
Zone Friend
|
I think it may also help to know that '_loesch' originates from German "löschen" = "delete" resp. (in this context) "clear" in English
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
TEK - The Electronic Knights | Galahad/FLT | request.Demos | 11 | 21 September 2011 20:05 |
Ami-Tek?? | Mick_AKA | Amiga scene | 11 | 06 December 2007 20:54 |
TEK Rampage | bobbybearing | support.Demos | 4 | 05 March 2005 12:59 |
Larry, King Quest, Space Quest - fixed games | haynor666 | request.Old Rare Games | 8 | 01 May 2003 17:07 |
|
|