English Amiga Board


Go Back   English Amiga Board > Coders > Coders. General

 
 
Thread Tools
Old 02 February 2024, 15:41   #41
reassembler
Registered User
 
reassembler's Avatar
 
Join Date: Oct 2023
Location: London, UK
Posts: 116
Quote:
Originally Posted by jotd View Post
If you share that part of the code I may be able to help you out.
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
Quote:
Originally Posted by jotd View Post
That's very difficult to handle that in a smart way, and a lot of pixels are drawn then overwritten... Unless you perform a ton of horrible computations to handle clipping between bobs (argh....)
Tell me about it. Also OutRun draws back to front (i.e. furthest away stuff first) as you'd kind of expect the original programmers to do, given they had some amazing sprite hardware at their disposal!
reassembler is offline  
Old 02 February 2024, 16:06   #42
paraj
Registered User
 
paraj's Avatar
 
Join Date: Feb 2017
Location: Denmark
Posts: 1,159
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).
paraj is offline  
Old 02 February 2024, 16:20   #43
reassembler
Registered User
 
reassembler's Avatar
 
Join Date: Oct 2023
Location: London, UK
Posts: 116
Quote:
Originally Posted by paraj View Post
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).
If you mean, do I have my own VBlank routine running, then yes I do. It doesn't do much at the moment beyond updating the palette caching I mentioned (i.e. it updates colour registers based on what the main loop code previously queued).

Quote:
Originally Posted by paraj View Post
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).
System is off, so I'll use the CIA timer. It looks pretty straightforward.
reassembler is offline  
Old 02 February 2024, 17:32   #44
jotd
This cat is no more
 
jotd's Avatar
 
Join Date: Dec 2004
Location: FRANCE
Age: 52
Posts: 8,320
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:

Tell me about it. Also OutRun draws back to front (i.e. furthest away stuff first) as you'd kind of expect the original programmers to do, given they had some amazing sprite hardware at their disposal!
They had hardware sprite & zooming. Not the same league... Even the guys at Atari complained of the lack of this hardware when they designed Road Wars
jotd is offline  
Old 02 February 2024, 17:45   #45
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 55
Posts: 2,017
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.
Don_Adan is offline  
Old 02 February 2024, 18:09   #46
reassembler
Registered User
 
reassembler's Avatar
 
Join Date: Oct 2023
Location: London, UK
Posts: 116
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!!
reassembler is offline  
Old 02 February 2024, 20:05   #47
Toni Wilen
WinUAE developer
 
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,536
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.
Toni Wilen is offline  
Old 02 February 2024, 21:18   #48
jotd
This cat is no more
 
jotd's Avatar
 
Join Date: Dec 2004
Location: FRANCE
Age: 52
Posts: 8,320
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)
jotd is offline  
Old 05 February 2024, 00:06   #49
reassembler
Registered User
 
reassembler's Avatar
 
Join Date: Oct 2023
Location: London, UK
Posts: 116
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
Other than that I've been doing some general house-keeping. Removing the massive INCBINs for the sprites and other graphics - dynamically allocating memory and loading them from disk instead. The binary is now a manageable size.

Now that I have a working keyboard on hardware, I can start timing various blocks of code.
reassembler is offline  
Old 08 February 2024, 22:39   #50
reassembler
Registered User
 
reassembler's Avatar
 
Join Date: Oct 2023
Location: London, UK
Posts: 116
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.
Attached Thumbnails
Click image for larger version

Name:	PXL_20240208_212953215.jpg
Views:	280
Size:	990.0 KB
ID:	81592  
reassembler is offline  
Old 09 February 2024, 00:07   #51
gingerbeardman
Registered User
 
gingerbeardman's Avatar
 
Join Date: Apr 2010
Location: UK
Posts: 61
> 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.
gingerbeardman is offline  
Old 09 February 2024, 00:10   #52
reassembler
Registered User
 
reassembler's Avatar
 
Join Date: Oct 2023
Location: London, UK
Posts: 116
Quote:
Originally Posted by gingerbeardman View Post
> 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!?!
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.
reassembler is offline  
Old 09 February 2024, 02:14   #53
tomcat666
Retro Freak
 
tomcat666's Avatar
 
Join Date: Nov 2001
Location: Slovenia
Age: 51
Posts: 1,654
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.
tomcat666 is offline  
Old 09 February 2024, 08:51   #54
reassembler
Registered User
 
reassembler's Avatar
 
Join Date: Oct 2023
Location: London, UK
Posts: 116
Quote:
Originally Posted by tomcat666 View Post
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.
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.
reassembler is offline  
Old 09 February 2024, 11:19   #55
aros-sg
Registered User
 
Join Date: Nov 2015
Location: Italy
Posts: 191
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.
aros-sg is offline  
Old 09 February 2024, 11:50   #56
acidbottle
Registered User
 
acidbottle's Avatar
 
Join Date: Jul 2018
Location: Scotland
Posts: 837
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.
acidbottle is offline  
Old 09 February 2024, 12:09   #57
derSammler
Senior Member
 
Join Date: Jun 2001
Location: Germany
Posts: 1,659
Quote:
Originally Posted by aros-sg View Post
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.
Like Mega Race, more or less.
derSammler is offline  
Old 09 February 2024, 12:26   #58
aros-sg
Registered User
 
Join Date: Nov 2015
Location: Italy
Posts: 191
Quote:
Originally Posted by derSammler View Post
Like Mega Race, more or less.

From videos on YouTube it seems that game misses crucial horizontal scrolling/panning.
aros-sg is offline  
Old 09 February 2024, 16:09   #59
khph_re
Registered User
 
Join Date: Feb 2008
Location: Northampton/UK
Posts: 528
Quote:
Originally Posted by aros-sg View Post
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.
I've often thought you could render out track frames from wipeout and render them as an animation using this technique.
khph_re is offline  
Old 10 February 2024, 08:40   #60
aros-sg
Registered User
 
Join Date: Nov 2015
Location: Italy
Posts: 191
Quote:
Originally Posted by khph_re View Post
I've often thought you could render out track frames from wipeout and render them as an animation using this technique.

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.
aros-sg is offline  
 


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 342 Today 00:44
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

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 12:32.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.10707 seconds with 14 queries