Jump to content
  • entries
    657
  • comments
    2,692
  • views
    898,625

Frantic reboot?!?


SpiceWare

2,721 views

I was reviewing the source for Frantic this weekend and while I was going over the time-critical kernel loop:

KernelLoop:			;   70
lda #<DS_COLUP0		; 2 72
sta WSYNC		
KernelLoopNoWSYNC:
beq RepositionP0	; 2  2
sta COLUP0		; 3  5 - before 25
lda #<DS_COLUP1		; 2  7
beq RepositionP1	; 2  9
sta COLUP1		; 3 12 - before 25
stx ENAM0		; 3 15 - before 25	
lda #<DS_GRP0		; 2 17
sta GRP0		; 3 20 - before 25
sty ENAM1		; 3 23 - before 25
lda #<DS_PF2L		; 2 25
sta PF2			; 3 28 - before 38
lda #<DS_GRP1		; 2 30 - any
sta GRP1		; 3 33 - any
sty PF0			; 3 36 - PF0R, 28-49
lda #<DS_PF1R		; 2 38
sta PF1			; 3 41 - PF1R, 39-54
lda #<AMPLITUDE		; 2 43 - any
sta AUDV0		; 3 46 - any
lda #<DS_PF2R		; 2 48
sta PF2			; 3 51 - PF2R, 50-65	
ldy DS_PF0R_M1		; 4 55
lda #<DS_PF1L		; 2 57
ldx DS_PF0L_M0		; 4 61 - 0 triggers end-of-kernel
stx PF0			; 3 64 - PF0L, after 55
sta PF1			; 3 67 - PF1L, 66 - 28 	
bne KernelLoop		; 3 70 - 2  69 not taken
jmp KernelDone		; 3 72	
 

 

I noticed a few things that made me go hmmm :ponder:

 

I did a bit of rewrite and came up with this:

KernelLoopNoWSYNC:
       ; at this point the registers hold the following:
       ; A - graphics for player 0
       ; X - enable for missile 0
       ; Y - enable for missile 1 & PF0 for right side of screen
       ; PF0 and PF1 have already been updated for left side of room
       ; GRP1 (on VDEL) has been preloaded with player 1 graphics
       sta GRP0                ; 3  3 - before 25 - updates GRP1 too via VDEL
       lda #<DS_COLUP0         ; 2  5
       sta COLUP0              ; 3  8 - before 25
       lda #<DS_COLUP1         ; 2 10
       sta COLUP1              ; 3 13 - before 25
       stx ENAM0               ; 3 16 - before 25
       sty ENAM1               ; 3 19 - before 25
       lda #<DS_EVENT_BL       ; 2 21 - bit 7 triggers kernel event
       sta ENABL               ; 3 24 - before 25
       bmi KernelEvent         ; 2 26 - 3 27 if taken
       lda #<DS_PF2L           ; 2 28
       sta PF2                 ; 3 31 - PF2L, before 38
       sty PF0                 ; 3 34 - PF0R, 28-49
       ldy DS_PF0R_M1          ; 4 38 - any after sty PF0, loads for next line 
       lda #<DS_PF1R           ; 2 40
       sta PF1                 ; 3 43 - PF1R, 39-54
       lda #<AMPLITUDE         ; 2 45 - any
       sta AUDV0               ; 3 48 - any
       lda #<DS_PF2R           ; 2 50
       sta PF2                 ; 3 53 - PF2R, 50-65    
       ldx DS_PF0L_M0          ; 4 57 - 0 triggers end-of-kernel
       stx PF0                 ; 3 60 - PF0L, after 55
       lda #<DS_GRP1           ; 2 62
       sta GRP1                ; 3 65 - any, on VDEL
       lda #<DS_PF1L           ; 2 67
       sta.w PF1               ; 4 71 - PF1L, 66 - 28
       lda #<DS_GRP0           ; 2 73
       jmp KernelLoopNoWSYNC   ; 3 76/0

KernelEvent:                  ; 3 27
       ; Y has PF0 for right of screen, needs to be written 28-49 if not end-of-kernel
       ; A holds the Kernel Event 
       ; IF   A{6} = 1 then reposition Player 0
       ; ELIF A{5} = 1 then reposition Player 1
       ; ELSE exit display kernel loop
       ;
       ; have to update PF2 before figuring out which Kernel Event, otherwise
       ; PF2 is updated too late in the Reposition Player 1 routines
       ldx DS_PF2L             ; 4 31 
       stx PF2                 ; 3 34 - PF2L, before 38
       ASL                     ; 2 36
       BPL CheckRepo1          ; 2 38
       ; start of Reposition Player 0 routine

CheckRepo1:                     ; 3 39
       ASL                     ; 2 41
       BPL KernelDone          ; 2 43
       ; start of Reposition Player 1 routine

KernelDone:                     ; 3 44
       ; show lives/score
 

 

Namely what I noticed in the original routine was a WSYNC and 3 conditional branches, 2 of which occur during the premium horizontal retrace time (the first 22 cycles of the line).

 

The WSYNC is easy to get rid of, but eliminating it wouldn't buy enough time for anything useful. The 3 branches are for the reposition of player 0, reposition of player 1 and end-of-kernel. I wondered if I could combine the 3 conditional branches and free up enough time to enable the ball. The ball needs to be set during the horizontal retrace to prevent mid-screen shearing.

 

To do this I utilized an additional datastream, DF4DATA, that I aliased as DS_EVENT_BL (to make reading the code easier). The bits (76543210) in the datastream bytes are:

7 - event triggered

6 - reposition player 0 event

5 - reposition player 1 event

1 - ball enable flag

 

The end-of-kernel event is triggered with bit 7 on, and bits 5 & 6 both off.

blogentry-3056-0-24885600-1331083588_thumb.png

ball = dotted blue line, missile 0 = green/white lines, missile 1 = red lines

 

Next is to review and rewrite the reposition routines. There's a chance timing won't work out due to the extra cycles needed for controlling the ball, but if it does then Frantic's going to be rebooted so I can show 2 humanoid shots and 4 robot shots!

 

ROM

frantic_20120306.bin

 

Source

Frantic20120306.zip

 

 

I also did some minor updates to my jEdit mode file for Atari programming:

assembly-6502.xml.zip

JEDIT NAVIGATION
<PREVIOUS> <INDEX> <NEXT>

  • Like 1

2 Comments


Recommended Comments

thanks!

 

I've not started revising them (the reposition routines) yet, but in thinking over the changes I'm fairly sure it'll be doable. I suspect it will take up to twice as many scanlines to reposition the players. Currently player 0 takes 2 while player 1 takes 3.

 

I also suspect I can eliminate one of the 11 reposition kernels as I don't need the players to cover the full 160 pixel range. If so, that could help offset the increased ROM required by the new reposition routines.

 

If this all pans out then I'll probably also look at shrinking the sprites by 2 rows to help offset the increased scanlines to reposition the players. I also suspect it'll make it play better by increasing the space above/below the player in relation to the walls. It would also speed up a number of routines (copying sprite data into the buffer, collision checks, etc) as well as save some ROM as each graphic image will take less room.

Link to comment
Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...