LCC for the Gigatron. Take two.
Forum rules
Be nice. No drama.
Be nice. No drama.
Re: LCC for the Gigatron. Take two.
Releasing GLCC-RELEASE-1.1
This new version has a complete ANSI C 89 library with the trigonometrics and hyperbolic functions that were missing from 1.0.
It is available from the github page https://github.com/lb3361/gigatron-lcc.
Thanks to axelb, it now compiles under Windows using either cygwin or mingw64.
Linux and Mac users are simply encouraged to clone the directory and follow the instructions of the README.md file.
Todo: cmake...
This new version has a complete ANSI C 89 library with the trigonometrics and hyperbolic functions that were missing from 1.0.
It is available from the github page https://github.com/lb3361/gigatron-lcc.
Thanks to axelb, it now compiles under Windows using either cygwin or mingw64.
Linux and Mac users are simply encouraged to clone the directory and follow the instructions of the README.md file.
Todo: cmake...
Last edited by lb3361 on 01 Sep 2021, 21:42, edited 1 time in total.
Re: LCC for the Gigatron. Take two.
Gigatron LCC for Windows
Porting GLCC to Windows has several aspects. Besides compiling the GLCC executables for Windows and ensuring that invoking the command `glcc` or `glink` finds the correct version of Python, we also need to consider which supporting commands are available to a programmer writing Gigatron programs with GLCC. Under Unix, a programmer can rely on a`make` command and on many standardized commands to manipulate and process files. Under Windows, similar facilities exists but are different or sometimes require installing other packages. One solution is simply to install Cygwin https://www.cygwin.org. Thanks to axelb, GLCC can be built, installed, and used under Cygwin just like one builds it, install it, or use it under Unix. The only problem is that what was built in Cygwin remains in Cygwin. For instance, there is no easy way to execute such a version of GLCC from the Windows command line. Everything has to happen from the Cygwin command line.
Many readers of this post have already installed Git for Windows (https://gitforwindows.org). It turns out that Git for Windows comes with a very stable and very well optimized suite of Unix-like tools, derived from MSYS2, and accessible through the "Git Bash" start menu item. Since they are already on your system, why not providing GLCC for Windows as an addon?
Prerequisites:
[Update] We now have a CMake version that makes it *theoretically* possible with any compiler including Microsoft's MSVC.
[Update] I'll periodically update the Windows binary in this post to keep it current.
Porting GLCC to Windows has several aspects. Besides compiling the GLCC executables for Windows and ensuring that invoking the command `glcc` or `glink` finds the correct version of Python, we also need to consider which supporting commands are available to a programmer writing Gigatron programs with GLCC. Under Unix, a programmer can rely on a`make` command and on many standardized commands to manipulate and process files. Under Windows, similar facilities exists but are different or sometimes require installing other packages. One solution is simply to install Cygwin https://www.cygwin.org. Thanks to axelb, GLCC can be built, installed, and used under Cygwin just like one builds it, install it, or use it under Unix. The only problem is that what was built in Cygwin remains in Cygwin. For instance, there is no easy way to execute such a version of GLCC from the Windows command line. Everything has to happen from the Cygwin command line.
Many readers of this post have already installed Git for Windows (https://gitforwindows.org). It turns out that Git for Windows comes with a very stable and very well optimized suite of Unix-like tools, derived from MSYS2, and accessible through the "Git Bash" start menu item. Since they are already on your system, why not providing GLCC for Windows as an addon?
Prerequisites:
- Install Git for Windows (https://gitforwindows.org) with the default options.
- Install Python for Windows (https://www.python.org/downloads/windows), at least version 3.8, with the `py` launcher installed for all users.
- Download the attached file `glcc-1.3.zip` and extract it somewhere, for instance in `c:\glcc`.
- To use GLCC from the Windows command line, open a command window (cmd.exe), and add `c:\glcc\bin` to the search path with the following command. You can then invoke `glcc`, `glink`, and `gtsim` in this window.
Code: Select all
C> path c:\glcc\bin;%PATH%
- To use GLCC from the Git Bash, open a Git Bash window and add `/c/glcc/bin` to the search path with the following command. You can then invoke `glcc`, `glink`, and `gtsim` directly. You can also use `git` or any of the many unix-like commands available in Git bash. You can even invoke `make` because /c/glcc/bin also contains a Mingw version GNU-Make (https://packages.msys2.org/package/ming ... po=mingw32).
For instance you can directly compile versions of the horizon program by simply invoking the command `make`.
Code: Select all
joe@machine MINGW32 /Users/joe $ PATH=/c/glcc/bin:$PATH $ alias glcc=glcc.cmd
No need to change anything.Code: Select all
joe@machine MINGW32 /Users/joe $ cd /c/glcc/stuff/horizon joe@machine MINGW32 /c/glcc/stuff/horizon $ make glcc -map=32k,./horizon.ovl --no-runtime-bss-init -rom=v4 horizon.c -o horizon-v4.gt1 glcc -map=32k,./horizon.ovl --no-runtime-bss-init -rom=v5a horizon.c -o horizon-v5a.gt1 glcc -map=32k,./horizon.ovl --no-runtime-bss-init -rom=at67x horizon.c -o horizon-at67x.gt1 joe@machine MINGW32 /c/glcc/stuff/horizon $ ls -l ...
[Update] We now have a CMake version that makes it *theoretically* possible with any compiler including Microsoft's MSVC.
[Update] I'll periodically update the Windows binary in this post to keep it current.
- Attachments
-
- glcc-1.5.zip
- (1.47 MiB) Downloaded 53 times
-
- glcc-1.4.zip
- (1.44 MiB) Downloaded 88 times
-
- glcc-1.3.zip
- (1.43 MiB) Downloaded 166 times
Last edited by lb3361 on 21 May 2022, 10:51, edited 4 times in total.
Re: LCC for the Gigatron. Take two.
Now that GLCC is updated recently, how can I see the version of my installed files?
I am using virtual Ubuntu linux as enviroment.
I am using virtual Ubuntu linux as enviroment.
Re: LCC for the Gigatron. Take two.
Ooops. Good question. I should have a version string and a change log somewhere

In the mean time you can try `glcc -v` to know when the code was compiled.
Code: Select all
$ glcc -v
/c/glcc/lib/gigatron-lib/lcc -v
lcc: (compiled on Sep 14 2021)
- A file `GLCC.log` describing the changes (https://github.com/lb3361/gigatron-lcc/ ... r/LOG.glcc)
- A new option `-V` in glcc and glink to report the version.
The version is reported from command `git-describe --tags`. For instance the above version string means
Code: Select all
$ glcc -V GLCC_RELEASE_1.3-3-gf8c3d76
that the running version is 3 commit ahead of tag `GLCC_RELEASE_1.3` at commit `f8c3d76...`
Re: LCC for the Gigatron. Take two.
Release 1.4 of the Gigatron C Compiler
This new release has lots of little changes and bug fixes.
Windows users can also use the attached pre-compiled binaries.
Note: the compiler can generate code for an earlier version of at67's ROM with new vCPU instruction. However the current version of this ROM has been substantially improved in partially incompatible ways. I will update the compiler once the ROM is released.
This new release has lots of little changes and bug fixes.
- A more compact and more customizable console code. The screen geometry can be changed by overriding the data structure console_info and the function _console_reset(). The recognized control characters can be changed by overriding _console_ctrl().
- A slightly more compact code for formatted output (a.k.a. printf).
- A new function cprintf() that prints formatted output to the console, bypassing stdio. Using this function costs about 2KB but saves 2KB over using printf and importing all the stdio machinery.
- A new option --frags that shows how the program elements fit in the Gigatron memory.
- A simplified _start which reduces the library overhead for simple programs.
- Wrappers for more SYS_ functions.
- Lots of bug fixes.
Windows users can also use the attached pre-compiled binaries.
Note: the compiler can generate code for an earlier version of at67's ROM with new vCPU instruction. However the current version of this ROM has been substantially improved in partially incompatible ways. I will update the compiler once the ROM is released.
- Attachments
-
- glcc-1.4.zip
- (1.44 MiB) Downloaded 126 times
Re: LCC for the Gigatron. Take two.
Question about compiler. I have this lotto simulation program and I tested it with GCC in Linux. Worked fine, but GLCC is unable to compile it. Anything to fix here? Some point there was too little memory for program.
Code: Select all
./build/glcc ../CODE/lottosimu.c -o ../CODE/lottosimu.gt1
cpp: ../CODE/lottosimu.c:7 Syntax error in #include
cpp: ../CODE/lottosimu.c:8 Syntax error in #include
Code: Select all
/*----------------------------------------------------------------------+
| |
| lottosimu.c -- demonstrate lotto number simulation |
| / quick and dirty Eurojackpot |
| |
+----------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
void main()
{
int b0[5],bb[5],i,ii,total,game,cash,sw,saldo,jp,it;
int bt0[2],bbt[2];
int totalbt,eit,egame;
int sil; //printout silence mode
int cup; //cupoung silence mode
printf("\nEurojackpot simulation: ");
printf("\nEnter number of iterations 1-100000: ");
scanf("%d",&eit);
printf("\nEnter number of game rounds 1-3380: ");
scanf("%d",&egame);
printf("\nPrintout silence mode 0/1: ");
scanf("%d",&sil);
printf("\nCupoung silence mode 0/1: ");
scanf("%d",&cup);
for(it=0;it<eit;it++) //iterations 1-100000
{
cash=0;
for(game=0;game<egame;game++) //game rounds how many weeks 1-3380
{
/*----------------------------------------------------------------------+
| |
| |
| Eurojackpot - input rows |
| |
+----------------------------------------------------------------------*/
/*----------------------------------------------------------------------+
| |
| |
| Eurojackpot - input row 1 |
| |
+----------------------------------------------------------------------*/
sw=0;
//printf("\nEnter eurojackpot numbers 5pcs 1-50 R1: ");
for(i=0;i<5;i++)
{
b0[i]=rand() % 50 +1;
for(ii=0;ii<5;ii++)
{
if(b0[ii] == b0[i] && (ii != i)) sw=1;
}
if(sw==1){
i--;
sw=0;
}
}
sw=0;
//printf("\nEnter eurojackpot starnumbers 2pcs 1-10 R1: ");
for(i=0;i<2;i++)
{
bt0[i]=rand() % 10 +1;
for(ii=0;ii<2;ii++)
{
if(bt0[ii] == bt0[i] && (ii != i)) sw=1;
}
if(sw==1){
i--;
sw=0;
}
}
if(cup != 1) printf("\nEurojackpot R1:\t\t\t %d + %d + %d + %d + %d * %d + %d\n",b0[0],b0[1],b0[2],b0[3],b0[4],bt0[0],bt0[1]);
/*----------------------------------------------------------------------+
| |
| |
| Eurojackpot - input right row |
| |
+----------------------------------------------------------------------*/
sw=0;
//printf("\nEnter winning eurojackpot numbers 5pcs 1-50: ");
for(i=0;i<5;i++)
{
bb[i]=rand() % 50 +1;
for(ii=0;ii<5;ii++)
{
if(bb[ii] == bb[i] && (ii != i)) sw=1;
}
if(sw==1){
i--;
sw=0;
}
}
sw=0;
//printf("\nEnter winning eurojackpot starnumbers 2pcs 1-10: ");
for(i=0;i<2;i++)
{
bbt[i]=rand() % 10 +1;
for(ii=0;ii<2;ii++)
{
if(bbt[ii] == bbt[i] && (ii != i)) sw=1;
}
if(sw==1){
i--;
sw=0;
}
}
if(cup != 1) printf("\nEurojackpot winning row:\t\t\t %d + %d + %d + %d + %d * %d + %d\n",bb[0],bb[1],bb[2],bb[3],bb[4],bbt[0],bbt[1]);
/*----------------------------------------------------------------------+
| |
| |
| Eurojackpot - output results |
| |
+----------------------------------------------------------------------*/
jp=rand() % 80000000 + 10000000; //jackpot 10-90 milj. euro
/*----------------------------------------------------------------------+
| |
| |
| Eurojackpot - output row 1 |
| |
+----------------------------------------------------------------------*/
total=0;
for(i=0;i<5;i++)
{
for(ii=0;ii<5;ii++)
{
if(bb[i]==b0[ii])
{
total++;
}
}
}
totalbt=0;
for(i=0;i<2;i++)
{
for(ii=0;ii<2;ii++)
{
if(bbt[i]==bt0[ii])
{
totalbt++;
}
}
}
if(cup != 1) printf("\nEurojackpot numbers correct R1:\t\t\t %d * %d\n",total,totalbt);
if(total==5 && totalbt==2) {
cash=cash+jp;
if(sil != 1) printf("\nEurojackpot\t\t\t %d euro win\n",jp);
}
if(total==5 && totalbt==1) {
cash=cash+500000;
if(sil != 1) printf("\nEurojackpot 500 000 euro win\n");
}
if(total==5 && totalbt==0) {
cash=cash+100000;
if(sil != 1) printf("\nEurojackpot 100 000 euro win\n");
}
if(total==4 && totalbt==2) {
cash=cash+4200;
if(sil != 1) printf("\nEurojackpot 4200 euro win\n");
}
if(total==4 && totalbt==1) {
cash=cash+240;
if(sil != 1) printf("\nEurojackpot 240 euro win\n");
}
if(total==4 && totalbt==0) {
cash=cash+100;
if(sil != 1) printf("\nEurojackpot 100 euro win\n");
}
if(total==3 && totalbt==2) {
cash=cash+60;
if(sil != 1) printf("\nEurojackpot 60 euro win\n");
}
if(total==2 && totalbt==2) {
cash=cash+20;
if(sil != 1) printf("\nEurojackpot 20 euro win\n");
}
if(total==3 && totalbt==1) {
cash=cash+18;
if(sil != 1) printf("\nEurojackpot 18 euro win\n");
}
if(total==1 && totalbt==2) {
cash=cash+10;
if(sil != 1) printf("\nEurojackpot 10 euro win\n");
}
if(total==2 && totalbt==1) {
cash=cash+8;
if(sil != 1) printf("\nEurojackpot 8 euro win\n");
}
/*----------------------------------------------------------------------+
| |
| |
| Eurojackpot - reports |
| |
+----------------------------------------------------------------------*/
saldo = cash - game * 2 -2;
if(sil != 1 && saldo > 1) printf("\nEurojackpot game round, win, 1 euro saldo:\t\t\t %d+%d+%d\n",game,cash,saldo);
if(sil != 1 && saldo > 10) printf("\nEurojackpot game round, win, 10 euro saldo:\t\t\t %d+%d+%d\n",game,cash,saldo);
if(sil != 1 && saldo > 100) printf("\nEurojackpot game round, win, 100 euro saldo:\t\t\t %d+%d+%d\n",game,cash,saldo);
if(sil != 1 && saldo > 1000) printf("\nEurojackpot game round, win, 1 000 euro saldo:\t\t\t %d+%d+%d\n",game,cash,saldo);
if(sil != 1 && saldo > 10000) printf("\nEurojackpot game round, win, 10 000 euro saldo:\t\t\t %d+%d+%d\n",game,cash,saldo);
if(sil != 1 && saldo > 100000) printf("\nEurojackpot game round, win, 100 000 euro saldo:\t\t\t %d+%d+%d\n",game,cash,saldo);
if(sil != 1 && saldo > 1000000) printf("\nEurojackpot game round, win, 1 000 000 euro saldo:\t\t\t %d+%d+%d\n",game,cash,saldo);
if(sil != 1 && saldo > 10000000) printf("\nEurojackpot game round, win, 10 000 000 euro saldo:\t\t\t %d+%d+%d\n",game,cash,saldo);
if(sil != 1 && saldo > 100000000) printf("\nEurojackpot game round, win, 100 000 000 euro saldo:\t\t\t %d+%d+%d\n",game,cash,saldo);
}
//if(saldo > 1000000)
printf("\nEurojackpot iteration, game round, win, saldo:\t\t\t %d + %d + %d + %d\n",it,game,cash,saldo);
}
}
Re: LCC for the Gigatron. Take two.
Seems there was some invisble chracter in text. Cleaned everything with nano editor and got off syntax errors.
Now it seems using printf and maybe scanf eats too much memory.
I made one version without any output printf and was able to compile it to romv5a, but it didn\t compile to romv4.
There was some notes in github/lb3361 about doing this low level to save memory.
I tried some of console functions. Pretty clear how to output strings or chars, but what about numbers...lets say 1234?
Now it seems using printf and maybe scanf eats too much memory.
I made one version without any output printf and was able to compile it to romv5a, but it didn\t compile to romv4.
There was some notes in github/lb3361 about doing this low level to save memory.
I tried some of console functions. Pretty clear how to output strings or chars, but what about numbers...lets say 1234?
Code: Select all
#include <stdio.h>
#include <stdlib.h>
#include <gigatron/console.h>
void main()
{
int b0[5],bb[5],i,ii,total,game,cash,sw,saldo,jp,it;
int bt0[2],bbt[2];
int totalbt,eit,egame;
int sil; //printout silence mode
int cup; //cupoung silence mode
console_state.cx = 0;
console_state.cy = 0;
console_state.fgbg = (((48-48)*6+1) & 0x3f) << 8;
console_print("Eurojackpot simu:", 17);
console_state.cx = 0;
console_state.cy = 1;
console_state.fgbg = (((48-48)*6+1) & 0x3f) << 8;
console_print("Nbr of iterations:", 20);
scanf("%d",&eit);
console_state.cx = 0;
console_state.cy = 2;
console_state.fgbg = (((48-48)*6+1) & 0x3f) << 8;
console_print("Nbr of games:", 20);
scanf("%d",&egame);
console_state.cx = 0;
console_state.cy = 3;
console_state.fgbg = (((48-48)*6+1) & 0x3f) << 8;
console_print("Printout silence 0/1:", 21);
scanf("%d",&sil);
console_state.cx = 0;
console_state.cy = 4;
console_state.fgbg = (((48-48)*6+1) & 0x3f) << 8;
console_print("Cupoung silence 0/1:", 20);
scanf("%d",&cup);
for(it=0;it<eit;it++) //iterations 1-100000
{
cash=0;
for(game=0;game<egame;game++) //game rounds how many weeks 1-3380
{
sw=0;
for(i=0;i<5;i++)
{
b0[i]=rand() % 50 +1;
for(ii=0;ii<5;ii++)
{
if(b0[ii] == b0[i] && (ii != i)) sw=1;
}
if(sw==1){
i--;
sw=0;
}
}
sw=0;
for(i=0;i<2;i++)
{
bt0[i]=rand() % 10 +1;
for(ii=0;ii<2;ii++)
{
if(bt0[ii] == bt0[i] && (ii != i)) sw=1;
}
if(sw==1){
i--;
sw=0;
}
}
//if(cup != 1) printf("\nRow1:%d+%d+%d+%d+%d*%d+%d\n",b0[0],b0[1],b0[2],b0[3],b0[4],bt0[0],bt0[1]);
sw=0;
for(i=0;i<5;i++)
{
bb[i]=rand() % 50 +1;
for(ii=0;ii<5;ii++)
{
if(bb[ii] == bb[i] && (ii != i)) sw=1;
}
if(sw==1){
i--;
sw=0;
}
}
sw=0;
for(i=0;i<2;i++)
{
bbt[i]=rand() % 10 +1;
for(ii=0;ii<2;ii++)
{
if(bbt[ii] == bbt[i] && (ii != i)) sw=1;
}
if(sw==1){
i--;
sw=0;
}
}
//if(cup != 1) printf("\nWinning row:%d+%d+%d+%d+%d*%d+%d\n",bb[0],bb[1],bb[2],bb[3],bb[4],bbt[0],bbt[1]);
jp=rand() % 80000000 + 10000000; //jackpot 10-90 milj. euro
total=0;
for(i=0;i<5;i++)
{
for(ii=0;ii<5;ii++)
{
if(bb[i]==b0[ii])
{
total++;
}
}
}
totalbt=0;
for(i=0;i<2;i++)
{
for(ii=0;ii<2;ii++)
{
if(bbt[i]==bt0[ii])
{
totalbt++;
}
}
}
//if(cup != 1) printf("\nNumbers correct Row1:%d*%d\n",total,totalbt);
if(total==5 && totalbt==2) {
cash=cash+jp;
//if(sil != 1) printf("\n%d euro win\n",jp);
}
if(total==5 && totalbt==1) {
cash=cash+500000;
//if(sil != 1) printf("\n500 000 euro win\n");
}
if(total==5 && totalbt==0) {
cash=cash+100000;
//if(sil != 1) printf("\n100 000 euro win\n");
}
if(total==4 && totalbt==2) {
cash=cash+4200;
//if(sil != 1) printf("\n4200 euro win\n");
}
if(total==4 && totalbt==1) {
cash=cash+240;
//if(sil != 1) printf("\n240 euro win\n");
}
if(total==4 && totalbt==0) {
cash=cash+100;
//if(sil != 1) printf("\n100 euro win\n");
}
if(total==3 && totalbt==2) {
cash=cash+60;
//if(sil != 1) printf("\n60 euro win\n");
}
if(total==2 && totalbt==2) {
cash=cash+20;
//if(sil != 1) printf("\n20 euro win\n");
}
if(total==3 && totalbt==1) {
cash=cash+18;
//if(sil != 1) printf("\n18 euro win\n");
}
if(total==1 && totalbt==2) {
cash=cash+10;
//if(sil != 1) printf("\n10 euro win\n");
}
if(total==2 && totalbt==1) {
cash=cash+8;
//if(sil != 1) printf("\n8 euro win\n");
}
saldo = cash - game * 2 -2;
//if(sil != 1 && saldo > 100) printf("\nGame,win,100 euro saldo:%d+%d+%d\n",game,cash,saldo);
//if(sil != 1 && saldo > 1000) printf("\nGame,win,1000 euro saldo:%d+%d+%d\n",game,cash,saldo);
//if(sil != 1 && saldo > 10000) printf("\nGame,win,10000 euro saldo:%d+%d+%d\n",game,cash,saldo);
//if(sil != 1 && saldo > 100000) printf("\nGame,win,100000 euro saldo:%d+%d+%d\n",game,cash,saldo);
//if(sil != 1 && saldo > 1000000) printf("\nGame,win,1000000 euro saldo:%d+%d+%d\n",game,cash,saldo);
//if(sil != 1 && saldo > 10000000) printf("\nGame,win,10000000 euro saldo:%d+%d+%d\n",game,cash,saldo);
}
console_state.cx = 0;
console_state.cy = 10;
console_state.fgbg = (((48-48)*6+1) & 0x3f) << 8;
console_print("Iteration,game,win,saldo:", 25);
//printf("\n%d+%d+%d+%d\n",it,game,cash,saldo);
}
}
Last edited by veekoo on 01 Feb 2022, 11:25, edited 1 time in total.
Re: LCC for the Gigatron. Take two.
Recent compiler versions have "cprintf" in "console.h", which is far better than "printf". It bypasses stdio like "console_print" but can print numbers, etc. However, if you use scanf, you still bring stdio in your program. To read an integer, you can instead write a small routine that uses "console_readline" and "atoi" or "strtol".
Something like:
You can also use option '-Wl-d' or '--frags' to see what's being compiled in.
Finally you can also use '-map=conx' to steal memory from the video buffer (just like msbasic). This doubles the usable memory on a 32k gigatron.
Something like:
Code: Select all
...
#include <gigatron/console.h>
...
int readint(const char *prompt)
{
char buffer[32];
cprintf(prompt, strlen(prompt));
console_readline(buffer, sizeof(buffer));
return atoi(buffer);
}
void main()
{
...
cprintf("\nEurojackpot simulation: ");
elt = readint("\nEnter number of iterations 1-100000: ");
...
Finally you can also use '-map=conx' to steal memory from the video buffer (just like msbasic). This doubles the usable memory on a 32k gigatron.
Re: LCC for the Gigatron. Take two.
Spot on advices! With minimal change to previous version I was able to fit it normal size. I compiled it to both romv4 and romv5a. The sizes were 11987 bytes vs 9542 bytes. Minor changes with layout might be in place otherwise it work same way as in LinuxPC
Re: LCC for the Gigatron. Take two.
Two more remarks:
- I believe that it would be better to consolidate the cprintf calls that are very similar. Otherwise you need to code many strings that are almost identical.
- GLCC ints are only 16 bits long, that is 0 to 65535. To represent a 500000 jackpot you need to use "long int". The bad news is that using long ints substantially increases the code size.