Jump to content
IGNORED

gosub bug in bB?


Fort Apocalypse

Recommended Posts

Ok... been trying to figure out bugs in my game today, and my first bug find was a bug in the code that I had written to try to reproduce bugs! :)

 

However, I did find what looks to be a bug in subroutines in Batari Basic. Please try out the attached code and hit the select button 4 times. On the 4th time, it turns the pfscorecolor a color I didn't set it to and freezes.

 

Happens in Stella 2.3.5 in Win XP.

 

Thanks in advance...

 

gosub_bug.basgosub_bug.bas.bin

Link to comment
Share on other sites

However, I did find what looks to be a bug in subroutines in Batari Basic. Please try out the attached code and hit the select button 4 times. On the 4th time, it turns the pfscorecolor a color I didn't set it to and freezes.

It's caused by your use of the "pop" command. You're popping the last return address off of the stack, which is okay as long as you're trying to cancel the last "gosub." But then you're jumping too far out of the nested "gosub" calls:

 

(1) in selectloop -- gosub plyr0spr -- then return -- so this one's kosher.

(2) still in selectloop -- if something then gosub testgosub (else goto selectloop).

(3) in testgosub -- gosub testgosub2.

(4) in testgosub2 -- gosub testgosub3.

(5) in testgosub3 -- if something then pop, then goto selectloop. <--- BAAAHHHMMMPP!

(6) (else) still in testgosub3 -- return to testgosub2.

(7) back in testgosub2 -- return to testgosub.

(8) back in testgosub -- return to selectloop.

(9) back in selectloop -- goto selectloop.

 

When you get to (5), you've made three "gosub" calls without a single "return." If the "if" is taken and you "pop" the last return address, you cancel the third "gosub" (4), but that still leaves the two return addresses from (3) and (2). So if you jump back to (1) and start the whole process over, you've left two return addresses on the stack. As long as you don't take that "if" in (5), you keep doing a "return" to balance/complete each "gosub." But each time you take that "if" in (5), you're leaving two more return addresses on the stack. So after you take that "if" a few times, there are too many return addresses on the stack, and the stack gets pushed down into where the variables are in the upper portion of zero-page RAM, thus resulting in the unexpected color change and freeze-up.

 

Note that the "pfscorecolor" variable is at $F4, so the return addresses on the stack would be as follows:

 

$F4 = pfscorecolor

$F4/$F5 = return address

$F6/$F7 = return address

$F8/$F9 = return address

$FA/$FB = return address

$FC/$FD = return address

$FE/$FF = return address

 

In other words, once you hit the point where the sixth return address gets pushed onto the stack, the return address will overwrite the value in "pfscorecolor," causing the color change. That by itself is okay, since you aren't making any further changes to "pfscorecolor" after having set it up in the initialization portion of your code-- it basically amounts to nothing more than a display issue.

 

However, "pfscore1" is at $F2, and "pfscore2" is at $F3, so the very next "gosub" after that-- which pushes a seventh return address onto the stack-- will wipe out "pfscore1" and "pfscore2." Again, this isn't a fatal error-- it will just mess up the values in those two variables. Unfortunately, once you get back into "selectloop," you're setting "pfscore1" and "pfscore2" again, which is destroying the return address that had gotten pushed there. So when the program tries to use that address to "return" from the "gosub," it ends up going to address $A8A8, which is the same as $08A8, which is the same as $00A8, which is part of the zero-page RAM-- in particular, it's one of the bytes in the playfield RAM, the first 8 pixels of pfrow 1, to be exact. There's no executable code there-- in fact, due to your playfield design, there will usually be a $00 there, which will bring the 6507 to a screeching halt. :)

 

The solution is very simple-- "pop" three times on the ceiling if you... uh, I mean, "pop" three times instead of just once before you "goto selectloop," so you'll remove all three return addresses from the stack before you start the whole process over again.

 

Michael

Edited by SeaGtGruff
Link to comment
Share on other sites

Ok... been trying to figure out bugs in my game today, and my first bug find was a bug in the code that I had written to try to reproduce bugs! :)

 

However, I did find what looks to be a bug in subroutines in Batari Basic. Please try out the attached code and hit the select button 4 times. On the 4th time, it turns the pfscorecolor a color I didn't set it to and freezes.

 

Happens in Stella 2.3.5 in Win XP.

 

Thanks in advance...

 

gosub_bug.basgosub_bug.bas.bin

The problem is that when you issue the pop command, your gosubs are three levels deep, and pop only brings you up one level. Change the line to " if !g{0} then pop : pop : pop : goto selectloop" and that should fix it.

 

EDIT: Thanks, Michael... I'm a little slow on the draw...

Edited by batari
Link to comment
Share on other sites

EDIT: Thanks, Michael... I'm a little slow on the draw...

Not really, it's the other way around. We both posted at the same time (1:40), but I spent 20 minutes writing my post. So you saw the question by Fort Apocalypse, whipped out your gun, and fired off the correct answer. But meanwhile, 20 minutes before that, I saw the question, eased my gun out of its holster (careful, I might have forgotten to put on the safety), checked to be sure the safety was on, looked down the barrel to see if there was any dust in there, blew into it just to be sure, fumbled a bullet out of my pocket, dropped it in the dirt, put my gun back into its holster (can't try to hold onto too many things at once), picked up the fallen bullet, got my handkerchief out of my pocket, carefully wiped the dirt off the bullet until it was shiny again (ooh, sparkly!), noticed my reflection in the bullet (darn, how long has that glob of mustard been on my face?), wiped my face, put my handkerchief back into my pocket, eased my gun out of its holster again, opened up the spinny-around-thingy that the bullets go into (what do they call that again?), slid the bullet in, closed it up, realized that if there hadn't been a bullet in the gun to begin with then I didn't need to have worried about whether or not the safety was on, took the safety off, looked into the barrel again to make sure it was still dust-free, realized I was looking down the barrel of a loaded gun with the safety off (oops!), carefully pointed the gun away from my face (whew!), put the safety back on, looked back into the barrel again (never did finish looking for that pesky dust molecule), blew into the barrel, saw that I accidentally blew a drop of spit into the barrel, pulled out my handkerchief again, wiped the spit out of the barrel, put away my handkerchief, took a nice comfortable squatting position behind a rock, adjusted my hat to keep the sun out of my eyes, took careful aim, pulled the trigger, wondered why nothing happened (oh yeah, I put the safety back on), took the safety off, took careful aim (again), pulled the trigger, and hit the mark-- a fraction of a second before your bullet. :ponder:

 

Michael

Link to comment
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.
Note: Your post will require moderator approval before it will be visible.

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...
  • Recently Browsing   0 members

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