Jump to content
Sign in to follow this  
Atarius Maximus

DragRace Hack Revisited: Auto-Shift

Recommended Posts

I disassembled Thomas J's automatic shifting hack of Dragster, as I was curious about the change, and wanted to see if I could incorporate it into my DragRace hack. Well, I found his change and it works, although it seems to cause a few graphic glitches in the game. I asked Thomas before posting this, he gave me his permission, and kind of "challenged" me to see if I could fix the graphic glitch. Hmmm....We'll see. :) I know this change makes the game too easy, but it's interesting none the less.

 

To change the normal Dragster bin into the automatic shifting version, make the following change:

 

Change This:

 

LF3E9: CMP    #$20   ;2

      BCC    LF3FF  ;2

      LDA    #$0F   ;2

      STA    $D0,X  ;4

      LDA    #$01   ;2

      STA    $D4,X  ;4

      LDA    #$04   ;2

      STA    $AB,X  ;4

      LDA    #$1A   ;2

      STA    $CE,X  ;4

      LDA    #$00   ;2

LF3FF: STA    $A8,X  ;4

 

To This:

 

LF3E9: CMP    #$20   ;2

      BCC    LF3FF  ;2

      LDA    #$1F   ;2

      LDY    $8D    ;3

      BNE    LF3FB  ;2

      LDY    $CC,X  ;4

      CPY    #$04   ;2

      BCS    LF3FB  ;2

      INC    $CC,X  ;6

LF3FB: LDY    $CC,X  ;4

      NOP           ;2

      NOP           ;2

 

My updated version of DragRace is attached below. Here is the link to my original DragRace Hack thread:

 

http://www.atariage.com/forums/viewtopic.php?t=24190

drauto.zip

Share this post


Link to post
Share on other sites

The original code has 34 cycles being used between those 2 tags. Have you tried moving those 2 NOP instructions a little further north? ;)

 

Also, the Y register is being used in the replacement. Is that OK to use? Is it being thrown out after this code executes? Or is an instruction expecting a value there? You might need to save it (going into the code) and restore it later.

Share this post


Link to post
Share on other sites

PostPosted: Thu Mar 18, 2004 7:47 pm    Post subject:

The original code has 34 cycles being used between those 2 tags. Have you tried moving those 2 NOP instructions a little further north? icon_wink.gif

 

Also, the Y register is being used in the replacement. Is that OK to use? Is it being thrown out after this code executes? Or is an instruction expecting a value there? You might need to save it (going into the code) and restore it later.

 

Thanks for the suggestions, Nukey. I'm going to try and take a look at this later tonight, right now I've got two screaming kids pulling me in two different directions.... Ugh.

Share this post


Link to post
Share on other sites

Ahhhh.. The kids are in bed, I've got some time to myself. I moved the NOP instructions "further north" as you suggested, but their placement didn't seem to make any difference. I suspect it is related to what you mentioned after that, the Y register is probably going to have to be read first then restored. Well, I'm not 100% sure how to go about that, so I guess it's time to get started on the fun part, some trial and error coding. :) How significant is it that the replacment code uses 33 cycles, whereas the original code uses 34?

Share this post


Link to post
Share on other sites

LOL AM....I thought you were sitting on a porch somewhere with NEO drinking a bartles and james discussing the latest hacks you both just came up with!

 

:D

 

:thumbsup:

 

Cheers

Share this post


Link to post
Share on other sites
thought you were sitting on a porch somewhere with NEO drinking a bartles and james discussing the latest hacks you both just came up with!

 

Um, Yeah! That's exactly what we do! :D :D :D

 

post-2143-1079706875.jpg

Share this post


Link to post
Share on other sites

If the program is expecting a specific amount of time to be happening at that point, even 1 cycle will throw things off. Why is Y loaded at the end? Is anything done with that?

Share this post


Link to post
Share on other sites
If the program is expecting a specific amount of time to be happening at that point, even 1 cycle will throw things off.

I figured that was the case, and that could be the root cause of the problem.

 

Why is Y loaded at the end? Is anything done with that?

I'm not exactly sure. I'm probably going to reveal my ignorance if I start talking about what I think is going on in the code. :)

 

Here's what I've written down so far, still working on figuring out exactly what's going on, though:

 

LF3E9: CMP    #$20   ;2   Compare Accumulator

      BCC    LF3FF  ;2     Branch if A is less than or equal to #$20

      LDA    #$1F   ;2   Load A Register 

      LDY    $8D    ;3   Load Y Register

      BNE    LF3FB  ;2     Branch to LF3FB if Y is Not Zero

      LDY    $CC,X  ;4   Load Y (Zero Page)

      CPY    #$04   ;2   Compare Y Register

      BCS    LF3FB  ;2     Branch on Carry Set. If it's a set, the branch is taken. If it's clear, then Increment Memory

      INC    $CC,X  ;6   Increment Memory by 1(?)

LF3FB: LDY    $CC,X  ;4   Load Y (Zero Page)

      NOP           ;2   No Operation (Waste 2 Cycles)

      NOP           ;2   No Operation (Waste 2 Cycles)

 

Here's where my "guessing" comes in, so don't be too hard on me. :) I think that A and Y are being compared because they represent the current revs and the max engine rev. If they aren't equal, Memory is incremented by 1 until they do. When they are equal, the BCS takes you to LF3FB, where Y is loaded again. Why? I don't know. I'm still working on it. ;)

 

AM

 

EDIT: Corrections made to Code comments (Thanks, Nukey Shay).

Share this post


Link to post
Share on other sites

Correction:

 

BNE LF3FB ;2 Branch to LF3FB if A and Y are not equal

 

should be described as...

 

BNE LF3FB ;2 Branch to LF3FB if Y is NOT zero

 

The A register has nothing to do with it...since it's not being compared to Y in any way.

Share this post


Link to post
Share on other sites

Another one:

 

CMP #$20 ;2 Compare Accumulator

BCC LF3FF ;2 Branch on Carry Clear...if the result of the comparison is less than the accumulator(?)

 

 

...

 

 

CMP #$20 ;2 Compare Accumulator to $20 (decimal 32)

BCC LF3FF ;2 Branch if A is less than or equal to #$20

Share this post


Link to post
Share on other sites

Thanks again. If I can figure out exactly what each of these lines of code are actually doing, that will help immensely.

Share this post


Link to post
Share on other sites

No prob. Keep in mind that people often use branching instructions as a replacement for JMP (which takes 3 bytes and uses 3 cycles). An example like...

 

AND #$7F

JMP Nextline

 

...could be trimmed to...

 

AND #$7F

BPL Nextline

 

Nothing to do with your code example above, but useful to keep in mind so that you'll recognise when the program will ALWAYS branch. In this example, the upper bit is trimmed off by the AND instruction (that bit is used to determine if a value is positive or negative). Since the bit is now gone, we can just branch if plus...as long as it's a short distance.

Share this post


Link to post
Share on other sites

No prob. Keep in mind that people often use branching instructions as a replacement for JMP (which takes 3 bytes and uses 3 cycles). An example like...  

 

AND #$7F  

JMP Nextline  

 

...could be trimmed to...  

 

AND #$7F  

BPL Nextline  

 

Wow, very cool, useful info. It makes so much more sense when it's explained like you did, rather than just reading a technical document that explains instructions & syntax.

 

Regarding the code sample itself, what I'm struggling with the most is knowing exactly what the A and Y Registers represent. :? Any Ideas?

Share this post


Link to post
Share on other sites

Impossible to determine from such a small snippet. A is loaded with #$1F (the lower 5 bits turned on)...but then does nothing with that value. Y is also loaded with a new value at the end. Something must be happening with A and Y below that area I'd imagine.

Share this post


Link to post
Share on other sites
Impossible to determine from such a small snippet.

Yeah, I figured that. I'll have to dive a little deeper into the code to really figure this out, which is what I expected.

 

A is loaded with #$1F (the lower 5 bits turned on)...but then does nothing with that value. Y is also loaded with a new value at the end. Something must be happening with A and Y below that area I'd imagine.

Thank you for your comments and your help, I know you're plenty busy with other things. Now it's time to get to work on that new SI Deluxe Explosion sound! ;)

Share this post


Link to post
Share on other sites

I really would like to help, but I absolutely can't remember what I did then. And it would take away a lot of fun, wouldn't it? ;)

 

Anyway, I would suggest looking the fire button code (something with INPT4/5). There the gears are shifted and probably you can recognize some variables there.

Share this post


Link to post
Share on other sites

Thanks for the tip, Thomas. Right now I'm making notes on the code using some 6502 documentation I downloaded. I'm just trying to figure out what everything does, which is pretty difficult for me. It's fun trying to figure it all out though, you're right!

Share this post


Link to post
Share on other sites
Hey, I finally broke 6 seconds on Dragster!  

 

|icon_innocent.gif

 

  :ponder:

 

Seriously...is that a screenshot from a run using the auto-shift hack?

 

What exactly does the hack do...automatically shift gears when the RPMs reach maximum? What happens in 4th gear when RPMs reach maximum?

Share this post


Link to post
Share on other sites
Seriously...is that a screenshot from a run using the auto-shift hack?

 

Yes, that score is from the hacked version. My best time with Dragster using unmodified code is 6.07.

 

What exactly does the hack do...automatically shift gears when the RPMs reach maximum? What happens in 4th gear when RPMs reach maximum?

 

Well, you could download it and try! :D :D

 

Yes, the car automatically shifts when the revs reach maximum. In 4th gear, it revs up to the limit and stay there. You can never blow your engine. To play the game, all you're really doing is holding down the button for the entire race. Not a whole lot of fun, really.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   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...
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...