Jump to content
IGNORED

GCC for the TI


insomnia

Recommended Posts

I've noted that the compiler doesn't generate float (double) literals correctly. Has anyone other than insomnia made any successful attempts at updating the GCC compiler or are we all running with frozen version? As far as I can tell insomnia has permanently left the building. I'm willing to take a go at it at some point, being a fairly low priority. But if someone else is maintaining the compiler in anyway I will happily request help from that person.

 

I pretty much have all the double math and conversion methods complete, including those that the GCC compiler calls when substituting operators. The descriptions and examples of radix 100 are unfortunately incorrect, possibly being the root cause of the compiler's incorrect implementation. From https://www.unige.ch/medecine/nouspikel/ti99/reals.htm:

 

exponent  mantissa                                      decimal

>40      >01 >02 >03 >04 >05 >06 >07   1.020304050607 correct
>41      >01 >02 >03 >04 >05 >06 >0B   10.20304050611 incorrect -- notice that the exponent is 41, thus the number must be >= 100.0. 
                                                      This is mixed radix 10 and 100. The actual value is 10x that stated.

>40        >10 >20 >30 >40 >50 >61 >10.    10.20304050611  correct

 

These TI tech pages are rich with info and I've learned a lot from them. I suspect this has gone relatively unnoticed since the use for doubles is quite limited--its not as if we're all out there developing scientific applications, and generally most math going on is probably integer-based. Much of my current project is developing C libraries, usually those included in libc, at least the more commonly used, and the floating point support is just part of completing the missing aspects. 

  • Like 1
Link to comment
Share on other sites

1 hour ago, Lee Stewart said:

 

Actually, for your example hex to match the floating point decimal number following it, the hex should be

>40   >0A >14 >1E >28 >32 >3D >0A

 

...lee

LOL, yes, you are right! Just goes to show the challenge of radix 100 on my brain.

  • Like 2
Link to comment
Share on other sites

  • 2 months later...

Hi all, I finally have something working with this compiler.  It took me most of the day to work through the various instructions on this thread.  I can't stand docker and only use VMs when absolutely necessary so have a locally installed version instead (debian desktop).  I cloned libti99 and built gcc and binutils including @jedimatt42's instructions to fix the duplicate do_wide problem and @mrvan's updated elf2cart.c and start_cart.asm (though I don't see significant changes in the latter to what is in @Tursi's code in libti99).
 

Even with the above I was getting a jump to >0000 as the address in @>8320 wasn't set to vdpvchar().  Turns out I had .data=8320 in my Makefile which seems to override libti99's value of >2080 and mess up data init.
 

And then just figuring out what I had to call in libti99 to get my text to appear - I made a false assumption that character pattern table is filled by default - but it isn't.
 

It would be good if this project had a maintainer and it was on a github somewhere we could contribute.  Would @insomnia mind if we did that? 

#include <vdp.h>

int main(void)
{
    set_graphics(0);
    charset();
    puts("hello world");
    while(1);
    return 0;
}

image.thumb.png.e7e8016280b6b400f500ccc993d8f181.png

  • Like 4
Link to comment
Share on other sites

libti99 includes two sample applications - example.c is literally what you were looking for as all it does is load the character set, define a smiley face character, and put them on the screen. ;)

image.thumb.png.d0320eb75be54e3ea84705921432ae40.png
 

Spoiler


// Sample app using conio to print hello.

#include <conio.h>
#include <vdp.h>

const char newDef[8] = { 0x3c,0x42,0xa5,0x81,0xa5,0x99,0x42,0x3c };

int main(void)
{
    set_graphics(VDP_SPR_16x16);                        // set video mode
    charsetlc();                                        // load character set with lowercase
    vdpmemset(gImage, 32, 768);                         // clear screen
    VDP_SET_REGISTER(VDP_REG_COL, COLOR_MEDGREEN);   	// set screen color
    vdpmemset(gColor, 0x10, 32);                        // set colors to black on transparent
   
    vdpmemcpy(gPattern+42*8, newDef, 8);                // redefine character 42

    gotoxy(2,2);                                        // set cursor position

    cprintf("Hello *");                                 // say hi

    while(1) {                                          // spin forever
        VDP_INT_POLL;                                   // enable interrupts during the loop so QUIT works
    };

    return 0;
}

 

 

Sorry you had to fight through it, but at least you are there now! Be aware that the compiler still has some issues with multiply/divide and rarely with char<->int conversion. Be suspicious when you have unexpected behaviour and check the listing carefully or step through with a debugger. Also consider always saving the listing file. ;)

 

I've got an updated libti99 that I hope to promote to main soon, it pulls the TI and Coleco versions together into one shared one and adds features that were piecemeal in each. Also want to release some small updates for banking - I know everyone has their favorite way but my Super Space Acer development forced me to create a favorite for myself. That will cause at least some slight documentation to exist. ;)

 

  • Like 4
Link to comment
Share on other sites

Hi @mrvan!
Please do. The compiler needs some fixes badly. I have reported here several bugs.
I use it in my Cross-Lib project, which is about using the very same game code (with some abstract APIs) to be compiled with more than a dozen different C cross-compilers.
GCC for TI is the only one that needs code adaptations and work arounds.
I have written 8 games and several test cases in Cross-Lib that can be built with several cross-compilers and could provide some non-trivial tests.

There is at least an alternative compiler that I have not been able to test because it its installation and usage is not straightforward:
https://github.com/EtchedPixels/pcc-tms9995

Indeed, if you even decide to work on the compiler, it may help you and other devs to create a GitHub repository so that your effort can be shared and maybe someone else could contribute.

Link to comment
Share on other sites

55 minutes ago, Fabrizio Caruso said:

There is at least an alternative compiler that I have not been able to test because it its installation and usage is not straightforward:
https://github.com/EtchedPixels/pcc-tms9995

Yeah, tried too compile that one myself (because I was interested in giving Fuzix a spin) and didn't manage to build it either. I'm not sure if @EtchedPixels is planning to finish this at some point, but it would be good to have an alternative.

 

I also looked at what it would take to create a backend for a more modern version of gcc or perhaps even llvm, but there's a clear mismatch between the skills required to tackle that kind of job and my current capabilities :).

  • Like 1
Link to comment
Share on other sites

5 hours ago, Tursi said:

 

 libti99 includes two sample applications - example.c is literally what you were looking for as all it does is load the character set, define a smiley face character, and put them on the screen. ;)

 

D'oh!  How did I miss that 🙂

 

5 hours ago, Tursi said:

Sorry you had to fight through it, but at least you are there now! Be aware that the compiler still has some issues with multiply/divide and rarely with char<->int conversion. Be suspicious when you have unexpected behaviour and check the listing carefully or step through with a debugger. Also consider always saving the listing file. ;)

 

It was a good way to get over the learning curve.  But I'm seeing even more fundamental issues.  This:
 

short func (short x)
{
    short a = 55;
    return a;
}


emits this:
 

0000010a <func>:
 10a:	02 2a ff fa 	ai r10, >FFFA
 10e:	c6 89       	mov r9, *r10
 110:	c2 4a       	mov r10, r9
 112:	ca 41 00 02 	mov r1, @>0002(r9)
 116:	02 01 00 37 	li r1, >0037
 11a:	c6 41       	mov r1, *r9
 11c:	c0 59       	mov *r9, r1
 11e:	c2 5a       	mov *r10, r9
 120:	02 2a 00 06 	ai r10, >0006
 124:	04 5b       	b *r11


Surely 112 and 116 are transposed and then 11a clobbers the base pointer.  Hmmmm.  Doesn't happen with -O2 I wonder if optimisation hides issues.  I'll keep digging

(Correction, 112 is correct, it is saving the parameter to the function stack frame)

  • Like 3
Link to comment
Share on other sites

Os is working fine on Super Space Acer (mostly) so far. O2 also works well for me. I have zero luck with O1 and no optimization flag at all.

 

But yeah, sometimes it spits out some odd patterns. I think Insomnia did most of his testing on O2. 

 

Unfortunately the compiler backend is a bit over my head too. Before Insomnia did this I took a stab at it and got as far as Hello World compiling, but there were still a lot of issues. Mine was pretty much a dead end, but I found starting with the PDP11 port was not too bad.

 

I saw a project where someone created a cross-compiler for a subset of Intel 386 assembly and output 6502 from that. The advantage was they could use the latest Intel compiler to generate the code, then have the slightly simpler task of converting the assembly. Slightly simpler is still a pretty big challenge.. and going from 386 to 9900 would actually leave some performance on the table since we have more registers. ;) But it's a tempting idea.

 

  • Like 2
Link to comment
Share on other sites

1 hour ago, Tursi said:

Os is working fine on Super Space Acer (mostly) so far. O2 also works well for me. I have zero luck with O1 and no optimization flag at all.

 

But yeah, sometimes it spits out some odd patterns. I think Insomnia did most of his testing on O2. 

 

Unfortunately the compiler backend is a bit over my head too. Before Insomnia did this I took a stab at it and got as far as Hello World compiling, but there were still a lot of issues. Mine was pretty much a dead end, but I found starting with the PDP11 port was not too bad.

 

I saw a project where someone created a cross-compiler for a subset of Intel 386 assembly and output 6502 from that. The advantage was they could use the latest Intel compiler to generate the code, then have the slightly simpler task of converting the assembly. Slightly simpler is still a pretty big challenge.. and going from 386 to 9900 would actually leave some performance on the table since we have more registers. ;) But it's a tempting idea.

 

Interesting, so I'm in uncharted territory with no optimisation.  Ok well it's probably the easiest place to start.  I'll see if I can figure out enough of the back-end to fix this issue.  See you in 6 months or so 🙂

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

35 minutes ago, khanivore said:

Interesting, so I'm in uncharted territory with no optimisation.  Ok well it's probably the easiest place to start.  I'll see if I can figure out enough of the back-end to fix this issue.  See you in 6 months or so 🙂

Not so much uncharted territory as I believe it actually doesn't work. SSA's codebase crashes the compiler with optimizations unspecified. ;) I believe it has problems with register allocation.

 

  • Sad 1
Link to comment
Share on other sites

1 hour ago, Tursi said:

Not so much uncharted territory as I believe it actually doesn't work. SSA's codebase crashes the compiler with optimizations unspecified. ;) I believe it has problems with register allocation.

 

Yeah register allocation is the bit I'm looking at.  I was thinking its a good starter bug to familiarise.

  • Like 2
Link to comment
Share on other sites

6 hours ago, TheMole said:

Yeah, tried too compile that one myself (because I was interested in giving Fuzix a spin) and didn't manage to build it either. I'm not sure if @EtchedPixels is planning to finish this at some point, but it would be good to have an alternative.

 

I also looked at what it would take to create a backend for a more modern version of gcc or perhaps even llvm, but there's a clear mismatch between the skills required to tackle that kind of job and my current capabilities :).

I looked at LLVM--yikes. The MSP430 backend might be close to the 9900 though.
 

MSP430 is a TI processor that is still evolving. It's also 16 bits, 64K total address space, fixed registers. However the LLVM backend notes say "not tested much".  
 

I'm tempted to try out the LLVM clang MSP430, for the TI LaunchPad I'm using for my reflow oven. But that might be a big job, first trying to get TI's starter C code away from their Code Composer environment. 
 

But back to the 9900.  You mention a 386 to 6502 translator. Idea: MSP430 to 9900 translator. I think the MSP430 is the only 16-bit target supported in LLVM. 
 

  • Like 2
  • Thanks 1
Link to comment
Share on other sites

Testing a theory ....

I think that in the prologue and epilogue code in tms9900.c, the allocated stack space to save the registers and the space for the stack frame are in the wrong order and the tms9900 code and GCC are both stepping on each others' storage at @0[SP].  The GCC codebase is a bit big (who knew!) so rather than wading through 3 million or so lines to find where it decides to allocate space on the stack for locals, I refactored tms9900.c to make two separate additions/substractions to SP and it seems to be generating better code now.

I don't see any stack frames output with -O2 as I guess the optimiser makes better use of registers and rarely needs a stack frame but if it is a bug then at some point it would surface even with -O2/-O3.  It seems -O2/-O3 would just hide this issue.

I'll try and get this up on github tomorrow to avoid more patches, but for now here's my attempted solution:

tms9900.patch

  • Like 5
Link to comment
Share on other sites

Hi @khanivore
If possible, could you please simplify the installation process? Many people (including myself) have struggled to install the compiler. I have managed after several failed attempts.

By the way, the current version fails on 3 out of my 8 Cross-Lib (https://github.com/Fabrizio-Caruso/CROSS-LIB) games with this error:

games/stinger/main.c:1069: internal compiler error: output_operand: invalid expression as operand


The error does not make much sense to me also because all my games are correctly compiled by all other compilers (more than a dozen) including recent GCC versions.

For example in one game line 1069 is the last line (closed brace) of this function

void power_up_effect(void)
{    
    ++powerUp;
    
    if(!(powerUp%5))
    {
        activate_hyper();
    }
    
    display_power_up_counter();
    increase_score(POWERUP_POINTS);
    
    switch(powerUp)
    {    
        case 1:
            stinger_reload_loops=YELLOW_SPEED_VALUE;
        break;
           
        case 2:
            stinger_reload_loops=GREEN_SPEED_VALUE;
        break;
        
        case 3:
            fire_power = YELLOW_FIRE_POWER_VALUE;
        break;
        
        case 4:
            fire_power = GREEN_FIRE_POWER_VALUE;
        break;
        
        // case 5:
        // break;
        
        case 17:
            #if !defined(_XL_NO_COLOR)
            powerUpItem._color = SECRET_COLOR;
            #endif
        break;
        
        case 18:
            secret_locked = 0;
			#if !defined(_XL_NO_COLOR)
            powerUpItem._color = _XL_WHITE;
			#endif

        break;
        
        default:
        break;
    }
    display_power_ups();
}


 

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

I'll just throw in here, Fred has offered to make the source code to his C compiler available, we also have the source code to Clint's C compiler which ran on the amiga, pc and geneve. It might be easier to maintain that for the TI, then trying to respond to upgrades when they are made in more mainstream compilers like gcc, clang, etc.

  • Like 1
Link to comment
Share on other sites

45 minutes ago, dhe said:

I'll just throw in here, Fred has offered to make the source code to his C compiler available, we also have the source code to Clint's C compiler which ran on the amiga, pc and geneve. It might be easier to maintain that for the TI, then trying to respond to upgrades when they are made in more mainstream compilers like gcc, clang, etc.

It's a good point.  gcc-4.4.0 is already over 10 yrs old and a rebase from latest could be very painful.  Then again our needs from a compiler for tms9900 are likely to be very stable.  I'll create a repo anyway for the GCC one and we at least have options then.

Link to comment
Share on other sites

3 hours ago, Fabrizio Caruso said:

Hi @khanivore
If possible, could you please simplify the installation process? Many people (including myself) have struggled to install the compiler. I have managed after several failed attempts.

Yeah, will definitely try to make it easier.  I can create .deb files for those on debian/ubuntu, but windows/cygwin users would still need to build from source.  Right now I'm caught between committing the entire gcc source to github or just archiving the files that change and generating new patch files on each release.  I'll stick with deltas for now I think.

 

3 hours ago, Fabrizio Caruso said:

By the way, the current version fails on 3 out of my 8 Cross-Lib (https://github.com/Fabrizio-Caruso/CROSS-LIB) games with this error:

games/stinger/main.c:1069: internal compiler error: output_operand: invalid expression as operand

I can't see any issues with the code fragment you posted but will take a look once I get the github set up.

  • Like 2
Link to comment
Share on other sites

1 hour ago, Fabrizio Caruso said:

@khanivore Thanks!

Could you please document the exact steps to install from source?
 

The install script *should* do everything for you.  Just clone the main branch and run install.sh but let me know if anything doesn't work.  I just merged the stack frame fix with an updated README

  • Like 1
  • Thanks 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   1 member

×
×
  • Create New...