Jump to content
IGNORED

jzIntv Error Messages/Halts/Exception Handling


PuzZLeR

Recommended Posts

I feel maybe a thread on why your game crashes should be addressed, especially when jzIntv gives some clue. Hopefully any others searching and landing here, may find my issue, or any issue they wish to add here, helpful. Not sure exactly what does this, as it could be memory, data size, ROM segments, or even the epilogue and prologue files, etc,

 

For example, what do these mean?

HALT! PC=0001 Instr =   44670445 MS =  4306602950
HALT! PC=0001 Instr =   25051447 MS =  2420394193

Or, better yet:

CPU off in the weeds @ PC == 0400, w = ffff     0] Snd:[  0.04%  4  1.872]
instruction count: 38178281

Note: one such message was addressed here:

http://atariage.com/forums/topic/247276-intybasic-using-print-at-for-background-images/

for the following:

HALT! PC=7004 Instr =         78 MS =         62
Link to comment
Share on other sites

Ok, first a question: Are you writing a new game, or are you trying to get an existing game to function that isn't functioning? Since you asked here in the programming forum, I'll assume you're writing a new game for now.

 

All four of the messages you quoted above mean essentially the same thing: jzIntv detected that your program either jumped into non-executable space (the first two indicate you're trying to execute from location $0001, which is the STIC's registers), or it tried to execute something that didn't look like a valid opcode (the "off in the weeds", where it fetched the value $FFFF from location $0400 and tried to execute it, but $FFFF isn't a valid opcode.)

 

 

Have you taken a look at the debugger tutorial here? http://wiki.intellivision.us/index.php?title=Introducing_jzIntv%27s_Debugger

 

I wrote it a long while ago, and while it's pretty basic, it will get you started.

 

Also, if you run in the debugger, you can turn on register history with the 'h' command. When your game crashes, jzintv will write out a file called "dump.hst" with a history of the last ~65,000 instruction that ran leading up to your crash. That's often helpful for figuring out where you crashed.

 

 

If you're coding in IntyBASIC, I believe the SDK has a run-in-debugger mode that may be useful. (I haven't tried it, myself.) Also, have a look at the listing file generated by the assembler. If the assembler put any code in the $7000 - $7FFF range, that's a likely source of your issues.

  • Like 1
Link to comment
Share on other sites

I can tell you from much experience that "off in the weeds" means a serious problem with your flow control. You've not closed a loop properly, or you've done something like recursively call the same PROC over and over, or something equally horrible. You usually slap your head when you figure out what you did, because these things are painfully obvious once you spot them. I don't bother with a debugger, I just follow through and see where the code starts to go funky.

 

Mixing and interlining GOTOs and GOSUBs is a great way to trigger this sort of behaviour. As is confusing the two.

  • Like 1
Link to comment
Share on other sites

Another thing to watch out for is whether you have overflown the memory segment and need an ASM ORG $xxxxx command

 

Look at your LST file and see if the memory map has been breeched.

The 42k.bas shows addresses and range. If any of the addresses in the LST are outside then you have overflowed and need an ASM ORG

  • Like 1
Link to comment
Share on other sites

Hi my friends – thanks for your responses! I’ve been searching for memory leaks since, positioning ORGs, combing through loops in “safe moded code”, etc, since these suggestions, still hopeful of a solution. :)

 

Yes, this is for my game and WIP contest entry, looking to fix it, and finish it. I could have asked on the game thread, but felt that this problem is a minor science, and thread, in itself, especially when it seemed to spawn a life of its own.

 

Long story short, yes indeed, it’s a loop that is going haywire. It’s the “GAME OVER/PLAY AGAIN” loop on my game that allows you to replay. The game plays fine (especially after a few fixes since). And no matter how high your score, or how long your 1st play is, there is no crash. Same with the 2nd, 3rd replays, up until 2-3 more. When you start the 6th or 7th replay, the graphics become glitchy. About 3 replays later, the game crashes.

 

Something to do with the way the game restarts (to the beginning) causes this problem. Something may be overloading the memory just a bit more over the brink on every replay until collapse.

 

I could easily just remove the GAME OVER/PLAY AGAIN feature, demand a hard restart to play again, and the problem could be swept under the carpet. I’d be fine with that. (I really didn’t care for this feature – it was a contest recommendation.)

 

However, just for show, can I have you folks look at the dump files if there’s any clue? Nothing seems to cross over into $6FFF-$7000, with or without the ORG statement. Even with ORG $C040, it still crashes.

 

Again, thanks for all the help! :)

 

 

One is the dump.cpu without ORG, and the other is with ORG $C040. Copied both into text files so the Forum can accept them.

Dump with ORG c040.txt

Dump.txt

Link to comment
Share on other sites

Check if your program in a procedure when the reset occur. If you are in a procedure, have the procedure reach the return end, so it can go back to the main loop, so you're popping the return data off the stack. And the stack I believe is located in the STIC memory.

 

I would check all your procedure for the goto statement and make sure it only for the procedure and not jumping in other procedures or back to the mainloop.

 

If the program is in the main loop, then goto <label> should be fine.

  • Like 1
Link to comment
Share on other sites

The most common bug for this would be a GOSUB from where your program goes back without doing RETURN, this would slowly make stack to get bigger and ultimately causing a crash.

 

You can use the STACK_CHECK feature of IntyBASIC to try detect this. (check manual)

  • Like 1
Link to comment
Share on other sites

 

attachicon.gifDump.txt

One is the dump.cpu without ORG, and the other is with ORG $C040. Copied both into text files so the Forum can accept them.

 

Hmm... Those are the wrong "dump"s for what was asked. That's actually a "core dump" (i.e., memory dump). What would be helpful is a "execution history dump," which displays the last several thousand steps the CPU took leading to the crash.

 

To do this, you run with the debugger on ("-d" option in jzIntv and SDK). Program execution will halt immediately at the debugger prompt. Just enter the "H" command to enable history tracking, then "R" to run your program normally. Let it crash, and it will return to the debugger prompt. Enter the "D" command to dump the history. This will create file "dump.hst".

 

Post the history dump here and we'll take a look. Also, it would be extremely helpful if you could post your code -- at least the parts relevant to your "restart" loop.

 

If I had to guess, you are branching to what you believe is the beginning of your game from within a procedure, and not returning properly. After a few times of doing this, the stack is smashed, causing the CPU to go into the weeds.

  • Like 1
Link to comment
Share on other sites

Fixed it! :grin: :thumbsup:

 

Not a programmer by trade, or even programmed in years, or maybe since school, but I had to go back here to dealing with stacks, interrupts, flows, memory allocation, recursive functions, loop invariants, etc.

 

And the problem was that, although I did always remember the motto about GOTOs – not only are they “for the lazy”, and build bad habits, but they are DANGEROUS, I still indulged more than I should have. You live, and you learn.

 

Thank you all for your awesome advice. You were correct with the flow problems.

 

@Nanochess - BINGO!

 

And thanks for implementing this in IntyBASIC 0.9. What's really cool about STACK_CHECK is that it nails it just before the graphic glitching even begins, long before the eventual crash. It’s clear now that the graphics going funky meant that the program was bleeding before dying.

 

But, STACK_CHECK just kills your game before the torture begins.

 

But it shouldn’t come as a surprise when the posts before did indeed point to memory and looping problems. Once again, you all have my thanks for coming to my rescue. :)

 

(PS: For many years now in the A/V Forums, where I also hang out, I got used to being the advice giver. It’s very nice to be on the receiving as well as I’m learning here too.)

post-44654-0-80055100-1454135049_thumb.png

  • Like 2
Link to comment
Share on other sites

My advice would be to post your source code as it is now.

 

Post the history dump here and we'll take a look. Also, it would be extremely helpful if you could post your code -- at least the parts relevant to your "restart" loop.

 

It’s not that my source code is secret, it’s just that I wasn’t ready to make it public till I fixed it a bit. However, now that this problem’s been fixed, I will be very happy too, soon, on my game thread.

 

The way I solved this problem is in light of freewheel’s post, with good ol’ paper and pen old-school flow charting, then removing some GOTO statements, and replacing them with breaks instead (RETURN), and taking care of business once the called, and calling, procedures, return control to the main program.

 

But, for academics, and for the sake of completion, here’s the rogue code fragment that was causing the most problems (abridged for clarity):

game_over: procedure
cls
print at screenpos(5, color cs_white, "GAME OVER"
if #score>#hiscore then #hiscore=#score: print at screenpos(3,5) color cs_red, "NEW HIGH SCORE"
print at screenpos(3,3) color cs_white, "SCORE ":print at screenpos(11,3) color cs_white, <5>#score:print at screenpos(16,3) color cs_white, "00"
print at screenpos(3,4) color cs_white, "HIGH ":print at screenpos(11,4) color cs_white, <5>#hiscore:print at screenpos(16,4) color cs_white, "00"
print at screenpos(5, color cs_white, "GAME OVER"
print at screenpos(4,0) color cs_white, "PRESS DISC TO"
print at screenpos(5,1) color cs_green, "PLAY  AGAIN"
game_over_loop:
if (cont.button+cont.left+cont.right+cont.up+cont.down)=0 then goto game_over_loop else goto title_screen_control
end

This was the GAME OVER/PLAY AGAIN subroutine at the end. I see now how this proc/loop never terminates - notice the code at the end that, either, infinitely loops or goes to the title screen.

 

This alone can explode a stack. I just changed this whole proc to a label, and made other adjustments too.

 

And attached also is the HST file requested (thanks DZ-Jay for clarifying). I had to convert it to a text file so the Forum can accept it, but all the info should be there.

 

Hopefully the info here is helpful to others in the future. Once more, you all have my thanks.

dump.hst.txt

Link to comment
Share on other sites

Fixed it! :grin: :thumbsup:

 

Not a programmer by trade, or even programmed in years, or maybe since school, but I had to go back here to dealing with stacks, interrupts, flows, memory allocation, recursive functions, loop invariants, etc.

 

And the problem was that, although I did always remember the motto about GOTOs not only are they for the lazyŽ, and build bad habits, but they are DANGEROUS, I still indulged more than I should have. You live, and you learn.

 

Thank you all for your awesome advice. You were correct with the flow problems.

 

@Nanochess - BINGO!

 

And thanks for implementing this in IntyBASIC 0.9. What's really cool about STACK_CHECK is that it nails it just before the graphic glitching even begins, long before the eventual crash. Its clear now that the graphics going funky meant that the program was bleeding before dying.

 

But, STACK_CHECK just kills your game before the torture begins.

 

But it shouldnt come as a surprise when the posts before did indeed point to memory and looping problems. Once again, you all have my thanks for coming to my rescue. :)

 

(PS: For many years now in the A/V Forums, where I also hang out, I got used to being the advice giver. Its very nice to be on the receiving as well as Im learning here too.)

I'm glad that I could help you. I'm checking alternatives for helping to debug faster, GroovyBee has suggested warnings for jumping out of a PROCEDURE.

  • Like 1
Link to comment
Share on other sites

 

 

It’s not that my source code is secret, it’s just that I wasn’t ready to make it public till I fixed it a bit. However, now that this problem’s been fixed, I will be very happy too, soon, on my game thread.

 

The way I solved this problem is in light of freewheel’s post, with good ol’ paper and pen old-school flow charting, then removing some GOTO statements, and replacing them with breaks instead (RETURN), and taking care of business once the called, and calling, procedures, return control to the main program.

 

But, for academics, and for the sake of completion, here’s the rogue code fragment that was causing the most problems (abridged for clarity):

game_over: procedure
cls
print at screenpos(5, color cs_white, "GAME OVER"
if #score>#hiscore then #hiscore=#score: print at screenpos(3,5) color cs_red, "NEW HIGH SCORE"
print at screenpos(3,3) color cs_white, "SCORE ":print at screenpos(11,3) color cs_white, <5>#score:print at screenpos(16,3) color cs_white, "00"
print at screenpos(3,4) color cs_white, "HIGH ":print at screenpos(11,4) color cs_white, <5>#hiscore:print at screenpos(16,4) color cs_white, "00"
print at screenpos(5, color cs_white, "GAME OVER"
print at screenpos(4,0) color cs_white, "PRESS DISC TO"
print at screenpos(5,1) color cs_green, "PLAY  AGAIN"
game_over_loop:
if (cont.button+cont.left+cont.right+cont.up+cont.down)=0 then goto game_over_loop else goto title_screen_control
end

This was the GAME OVER/PLAY AGAIN subroutine at the end. I see now how this proc/loop never terminates - notice the code at the end that, either, infinitely loops or goes to the title screen.

 

This alone can explode a stack. I just changed this whole proc to a label, and made other adjustments too.

 

And attached also is the HST file requested (thanks DZ-Jay for clarifying). I had to convert it to a text file so the Forum can accept it, but all the info should be there.

 

Hopefully the info here is helpful to others in the future. Once more, you all have my thanks.

 

GOTO's are a powerful construct, and indeed, it's the only real control flow mechanism available in Assembly Language, but they must be used with care. In higher-level languages like BASIC, which follow a more "structured" approach, it is best to just avoid them completely.

 

This requires a rather significant shift in reasoning, for the "spaghetti code" that GOTO promotes, in its purest form, is actually quite intuitive and close to how we think of program flow: do this or else go somewhere else.

 

In contrast, the "structure programming" method will have you thinking not in terms of control flow strictly, but of functional blocks all tied together by a main program: this small block does this, that small block does the other thing, etc.; and the main program is in charge of deciding which to call when. In this approach, the sub-routine block does not alter flow, but merely influences the state of the program. It is up to your main program to Do The Right Thing depending on the newly updated state.

 

In other words, your "Game Over" routine should be in charge of displaying the game-over screen and waiting for a key to be pressed, but that's it. Once it receives the input it expects, it just returns to the main program, who is then in charge of restarting the game.

 

There are obviously many ways to skin this cat, and this is just one. However, good structured programming leads to easier to follow control flow, less scary bugs, and more elegant code. :)

 

-dZ.

  • Like 1
Link to comment
Share on other sites

I'm glad that I could help you. I'm checking alternatives for helping to debug faster, GroovyBee has suggested warnings for jumping out of a PROCEDURE.

 

Yes, you all helped. Even though I solved it in ways that carlsson, freewheel, Kiwi and DZ-Jay mentioned, just manually scanning the code for loops on auto-pilot and GOTO statements, particularly those inside PROCs, however the STACK_CHECK message was confirmation initially. A problem is much easier solved when you know what it is. I like this statement and will now use it in all my IntyBASIC programs. :)

 

And, yes, I was going to ask about preventative measures, even before STACK_CHECK kicks in. Some warnings would be a good idea. Nagging, but necessary.

 

And feel free to give me credit for providing a disaster example. :grin:

  • Like 1
Link to comment
Share on other sites

 

Yes, you all helped. Even though I solved it in ways that carlsson, freewheel, Kiwi and DZ-Jay mentioned, just manually scanning the code for loops on auto-pilot and GOTO statements, particularly those inside PROCs, however the STACK_CHECK message was confirmation initially. A problem is much easier solved when you know what it is. I like this statement and will now use it in all my IntyBASIC programs. :)

 

And, yes, I was going to ask about preventative measures, even before STACK_CHECK kicks in. Some warnings would be a good idea. Nagging, but necessary.

 

And feel free to give me credit for providing a disaster example. :grin:

 

One note: You should only use the "STACK_CHECK" statement during debugging and testing, then remove it before release. Like similar debugging features in other languages, it generates additional code that may slow down your program in order to test the stack on every frame.

  • Like 1
Link to comment
Share on other sites

 

GOTO's are a powerful construct, and indeed, it's the only real control flow mechanism available in Assembly Language, but they must be used with care. In higher-level languages like BASIC, which follow a more "structured" approach, it is best to just avoid them completely.

 

This requires a rather significant shift in reasoning, for the "spaghetti code" that GOTO promotes, in its purest form, is actually quite intuitive and close to how we think of program flow: do this or else go somewhere else.

 

In contrast, the "structure programming" method will have you thinking not in terms of control flow strictly, but of functional blocks all tied together by a main program: this small block does this, that small block does the other thing, etc.; and the main program is in charge of deciding which to call when. In this approach, the sub-routine block does not alter flow, but merely influences the state of the program. It is up to your main program to Do The Right Thing depending on the newly updated state.

 

In other words, your "Game Over" routine should be in charge of displaying the game-over screen and waiting for a key to be pressed, but that's it. Once it receives the input it expects, it just returns to the main program, who is then in charge of restarting the game.

 

There are obviously many ways to skin this cat, and this is just one. However, good structured programming leads to easier to follow control flow, less scary bugs, and more elegant code. :)

 

-dZ.

 

Yes, GOTOs are very powerful, but, you've made me realize that power when abused can be corrupt, as is this example.

 

And, as I was redoing my code, I do realize there are ways to "go around going around" with just using such GOTO statements. The key was, and will be from now on, return (properly) to the Main Program, and keep the flow in mind. I use to write stuctured programs in the past, but for some reason, maybe the rush of the contest deadline and my late start, just thought I could wing it with GOTO. I did to some extent, but there were consequences.

 

In academics GOTOs are typically frowned upon, and for many a good reason.

 

Yes, there are many other ways to skin this cat, particularly with a higher level language like IntyBASIC, and with better, more elegant code, will prevent such crashes.

 

I still have a couple of GOTOs in my code, and will continue to use them, particularly for game control inputs, but they will have much more limited range. They will be grounded with supervision, not given the power to be warp zones.

Link to comment
Share on other sites

 

One note: You should only use the "STACK_CHECK" statement during debugging and testing, then remove it before release. Like similar debugging features in other languages, it generates additional code that may slow down your program in order to test the stack on every frame.

 

Yes indeed, and worth pointing this out. STACK_CHECK is a tool to use as you're building your program, for sure, but yeah, I agree it should be removed when after you're certain it didn't provide any warnings or halts. It's not necessary for prime time when your program is complete.

Link to comment
Share on other sites

GOTOs is fine. Just don't goto out of a procedure/function. I think compiler warning or a rubber wall between name:procedure return:end branch would keep the program from jumping out of a procedure.

 

Just for the record, as soon as I removed those GOTOs that jumped out of PROC (there were actually two of them giving problems) the program was fine. That's all I really needed to do (but did make a few adjustments in the Main Program).

 

I did leave a couple there, but I know those are safe since they hover in the Main Program.

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