Shop OBEX P1 Docs P2 Docs Learn Events
Catalina 2.9 - Page 3 — Parallax Forums

Catalina 2.9

1356715

Comments

  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-02-08 05:00
    @heater, Yikes?!!

    Hi Ross, re "I use gcc on both Windows and Linux."

    I think I'm missing something obvious with this one. This site http://gcc.gnu.org/releases.html leads you to this page http://gcc.gnu.org/gcc-4.5/ which leads you to this page http://gcc.gnu.org/svn.html and, you know, I just wanted the files!! :(

    Back to heater, I think what we have with Catalina is this amazing piece of code that is being greatly under utilised at the moment. BDSC is great, but it exists in CP/M so it is limited by the 64k memory limit. Catalina breaks out of this limit and can run free with as much ram as you want to throw at it.

    So my generic idea is to somehow leverage the power of Catalina into other languages. Ross has stuck with ANSI standards and this means at least we do have a standard.

    Qt is great but even a "hello world" seems to have one non ANSI line of code in it. Maybe it will end up the only one but it is mildly concerning in terms of standards. And look, I can't resist, I can feel a rant coming on, here it comes... /rant/ why, oh why, with a simple .exe can't they wrap up the .dll as well? No-one else ever is going to use that .dll. The .exe is not the compiled program. It is half the compiled program. How hard can it be to produce a single executable file?? /end rant/

    So, back to the real world, BCX produces some somewhat hybrid code, but Ross has already shown that it can be converted to ANSI C. In particular, BCX can include raw C code in a Basic program, so it can be possible to write simple C functions in standard ANSI C to replace non ANSI C produced by the converter.

    Where this could take us is very flexible code that can run on the Propeller, on a PC and on Linux. And Zog? I think that is a worthy goal worth pursuing.

    So what I want to do is write a BCX to ANSI C converter, and I want to write that in ANSI C. Which I might choose to write in Basic first!

    So my next little quest is for a simple C compiler that can run the same code Catalina is running.

    Tiny C can produce a complete self contained .exe from this
     #include <stdio.h>
     void main()
     {
        printf("%s","hello world");
        while(1);
     }
    

    But can it do the same for Linux?

    Dumb question here, but can Catalina produce code that can run on a PC?

    If not, what I would like is a simple C compiler that can take a program and can run on multiple platforms. If we stick to ANSI C, Catalina is that program for the propeller. Maybe GCC or Qt can do it for the PC. Not sure about linux. TinyC works for me on a PC but what about other OS'?

    I hope that all makes sense!
  • Heater.Heater. Posts: 21,230
    edited 2011-02-08 05:48
    Dr_A,

    Don't worry I'm only debating the LMM issue for fun.

    Now to business...

    You really don't want to be getting your GCC from gnu.org. They have the source for it...but then you would need to compile it into a working compiler...but then you would need a working GCC to compile it... but then....

    Normally Linux users get their GCC along with the OS.

    You already have a perfectly good C89 compliant GCC C compiler on your machine. It's in the Qt IDE. Just write C89 standard code into there and it will compile and run just fine.

    Have a look at "compile output" (look for the "build issues" drop down menu. I'm sure you will see the QT IDE is running a mingw version of GCC. You will be able to see it's path there. Then you can use it from the command line as a regular C compiler. (No funny command line switches added by the QT IDE) and no C++ or Qt libs involved.

    Otherwise there is:
    mingw http://www.mingw.org/
    cygwin http://www.cygwin.com/
    BloodShed http://www.bloodshed.net/download.html

    Don't get me wrong I have the highest respect for Ross and Catalina, it is an amazing piece of work that I hope to see more widely adopted.

    BDSC is, well, just for fun.

    Using Catalina to enable other language support is an excellent idea. Ross already has Lua for example. BASIC would be welcome by many. A standards compliant C for the basis of these things is essential.

    There is nothing mildly concerning about standards with Qt. It's just C++ not C.

    As for dll's. A valid rant. But consider on my Linux box those shared libs are actually used by my entire GUI desktop and a bunch of apps. We will find a way to build a statically linked self contained Qt executable for Windows.
    Where this could take us is very flexible code that can run on the Propeller, on a PC and on Linux. And Zog? I think that is a worthy goal worth pursuing.
    Zog thinks this is an excellent idea as well. By the way, that's what C is all about and why everyone and his dog want's C on the Prop.
    So my next little quest is for a simple C compiler that can run the same code Catalina is running. Dumb question here, but can Catalina produce code that can run on a PC?
    Catalina is actually LCC plus a back end code generator for the Propeller. So what you are really asking for is LCC to produce code for x86 Windows. See here http://www.cs.virginia.edu/~lcc-win32/ or http://www.programmersheaven.com/download/31851/download.aspx or wherever.
  • Heater.Heater. Posts: 21,230
    edited 2011-02-08 05:51
    Oh forgot, Tiny C also works on Linux just fine.
  • RossHRossH Posts: 5,547
    edited 2011-02-08 14:20
    Heater & Dr_A,

    I wont respond to each point in your emails individually (don't you guys ever sleep?). But here are some points, in no particular order ....

    • Heater and I will no doubt resume the LMM argument periodocally. Neither of us really expects to win - it's the argument that counts. Winning is less important than scoring a good point here and there :smile:
    • I use the MinGW (and MSYS) distribution of gcc for Windows. Some details are given in the Catalina reference manual. On Linux (as heater points out) gcc is nearly always included - or is downloadable as an easily installable package. Don't try and compile it from scratch!
    • There's no need to port Catalina to Windows (or Linux) - just use LCC instead. If you need a set of ANSI C libraries, you can use the Amsterdam Compiler Kit C libraries (these are what the Catalina libraries are based on). Or you can use LCC-Win32 (this is a compiler based on LCC - it is free for non-commercial use but not open source).
    • I always intended Catalina to be used as the basis for other languages for the Propeller - I just never seem to get time to do any work on them! You can either translate them to C and then use Catalina to compile them (as Dr_A is doing, or Lua or Pascal or Dumbo Basic does) or else compile them to PASM and then just make use of the Catalina targets, LMM kernel and other support tools - i.e. loaders, libraries etc. This latter technique has not yet been exploted by anyone (including me!) but is likely to give much faster results than using C as an intermediate language.
    • Thanks for the kind words about Catalina.
    Ross.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-02-08 14:49
    No we don't sleep! Back into the coding...
  • Martin HodgeMartin Hodge Posts: 1,246
    edited 2011-02-08 15:41
    Ross.

    I would like to repackage Catalina with pre-compiled "armel" binaries for the Z2. Do I have your permission?
  • RossHRossH Posts: 5,547
    edited 2011-02-08 16:10
    Ross.

    I would like to repackage Catalina with pre-compiled "armel" binaries for the Z2. Do I have your permission?

    Hi Martin,

    Thanks for asking - by all means include it. If you are going to include release 2.9, please also include the latest C3 patch, which also adds debugger support for all platforms. I have just added a copy of this patch to the Catalina Source Forge site (along with the 2.9 distribution files).

    For future reference (and for others who may want to do the same) you don't really need to ask my permission. Since Catalina is open source, you just need to comply with the various license terms.

    For the technically minded, these are the LGPL, GPL & MIT licenses, plus the two special ones for LCC and the Amsterdam Compiler Kit C libraries - but all these licenses permit redistribution provided their license conditions are preserved intact in the redistribution.

    Ross.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-02-08 19:33
    I've taken all the code so far and automated it. Rewriting an IDE for Qt is a little bit daunting at the moment so I'm doing this with vb.net because I can code this much quicker. However, I've written the code in such a way that it makes multiple passes through the .c file and each time makes a few changes and saves as a new file. So this should be the sort of code that is easier to port over to a console C application, and/or other code that runs on Linux and Windows.

    Not sure if there is a Basic program that runs on both??

    In any case, one thing that is nice about converting the output of BCX into C89 is that it compiles with TinyC. So it is getting to the stage of being possible to write code in Basic and translate it to something that will run on the propeller and on multiple platforms.

    I put in some syntax highlighting.

    This isn't finished and obviously every instruction will need to be tested, but the code below does test out a few key concepts - eg replacing lines with new lines, inserting new code, searching for code and replacing with other code that is bigger or smaller.

    As an aside, see the second screenshot,
    typedef unsigned char UCHAR;
    
    should that be in the section System Variables? Or another section?

    It sort of looks a bit lonely up there with the #includes.

    vb.net code below:
        Sub RunBCX()
            Dim Location As New Process
            Dim i As Integer
            Dim Lineoftext As String
            ' save the file
            RichTextBox4.SaveFile("C:\Program Files\Catalina\Demos\" + BigBasicFile, RichTextBoxStreamType.PlainText)
            ' copy to Cat1.bas
            FileCopy("C:\Program Files\Catalina\Demos\" + BigBasicFile, "C:\Program Files\Catalina\Demos\Cat1.bas")
            ' copy cat1.bas to BCX directory
            FileCopy("C:\Program Files\Catalina\Demos\Cat1.bas", "C:\Program Files\BCX\Bin\Cat1.bas")
            ' create a batch file
            FileOpen(1, "C:\Program Files\BCX\Bin\Cat.bat", OpenMode.Output)
            PrintLine(1, "BC cat1.bas")
            If CompilePause = True Then
                PrintLine(1, "pause") ' leaves batch file window open so can see errors
            End If
            FileClose(1)
            ' run BC and convert to cat1.c
            Location.StartInfo.FileName = "cat.bat"
            Location.StartInfo.WorkingDirectory = "C:\Program Files\BCX\Bin"
            Location.Start() ' shell the startup file
            Do
                ' wait till batch file finishes
            Loop Until Location.HasExited = True
            ' now start the multipass editing process
            ' step 1 - remove all the windows #includes
            i = 0
            FileOpen(1, "C:\Program Files\BCX\Bin\Cat1.c", OpenMode.Input)
            FileOpen(2, "C:\Program Files\BCX\Bin\Cat2.c", OpenMode.Output)
            While EOF(1) = False
                Lineoftext = LineInput(1)
                If i > 0 Then i += 1 ' increment the counter
                If Lineoftext = "// End of Object/Import Libraries To Search" Then
                    i = 1 ' start a counter
                End If
                If i > 3 Then
                    PrintLine(2, Lineoftext) ' save this line
                End If
            End While
            FileClose(1)
            FileClose(2)
            ' step 2 - add in the essential #includes
            ' later might not include all of these if running not in external memory
            ' list of catalina .h files is C:\Program Files\catalina\source\lib\include
            FileOpen(1, "C:\Program Files\BCX\Bin\Cat2.c", OpenMode.Input)
            FileOpen(2, "C:\Program Files\BCX\Bin\Cat3.c", OpenMode.Output) ' save as cat3.c
            PrintLine(2, "#include <stdio.h>")
            PrintLine(2, "#include <stdlib.h>")
            PrintLine(2, "#include <string.h>")
            PrintLine(2, "#include <math.h>")
            PrintLine(2, "#include <ctype.h>")
            PrintLine(2, "#include <errno.h>")
            PrintLine(2, "#include <float.h>")
            PrintLine(2, "#include <inttypes.h>")
            PrintLine(2, "#include <limits.h>")
            PrintLine(2, "#include <mathconst.h>")
            PrintLine(2, "")
            ' and possibly some more #includes
            PrintLine(2, "typedef unsigned char UCHAR;") ' so UCHAR works
            While EOF(1) = False
                Lineoftext = LineInput(1) ' read the line
                PrintLine(2, Lineoftext) ' save this line
            End While
            FileClose(1)
            FileClose(2)
            ' step 3 - replace some string handling functions
            i = -1
            FileOpen(1, "C:\Program Files\BCX\Bin\Cat3.c", OpenMode.Input)
            FileOpen(2, "C:\Program Files\BCX\Bin\Cat4.c", OpenMode.Output)
            While EOF(1) = False
                Lineoftext = LineInput(1)
                If i <> -1 Then i += 1 ' increment the counter
                If Lineoftext = "char *left (char *S, int length)" Then
                    i = 0 ' start the counter and stop saving lines
                End If
                If i = 8 Then ' add in new code - solution thanks to Kuroneko
                    PrintLine(2, "char *left (char *S, int length)")
                    PrintLine(2, "{")
                    PrintLine(2, "  char *strtmp;")
                    PrintLine(2, "  register int tmplen = strlen(S);")
                    PrintLine(2, "  if(length<1) return BCX_TmpStr(1);")
                    PrintLine(2, "  if(length<tmplen) tmplen=length;")
                    PrintLine(2, "  strtmp = BCX_TmpStr(tmplen);")
                    PrintLine(2, "  return (char*)memcpy(strtmp,S,tmplen);")
                    PrintLine(2, "}")
                    i = -1 ' reset the counter
                End If
                ' and replace one line for mid - can't define values in C89 like this
                If Lineoftext = "char*   mid (char*, int, int=-1);" Then
                    Lineoftext = "char*   mid (char*, int, int);"
                End If
                If i = -1 Then PrintLine(2, Lineoftext) ' save this line
            End While
            FileClose(1)
            FileClose(2)
            ' step 4 - add in RossHs strupr code
            FileOpen(1, "C:\Program Files\BCX\Bin\Cat4.c", OpenMode.Input)
            FileOpen(2, "C:\Program Files\BCX\Bin\Cat5.c", OpenMode.Output) ' save as cat3.c
            While EOF(1) = False
                Lineoftext = LineInput(1) ' read the line
                If Lineoftext = "//               Standard Prototypes" Then
                    PrintLine(2, Lineoftext) ' save this line
                    Lineoftext = LineInput(1) ' read the line
                    PrintLine(2, Lineoftext) ' save this line
                    Lineoftext = LineInput(1) ' read the line
                    PrintLine(2, Lineoftext) ' save this line
                    Lineoftext = "char *strupr(char *);" ' save declaration
                End If
                If Lineoftext = "//                 Runtime Functions" Then
                    PrintLine(2, Lineoftext) ' save this line
                    Lineoftext = LineInput(1) ' read the line
                    PrintLine(2, Lineoftext) ' save this line
                    Lineoftext = LineInput(1) ' read the line
                    PrintLine(2, Lineoftext) ' save this line
                    PrintLine(2, "char *strupr(char *string) {")
                    PrintLine(2, "    int i, len;")
                    PrintLine(2, "    len = strlen(string);")
                    PrintLine(2, "    for (i = 0; i < len; i++) {")
                    PrintLine(2, "      if (!isupper(string[i])) {")
                    PrintLine(2, "      string[i] = toupper(string[i]);")
                    PrintLine(2, "    }")
                    PrintLine(2, "  }")
                    PrintLine(2, "  return string;")
                    PrintLine(2, "}")
                    Lineoftext = vbCrLf ' add a space
                End If
                PrintLine(2, Lineoftext) ' save this line
            End While
            FileClose(1)
            FileClose(2)
            ' if add more steps here, change the filecopy name below
            ' now copy this file back to the catalina directory and open it in the catalina text window
            FileCopy("C:\Program Files\BCX\Bin\Cat5.c", "C:\Program Files\Catalina\Demos\NEW.C")
            RichTextBox1.LoadFile("C:\Program Files\Catalina\Demos\NEW.C", RichTextBoxStreamType.PlainText)
            CatalinaFile = "NEW.C" ' filename
    
    1024 x 768 - 130K
    1024 x 768 - 123K
  • RossHRossH Posts: 5,547
    edited 2011-02-08 19:46
    Dr_Acula wrote: »
    As an aside, see the second screenshot,
    typedef unsigned char UCHAR;
    
    should that be in the section System Variables? Or another section?

    It sort of looks a bit lonely up there with the #includes.

    You'll probably find more such - so stick it in it's own include file - e.g. dr_a_bcx.h and then instead add a line usch as #include "dr_a_bcx.h" (note the use of "" instead of <>). This will make it easier to add more such things later.

    Ross.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-02-09 04:12
    Good thinking. I'll take a look at that.

    Making a lot of progress. Some Basic instructions work as-is. Some need a bit more work.

    Huge arrays - 50000 integers = working
    VAL and STR$ = working
    ASC and CHR$ = working (needed to rewrite chr$ considerably)
    strings - in addition to the ones above, now have lcase and concat
    Block comments (even vb.net can't do that one!)

    But I've got a little stuck with instr - searching for strings within strings.
    Basic code
    lineoftext1$="12345abc6789"
    lineoftext2$="abc"
    a=instr(lineoftext1$,lineoftext2$,3,0) ' instr search for characters. Last value is needed, use dummy 0 (matches case)
    

    which outputs a whole lot of C
    int instr(char* mane,char* match,int offset,int sensflag)
    {
      register char *s;
      if (!mane || !match || ! *match || offset>(int)strlen(mane)) return 0;
      if (sensflag)
        s = _stristr_(offset>0 ? mane+offset-1 : mane,match);
      else
        s = _strstr_(offset>0 ? mane+offset-1 : mane,match);
      return s ? (int)(s-mane)+1 : 0;
    }
    
    
    char  *MakeLCaseTbl (void)
    {
      static char tbl[257];
          int i; for (i=0; i < 256; i++)
      tbl[i] = i;
      tbl[0] = 1;
      tbl[256] = 0;
      CharLowerA((char *)tbl);
      tbl[0] = 0;
      return tbl;
    }
    
    
    char *_stristr_(char *String, char *Pattern)
    {
      int   mi=-1;
      while(Pattern[++mi])
       {
         if(String[mi]==0) return 0;
         if(LowCase[(unsigned char)String[mi]]!=LowCase[(unsigned char)Pattern[mi]])
           { String++; mi=-1; }
       }
      return String;
    }
    
    
    char *_strstr_(char *String, char *Pattern)
    {
      int   mi=-1;
      while(Pattern[++mi])
       {
         if(String[mi]==0) return 0;
         if(String[mi]!=Pattern[mi])
           { String++; mi=-1; }
       }
      return String;
    }
    

    The line that catalina does not like is CharLowerA (addit - comes up also in HEX2DEC)

    I suspect this is not ANSI C89. Description is CharLowerA is exported by user32.dll. Converts a character string or a single character to lowercase. If the operand is a character string, the function converts the characters in place.

    Is there something similar in C89?
  • Heater.Heater. Posts: 21,230
    edited 2011-02-09 04:32
    How on earth does CharLowerA() know whether it's parameter is a pointer to a single character or a character string?

    Is it so that it actually converts the string at the given pointer address to lower case and returns the first character as lower case as well. That seems dangerous as if the parameter points to a single character it may corrupt data following it if there is no following NULL.

    In C we have such things as toupper() and tolower() which can be used to create the missing functions.

    http://pubs.opengroup.org/onlinepubs/009695399/functions/toupper.html
  • Heater.Heater. Posts: 21,230
    edited 2011-02-09 04:48
    OK CharLower, CharLowerA and CharLowerW are described here:http://msdn.microsoft.com/es-mx/library/ms647467(en-us,VS.85).aspx

    Answer to my question is:
    If the high-order word of this parameter is zero, the low-order word must contain a single character to be converted.
    Which means that if you give it a string at an address less than $1FFFF then it thinks you are passing it a single character and everything fails.

    This seems to be a quite likely scenario in your application on the Prop.

    Isn't Windows wonderful?
  • RossHRossH Posts: 5,547
    edited 2011-02-09 14:01
    Heater. wrote: »
    OK CharLower, CharLowerA and CharLowerW are described here:http://msdn.microsoft.com/es-mx/library/ms647467(en-us,VS.85).aspx

    Answer to my question is:

    Which means that if you give it a string at an address less than $1FFFF then it thinks you are passing it a single character and everything fails.

    This seems to be a quite likely scenario in your application on the Prop.

    Isn't Windows wonderful?

    Yes, Windows is a gem, isn't it?. Don't you just love this bit (taken verbatim from Heater's reference above):
    There is no indication of success or failure. Failure is rare. There is no extended error information for this function; do not call GetLastError.
    I'm definitely writing my next nuclear reactor controller in Windows!

    Ross.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-02-09 15:33
    Yes, I know windows is a pain. Converting BCX to C89 is a worthy goal though.

    I added another compile option to the catalina IDE. Now you can choose to compile with Catalina or with TinyC. Just hit F10 or F12. Compile/Run is instant for TinyC. And it is really useful to have a common language that works on a PC and works on the propeller.

    (yes, ok, I have had to fudge the program to get TinyC to work - I have a little code that removes the code that changes the screen color t_color and t_setpos, and also there is no mathconst.h for tinyc).

    It is also useful as part of the 'standardisation' process to test the code on two platforms.

    So - back to the problem
    char  *MakeLCaseTbl (void)
    {
      static char tbl[257];
          int i; for (i=0; i < 256; i++)
      tbl[i] = i;
      tbl[0] = 1;
      tbl[256] = 0;
      CharLowerA((char *)tbl);
      tbl[0] = 0;
      return tbl;
    }
    

    I'm not actually sure what this subroutine is doing. Is it creating a table with values 0 to 255 but any ascii character that is upper case gets stored as lower case? ie tbl[65] contains 97

    Heater suggested ctype.h and tolower()

    but this uses integers, and the above code is using char

    So is there any special casting that is needed to convert this line
      CharLowerA((char *)tbl);
    

    to something that uses tolower()
  • RossHRossH Posts: 5,547
    edited 2011-02-09 16:14
    Dr_A,

    Try this:
    #include <ctype.h>
    
    char *MakeCaseTbl (void) {
       static char tbl[257];
       int i; 
    
       for (i = 0; i < 256; i++) {
         tbl[i] = tolower(i);
      }
      tbl[256] = 0;
      return tbl;
    }
    
    Ross.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-02-09 16:36
    You are a legend Ross! That works brilliantly. Adding this now to the precompiler.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-02-09 18:09
    That also fixed up Hex2Dec and Hex$, so now hex functions are working too.

    One minor thing with hex is that DWORD is not defined, so I took a punt and used typedef to make it an unsigned long. Would this be the best choice for 32 bits?
    int Hex2Dec (char *szInput)
    {
      char   ch;
      char  *dwLen   = szInput+strlen(szInput);
      DWORD  dwOut   = 0;
      while(*szInput)
        {
          ch = LowCase[(unsigned char)*szInput++];
          if((ch >= 'a' && ch <= 'f')  || (ch >= '0' && ch <= '9'))
            dwOut |=((int)ch - (ch>'9' ? 'a'-10 : '0')) << ((dwLen - szInput) << 2);
        }
      return dwOut;
    }
    

    print hex2dec("0xFFFFFFFF") prints -1
    0xFFFF prints 65535

    I'm used to 16 bits so to my eyes, FFFF is -1. Maybe someone used to programming a 64 bit machine would consider FFFFFFFF to be 4294967295.

    It probably doesn't matter in terms of the debate, but from my point of view I want to make sure than my choice for DWORD is correct. Your thoughts?
  • kuronekokuroneko Posts: 3,623
    edited 2011-02-09 18:15
    If strtol() is available (in Catalina) you might as well use that, i.e. strtol(szInput, NULL, 16).
  • RossHRossH Posts: 5,547
    edited 2011-02-09 18:33
    kuroneko wrote: »
    If strtol() is available (in Catalina) you might as well use that, i.e. strtol(szInput, NULL, 16).

    Yes strtol() is available in Catalina.

    As to DWORD - I would just use unsigned - see http://msdn.microsoft.com/en-us/library/cc230318%28PROT.10%29.aspx

    Ross.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-02-09 19:01
    Thanks for that. Sorry to keep asking all these questions. I guess it is worth pointing out that each question results in another instruction working, and I'm managing to solve about two out of three now without asking.

    This one is for the string function, convert 10,65 to "AAAAAAAAAA
    The line starting with "register" is creating all sorts of errors. (addit see below, it is the line above) But it compiles ok with TinyC. This is a strange one because that line looks almost identical to lines used many times in the code.
    char *string (int count, int a)
    {
      if(count<1) return BCX_TmpStr(1);
      register char *strtmp = BCX_TmpStr(count);
      return (char*)memset(strtmp,a,count);
    }
    

    addit, I think the error actually is in the line above, if(count... because commenting out that line lets it compile
      //if(count<1) return BCX_TmpStr(1);
    

    come to think of it, why would you pass zero to this function? Anyway, is there a different way to write that line?

    Addit - solved this one. Need to swap the order of the lines. Register it before any if statements.

    I'm going to put a little note here to myself as this problem has come up with some other statements. need to register values before using them. So the order of the code changes. I hope I have done this right!
    source
    char *trim (char *S)
    {
      while(*S==32 || *S==9 || *S==10 || *S==11 || *S==13)
        S++;
      register int i = strlen(S);
      while( i>0 && (S[i-1]==32 || S[i-1]==9 || S[i-1]==10
                 || S[i-1]==11 || S[i-1]==13))
        i--;
      char *strtmp=BCX_TmpStr(i);
      return (char*)memcpy(strtmp,S,i);
    }
    

    new code
    char *trim (char *S)
    {
       register int i = strlen(S);
       char *strtmp=BCX_TmpStr(i);
       while(*S==32 || *S==9 || *S==10 || *S==11 || *S==13)
          S++;
       while( i>0 && (S[i-1]==32 || S[i-1]==9 || S[i-1]==10 || S[i-1]==11 || S[i-1]==13))
          i--;
       strtmp=BCX_TmpStr(i);
       return (char*)memcpy(strtmp,S,i);
    }
    
  • RossHRossH Posts: 5,547
    edited 2011-02-09 19:48
    Dr_Acula wrote: »
    Addit - solved this one. Need to swap the order of the lines. Register it before any if statements.

    Yes, this is a C89/C99 difference. LCC has been updated (by others) to be C99 compatible - when I get some time I'll look at doing this for Catalina - the differences are (for the most part) reasonably simple.

    For future reference, here is a quick summary of the differences between C89 and C99: http://home.datacomm.ch/t_wolf/tw/c/c9x_changes.html.

    Tthe difference you just fell foul of is given in this document as no. 12. However, you should also note that some of the differences listed are already supported by Catalina (e.g. the C++ style comments, given in the document as no. 10).

    When I get time I'll produce a "Catalina-specific" list.

    Ross.
  • RossHRossH Posts: 5,547
    edited 2011-02-09 19:54
    Dr_Acula wrote: »
    I'm going to put a little note here to myself as this problem has come up with some other statements. need to register values before using them. So the order of the code changes. I hope I have done this right!
    source

    Dr_A,

    All you have to do is separate the declaration of the variable from its usage, and put the declaration at the start of the block. For example:
    char *trim (char *S)
    {
      char *strtmp;
      register int i;
    
      while(*S==32 || *S==9 || *S==10 || *S==11 || *S==13)
        S++;
      i = strlen(S);
      while( i>0 && (S[i-1]==32 || S[i-1]==9 || S[i-1]==10
                 || S[i-1]==11 || S[i-1]==13))
        i--;
      strtmp=BCX_TmpStr(i);
      return (char*)memcpy(strtmp,S,i);
    }
    
    Also, for future reference, the word register here is just a hint to the compiler that the variable should be put into a machine register if possible (rather than on the stack) - usually because it makes the code run faster. However, a compiler is free to ignore it if the request cannot be honoured.

    Ross.
  • potatoheadpotatohead Posts: 10,261
    edited 2011-02-09 20:05
    Re: LMM being virtual.

    I know you two have hashed this out, but... a coupla thoughts to share.

    At a minimum, it's a "supervisor" kind of mode where there are meta-instructions. That's not quite the same as direct execution, though it does get executed directly by the COG, after being fetched. Seems to me, that's more than just running a program on a COG directly.
  • RossHRossH Posts: 5,547
    edited 2011-02-09 20:36
    Hi potatohead,

    Just for arguments sake, if the LMM loop fetched (say) 8 instructions at a time instead of 1 and then executed them, would you say the same?

    I think most people would regard that as being "native" execution using overlays.Or if 8 instructions is not enough, then how about I load 64 at a time? At what size of overlay does "non-native execution" turn into "native execution via overlays"? 128 instructions? 256?

    The main reason it is not done this way is that it would actually be slower on the Prop I than the current LMM 1-instruction overlay (but maybe not on the Prop II, if my understanding of the instruction set is correct!). Plus of course any jumps in the code, and any "long immediate" operands would have to be handled slightly differently - but I have a mechanism (albeit slower) for handling that (clue: how do you get hold of the Propeller's internal PC if you need to know it?. And by the way, this is also a counter to Heater's argument about LMM requiring an additional and artifically maintained PC - but I'll hold fire on that one till he has the temerity to raise it again :smile:)

    Ross.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-02-09 21:37
    Making lots of progress now. The problem instructions seem to be strings. I have all the essentials working. The maths seem ok as are program loops and files. Lots of things working out of the box - even things that never were part of the earlier basics eg
    print bin2dec("00000001") << 4
    

    There are many instructions specific to a GUI on a PC so rather than trying to do those, next step might be to start with the Basic Stamp manual and see if I can get all those working.

    Test program so far
    ' Big Basic for external memory on the Propeller using BCX Basic to C converter and Catalina
    
    call WhiteOnBlue
    dim a as integer
    dim i as integer
    for a=1 to 3
        print "hello world";
        print a
    next a
    $COMMENT
    ' file test copied from bcx examples - files work - commented out for speed 
    print "Opening file for output"
    DIM MyFileHandle@ ' BCX Reserves @ for "C" FILE* data types
    OPEN "new.txt" FOR OUTPUT  AS  FP1
    MyFileHandle@ = FP1
    FPRINT MyFileHandle@, "This is a test"
    CLOSE FP1
    print "Closing file"
    $COMMENT
    
    ' ASC function 
    DIM Mystring$ as string * 80 ' 80 characters
    DIM RetVal%
    Mystring$="A"
    print Mystring$
    RetVal% = ASC(Mystring$) 
    PRINT RetVal%
    
    'CHR$ function - opposite of ASC
    a=65
    Mystring$=chr$(a) ' declared in asc
    print "Character should be A: ";Mystring$
    
    'VAL function - converts string to double number. From the BCX help file
    DIM StringNum$ as string * 20
    DIM RetDub# 
    StringNum$="3.1415927"
    RetDub#=VAL(StringNum$)
    print RetDub#
    
    'STR$ function - opposite of VAL. Converts number to string
    DIM RetStr$ as string * 20
    DIM DoubleNumber#
    DoubleNumber# = 1.23456789
    RetStr$ = STR$(DoubleNumber#)
    print RetStr$
    
    
    ' Test some inline C code - pass a value in myarray, C changes it, print the return value
    
    dim myarray[5] as integer ' this can be much bigger if you like, eg 50000
    myarray[1]=100
    print myarray[1]
    call TestCCode
    print myarray[1]
    
    ' test some string functions
    
    dim lineoftext1$ as string * 80 ' strings must end in $ otherwise compiler doesn't copy properly
    dim lineoftext2$ as string * 80
    lineoftext1$="Hello World" ' string name is case sensitive
    lineoftext2$=left$(lineoftext1$,4) ' left characters
    print "Left$ test ";lineoftext2$
    lineoftext2$=mid$(lineoftext1$,5,4) ' mid characters
    print "Mid$ test ";lineoftext2$
    lineoftext2$=ucase$(lineoftext1$) ' upper case
    print "Upper case test ";lineoftext2$
    lineoftext2$=right$(lineoftext1$,3) ' right characters
    print "Right$ test ";lineoftext2$
    lineoftext1$="Hello"
    lineoftext2$="World"
    concat(lineoftext1$,lineoftext2$) ' add two strings - same as + or & in vb.net
    print "String concat test ";lineoftext1$
    lineoftext1$="ABCDEFG"
    lineoftext2$=lcase$(lineoftext1$) ' lower case
    print "Lower case test ";lineoftext2$
    a=1000
    lineoftext1$=hex$(a) ' hex$ working
    print lineoftext1$
    dim retval% ' hex2dec = two errors, DWORD (which I think can be changed to unsigned long) and CharLowerA which instr also is unhappy about
    retval%=hex2dec("0xFFFF") ' reverse of hex$, can use 0x or &H syntax or even FFFF
    print "Hex2Dec test ";retval%
    lineoftext1$="12345abc6789"
    lineoftext2$="abc"
    a=instr(lineoftext1$,lineoftext2$,3,0) ' instr search for characters. Last value is needed, use dummy 0 (matches case)
    print "Instr test, string is at position ";a
    a=255
    lineoftext1$=bin$(a) ' test binary
    lineoftext1$=lpad$(lineoftext1$,16,48) ' test adding leading zeros with lpad so is always 16 char long
    print "Binary value is ";lineoftext1$ ' test binary to strings and back again
    lineoftext1$="0000000001010101"
    print "Binary string to decimal ";Bin2dec(lineoftext1$) ' binary
    
    lineoftext1$=string$(10,65)
    print "String function ";lineoftext1$' n characters of ascii value m
    lineoftext1$="   trim test    " ' trim off leading zeros, spaces etc
    lineoftext1$=trim$(lineoftext1$)
    print "Trim test:";lineoftext1$
    
    ' test a string array
    
    dim stringarray[5] as string * 80 ' 80 characters
    stringarray[1]="Hello"
    stringarray[2]="World"
    print stringarray[2]
    
    ' bitwise operators - there are many more of these but they all seem to work ok without code changes
    a=1
    a=a << 10
    print "bitwise shift left";a
    a=a >> 4
    print "bitwise shift right";a
    a=1
    a=a and 0xFF
    print "logical and";a
    a=a or 0xFF
    print "logical or";a
    print "test starting with a binary string and shifting"; bin2dec("00000001") << 4
    
    ' test program control loops - FOR is already tested above
    a=1
    do
        print a
       a=a+1
    loop until a=3
    print "Do loop finished"
    
    a=1
    while a <3
        print a
        incr(a)' translates to a++ in C
    wend
    print "Wend loop finished"
    
    a=5
    select case a
        case 1
          print "1"
        case > 1 and < 6
          print "more than 1 and less than six"  
        case else
          print "something else"
    end select
    
    ' test functions
    
      print addnumbers(5,6)
      
    ' test some maths with floating point numbers
    
    dim number1 as double
    number1=1.2345
    print number1
    print sin(number1)
    print log(number1)
    
    
    
    
    
    
    $CCODE
    while(1); // loop instead of finishing
    $CCODE
    
    ' and exitprocess does not work on the propeller. So don't use END for the moment
    
    ' subroutines and functions
    
    function addnumbers(a as integer, b as integer)
      dim returnvalue as integer
      returnvalue = a + b
      function=returnvalue
    end function
    
    sub TestCCode
     $CCODE
      // declare the variables:
      int nNumber;
      int *pPointer;
      // now, give a value to them:
      nNumber = 15;
      pPointer = &nNumber;
      // print out the value of nNumber:
      printf("nNumber is equal to : %d\n", nNumber);
      // now, alter nNumber through pPointer:
      *pPointer = 25;
      // prove that nNumber has changed as a result of the above
      // by printing its value again:
      printf("nNumber is equal to : %d\n", nNumber);
      
      myarray[1]=110;
      
     $CCODE
    end sub
    
    Sub WhiteOnBlue()                       ' white text on blue background
    $CCODE
      int i;
      for (i=0;i<40;i++)
        {
          t_setpos(0,0,i);                 // move cursor to next line
          t_color(0,0x08FC);               // RRGGBBxx eg dark blue background 00001000 white text 11111100
        }
    $CCODE
    End Sub
    
  • RossHRossH Posts: 5,547
    edited 2011-02-09 21:41
    Hi Dr_A,

    That's very impressive!

    Can you post the translated C version of the same code (you may need to zip it up)?

    Ross.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-02-09 21:50
    Sure. This is a one keypress exercise. This might be getting close for a release?
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    #include <ctype.h>
    #include <errno.h>
    #include <float.h>
    #include <inttypes.h>
    #include <limits.h>
    #include <ctype.h>
    
    // *************************************************
    //                Typedef
    // *************************************************
    
    typedef unsigned char UCHAR;
    typedef unsigned long DWORD;
    
    // *************************************************
    //                System Variables
    // *************************************************
    
    static char *LowCase;
    
    // *************************************************
    //            User Global Variables
    // *************************************************
    
    static int     a;
    static int     i;
    static int     RetVal;
    static double  RetDub;
    static double  DoubleNumber;
    static int     retval;
    static double  number1;
    static char    Mystring[80];
    static char    StringNum[20];
    static char    RetStr[20];
    static int     myarray[5];
    static char    lineoftext1[80];
    static char    lineoftext2[80];
    static char    stringarray[5][80];
    
    
    
    // *************************************************
    //               Standard Macros
    // *************************************************
    
    #define BAND &
    #define BOR |
    #define VAL(a)(double)atof(a)
    
    
    // *************************************************
    //               Standard Prototypes
    // *************************************************
    
    char *strlwr(char *);
    char *strupr(char *);
    char*   BCX_TmpStr(size_t);
    char*   lcase (char*);
    char*   ucase (char*);
    char*   mid (char*, int, int);
    char*   trim (char*);
    char*   left (char*,int);
    char*   right (char*,int);
    char*   lpad (char*,int,int);
    char*   string (int,int);
    char*   str (double);
    char*   hex (int);
    char*   Bin (int);
    char*   chr(int);
    int     instr(char*,char*,int,int);
    char    *MakeLCaseTbl(void);
    char    *_stristr_(char*,char*);
    char    *_strstr_(char*,char*);
    int     Bin2Dec (char*);
    int     Hex2Dec (char*);
    
    // *************************************************
    //               User Prototypes
    // *************************************************
    
    int     addnumbers (int, int);
    void    TestCCode (void);
    void    WhiteOnBlue (void);
    
    
    // *************************************************
    //            User Global Initialized Arrays
    // *************************************************
    
    
    // *************************************************
    //                  Main Program
    // *************************************************
    
    int main(int argc, char *argv[])
    {
    LowCase = (char*)calloc(257,1);
    LowCase = MakeLCaseTbl();
    WhiteOnBlue();
    for(a=1; a<=3; a+=1)
      {
        printf("%s","hello world");
        printf("% d\n",(int)a);
      }
    // ' file test copied from bcx examples - files work - commented out for speed 
    // print "Opening file for output"
    // DIM MyFileHandle@ ' BCX Reserves @ for "C" FILE* data types
    // OPEN "new.txt" FOR OUTPUT  AS  FP1
    // MyFileHandle@ = FP1
    // FPRINT MyFileHandle@, "This is a test"
    // CLOSE FP1
    // print "Closing file"
    strcpy(Mystring,"A");
    printf("%s\n",Mystring);
    RetVal=(UCHAR)*(Mystring);
    printf("% d\n",(int)RetVal);
    a=65;
    strcpy(Mystring,chr(a));
    printf("%s%s\n","Character should be A: ",Mystring);
    strcpy(StringNum,"3.1415927");
    RetDub=VAL(StringNum);
    printf("% .15G\n",(double)RetDub);
    DoubleNumber=1.23456789;
    strcpy(RetStr,str(DoubleNumber));
    printf("%s\n",RetStr);
    myarray[1]=100;
    printf("% d\n",(int)myarray[1]);
    TestCCode();
    printf("% d\n",(int)myarray[1]);
    strcpy(lineoftext1,"Hello World");
    strcpy(lineoftext2,left(lineoftext1,4));
    printf("%s%s\n","Left$ test ",lineoftext2);
    strcpy(lineoftext2,mid(lineoftext1,5,4));
    printf("%s%s\n","Mid$ test ",lineoftext2);
    strcpy(lineoftext2,ucase(lineoftext1));
    printf("%s%s\n","Upper case test ",lineoftext2);
    strcpy(lineoftext2,right(lineoftext1,3));
    printf("%s%s\n","Right$ test ",lineoftext2);
    strcpy(lineoftext1,"Hello");
    strcpy(lineoftext2,"World");
    strcat(lineoftext1,lineoftext2);
    printf("%s%s\n","String concat test ",lineoftext1);
    strcpy(lineoftext1,"ABCDEFG");
    strcpy(lineoftext2,lcase(lineoftext1));
    printf("%s%s\n","Lower case test ",lineoftext2);
    a=1000;
    strcpy(lineoftext1,hex(a));
    printf("%s\n",lineoftext1);
    retval=Hex2Dec("0xFFFF");
    printf("%s% d\n","Hex2Dec test ",(int)retval);
    strcpy(lineoftext1,"12345abc6789");
    strcpy(lineoftext2,"abc");
    a=instr(lineoftext1,lineoftext2,3,0);
    printf("%s% d\n","Instr test, string is at position ",(int)a);
    a=255;
    strcpy(lineoftext1,Bin(a));
    strcpy(lineoftext1,lpad(lineoftext1,16,48));
    printf("%s%s\n","Binary value is ",lineoftext1);
    strcpy(lineoftext1,"0000000001010101");
    printf("%s% d\n","Binary string to decimal ",(int)Bin2Dec(lineoftext1));
    strcpy(lineoftext1,string(10,65));
    printf("%s%s\n","String function ",lineoftext1);
    strcpy(lineoftext1,"   trim test    ");
    strcpy(lineoftext1,trim(lineoftext1));
    printf("%s%s\n","Trim test:",lineoftext1);
    strcpy(stringarray[1],"Hello");
    strcpy(stringarray[2],"World");
    printf("%s\n",stringarray[2]);
    a=1;
    a=a<<10;
    printf("%s% d\n","bitwise shift left",(int)a);
    a=a>>4;
    printf("%s% d\n","bitwise shift right",(int)a);
    a=1;
    a=a BAND 0xFF;
    printf("%s% d\n","logical and",(int)a);
    a=a BOR 0xFF;
    printf("%s% d\n","logical or",(int)a);
    printf("%s% d\n","test starting with a binary string and shifting",(int)Bin2Dec("00000001")<<4);
    a=1;
    for(;;)
      {
        printf("% d\n",(int)a);
        a+=1;
        if(a==3)
          {
            break;
          }
      }
    printf("%s\n","Do loop finished");
    a=1;
    while(a<3)
      {
        printf("% d\n",(int)a);
        (a)++;
      }
    printf("%s\n","Wend loop finished");
    a=5;
    for(;;)
    {
      if(a==1)
        {
          printf("%s\n","1");
          break;
        }
      if(a>1&&a<6)
        {
          printf("%s\n","more than 1 and less than six");
          break;
        }
        // case else
        {
          printf("%s\n","something else");
        }
      break;
    }
    printf("% d\n",(int)addnumbers(5,6));
    number1=1.2345;
    printf("% .15G\n",(double)number1);
    printf("% .15G\n",(double)sin(number1));
    printf("% .15G\n",(double)log(number1));
    while(1); // loop instead of finishing
      return 0;   //  End of main program
    }
    
    // *************************************************
    //                 Runtime Functions
    // *************************************************
    
    char *strupr(char *string) {
        int i, len;
        len = strlen(string);
        for (i = 0; i < len; i++) {
          if (!isupper(string[i])) {
          string[i] = toupper(string[i]);
        }
      }
      return string;
    }
    
    
    char *strlwr(char *string) {
        int i, len;
        len = strlen(string);
        for (i = 0; i < len; i++) {
          if (!islower(string[i])) {
          string[i] = tolower(string[i]);
        }
      }
      return string;
    }
    
    
    char *BCX_TmpStr (size_t Bites)
    {
      static int   StrCnt;
      static char *StrFunc[2048];
      StrCnt=(StrCnt + 1) & 2047;
      if(StrFunc[StrCnt]) free (StrFunc[StrCnt]);
      return StrFunc[StrCnt]=(char*)calloc(Bites+128,sizeof(char));
    }
    
    
    char *left (char *S, int length)
    {
      char *strtmp;
      register int tmplen = strlen(S);
      if(length<1) return BCX_TmpStr(1);
      if(length<tmplen) tmplen=length;
      strtmp = BCX_TmpStr(tmplen);
      return (char*)memcpy(strtmp,S,tmplen);
    }
    
    char *right (char *S, int length)
    {
      int tmplen = strlen(S);
      char *BCX_RetStr = BCX_TmpStr(tmplen);
      tmplen -= length;
      if (tmplen<0) tmplen = 0;
      return strcpy(BCX_RetStr, &S[tmplen]);
    }
    
    
    char *lpad (char *a, int L, int c)
    {
      char *strtmp;
      L=L-strlen(a);
      if(L<1) return a;
      strtmp = BCX_TmpStr(L);
      memset(strtmp,c,L);
      return strcat(strtmp,a);
    }
    
    
    char *mid (char *S, int start, int length)
    {
      char *strtmp;
      register int tmplen = strlen(S);
      if(start>tmplen||start<1) return BCX_TmpStr(1);
      if (length<0 || length>(tmplen-start)+1)
        length = (tmplen-start)+1;
      strtmp = BCX_TmpStr(length);
      return (char*)memcpy(strtmp,&S[start-1],length);
    }
    
    
    char *trim (char *S)
    {
       register int i = strlen(S);
       char *strtmp=BCX_TmpStr(i);
       while(*S==32 || *S==9 || *S==10 || *S==11 || *S==13)
          S++;
       while( i>0 && (S[i-1]==32 || S[i-1]==9 || S[i-1]==10 || S[i-1]==11 || S[i-1]==13))
          i--;
       strtmp=BCX_TmpStr(i);
       return (char*)memcpy(strtmp,S,i);
    }
    
    
    char *ucase (char *S)
    {
      register char *strtmp = BCX_TmpStr(strlen(S));
      return strupr(strcpy(strtmp,S));
    }
    
    
    char *lcase (char *S)
    {
      register char *strtmp = BCX_TmpStr(strlen(S));
      return strlwr(strcpy(strtmp,S));
    }
    
    
    char *str (double d)
    {
      register char *strtmp = BCX_TmpStr(24);
      sprintf(strtmp,"% .15G",d);
      return strtmp;
    }
    
    
    char *hex (int a)
    {
      register char *strtmp = BCX_TmpStr(16);
      sprintf(strtmp,"%X",a);
      return strtmp;
    }
    
    
    char *string (int count, int a)
    {
      register char *strtmp = BCX_TmpStr(count);
      if(count<1) return BCX_TmpStr(1);
      return (char*)memset(strtmp,a,count);
    }
    
    
    char *chr (int a)
    {
       register char *strtmp = BCX_TmpStr(11);
       strtmp[0] = a;
       strtmp[1] = 0;
       return strtmp;
    }
    
    
    char* Bin(int number)
    {
      char *strtmp = BCX_TmpStr(2048);
       itoa(number,strtmp,2);
      return strtmp;
    }
    
    
    int instr(char* mane,char* match,int offset,int sensflag)
    {
      register char *s;
      if (!mane || !match || ! *match || offset>(int)strlen(mane)) return 0;
      if (sensflag)
        s = _stristr_(offset>0 ? mane+offset-1 : mane,match);
      else
        s = _strstr_(offset>0 ? mane+offset-1 : mane,match);
      return s ? (int)(s-mane)+1 : 0;
    }
    
    
    char *MakeLCaseTbl (void) {
       static char tbl[257];
       int i; 
       for (i = 0; i < 256; i++) {
          tbl[i] = tolower(i);
       }
       tbl[256] = 0;
       return tbl;
    }
    
    
    char *_stristr_(char *String, char *Pattern)
    {
      int   mi=-1;
      while(Pattern[++mi])
       {
         if(String[mi]==0) return 0;
         if(LowCase[(unsigned char)String[mi]]!=LowCase[(unsigned char)Pattern[mi]])
           { String++; mi=-1; }
       }
      return String;
    }
    
    
    char *_strstr_(char *String, char *Pattern)
    {
      int   mi=-1;
      while(Pattern[++mi])
       {
         if(String[mi]==0) return 0;
         if(String[mi]!=Pattern[mi])
           { String++; mi=-1; }
       }
      return String;
    }
    
    
    int Bin2Dec (char *cptr)
    {
      register int i, j = 0;
      while(cptr && *cptr && strchr("01", *cptr))
      {
        i = *cptr++ - '0';
        j <<= 1;
        j |= (i & 0x01);
      }
     return(j);
    }
    
    
    int Hex2Dec (char *szInput)
    {
      char   ch;
      char  *dwLen   = szInput+strlen(szInput);
      DWORD  dwOut   = 0;
      while(*szInput)
        {
          ch = LowCase[(unsigned char)*szInput++];
          if((ch >= 'a' && ch <= 'f')  || (ch >= '0' && ch <= '9'))
            dwOut |=((int)ch - (ch>'9' ? 'a'-10 : '0')) << ((dwLen - szInput) << 2);
        }
      return dwOut;
    }
    
    
    
    // ************************************
    //       User Subs and Functions
    // ************************************
    
    
    int addnumbers (int a, int b)
    {
      static   int      returnvalue;
      memset(&returnvalue,0,sizeof(returnvalue));
      returnvalue=a+b;
      return returnvalue;
    }
    
    
    void TestCCode (void)
    {
      // declare the variables:
      int nNumber;
      int *pPointer;
      // now, give a value to them:
      nNumber = 15;
      pPointer = &nNumber;
      // print out the value of nNumber:
      printf("nNumber is equal to : %d\n", nNumber);
      // now, alter nNumber through pPointer:
      *pPointer = 25;
      // prove that nNumber has changed as a result of the above
      // by printing its value again:
      printf("nNumber is equal to : %d\n", nNumber);
    
      myarray[1]=110;
    
    }
    
    
    void WhiteOnBlue (void)
    {
      int i;
      for (i=0;i<40;i++)
        {
          t_setpos(0,0,i);                 // move cursor to next line
          t_color(0,0x08FC);               // RRGGBBxx eg dark blue background 00001000 white text 11111100
        }
    }
    
    
    


    The secret is to add little functions to change the output from BCX. This is an example of how one works. I'd be wondering if maybe this could be translated from vb.net into BCX. Then BCX could translate itself? (not so silly, since the source of BCX is written in Basic and it can translate itself).
        Function Trim_Replace(ByVal Lineoftext As String, ByVal SaveFlag As Boolean)
            ' swap around the declarations so they are all at the start, eg register. TinyC does not mind but Catalina does. 
            'char *trim (char *S)
            '{
            ' while(*S==32 || *S==9 || *S==10 || *S==11 || *S==13)
            ' S++;
            'register int i = strlen(S);
            'while( i>0 && (S[i-1]==32 || S[i-1]==9 || S[i-1]==10
            '|| S[i-1]==11 || S[i-1]==13))
            'i--;
            'char *strtmp=BCX_TmpStr(i);
            'return (char*)memcpy(strtmp,S,i);
            '}
            If Strings.Left(Lineoftext, 20) = "char *trim (char *S)" Then
                For i = 1 To 10 ' replace function
                    Lineoftext = LineInput(1) ' read in lines and discard
                Next
                PrintLine(2, "char *trim (char *S)")
                PrintLine(2, "{")
                PrintLine(2, "   register int i = strlen(S);")
                PrintLine(2, "   char *strtmp=BCX_TmpStr(i);")
                PrintLine(2, "   while(*S==32 || *S==9 || *S==10 || *S==11 || *S==13)")
                PrintLine(2, "      S++;")
                PrintLine(2, "   while( i>0 && (S[i-1]==32 || S[i-1]==9 || S[i-1]==10 || S[i-1]==11 || S[i-1]==13))")
                PrintLine(2, "      i--;")
                PrintLine(2, "   strtmp=BCX_TmpStr(i);")
                PrintLine(2, "   return (char*)memcpy(strtmp,S,i);")
                PrintLine(2, "}")
                SaveFlag = False
            End If
            Return SaveFlag
        End Function
    
  • potatoheadpotatohead Posts: 10,261
    edited 2011-02-09 21:53
    Yes I would say the same. IMHO, the differentiator for me is whether or not there are meta-tasks, and where the intent of the program is embodied.

    With LMM, whether it's one instruction, or a few, or 8, whatever, the center of attention isn't the kernel running in the COG. That is a meta-task, necessary and contributory to the primary task, embodied in the LMM program. That's virtualization, or at a minimum a model similar to a micro-code one where there is some program-ability, used to facilitate execution, and or provide high speed services to the program being executed. A supervisor kernel facilitates the execution of the program.

    We've seen some programs that are a mix of PASM and LMM, where the main intent is embodied in the PASM, with the meta-task being to fetch different parts of the program as needed. I would characterize that differently, as a overlay.

    Subtle, but IMHO, significant.

    Edit:

    One other distinction would be whether or not the meta-program is general purpose or not. Using the overlay technique is specialized, in that the workflow to realize it is consistent, but the actual implementation is case by case, depending on the program intent necessary at the time.

    When that is general purpose, it then is enabling, not primary, which speaks again to supervisory code, or modes, and or the core of virtual machines.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-02-09 22:02
    For those with vb.net, attached is the code. You will also need BCX installed in the default c:\program files\bcx and it helps to have TinyC installed, also in the default c:\program files\tcc

    One could certainly argue the merits of taking the post BCX conversion part and turning that into a standalone .exe so that the linux people can use this. Heater found Qt which can run C on multiple platforms. I wonder if there is an equivalent program for Basic programmers?
  • RossHRossH Posts: 5,547
    edited 2011-02-09 22:03
    Hi Dr_A,

    It would seem a beta release may in order! Although I do think your idea of trying to do a fairly complete emulation of some variant of BASIC (like PBASIC) would make a very good first release.

    Ross.
Sign In or Register to comment.