Jump to content
  • entries
    16
  • comments
    28
  • views
    31,389

Faster Initialization

Omegamatrix

1,297 views

Most (not all) Atari 2600 games use an initialization routine that clears the RIOT ram and sets the TIA registers to a known state. The most optimal code to do this is:

    cld    ldx    #0    txa.loopClear:    dex    txs    pha    bne    .loopClear

Andrew Davie wrote that, I think. Brilliant piece of code really. :) Clears everything and leaves A=0, X=0, and Stack Pointer = $FF. Takes only nine bytes too!

 

 

Sometimes when you are writing a game you switch banks to an entirely new kernel (say from a title screen to the game screen), and you need to run a clear routine once again. You can run into a bit of wall because the code takes 36 scanlines and 22 cycles to execute. You most likely will spend too much time clearing and have a frame that bounces on your TV because it took too many scanlines.

 

 

To claw some cycles back I wrote this routine. It is an attempt to balance the cost of extra bytes vs how much time can be gained.

    cld    lda    #0    ldx    #CXCLR    txs    ldx    #28.loopClearFaster:    pha    pha    pha    pha    pha    pha    dex    bpl    .loopClearFaster    txs

This only takes 10 scanlines and 48 cycles. That's pretty good performance for just another nine bytes. You can tweak it more by adding a PHA or taking one away. The six PHA's seemed the most balanced routine for cost vs performance to me. What I also really love about this routine is that it ends with A=0, X=$FF, and SP = $FF. Having X=$FF after the routine is useful most of the time. :) There always seems to be a lot of ram locations that need to get populated with $FF such as high pointers to the $FF page.

 

 

If you are using the nine byte routine then another trick to set a few registers to $FF is to simply DEC them since you know they are already set to zero. When doing a lot of storing you might be better off with a loop, or a loop with a look up table. If it is just a few then try DEC as it saves a byte over using TSX (SP=$FF at this time) and STX.

    cld    ldx    #0    txa.loopClear:    dex    txs    pha    bne    .loopClear        dec    playerGfxPtrHi   ; 0 ---> $FF    dec    enemyGfxPtrHi    ; 0 ---> $FF

Most people will have noticed I didn't use a SEI. That is optional for the 2600 as there is not interrupt line. However, I'm not sure about all the clone systems that were made. Some might have real 6502's in there. At one byte it doesn't really kill a person to include it. If you don't care, then one can also make use of the interupt flag as a 1 bit storage container. I did so in routine for a Sega Genesis Controller conversion of Starmaster.

 

 

  • Like 1


2 Comments


Recommended Comments

The second line of these clears should be "ldx #0" :)

Otherwise you're initialising everything with unknown!!

Share this comment


Link to comment

The second line of these clears should be "ldx #0" :)

Otherwise you're initialising everything with unknown!!

Quite right, and fixed!! :)

Share this comment


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...