Jump to content
IGNORED

TI GCC and the Flash ROM


mindlord

Recommended Posts

So, I'm climbing on the shoulders of giants again.

What do I need to do to set up TI GCC to output a image file suitable for use in the Flash99 cart?

 

It would be neat to make small programs that don't require the 32K expansion if possible, but I can accept that reality if necessary.

 

Thanks for any help you can provide.

Link to comment
Share on other sites

I am not sure you will be able to do it without the 32KiB expansion RAM because there is probably not enough writable space in scratchpad RAM (up to 256 bytes). That said, this topic, though a bit convoluted in spots, may help:

 

Creating bank switched cartridges with gcc

 

Read the whole thing (if you can stand the side trips, especially mine! :-o ) and, especially, @Tursi's post #63.

 

...lee

Link to comment
Share on other sites

I don't think you'll get many GCC programs to run without the 32k memory expansion (at least not with a lot of work to the compiler)... the stack is stored in CPU memory, as is all the data, and you are not going to get very much code running with 256 bytes of RAM to store both in. It's theoretically possible to adapt the compiler to store its data in VDP, but it's a lot of work and means new libraries need to be created to support it.

Link to comment
Share on other sites

To Tursi's point, you won't have a lot of room left to do interesting things in C without 32k memory expansion. However, it is possible as long as you limit the number of variables you use in your program. You basically have 224 bytes of RAM at your disposal to do things with (32 bytes are taken up by the registers used by gcc itself), so that's room for 112 integers in total (global + local variables in the entire call stack). You do have 8k (or up to 32k if you do banking, but banking tends to eat up RAM as well for the trampoline functions) available for code and constants, so that's a decent amount.

 

I have compiled things with gcc for systems without 32k before, but just as a proof of concept (and to display a message in my game when it detects that no 32k RAM expansion is detected).

Link to comment
Share on other sites

  • 5 weeks later...

I've gotten my Flash99 and I'm ready to explore this alien world.

 

If I understand The Mole correctly, No special steps need to be taken, just careful memory management for an 8k ROM. Heavy use of CONSTs and Read Only dataspace from the ROM area. There's also some storage in the VDP, if you're willing to sacrifice character sets, am I right?

Bank switching is out of my realm at the moment, and I'd need pointers to research material to learn how it's done.

 

I'm sure I can do some fun stuff with 224 bytes of RAM.

  • Like 1
Link to comment
Share on other sites

... There's also some storage in the VDP, if you're willing to sacrifice character sets, am I right? ...

 

There's plenty of space in VRAM without sacrificing character sets. You just can't run Assembly Language Code (ALC) from there. You can write the VRAM transfer routines in ROM. You only need the limited CPU RAM for writing values that must be manipulated directly by ALC. Of course, I'm talking about ALC programming. I will defer to the likes of @TheMole and @Tursi for GCC.

 

...lee

Link to comment
Share on other sites

So, I'm climbing on the shoulders of giants again.

 

What do I need to do to set up TI GCC to output a image file suitable for use in the Flash99 cart?

 

It would be neat to make small programs that don't require the 32K expansion if possible, but I can accept that reality if necessary.

 

Thanks for any help you can provide.

You could use Java for the TI-99/4A.

 

 

This ended up being a pretty awkward system. The CPU, a TMS9900, only has direct access to 256 bytes of RAM and could only access video / sound registers by reading / writing a couple memory addresses. There is a chunk of extra RAM attached to the video processor, but I decided to just use the 256 byte area for variables. I figured it's not like anyone is going to use this for anything serious anyway.

Also the Bricks demo has been done in Java.

 

;)

Edited by sometimes99er
Link to comment
Share on other sites

  • 2 weeks later...

I wouldn't count gcc out for stock console authoring.

If you generate the mapfile on linkage you can see pretty well how much data segments are consuming. Keep you call stacks shallow. VDP can be used for global state manually on a case by case basis.

 

Gaming from the era should be feasible.

 

I was able to set the data segment to >8300 and edit crt0.asm to set the stack to >83FE, and work with libti99 a bit. ( I haven't figured out the proper way to set the stack location )

 

It seems like a good challenge.

 

For most calls, your stack won't even grow. Or at least you can control it by adopting a style where your game loop is in main.

 

Vdp Interrupt and console rom routines will squeeze you, but aren't there alternate techniques

For all that they offer?

 

-M@

Link to comment
Share on other sites

If you are going to try and take over the scratchpad, I'd recommend ditching the console interrupt function and all other ROM routines. Most of them are easily replaced anyway, and you can poll the VDP for interrupt state.

 

I can't remember if the GCC stack is pre-decrement or post, but in this case it's worth checking. If it's pre-decrement you can set the stack to >8400 and get two more bytes to work with.

 

You could create wrapper functions to store game data in VDP RAM, and so have just a handful of globals and stack data. There's a good chance that might work.

 

I'm sort of reversing my stance from above due to this thread forcing me to think about it more, hehe. There are still some challenges, but it's mostly just keeping an eye on what you're doing. ;)

  • Like 1
Link to comment
Share on other sites

Yep, I was able to set the stack to >8400... I realized after I posted, that I started with one word lower because 'it would work' without having to think... I was again just trying to get something done. The original value was >4000 which is pre-decrement for top of the lower 8k expansion.

 

Here is the 32k ram mem tester I put together that uses libti99, and keeps itself in ROM and scratchpad. I'm not doing anything real interesting, but it shows the change to crt0.asm, and the Makefile with the linker statement to place the data and code. This runs without ram... although, oddly the purpose is to check ram... :)

 

32kmemtest.zip - runs completely out of scratchpad & ROM.

 

matthew180's write up on this forum about game authoring in assembly seem like they apply equally well in concept to this language.

 

-M@

  • Like 2
Link to comment
Share on other sites

  • 2 weeks later...

So, I compiled and ran a program that threw some sprites on the screen and moved them around with the keyboard. Fun stuff. Interesting thing though, Tursi's vdpwaitint() function seems to trigger video corruption.

void vdpwaitvint() {
// wait for a vertical interrupt to occur (enables interrupts - first call may not wait)
VDP_INT_ENABLE; 
while (VDP_INT_COUNTER == gSaveIntCnt) { } 
gSaveIntCnt=VDP_INT_COUNTER; 
VDP_INT_DISABLE; 
}
Link to comment
Share on other sites

 

So, I compiled and ran a program that threw some sprites on the screen and moved them around with the keyboard. Fun stuff. Interesting thing though, Tursi's vdpwaitint() function seems to trigger video corruption.

void vdpwaitvint() {
// wait for a vertical interrupt to occur (enables interrupts - first call may not wait)
VDP_INT_ENABLE; 
while (VDP_INT_COUNTER == gSaveIntCnt) { } 
gSaveIntCnt=VDP_INT_COUNTER; 
VDP_INT_DISABLE; 
}

 

 

If you are operating with the C stack working back from 8400, then you need to leave the interrupts disabled, pretty much all of the time... ( I clear some of that and use his halt function when I'm done, just as a quick hack )

 

Instead, I'm using something like this:

while(!inGameLoop) {
    VDP_WAIT_VBLANK_CRU
    counter++;

    if (counter % 2 == 0) {
      // do stuff every 30th a second...
    }
    if (counter % 6 == 0) {
      // do stuff every 10th a second...
    }
}

This doesn't turn the interrupt on. So the OS ROM handler doesn't go screwing with anything.

 

-M@

Link to comment
Share on other sites

Like jediMatt says. vdpwaitint() enables the VDP interrupt and waits for the jiffy counter to increment. VDP_WAIT_VBLANK_CRU is intended for this sort of situation where you can't use the console ROM interrupt, instead it sets up the CRU (R12) and waits for the interrupt line to go high. Based on testing in the distant past this seemed the safest way to poll. Note that as written you lose the VDP status register, it's read into R12 then discarded. (I should probably change the definition so it can return that value in case the user wants it.)

  • Like 1
Link to comment
Share on other sites

Keeping the status could be nice for knowing if you need to investigate sprite collisions.

Agreed - pushed to github for VDP_WAIT_VBLANK_CRU_STATUS(x) - drop a variable in 'x' to receive the status register. (Note, of course, the vertical interrupt bit will always be set, since that's what the macro waits for ;) ).

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