Jump to content
IGNORED

Classic99 Updates


Tursi

Recommended Posts

I don't think we had a thread for this, so I figured I'd start one, since many people here are using my emulator.

 

11 June 2010

-Add ability to breakpoint on uninitialized memory read (console RAM only for now, no AMS)

-added 3x scaling to the video size menu

-save default scaling size

-Fixed broken continue and Step Over in debugger

-Added cycle counting and hex data to disassembly window

-changed default memory pointers to something more useful than R0

-made changing the filter mode reset the screen scaling size

-debugger now allows changing any memory type from any view window - VDP now has a V prefix, GROM has a G prefix. See docs.

-added memory type enums to the debugger display (code change only)

 

http://harmlesslion.com/software/classic99

  • Like 2
Link to comment
Share on other sites

Thanks a million, Tursi. I'm a regular (obsessive) Classic99 user, and I'm glad you decided to start a thread on it. I know this isn't a high priority, but man... a SAVE STATE feature would be A-MAZE-ING, if you ever get the time...

 

Any further ideas on creating the .exe for standalone games? The "Lemonade Stand" .exe you made for me is just great. =) Thanks for posting this update--- I'll be DLing the newest version, as I think mine is out of date now. YOU ROCK

Link to comment
Share on other sites

Excellent! And all the while I thought I was using the continue and step over incorrectly somehow. Saving the default scaling size is nice too (little details make all the difference), as are all the debugger changes (I use it quite a bit!)

 

Suggestions if you want them:

 

Something that would be nice to have is a list of address start points that are in the REF/DEF table, and maybe a list of any addresses that are branched to via B, BL, or BLWP. Where I'm going with this is, when you start a debug session on your code, you have to first find where it is loaded, which means digging through the REF/DEF table manually. If you are working with a ROM cart then it is a little easier since things always start at 6000, however that is just the header and not the actual code start point.

 

Next you have to single step until you get to the point where you want to debug. Since the debugger does not allow the disassembly window address to be changed, you can't find the address of the various subroutines until you execute them. Since the "step over" feature was broken, this could take a long time when trying to get to a subroutine deep in the code. Even with step-over it could take a long time. The only alternative to single-stepping would be manual disassembly by looking at raw memory to find the subroutine entry points to set break points.

 

I know it is not possible to totally disassemble memory that has not been executed, but it would be nice to be able to change the disassembly window and just have best-guess code displayed if the code has not been executed already. Most of the time the disassembly will be correct and would allow you to find those entry point addresses so break-points can be set up.

 

Matthew

Edited by matthew180
Link to comment
Share on other sites

I was just trying the step-over feature and it still does not seem to work. I loaded a cart program I wrote and set a break point at the main entry point. The first thing the code does is set up the VDP with a bunch of calls to my VWTR routine, and I want to skip going into each call. So I'm sitting on the first call and it looks like this:

 

 602C  0200  li   R0,>0002        (16)
       0002
> 6030  06A0  bl   @>620a         
       620A
 6034  0200  li   R0,>0206       
       0206
 6038  06A0  bl   @>620a 

 

I *thought* that hitting step-over at this point would execute until the return and the debugger would be sitting at address >6034. However, when I hit step-over, the program executes non stop as if I had hit the "normal speed" button. Am I using the step-over feature incorrectly?

 

Matthew

Link to comment
Share on other sites

I was just trying the step-over feature and it still does not seem to work. I loaded a cart program I wrote and set a break point at the main entry point. The first thing the code does is set up the VDP with a bunch of calls to my VWTR routine, and I want to skip going into each call. So I'm sitting on the first call and it looks like this:

 

 602C  0200  li   R0,>0002        (16)
       0002
> 6030  06A0  bl   @>620a         
       620A
 6034  0200  li   R0,>0206       
       0206
 6038  06A0  bl   @>620a 

 

I *thought* that hitting step-over at this point would execute until the return and the debugger would be sitting at address >6034. However, when I hit step-over, the program executes non stop as if I had hit the "normal speed" button. Am I using the step-over feature incorrectly?

 

Matthew

 

It is also giving me problems - I think there may still be an issue with it. I'm sure Tursi will have a look when he has a spare moment ;-)

Link to comment
Share on other sites

Something that would be nice to have is a list of address start points that are in the REF/DEF table, and maybe a list of any addresses that are branched to via B, BL, or BLWP.

 

The REF/DEF table is possible, I guess, but now you're asking me to interpret the operating system. I'd kind of like to focus on the hardware till that's closer to my satisfaction. I will keep it in mind, though, because I have parsed that table manually as well.

 

A list of branches is definately a long-term sort of idea. :) That WOULD be a tricky thing, since you'd have to pre-emptively execute the program and take every branch to find them all. ;)

 

Where I'm going with this is, when you start a debug session on your code, you have to first find where it is loaded, which means digging through the REF/DEF table manually. If you are working with a ROM cart then it is a little easier since things always start at 6000, however that is just the header and not the actual code start point.

 

I see your problem... my first thinking is that you will save yourself a lot of hassle if you have your assembler output a listing file, and use that as a reference.

 

Absolute code is a bit easier to debug for the reasons you list, but if you absolutely (hehe) must develop with dynamic code (many reasons why you might!), you can still help yourself out. Do something early in your program that you can breakpoint on, like a write access to a particular address in console ROM, or loading a particular value into a VDP register. Remember that the debugger is not limited to PC breakpoints, they are very flexible and there are all kinds of ways you could trigger it. (This is partly why I've resisted "breakpoint" psuedo-ops in the emulation).

 

Even the ROM example you list is pretty easy.. the structure of your ROM header will rarely change, so if you know that the START label in your header will always be at, say, >600A, you can breakpoint on read to >600A as the console won't look at the start address till you select the cartridge in the menu (IIRC).

 

Next you have to single step until you get to the point where you want to debug. Since the debugger does not allow the disassembly window address to be changed, you can't find the address of the various subroutines until you execute them.

 

Agreed this is a bit of a hassle, but I've used the external listing file to solve that.

 

Since the "step over" feature was broken, this could take a long time when trying to get to a subroutine deep in the code. Even with step-over it could take a long time. The only alternative to single-stepping would be manual disassembly by looking at raw memory to find the subroutine entry points to set break points.

 

Again, take another look at the breakpoints. It's so easy to catch a unique behaviour in the code, and if there isn't already one, you can easily add one. For example, if you added a MOV R0,@>0000, then you can add a breakpoint on write to >0000. It'll have no effect on the console or the emulation, but it's easy to trap. And you could set up a whole set of these breakpoint "IDs" with different target addresses, and with a single breakpoint trap all of them (using a range), or specify only the ones you want.

 

Most of my personal work is with absolute code, so I just look at the listing file to get the addresses I want. I'd like to have it parse the listing file or object file someday to get labels... the listing file is more likely since the object file will only contain DEFs.

 

I know it is not possible to totally disassemble memory that has not been executed

 

Sure it is, the emulator does it all the time. The caveat is that the first instruction you start with needs to be valid, if you start on data you may get misaligned instructions.

 

but it would be nice to be able to change the disassembly window and just have best-guess code displayed if the code has not been executed already. Most of the time the disassembly will be correct and would allow you to find those entry point addresses so break-points can be set up.

 

The inability to page is more of a design issue right now, there's no serious reason it couldn't be done, I think.

Link to comment
Share on other sites

I *thought* that hitting step-over at this point would execute until the return and the debugger would be sitting at address >6034. However, when I hit step-over, the program executes non stop as if I had hit the "normal speed" button. Am I using the step-over feature incorrectly?

 

I believe so... it appears to be working for me.

 

My first question would be, is it returning /exactly/ to the next address? it looks from your sample like it should, but if you increment the return address you can't step over. The problem is that there is no return statement on the 9900, so it first makes sure the instruction in question set a return address (otherwise it just steps), then it runs until it hits that address.

 

Also, if you breakpoint inside the step-over routine, the step over is cancelled.

 

Finally, of course, make sure Scroll Lock is on. When Scroll Lock is off, breakpoints don't work (but neither do the shortcut debugger keys).

 

it's possible you are hitting a bad state and it's losing track of what it's doing, I haven't logged enough time with the new step-over code myself, but I just tried it again here on BL's and it did the right thing. If you can give me a reproducable failure then I can fix it. :)

Link to comment
Share on other sites

I see your problem... my first thinking is that you will save yourself a lot of hassle if you have your assembler output a listing file, and use that as a reference.

 

I do make extensive use of the listing file. But the listing file for relocatable code only contains offsets since the final addresses are resolved at load time. So you still have to do a lot of manual adjustments to find the locations.

 

I know it is not possible to totally disassemble memory that has not been executed

 

Sure it is, the emulator does it all the time. The caveat is that the first instruction you start with needs to be valid, if you start on data you may get misaligned instructions.

 

Since the 9900 has no code protection, a program can self modify, so there will be instances where you can't disassemble without execution. Also, the data for the X instruction, which becomes the actual instruction to execute, may not exist until run time. Of course these instances will be rare, but they do exist and the disassembly will be incorrect until execution if the data is set up at run time.

 

As for the "step over", the only thing you mentioned that I'm not doing is hitting "scroll lock", so I'll try that and see if it helps. I'm not sure I understand why scroll lock has to be on though? That is a rather obscure key and it is a little confusing.

 

Matthew

Link to comment
Share on other sites

I see your problem... my first thinking is that you will save yourself a lot of hassle if you have your assembler output a listing file, and use that as a reference.

 

I do make extensive use of the listing file. But the listing file for relocatable code only contains offsets since the final addresses are resolved at load time. So you still have to do a lot of manual adjustments to find the locations.

 

I did my best to cover that as well in my suggestions. :)

 

 

I know it is not possible to totally disassemble memory that has not been executed

 

Sure it is, the emulator does it all the time. The caveat is that the first instruction you start with needs to be valid, if you start on data you may get misaligned instructions.

 

Since the 9900 has no code protection, a program can self modify, so there will be instances where you can't disassemble without execution. Also, the data for the X instruction, which becomes the actual instruction to execute, may not exist until run time. Of course these instances will be rare, but they do exist and the disassembly will be incorrect until execution if the data is set up at run time.

 

These are probably good examples on the surface, but they won't work in my disassembly listing anyway. The disassembly only stores the address of code executed, not what the code was, so the history view will be incorrect if you use self-modifying code (or change cartridge ROM banks, for another common example). I'm not even sure if it attempts to store the result of an X instruction, I strongly doubt it.

 

I likewise doubt that you'll find very many disassemblers out there that attempt to cope with those cases on any platform. This is sort of an academic discussion at this point - if these were cases you were actually using the debugger for, you'd have already seen that it doesn't work that way.

 

As for the "step over", the only thing you mentioned that I'm not doing is hitting "scroll lock", so I'll try that and see if it helps. I'm not sure I understand why scroll lock has to be on though? That is a rather obscure key and it is a little confusing.

 

Scroll Lock is the Classic99 debugger enable key. Has been for 15 years now. There's only been a menu option to load the debugger for 2 or 3, conversely. ;) So the one is a little more tightly integrated than the other. But if you have Scroll Lock off, then NO breakpoints should work, not just Step Over.

 

I've considered removing the Scroll Lock requirement for Breakpoints but this is the first indication anyone has ever given me that they aren't using it, and I didn't want people who were NOT debugging to suddenly start encountering breakpoints and having no idea why. :) If I remove the dependency on the key, I will probably require the debug dialog to be open instead. :)

 

Scroll Lock's obscurity, as well as visible toggle nature, is the reason it was chosen. It's unlikely to interfere with normal operation. I'm surprised you aren't using the function keys to step, debug, etc, though. Those also require Scroll Lock to be active.

 

Guess I should finish the manual so you guys don't have to suffer through a text file, eh? ;)

Edited by Tursi
Link to comment
Share on other sites

oh yes Tursi, a manual would be great.

 

Also have an idea for the debugger (perhaps I already mentioned a while back):

 

Would it be possible to toggle the breakpoints on/off using checkboxes (in the breakpoints list) ?

Being able to save/load your breakpoints would also be real cool :)

Link to comment
Share on other sites

I know it is not possible to totally disassemble memory that has not been executed

 

Sure it is, the emulator does it all the time. The caveat is that the first instruction you start with needs to be valid, if you start on data you may get misaligned instructions.

 

I likewise doubt that you'll find very many disassemblers out there that attempt to cope with those cases on any platform. This is sort of an academic discussion at this point - if these were cases you were actually using the debugger for, you'd have already seen that it doesn't work that way.

 

Yes it is academic at this point, I was simply providing examples to back up my original statement. That's all. Not that is matters one way or another, but the emulator I'm working on (which I have not touched in over a year) does deal with decoding the X instruction's parameters and such. It has a "memory" and will indicate whether or not the instruction has been executed and marks memory locations as "code" or "data" as it runs and can confirm the contents of a given memory location. However, my main focus was less on a general purpose emulator and more on a debugger that happened to also be an emulator. It is irrelevant though since it is not done, but the parts that are done do work.

 

As for the "step over", the only thing you mentioned that I'm not doing is hitting "scroll lock", so I'll try that and see if it helps. I'm not sure I understand why scroll lock has to be on though? That is a rather obscure key and it is a little confusing.

 

Scroll Lock is the Classic99 debugger enable key. Has been for 15 years now. There's only been a menu option to load the debugger for 2 or 3, conversely. ;) So the one is a little more tightly integrated than the other. But if you have Scroll Lock off, then NO breakpoints should work, not just Step Over.

 

Well, I've only been using Classic99 since the Faire last year, or maybe for a small time prior to that... :-) I probably didn't use SL because I saw the "debug" menu option. I do use the F2, and I can assure you it does work without SL being active.

 

I just tested and having SL active does make the step-over work correctly. That's nice to know! I did find something odd when testing though:

 

1. Load a cart based program, open debug to find the start location, set a break point.

2. Close debug window, reset the emulator from File->Reset, hit SL key.

3. Press '2' then '2' again to run the cart program, break-point pauses execution.

 

At this point, when you open the debug window, the emulator un-pauses and continues execution. You need to have the debug window already open to prevent it from continuing. Not sure if this is intentional or not?

 

Guess I should finish the manual so you guys don't have to suffer through a text file, eh? ;)

 

I do try to RTFM before posting. Just a document that explains in a little more detail about each feature (and an example) would be good enough for me. ;-)

 

Matthew

Edited by matthew180
Link to comment
Share on other sites

Well, I've only been using Classic99 since the Faire last year, or maybe for a small time prior to that... :-) I probably didn't use SL because I saw the "debug" menu option. I do use the F2, and I can assure you it does work without SL being active.

 

Bug. :) But unsurprising. The STEP key always used to work. It is BREAKPOINTS that will not fire when Scroll Lock is inactive. Step Over works by setting a special internal breakpoint at the return address, so when Scroll Lock is off, like other Breakpoints, it doesn't hit.

 

I just tested and having SL active does make the step-over work correctly. That's nice to know! I did find something odd when testing though:

1. Load a cart based program, open debug to find the start location, set a break point.

2. Close debug window, reset the emulator from File->Reset, hit SL key.

3. Press '2' then '2' again to run the cart program, break-point pauses execution.

At this point, when you open the debug window, the emulator un-pauses and continues execution. You need to have the debug window already open to prevent it from continuing. Not sure if this is intentional or not?

 

Doesn't sound like reasonable behaviour. What I am probably going to do though is remove the Scroll Lock toggle and replace it with the debug window being open or not. So that should clear up that bug as well as making the behaviour a little more predictable.

 

Guess I should finish the manual so you guys don't have to suffer through a text file, eh? ;)

 

I do try to RTFM before posting. Just a document that explains in a little more detail about each feature (and an example) would be good enough for me. ;-)

 

Matthew

 

Ooooh, no, after all the hell I caught on the mailing list because nobody wants to read text files anymore, I started a full manual. Problem is that it's a lot of work and it's falling behind before it's even done. ;)

Link to comment
Share on other sites

Ooooh, no, after all the hell I caught on the mailing list because nobody wants to read text files anymore, I started a full manual. Problem is that it's a lot of work and it's falling behind before it's even done. ;)

 

Haha. I've learned the hard way, over years and years, that keeping things simple is the only way they will actually get done. That is the main reason I don't have an up to date web site. Every time I sit down to redo my site, my brain goes off on all the things I need it to have, and look, 3 years later and I still don't have a new up to date site.

 

IMO you need to just expand and elaborate the manual you have. Make it more clear, add extra detail and examples. People don't read manuals, which is usually why they are the last thing to get done. The only other suggestion I would have would be to make the docs a web page instead of a text file (or both). People are used to reading web pages and that is more like a "document" than a text file (to the majority, personally I don't care as long as I can get the info.)

 

Matthew

Link to comment
Share on other sites

IMO you need to just expand and elaborate the manual you have. Make it more clear, add extra detail and examples. People don't read manuals, which is usually why they are the last thing to get done. The only other suggestion I would have would be to make the docs a web page instead of a text file (or both). People are used to reading web pages and that is more like a "document" than a text file (to the majority, personally I don't care as long as I can get the info.)

 

I don't think that's really much different than I'm doing, except I'm doing it as PDF. I'll pop it up from the menu, too. A web page would take me longer to create, so I don't think I'll do that. It has screenshots, descriptions, etc. I don't know if it will be less "boring" (one of the criticisms of the text files), but I'll see if I can embed a little intrigue. :cool:

 

What I also wanted to do, and I think I have most of that in there already, was a little history, tech spects, and photos of the actual machine. ;)

 

Classic99 is technically still a beta application, since all the hardware isn't done to my satisfaction. Technically it shouldn't need any docs! :D

Link to comment
Share on other sites

  • 4 months later...

It's been a while, and this is a small update, but it's a relatively important one since it was biting people, so I wanted to get it out.

 

-Removed SDGROM concept

It was a neat idea that I had, and it will probably resurrect in some form with the GROM chip I made, but the original plans I had for it suffered from several design flaws and I won't be pursuing it any further.

 

-Fixed Speech Synth reset code

This looks like a bug in the 5220 emulation - during reset it would write a 0 nibble to the address shift register, throwing the whole thing out of alignment unless you wrote enough nibbles to re-align it. Net effect was no speech for the first run on Mark's program. (I need to rip this out anyway and replace it with the new code from MESS so the synth has the right chip. ;) )

 

-Fix setting of carry bit on SRC instruction

Stuart Conner found this for me - SRC was setting carry to be equal to the value in the LSB after the shift, and not the value shifted out of the LSB. Should be fixed!

 

-Fix for post-increment on the CPU to handle instructions that reference the same register for source and destination (this affects about half the opcodes!)

I started this a few weeks ago upon discovering that the Corcomp Diagnostics memory test failed. The problem was in this instruction:

 

MOV R3,*R3+

 

The test expected that the address of the memory location would be stored at each memory location, that is, >A000 = >A000, >A002 = >A002, etc. Unfortunately, my memory decode and opcode functionality didn't work with this - it would first get the address of the source and destination values, including handling post-increment, and THEN do the move itself (by which point the destination register had already been incremented, so the that DATA stored was off by 2).

 

I fixed that by separating the address aquisition and the post-increment operation, and that worked fine. But it introduced a new bug that caused even Extended BASIC to hang, so I couldn't release it. Tonight I worked that out, and it was this instruction in the GPL division code:

 

MOV *R3+,@>0008(R3)

 

This code is used in a loop to copy a floating point value from one place in scratchpad to another place 10 bytes ahead. The problem here is that now my code was doing the post increment on the SOURCE register too late, calculating the destination address before the post increment, and thus again being off by 2.

 

The process needed to make all these edge cases work, which makes perfect sense to me now that I've had to work it out, is:

 

-Calculate source address

-Get source data

-Apply source register post-increment

-Calculate destination address

-Store operation result

-Apply destination register post-increment

 

Anyway, that was a trickier one, but I'm always happy to resolve CPU bugs -- and now two are resolved! Still some issues though.. ARC303 still can't write compressed files. I looked at that and I see the block of code where it decides not to write the file (it does write the directory, but declines to actually process the FILE), but I don't follow what that code is trying to do or why it made that choice. And TI Logo II can't seem to move the turtle at 270 degrees (it's off by 45 degrees only at that angle). Win994A seems to have the same bug, but MESS works. Again, though, it's a little hard to see why right now.

 

-Make "Step over" work on branches that include a data statement after them or that otherwise increment the return address by 2

This was just a quickie because I was dealing with DSRLNK calls, which include a data statement after them. Just made it also check the next address.

 

-fix debugger - register match value is entered in hex again

There was a bug where you had to enter register match values in decimal. Fixed that.

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

Excellent work Tursi! I very much appreciate it. I also like the debugger fixes you did (step over+register match).

 

Quick question: is there any chance we can get USCD Pascal running in classic99 ?

I think that at this time there is no emulator supporting USCD Pascal, not even MESS.

I have the p-code card and should be able to dump the roms.

Link to comment
Share on other sites

Now, I don't want to push my luck, but here's another feature request for the debugger :P

 

I'd love to see the debugger span multiple windows. That way you could single-step your code and watch what happens in VDP/CPU/GROM memory.

Today do you have toggle back-and-forth, and that can-make you loose track of things, just saying ;)

Link to comment
Share on other sites

Quick question: is there any chance we can get USCD Pascal running in classic99 ? I think that at this time there is no emulator supporting USCD Pascal, not even MESS. I have the p-code card and should be able to dump the roms.

 

I already support it, it just doesn't work. ;) The ROMs are already in there, and are presumably correct.

 

However, it's pretty badly broken right now. It used to work up to the point of the first beep, at which point I was putting off more work until I supported disk images (since it doesn't use the normal file system as far as I know). Now however, it just seems to crash right away, probably I broke the paging when I removed the SDGROM. I wasn't too concerned since it didn't work before.

 

I thought PC99 supported it, though.

Link to comment
Share on other sites

Now, I don't want to push my luck, but here's another feature request for the debugger :P

 

I'd love to see the debugger span multiple windows. That way you could single-step your code and watch what happens in VDP/CPU/GROM memory.

Today do you have toggle back-and-forth, and that can-make you loose track of things, just saying ;)

 

Copy and paste into Notepad was invented for that! :)

 

Multiple windows are a pain, since I'm using raw Win32 I have to do all the window management by hand. It might happen someday but not likely soon. If you have trouble with copy and paste due to the windows repainting, that's what the 'freeze' button is for.

Link to comment
Share on other sites

Thanks a bunch! Classic 99 has really evolved into the de facto standard TI emulator, and it's so easy to use!

Now when can we expect a Linux version ;)

 

Thanks, I'm glad it's helpful to people. Linux probably won't happen anytime soon, but I won't say never. I've been eyeing some cross-platform devkits and wondering what projects might be good for them. ;)

Link to comment
Share on other sites

Hmmm... I just tried the new version, and the speech (in Parsec, which I tried) still sounds as garbled as in the old version.

By the way, if you import the new speech code from M.E.S.S., I found out that the rate of 680 kHz they are running the chip at is incorrect... 640 kHz would be the correct rate since it produces the correct pitch.

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