02 February 2024, 15:41 | #41 |
Registered User
Join Date: Oct 2023
Location: London, UK
Posts: 124
|
No problem. It's just stolen code from the examples with Bare Metal Programming really. Could be a simple problem, just haven't got round to debugging it as its hardware only.
Code:
; In my setup I do: move.l #CIAA_Handler,IRQ2(a0) ; Set the new CIAA IRQ vector move.l #CIAB_Handler,IRQ6(a0) ; Set the new CIAB IRQ vector ;-------------------------------------------------------------------------------------------------- ; Input & Keyboard Handling Routines ;-------------------------------------------------------------------------------------------------- KeyCode: dc.b 0 even ;-------------------------------------------------------------------------------------------------- ; This handler is called each time CIAA receives a byte from the keyboard. ; The keyboard needs a 200uS handshake signal. The signal is started by ; this interrupt handler which sets up an alarm on CIAB so that the ; CIAB_handler is called at the end of the handshake period. ; ; Using a value of 4 TOD counts means that the ALARM interrupt fill fire ; at somewhere between 190uS and 254uS for PAL systems. ;-------------------------------------------------------------------------------------------------- CIAA_Handler: MOVEM.L d0-d1,-(a7) MOVE.B CIAAICR,d0 ; Read source of CIAA IRQ BEQ.W .NoIRQ ; Not from CIAA! BTST #3,d0 ; Check the SP bit BEQ.W .NotKB ; Not set? Was not keyboard IRQ MOVE.B CIAASDR,d0 ; Read new value ROR.B d0 ; Set the bits in right order NOT.B d0 ; Account for active-low! MOVE.B d0,KeyCode ; Store new key code BSET.B #6,CIAACRA ; Change serial to output CLR.B CIAASDR ; Set the SP (KDAT) pin low. MOVEQ #0,d1 ; Ensure top bits will be cleared MOVE.B CIABTODHI,d1 ; Reading TODHI latches values SWAP d1 ; Move to bottom byte of top word MOVE.B CIABTODMID,d1 ; Read TOD middle byte ASL.W #8,d1 ; Move to top byte bottom word MOVE.B CIABTODLO,d1 ; Reading TODLO removes latch BSET.B #7,CIABCRB ; Writing to TOD will set alarm ADDQ.L #4,d1 ; Calculate the number of TOD counts required MOVE.B d1,d0 ; Make copy of the TODLO value ASR.W #8,d1 ; Move TODMID to low byte MOVE.B d1,CIABTODMID ; Write to TOD SWAP d1 ; Move TODHI to low byte MOVE.B d1,CIABTODHI ; Write to TOD MOVE.B d0,CIABTODLO ; Write TODLO to TOD MOVE.B #$84,CIABICR ; Enable TOD alarm interrupt .NotKB MOVE.W #$0008,$DFF000+INTREQ ; Acknowledge CIAA IRQ .NoIRQ MOVEM.L (a7)+,d0-d1 RTE ;-------------------------------------------------------------------------------------------------- ; This handler is called each time the TOD of CIAB reaches the ALARM value. ; When this happens the keyboard handshake on CIAA has finished and the ; keyboard can send the next value. ;-------------------------------------------------------------------------------------------------- CIAB_Handler: MOVEM.L d0,-(a7) MOVE.B CIABICR,d0 ; Read source of CIAB IRQ BEQ.W .NoIRQ ; Not from CIAB! BTST #2,d0 ; Check the TOD bit BEQ.B .NoIRQ ; Not set? Was not TOD counter IRQ BCLR.B #6,CIAACRA ; Change serial back to input. MOVE.B #$04,CIABICR ; Disable TOD alarm interrupt .NoIRQ MOVE.W #$2000,$DFF000+INTREQ ; Acknowledge CIAB IRQ MOVEM.L (a7)+,d0 RTE ; Called from my main loop! Controls: move.b KeyCode(PC),d0 ; Get the next key code beq .end2 ; No key pressed lea cpu1_ram,a5 cmpi.b #KEY_LEFT,d0 bne .key_right add.w #12,car_x(a5) bra .end1 .key_right cmpi.b #KEY_RIGHT,d0 bne .key_up sub.w #12,car_x(a5) bra .end1 .key_up cmpi.b #KEY_UP,d0 bne .key_down move.w #512,car_inc(a5) bra .end1 .key_down cmpi.b #KEY_DOWN,d0 bne .end1 move.w #0,car_inc(a5) .end1 ; Clear if you don't want the user to be able to hold the key ;clr.b KeyCode .end2 rts |
02 February 2024, 16:06 | #42 |
Registered User
Join Date: Feb 2017
Location: Denmark
Posts: 1,285
|
I assume you have taken over vblank interrupt from system? Otherwise it will reset ciab tod every frame. Also TOD latch doesn't work if ALARM bit is set. There is also TOD alarm bug, but don't think it will affect this case (though I could be wrong).
For figuring out where time is spent use some kind of timer around interesting sections of code. If you have clearly defined high level "sections" e.g. "game logic", "c2p", "sprites" etc. it should be fairly easy to time the easy of the and report numbers on screen (or accumulate time for each time e.g. specific functions are called, and report once per frame). That should help you narrow down where difference vs UAE is (probably something CPU heavy as chipset timing is usually accurate enough). If you have system available and KS2+ timer.device is fine and straightforward, if system is off CIAB TOD timer is good enough for rough estimates, otherwise just use a normal CIA timer (set reload value to $ffff, START+LOAD <run code> stop timer and read elapsed ticks). |
02 February 2024, 16:20 | #43 | ||
Registered User
Join Date: Oct 2023
Location: London, UK
Posts: 124
|
Quote:
Quote:
|
||
02 February 2024, 17:32 | #44 | |
This cat is no more
Join Date: Dec 2004
Location: FRANCE
Age: 52
Posts: 8,411
|
The code is very good and avoids the not satisfactory blocking delay loop which steals CPU cycles...
unless interrupt level 6 is not active or overwritten by something else like music player. It's interrupt level 6 which performs the handshake with proper timing. Check if the level 6 interrupt really calls CIAB_Handler Quote:
|
|
02 February 2024, 17:45 | #45 |
Registered User
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 56
Posts: 2,085
|
I dont think that using asr.w and asl.w is very good code. only lsr.w lsl.w is good for me for this case. Same for using movem.l d0,-(sp). If no special tricks for CCR handling, this is not good code. Most assemblers with auto optimisations as default will be change this to move.l d0,-(sp). Perhaps at end movem.l will be replaced with move.l too. I dont know if this movem.l is necessary for handling ACK.
|
02 February 2024, 18:09 | #46 |
Registered User
Join Date: Oct 2023
Location: London, UK
Posts: 124
|
Either way, the expected keyboard behaviour, which works in UAE, as an example:
1/ Hold down left or right cursor. Scroll world left and right until depressed. It's responsive and 100% reliable. On hardware I get: 1/ Hold down left or right cursor. World scrolls for a bit then stops. Then keypresses are intermittent or most likely not registered at all. Is it possible that I'm punishing the CPU so much on hardware that something else is grabbing priority from the interrupt handler?! Is that even possible. I guess some debug code on hardware will once again help. The last thing I expected, out of all the things to not work on hardware, was my borrowed keyboard routine!! |
02 February 2024, 20:05 | #47 |
WinUAE developer
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,595
|
Recent WinUAE versions log warning message if keyboard handshake is too short. UAE won't care if pulse is too short or too long, too many programs have CPU delay loops and different keyboard models have different handshake pulse requirements which forces UAE to accept everything.
Usual easy check: flash background color in both interrupts routines, do the flashes appear in correct order and in same frame? btw, there is no need to write anything to CIASDR (Why some examples have it? It has never been needed), setting serial port outmode bit is enough (and is what KS ROM also does) btw2, clear bit #7 of CIABCRB, at least when exiting your code to not confuse KS ROM routines too much. btw3, CIAs are slow to access, reading and writing all TOD registers wastes time, it probably is more optiomal to keep static ALARM value and only reset the TOD every time you need to "start" the timer. |
02 February 2024, 21:18 | #48 |
This cat is no more
Join Date: Dec 2004
Location: FRANCE
Age: 52
Posts: 8,411
|
interrupt 6 can't be delayed by other ones as it has highest priority. But if you're using move #$2700,SR each time you enter in a VBLANK that could delay (but not mask) cia 6. If you clear interrupt request with 7FFF and not $20 or $10 (relevant interrupt) then you could clear another interrupt request (but CIAs would keep interrupting so it doesn't apply here)
Color flashes are a good method, Toni is right (as always) |
05 February 2024, 00:06 | #49 |
Registered User
Join Date: Oct 2023
Location: London, UK
Posts: 124
|
Thanks for your responses. For the keyboard handling, in the end I studied the WHDLoad code and wrote a version based off that.
It's far simpler than what I had before, and works perfectly on hardware. I didn't get to the bottom of where the previous implementation was failing on hardware. I did try modifying the timing values, but to no avail. Anyway, here's the working code based off of WHDLoad's Keyboard.s Code:
move.l #KeyboardInterrupt,IRQ2(a0) move.w #(INTF_SETCLR|INTF_INTEN|INTF_PORTS|INTF_VERTB),INTENA(a5) ... SetupKeyboard: move.b #142,(CIAATALO) ; init timer-a (~200 µs) sf (CIAATAHI) move.b #$7f,(CIAAICR) ; allow interrupts from the keyboard & timer-a move.b #(CIAICRF_SETCLR|CIAICRF_SP|CIAICRF_TA),(CIAAICR) tst.b (CIAAICR) ; clear all ciaa-interrupt requests and.b #~(CIACRAF_SPMODE),(CIAACRA) ; set input mode move #INTF_PORTS,(CHIPBASE+INTREQ) ; clear ports interrupt rts KeyboardInterrupt: move.l d0,-(a7) btst #INTB_PORTS,(CHIPBASE+INTREQR+1) ; check if keyboard has caused interrupt beq.b .end move.b CIAAICR,d0 ; timer-a btst #CIAICRB_TA,d0 beq .cont sf CIAACRA ; set input mode (handshake end) bra.b .end .cont: btst #CIAICRB_SP,d0 beq.b .end move.b CIAASDR,d0 ; read keycode move.b #CIACRAF_SPMODE|CIACRAF_LOAD|CIACRAF_RUNMODE|CIACRAF_START,(CIAACRA) ; set output mode (handshake start) not.b d0 ror.b #1,d0 ; calculate rawkeycode move.b d0,KeyCode ; Store new key code .end: move.w #INTF_PORTS,(INTREQ+CHIPBASE) tst.w (INTREQR+CHIPBASE) ; to avoid timing problems on very fast machines we do another custom register access move.l (a7)+,d0 rte Now that I have a working keyboard on hardware, I can start timing various blocks of code. |
08 February 2024, 22:39 | #50 |
Registered User
Join Date: Oct 2023
Location: London, UK
Posts: 124
|
In a somewhat unexciting moment, the stats are in. See attachment.
Left Monitor: Real Amiga Right Monitor: WinUAE Big number bad. Small number good. As you can see my road routine kicks ass because it's highly optimized. The sprite routine provides enough time to make a cuppa whilst it renders. The C2P is slower than I expected, although I dunno what I was expecting. Inevitably, the sprite routine is mega slow because it does so much heavy lifting. And because I haven't started the second round of optimizations yet. The good thing is that I can now feel good, slowly shaving numbers of these values as I improve the routines. I can also tweak UAE settings to more closely match performance on hardware potentially. Other than that, I fixed the sprite layout bug that was annoyingly me tremendously. And got a few later stages of the game rendering for fun. There won't be anything particularly sexy to report for a while other than numbers decreasing. |
09 February 2024, 00:07 | #51 |
Registered User
Join Date: Apr 2010
Location: UK
Posts: 62
|
> Other than that, I fixed the sprite layout bug that was annoyingly me tremendously.
You can't say that and not tell us what it was!?! I look forward to seeing a series of decreasing numbers. |
09 February 2024, 00:10 | #52 |
Registered User
Join Date: Oct 2023
Location: London, UK
Posts: 124
|
As expected, a totally ridiculous bug of my own making. I wrote a routine that assumed an address register was previously set and it wasn't. Once found, very obvious. But there were approximately 100 obvious places to look before I found that one! Also the routine kind of half worked even though it was writing to the wrong area of memory.
|
09 February 2024, 02:14 | #53 |
Retro Freak
Join Date: Nov 2001
Location: Slovenia
Age: 51
Posts: 1,702
|
To get as close to real Amiga timings you need to tick both Cycle Exact boxes in the chipset tab on winuae. Without that winuae in AGA mode will fly compared to real Amiga, regardless of the accelerator.
|
09 February 2024, 08:51 | #54 |
Registered User
Join Date: Oct 2023
Location: London, UK
Posts: 124
|
I'm using those settings already on WinUAE. I imagine it's more a case of differences in FastRam timings. It's not like UAE can truly understand every combination of accelerator card that's out there. Either way it's not a problem, I just don't want to be lulled into a false sense of speed by not continuously testing on hardware.
|
09 February 2024, 11:19 | #55 |
Registered User
Join Date: Nov 2015
Location: Italy
Posts: 193
|
I wonder how racing games like Outrun would look if they used a Stardust 3d tunnel like fixed perspective + some scrolling/panning to create non-fixed-perspective illusion. Would this be hard to hack into cannonball engine just to see how it looks (basically assume ferrari is always in the middle of the "scene" horizontally and then pan towards were it really is)?
With that theoretically the whole background scenery / the track could be pre calculated or even be only some kind of pre-rendered animation. And you'd only have to handle the dynamic objects (cars) per frame. Yeah, there's still the thing with clipping (theoretically a car sprite could end up between scenery objects like trees) but maybe you could get aways with only some very simple fast/clipping were it's hard to notice if every once and then it is not 100 % correct. And/or have some scenery objects (like bushes between roads) handled like dynamic objects. Maybe a bit more problematic for Outrun (two roads -> horizontally large "scenes" -> panning) than less complex racing games. |
09 February 2024, 11:50 | #56 |
Registered User
Join Date: Jul 2018
Location: Scotland
Posts: 854
|
well this is shaping up real nicely, so smooth.
is this project in any way in conjunction with the agermose AGA outrun port that is also ongoing? just wondering, not seen it mentioned. |
09 February 2024, 12:09 | #57 |
Senior Member
Join Date: Jun 2001
Location: Germany
Posts: 1,667
|
|
09 February 2024, 12:26 | #58 |
Registered User
Join Date: Nov 2015
Location: Italy
Posts: 193
|
|
09 February 2024, 16:09 | #59 |
Registered User
Join Date: Feb 2008
Location: Northampton/UK
Posts: 537
|
I've often thought you could render out track frames from wipeout and render them as an animation using this technique.
|
10 February 2024, 08:40 | #60 | |
Registered User
Join Date: Nov 2015
Location: Italy
Posts: 193
|
Quote:
Something like Wipeout in theory may be better suited for this technique than Outrun (large required horizontal panning/shifting when there are two roads may end up being too much to look good if perspective is fixed), but otoh it seems in Wipeout there are also jumps/vertical movement, so that may not be good too. |
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Outrun AGA | agermose | project.Amiga Game Factory | 417 | 17 July 2024 19:08 |
Better Outrun port for Amiga | tekopaa | Retrogaming General Discussion | 399 | 14 April 2022 17:56 |
Outrun adfs | macce2 | request.Old Rare Games | 3 | 18 April 2021 21:22 |
would you like to have an Outrun like for Aga? | sandruzzo | Retrogaming General Discussion | 50 | 30 January 2013 12:03 |
Aweb: New APL 3.5Beta AOS4 PPC code + Milestone: KHTML porting started | Paul | News | 0 | 05 November 2004 11:21 |
|
|