Jump to content
IGNORED

Troubleshooting the DPC+ stack


Sprybug

Recommended Posts

Hey Guys, I'm trying to get my new Zed demo done in time for PRGE, but am running into a weird problem that I can't track down. One of the enemies values is doing weird things. I do a lot of push and pulling of the DPC+ stack because there are so many enemies on the screen at one time. I've been through the code several times and can not for the life of me figure out what's going on. Was using Stella to see if I could use the debugger to look at the DPC+ stack, where I push and pull a lot of these values to see if I could see what's going on, but I have no idea where the DPC+ stack is in the debugger, or even if it is available for me to look at in debug mode. Any help would be greatly appreciated!

  • Like 1
Link to comment
Share on other sites

Look in the symbol list for USERSTACK to see where it's located. The symbol list has the same filename as your .bas program but with .sym added as the extension. Once you know the location you'll be able to view it on the Cartridge RAM. You might also find the Get/SetValue functions I wrote up to be useful for storing/retrieving values w/out using the stack.

 

post-3056-0-24556600-1504567844_thumb.png

  • Like 1
Link to comment
Share on other sites

based on this:

echo "DPC free RAM=",($1000-(USERSTACK&$0FFF))d


specifically the &$0FFF, ignore the first digit and treat the value as $0DA5. The RAM display shows a page at a time, so scroll down (arrow) until the page [1] shows 0Dxx. The last two digits of the address correspond to the row[2] and column[3], so $0DA5 is where the green 00 is located.

 

Normally a stack goes backwards, so as you push values into it they'd be stored into DA5, DA4, DA3, etc. It's possible the bB stack implementation goes the other direction, if so they'll go into DA5, DA6, DA7, etc. You'll have to do some experiments to see how its implemented.

post-3056-0-13457800-1504571839_thumb.png

Link to comment
Share on other sites

Got it. I figured it went something like that, but I just needed some clarification. This definitely helps me out trying to troubleshoot. Yeah, the DPC+ in Batari is a bit tricky because of the reverse order when you pull things, which is why I want to look at how it's doing something to see if it's something I am doing wrong, although the funny thing is, I actually had it working at one point until I changed how it initialized fired missiles from the enemies. It uses Stack Space to store some information about the missile, like momentum, direction, etc. And it did work until I made that change. Funny thing, is it seems to work fine on enemy 0 that uses Player1 and Stack 255, but for some reason Player 2 and Stack 250 isn't returning the 1 value of the enemy type like it's supposed to, yet Player1 enemy type is, so it's something for me to work out. That change I made messed it up, but reviewing it over and over and over again, I can't seem to figure out what I did to mess it up. It's so bizarre to me. I've looked through everything several times. Hopefully, this will help me try to troubleshoot it.

  • Like 1
Link to comment
Share on other sites

To verify, yes it does ran backwards from the spot, so 0DA5,0DA4,0DA3,etc. I can see the pattern and see just how wrong the values are in there. Looking at my code, I can not for the life of me figure out why it's doing it though. I made a test routine, that once it loads all the sprite information that I want to those stack locations, I can use the score to show me what the first value is of that stack read, and it's just...wrong. I'm using it like I'm supposed to. For example I have a data table full of the enemy information. When loading up the level it reads the table and assigns the values to variables for each one of the enemies/sprites. After it loads the info, it then runs an ON K GOSUB routine to the proper initialization routine for each enemy. It goes to the right one because I can see them set up properly on screen, so I know it's reading the data table correctly. In those routines, I also set up a bit. Enemy 0 will have b{0} set as 1 so it knows that player1 is in use and should run its routines. Same goes for enemy 1 that uses b{1} and all the way up to {7}. That's all correct, but once I go and write the values, including K to the stack, things mess up and I have no idea why. I run my test after it loads and I use the score to check each K value that it reads from the stack and they are just wrong. I'm doing exactly what you are supposed to be doing too. For the writes, you set the stack up at its highest point for example on enemy 0, it's Stack 255 then next line is push k e m s

When I read, I use Stack 251 next line pull k e m s

But something is going wrong.

I'll put in some of my code in this initialization process:

ReadO2
 if !x then var4=OSLG[c]
 if x=1 then var4=OSLB[c]
 if x=2 then var4=OSLR[c]
 c=c+1
 if !x then var5=OSLG[c]
 if x=1 then var5=OSLB[c]
 if x=2 then var5=OSLR[c]
 c=c+1
 if !x then k=OSLG[c]
 if x=1 then k=OSLB[c]
 if x=2 then k=OSLR[c]
 e=3
 c=c+1
 m=0:s=0
 on k gosub Init0 Init1 Init2 Init3 Init4 Init5 Init6 Init7 Init7
 if c<z-3 then goto ReadO2
 gosub test bank5
 var4=SwitchData[y]
 y=y+1
 var5=SwitchData[y]
 y=y+1
 var6=SwitchData[y]
 if var6 then NUSIZ9{3}=1
 player9x=(var4*4)+8 
 player9y=var5*8
 gosub Switch_Color bank6
 gosub Switch_Off bank6
 a=0:c=0
 drawscreen
 return otherbank

Init0
 player1x=(var4*4)+8 
 player1y=var5*8
 b{0}=1
 gosub Enemy0Color bank6:gosub Standard1 bank6
 stack 255
 push k e m s
 return thisbank
Init1
 player2x=(var4*4)+8 
 player2y=var5*8
 b{1}=1
 gosub Enemy1Color bank6:gosub Tosser1 bank6
 stack 250
 push k e m s
 return thisbank
Init2
 player3x=(var4*4)+8 
 player3y=var5*8
 b{2}=1
 gosub Enemy2Color bank6:gosub Archer1 bank6
 stack 245
 push k e m s
 return thisbank

And of course it goes all the way down to Init7, but it would be redundant for me to put it all in.

BTW, when it is gosubing to bank6 there, those are only sprite color and sprite graphic tables its loading. Nothing else.

As for the reads when running the enemy routine. Let's take Enemy Player2 for example:

ObjectP2
 x=1:gosub ObjectR bank6
 NUSIZ2{3}=0
 if player0y>player2y && (player0x-32)<player2x && (player0x+32)>player2x && !m{1} then m{1}=1:s=0
 if player0x<player2x then NUSIZ2{3}=1
 if a<8 && s<8 then gosub Tosser1 bank6 else gosub Tosser2 bank6
 if !m{1} then OP2R
 s=s+1
 z=0
 if player0x>player2x then m{0}=0 else NUSIZ2{3}=1:z{2}=1:m{0}=1
 if s=8 then x=player2x:y=player2y:gosub InitEnemyFire bank4
 if s=48 then m{1}=0:s=0
OP2R
 x=1:gosub ObjectW bank6
 return thisbank
EB2
 temp2=(y+1)/8
 if m{0} then temp1=(x-15)/4 else temp1=(x-11)/4
 if !pfread(temp1,temp2) then gosub ECD
 goto OP2R

The routines ObjectR and ObjectW are Stack Read routines and Stack Write routines....for example:

ObjectR
 on x goto ObjectR1 ObjectR2 ObjectR3 ObjectR4 ObjectR5 ObjectR6 ObjectR7 ObjectR8 ObjectR8
ObjectR1
 stack 251
 pull k e m s
 return otherbank
 rem goto pullobject
ObjectR2
 stack 246
 pull k e m s
 return otherbank
 rem goto pullobject
ObjectW
 on x goto ObjectW1 ObjectW2 ObjectW3 ObjectW4 ObjectW5 ObjectW6 ObjectW7 ObjectW8 ObjectW8
ObjectW1
 stack 255
 push k e m s
 return otherbank
 rem goto pushobject
ObjectW2
 stack 250
 push k e m s
 return otherbank
 rem goto pushobject

I have no idea what is going on. Funny thing is, that as you see, in the firing routine in the Player2 enemy routine, it uses S as a counter. That magically somehow stay correct because it DOES count up and fire like it's supposed to, meaning that it is storing and reading the S variable correctly, but not the K one. I have no flippin' clue what is going on. I've been spending days on this and have gotten absolutely NOWHERE. It's kinda driving me bonkers.

I know K is not correct because looking in the stack tells me, but when I run the firing initalizing routing of the enemy to fire the missile it depends on reading that K variable from the stack to determine the kind of shot that the enemy is doing, and it ALWAYS picks the wrong one. The Tosser is supposed to shoot an arcing shot, and it never does. Not just that, but any time it uses missile1, the length of the missile is just one pixel instead of 8 pixels long and I'm not doing ANYTHING with those NUSIZ variable other than the 3rd bit that flips a sprite. It's strange, It used to work before I made a big change to my game, but I can't see what went wrong, at all.

If anybody wants to look at my Batari BASIC code, and it's pretty big, let me know.

Edited by Sprybug
  • Like 1
Link to comment
Share on other sites

Maybe a nice addition for a future release is to divide that large 'extra RAM' area into something more manageable and descriptive. Not that I'm volunteering; I already have 10+ issues in Github to work through :)

 

No problem, in fact I FINALLY FIGURED IT OUT. It's interesting how when you go and take your laptop somewhere else and work on something, it changes your focus. I discovered that the stack was being written too correctly, but it was changing to wrong values somewhere in the gameplay. So I took my test routine to show the stack values in my score and put it in a place to see if the values were right or wrong. Every time it was correct, I'd move it further down in the code until it finally showed incorrect values. Once it did that I looked at the code in the area and discovered that an old line of cold still existed that was messing it up. The ObjectR and ObjectW routines were new. However when it came back from ObjectW (Writing) in the enemy 0 routine, it did ANOTHER push k e m s (which was an old line before I did the routines) causing it to do another stack write further down, messing up Enemy 1's values. Once I took that out it behaved properly. Now I have one more issue to try and figure out and it just might be another forum post. For some reason, missile 1 is only 1 pixel wide, where missile 0 is 8 pixels wide like it should be. Haven't figure out why it's doing that yet.

  • Like 1
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...