Jump to content
IGNORED

GCC for the TI


insomnia

Recommended Posts

I have a semi-complex program that I've culled down to fit in a ROM. It includes file access though the DSRs. Migrating the program from EA5 to a ROM yields an otherwise working program short of the ability to perform file access. 

 

The DSR_OPEN dsrlnk returns 0 as expected, but DSR_READ dsrlnk returns DSR_ERR_FILEERROR. This only happens with the ROM program and not the EA5.

 

I suspect that something is set up by Extended Basic or Editor Assembler that then allows the EA5 to happily open and use files. This same something doesn't happen with my ROM-based program. I've found info that describes what XB and EA do to initialize the system but that seems to all be associated with setting up the VDP (modes, screen address, pattern address, etc.). 

 

Any thoughts on what that missing something is, or perhaps some pointers to documentation? Thank you in advance.

Link to comment
Share on other sites

Extended BASIC and EA both will place the DSRLNK assembly access routine in lower expansion RAM. If you are linking to that routine, you will have to include your own copy in the ROM.

 

There is an implementation in libti99. I borrowed and modified that for my needs with ForceCommand which is a cartridge ROM. I am confident I did not need to mod libti99's DSRLNK until I wanted to precache all the cards DSR addresses. 

 

https://github.com/tursilion/libti99/blob/189cb667a2b8753cc1d5e399d3355a9cbc9c7a09/files.h#L88

  • Like 1
Link to comment
Share on other sites

So I'm still chasing down these extra things that XB and EA set up that allow for file access using the DSRs.

 

 

I began to wonder if my MAME configuration was somehow damaged, so I wrote a small TI Basic program to read one of the files I have on the emulated hard drive. It read just fine with the emulated cartridge inserted.

 

By happenstance, I exited TI Basic with 'bye' and went to the TI splash screen and then selected my cartridge. It ran just fine. Fonts were loaded from disk, my sample file display method ran while using the C stdio f* methods, and all was good. Something was different... Turns out my cartridge program works after using TI Basic but not without. 

 

There's got to be something my ROM based program needs to do, and probably my EA5 programs should do. Any ideas???

 

Link to comment
Share on other sites

I'm a big fan of "data, not guesses". Have you stepped into the code to see where it goes off the rails? What DSRLNK are you using (there are certain number of assumptions that must be set up BEFORE calling the ROM DSR, or it will fail. DSRLNK should handle those.) What is returning "DSR_ERR_FILEERROR" (ie: the DSRLNK or the DSR ROM?), and what number is that anyway (since there are no real standards in naming)? (I'm guessing that's my naming... in which case be aware that FILEERROR is the DSR's fallback error code for "something went wrong" ;) ).

 

You could also run under Classic99 and just look at the debug log. A lot of common setup errors are explicitly called out there (even if the call succeeds, as the Classic99 DSR is more generous than the real one.)

 

We have full documented source to the TI Disk Controller, so it's also possible to step in there and see exactly what is missing.

 

  • Like 3
Link to comment
Share on other sites

When making a cartridge image you need to follow a few rules:

1. Don't depend on REFs to any EA support routines like DSRLNK. 

2. Must set up all VDP registers and charsets yourself. 

3. Respect the high end of VDP Ram. At power on,  the disk controller has allocated buffers there.
 

 

Best way to be sure is to reduce your cartridge program to one object file with no REFs. 

I'm not sure, when is this VDP RAM allocated and where is the pointer, in PAD?

  • Like 1
Link to comment
Share on other sites

On 6/16/2023 at 6:47 AM, jedimatt42 said:

Extended BASIC and EA both will place the DSRLNK assembly access routine in lower expansion RAM. If you are linking to that routine, you will have to include your own copy in the ROM.

 

There is an implementation in libti99. I borrowed and modified that for my needs with ForceCommand which is a cartridge ROM. I am confident I did not need to mod libti99's DSRLNK until I wanted to precache all the cards DSR addresses. 

 

https://github.com/tursilion/libti99/blob/189cb667a2b8753cc1d5e399d3355a9cbc9c7a09/files.h#L88

Thanks jedimatt42, I am using libti99. That was a big help confirming the dsrlnk methods from a rom based program (fcmd). Knowing that I could trust those methods allowed me to chase this elsewhere.

 

I have discovered the problem...and how glad I am...

Through a bit of trial and error, I've realized that there is a small number of seconds (~ 3) after startup for which my emulated hard disk drive controller doesn't respond to requests. I can start MAME and enter the cartridge program in less than a second and if I do so the hard drive will not respond. If I wait 3 or more seconds from the startup screen, file access works just fine. Doesn't require staying on the startup screen--moving to the cartridge menu is ok. So this could be an emulation thing only, or how the hard drive controller is, etc. I may never know. I don't have a physical TI machine yet. I have one on order, but even then will not have a real hard drive or floppy drive. The only "disk" access will be via TIPI. 

  • Like 3
Link to comment
Share on other sites

On 6/17/2023 at 4:01 AM, Tursi said:

It's worth noting the libti99 DSRLNK is a port of the Editor/Assembler DSRLNK. ;)

 

Also good to know. libti99 is at the core of all the work I'm doing. I'm very much depending on it. Thanks for developing it. And BTW, I saw a YouTube video of your Dragon's Lair port to TI99. I'm in awe. I also found the notes you took while on the journey and enjoyed reading them. I looked all over for a DL cartridge I could purchase and found not a one. I'm sure everyone that has one will not be letting theirs go.

Link to comment
Share on other sites

23 hours ago, FarmerPotato said:

When making a cartridge image you need to follow a few rules:

1. Don't depend on REFs to any EA support routines like DSRLNK. 

2. Must set up all VDP registers and charsets yourself. 

3. Respect the high end of VDP Ram. At power on,  the disk controller has allocated buffers there.
 

 

Best way to be sure is to reduce your cartridge program to one object file with no REFs. 

I'm not sure, when is this VDP RAM allocated and where is the pointer, in PAD?

Thanks FarmerPotato. This is all excellent advice. I'm using libti99 and it's keeping me honest and not using any external references, other than those for floating point support. They're fixed in ROM in the machine so relatively safe. I'm setting up the VDP registers and charsets. Amusingly the charset patterns were in the file that wasn't being opened so I was getting those clunky versions from the TI startup screen. Initially I thought my program was crashing because I saw nothing at all. That was because my style is mostly using lower case and those definitions were all blank--goodness! I found the references for VDP memory usage by # of files that can be simultaneously opened and use libti99's files() method to set them. One of my libraries is tracking allocations in RAM and VRAM so I can determine if any area is double booked. 

  • Like 2
Link to comment
Share on other sites

11 hours ago, mrvan said:

Thanks jedimatt42, I am using libti99. That was a big help confirming the dsrlnk methods from a rom based program (fcmd). Knowing that I could trust those methods allowed me to chase this elsewhere.

 

I have discovered the problem...and how glad I am...

Through a bit of trial and error, I've realized that there is a small number of seconds (~ 3) after startup for which my emulated hard disk drive controller doesn't respond to requests. I can start MAME and enter the cartridge program in less than a second and if I do so the hard drive will not respond. If I wait 3 or more seconds from the startup screen, file access works just fine. Doesn't require staying on the startup screen--moving to the cartridge menu is ok. So this could be an emulation thing only, or how the hard drive controller is, etc. I may never know. I don't have a physical TI machine yet. I have one on order, but even then will not have a real hard drive or floppy drive. The only "disk" access will be via TIPI. 

mame? set the configuration switch to wait for initialization on the tipi?

 

Link to comment
Share on other sites

On 6/18/2023 at 11:29 PM, FarmerPotato said:

I'm not sure, when is this VDP RAM allocated and where is the pointer, in PAD?

 

I believe the power-up routine of the TI disk DSR reserves VRAM space and posts the pointer to the first byte below this space. This pointer to highest available VRAM is, indeed, in Scratchpad RAM at >8370.

 

...lee

  • Like 3
Link to comment
Share on other sites

14 hours ago, Lee Stewart said:

 

I believe the power-up routine of the TI disk DSR reserves VRAM space and posts the pointer to the first byte below this space. This pointer to highest available VRAM is, indeed, in Scratchpad RAM at >8370.

 

...lee

Ooh. That's great information. I coded a table of lowest addresses for the FDP reserved area from what I found on the TI Tech Pages. Then used the array index based on the value passed to files(). Reading from scratchpad will be far more satisfying.

  • Like 1
Link to comment
Share on other sites

17 hours ago, arcadeshopper said:

mame? set the configuration switch to wait for initialization on the tipi?

 

I'm not yet using TIPI in in the MAME emulation, just emulated floppy and hard drives. I should look into that, though, as TIPI will be my only drive source in the physical TI99 I'll have once you ship me my machine :-). I'm looking forward to its receipt now that I have the FinalGROM and nowhere to insert it.

Link to comment
Share on other sites

When you use the MFM harddisk emulation in MAME (with the HFDC), it takes some seconds until the harddisk completes its spin-up. I think you can see it when you enable logging (-oslog or -log).

 

My problem is that in the real system I would fire up the harddrive some seconds before turning on the rest of the system, but I cannot do that in MAME.

  • Like 2
Link to comment
Share on other sites

  • 3 weeks later...
On 6/21/2023 at 2:25 AM, mizapf said:

When you use the MFM harddisk emulation in MAME (with the HFDC), it takes some seconds until the harddisk completes its spin-up. I think you can see it when you enable logging (-oslog or -log).

 

My problem is that in the real system I would fire up the harddrive some seconds before turning on the rest of the system, but I cannot do that in MAME.

Thanks mizapf. I think this is my issue. I’ll check into the logging.

  • Like 2
Link to comment
Share on other sites

Quick question to the gcc gurus here: has anyone ever used the VDP int hook to call a C function? I tried using it, but the program goes off into the weeds. Looking at the debugger, it shows that when the function is called, the WP is still pointing at the GPL workspace, but the function prologue will happily start pulling things from the stack (with a stack pointer pointing somewhere completely unrelated) which of course messes things up completely.

 

I want to implement a screen mode change using the 5th sprite interrupt, so need to be able to run a user interrupt routine...

  • Like 2
Link to comment
Share on other sites

Dunno about C on the TI, but in general, you wouldn't call a function from within an ISR. Generally, you'd just set a flag in the ISR to flag that an action is required, and pick it up in your main loop, then reset the flag. That's how I implement all ISRs on AVR/ESP32/ARM. The C function stack could be a little heavy to set up and tear down in an ISR? If  you restrict your ISRs to just setting simple flags you may not have to change the WP for the ISR at all. Just my two cents :thumbsup:

  • Like 3
Link to comment
Share on other sites

I agree Willsy.

 

I don't think that could work with GCC on the TI, having any random WP at the time the int goes off.

 

You might be able to reestablish the correct WP, needing assembler to do it, and reset it back when done.  Tricky.

 

But this is just based on my meagre understanding of the TI GCC, I've never used it.

  • Like 3
Link to comment
Share on other sites

Use a naked function to wrap the call (no need for assembly, but it's easier there ;) ) - it should set the correct workspace and can then call the desired code with C conventions, and then reverse the process when the function returns. (Edit: not automatically - that's all code you need to write.) It's not that difficult, but do ask yourself why you're doing it.

 

It's generally simpler to just set a flag in the ISR and have the C code check it periodically. If the code you're doing is that timing critical that polling isn't an option, you might be better off doing it all in asm. In cases like that, I've sometimes taken the assembly output of the compiler and then worked with that. ;)

 

... I don't think there is a 5th sprite interrupt, though. Are you sure about that?

 

 

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

12 minutes ago, Tursi said:

... I don't think there is a 5th sprite interrupt, though. Are you sure about that?

Not anymore, no :)

I assumed it was there, but I can't find any documentation supporting that assumption. I guess I can poll the status register instead...

 

But I will still investigate the interrupt hook, I want to be able to keep music playing (your vgmcomp2 player) while transferring big chunks of data from cartridge space to VRAM... GCC has a "naked" attribute, so it should be easy enough...

  • Like 3
Link to comment
Share on other sites

Polling works:

 

The blue bar at the bottom references different pattern and name tables from the top part of the screen, there are 5 transparent sprites at line 174, after drawing all the normal stuff, doing game logic, etc... I poll the VDP status register for the 5th sprite flag. As soon as it's detected, I flip some VDP registers, allowing me to show the status bar. There's about two lines of lag between detecting and having switched everything over, but on a screen like this it's almost completely invisible anyway.

  • Like 8
Link to comment
Share on other sites

That's really impressive! It kind of irks me that, back in the day, the C64 got all the attention, but the potential was always there in the TI - it was just kind of locked away. The games and demos we've seen in recent years for the TI show it quite comfortably hold its own with the C64 IMO. And it doesn't have 175 different shades of brown in its colour pallete, so the TI wins all 'round :lolblue:

  • Like 3
Link to comment
Share on other sites

I'd give my left nut for a dark gray in the tms9918a palette though...

 

Also, while I do agree that the TI was criminally underused in its time (just look at the MSX to see what could've been), I do think the C64 can outperform it by quite a bit. Yes, I think most everything done back in the day on the C64 can be done in one way or another on the TI as well, but if you look at some of the recent homebrews for the C64 there's clealy some stuff going on that is way out of our reach. I mean, Mayhem in Monsterland, Sonic, Eye of the Beholder, etc... are homebrew masterpieces :).

 

  • Like 3
  • Haha 1
Link to comment
Share on other sites

21 hours ago, TheMole said:

Polling works:

 

The blue bar at the bottom references different pattern and name tables from the top part of the screen, there are 5 transparent sprites at line 174, after drawing all the normal stuff, doing game logic, etc... I poll the VDP status register for the 5th sprite flag. As soon as it's detected, I flip some VDP registers, allowing me to show the status bar. There's about two lines of lag between detecting and having switched everything over, but on a screen like this it's almost completely invisible anyway.

That's the way to do it! But, do you really need to? It doesn't look like that screen is impossible to draw otherwise? Or are you out of characters? (On the other hand, it looks like the screen is pretty much done so no real need to worry about it ;) ).


 

Quote

But I will still investigate the interrupt hook, I want to be able to keep music playing (your vgmcomp2 player) while transferring big chunks of data from cartridge space to VRAM

 

Just remember to be careful there - your interrupt routine must not TOUCH the VDP address, or that concept will explode in very-hard-to-debug ways. ;) I personally just break my transfers into smaller chunks and have a poll-for-music function that checks if it's time to play. But a lot of my habits have changed with the ColecoVision putting the interrupt on an NMI, and just getting fed up with dealing with that. ;)

 

 

  • Like 3
Link to comment
Share on other sites

48 minutes ago, Tursi said:

That's the way to do it! But, do you really need to? It doesn't look like that screen is impossible to draw otherwise? Or are you out of characters? (On the other hand, it looks like the screen is pretty much done so no real need to worry about it ;) ).

The scrolling eats up a lot of patterns. I keep 8 pattern definition tables in VRAM, which normally would take up the full 16k. Since I need to fit all of the other tables (color, sprite attributes, nametable, sprite patterns) somewhere, I had to half the number of usable patterns. Mostly because of the sprite pattern definitions. So essentially, the background patterns take up the first half of the slot (128 patterns), the sprite patterns the second half. Then, take into account that each unique combination of two consecutive patterns takes up one definition (to let one scroll into the next), some losses for color table alignment, etc...

 

scrolling_max_patterns.thumb.png.38617516bb1c6af417c98af7b79580a3.png

 

So, I upload the font to one of the pattern tables where the second half isn't in use by anything else and set VDP register 4 to that table near the bottom of the screen, hence the need for the pseudo scanline interrupt...

 

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