Shop OBEX P1 Docs P2 Docs Learn Events
Catalina 2.6 - a FREE C compiler for the Propeller - The Final Frontier! - Page 16 — Parallax Forums

Catalina 2.6 - a FREE C compiler for the Propeller - The Final Frontier!

11416181920

Comments

  • Dr_AculaDr_Acula Posts: 5,484
    edited 2010-11-15 02:33
    Ah so it is just a shell to a program at the PC end. What is going on at the propeller end - does something need to be running as well? Or does payload toggle the DTR line and emulate a prop download?

    In which case - is it an eeprom or ram load?

    This could greatly speed up the compile/download/run cycle. And with an IDE - one can add this as another compile option. I have an option already to select XMM or LMM so that will need to go to the command line.
  • RossHRossH Posts: 5,580
    edited 2010-11-15 02:39
    Dr_Acula wrote: »
    Ah so it is just a shell to a program at the PC end. What is going on at the propeller end - does something need to be running as well? Or does payload toggle the DTR line and emulate a prop download?

    In which case - is it an eeprom or ram load?

    No, nothing needs to be running on the Prop - payload toggles DTR to reset the prop just like the Parallax loader does. This activate the built-in load program on the Prop. That's all you need to do to download Catalina LMM programs (which are just normal Propeller binaries). But to download XMM programs you must first downloads a special XMM loader - this implements a different protocol to download the next program, and payload also switches protocol automatically.

    The default is to download to RAM - but just add -e to download to EEPROM (this is only possible for LMM programs, of course!).

    Ross.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2010-11-15 03:19
    That sounds like it will integrate perfectly into the IDE. Use payload for debugging. Then use xmodem to save the final copy to the sd card. Can't wait to get home from work and try this!
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2010-11-15 05:35
    Ok, I haven't fixed the com port problem yet nor done an INI, but see attached, I have added a new option using payload for a compile.

    This works at 115200 baud. This is amazing!

    A compile/download/run is now only 9 seconds.

    I'll need to add the option for XMM, but for a quick and simple compile, it works extremely well because the OS can be Kyedos, but for a quick download it downloads to ram, so this means that it downloads and runs quicker, but does not overwrite Kyedos. Perfect!

    And when you have the code debugged, put a permanent copy on the sd card with the slower xmodem transfer.

    This is extremely easy to use, as File/New creates a working C program pre-written, and then a download is just a one click affair.

    I might think about some options to add in skeleton code for the dummy plugin.
  • RossHRossH Posts: 5,580
    edited 2010-11-15 05:46
    Hi Dr_A,

    Godd work - but it's way past my bedtime now! I'll try it out tomorrow.

    Ross.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2010-11-22 21:22
    Hi Ross,

    I'm thinking of ways to build a graphical IDE on the propeller. You know, drag and drop buttons and text boxes onto the screen, then glue them together with a bit of code.

    1) The tile driver thread is evolving rapidly. I'm using a 160x120 full color driver from Kye, and there is now one that goes up to 256 bytes (I haven't pushed this to the limit yet).
    2) For any graphics program, more hub ram = better graphics.
    3) Taken to extremes, this leaves little or no room for code in hub ram.
    4) I think this rapidly reduces the choice of languages, and the one I think can solve this problem is Catalina running in external ram. This code exists.

    *** Building a graphical program on the Propeller ***

    Creating a graphical IDE ought to be graphical in itself. For instance, rather than saying "button n is x by y bytes" in code, it is more intuitive to grab button n and draw it on the screen and move it around with the mouse. You can see what you are doing - see below for the IDE in .net and the equivalent screen on a propeller.

    So - the next technical challenge - how could you do this either on the propeller or on a PC?

    I have pondered a number of ways but they are all difficult to code. However, there is one way that is quite simple - use vb.net

    So - attached is a screenshot of the Catalina IDE. There are now two tabs - the "code" tab and the "Visual IDE" tab.

    A form shows how big the propeller screen is (this is 160x120, but Baggers has one nearly 256 bytes wide).

    In .net, you can draw any number of buttons, text boxes, labels etc on the form and make them all invisible. If you then click on a "new item" button, you can then resize the button/text box etc on the screen. I've not quite worked out the simplest way but one solution might be to click a "increase" or "decrease" button. Or maybe even click a button that says "place here" and then click in the propeller form screen and it detects where the mouse was clicked. It then makes the appropriate button/textbox/label visible so you can see it and edit it.

    Then, much as in .net, once you have the screen looking how you want it, click on an object (eg a button), and then click the "code" button and it wil change to the Catalina code tab, and pre-fill in a C function.

    I think you can code a lot with just a handful of objects - button, radiobutton, checkbox, label and picturebox.

    One might also create some skeleton code on startup that is a main that polls the mouse for clicks and then calls the appropriate function.

    So I was wondering if it is possible to take a look at the attached code and see how hard it would be to turn Kye's 160x120 display driver into a self contained piece of cog code?

    (Kye's sd driver code would be a bonus, and don't worry about the keyboard code as you already have this - though down the track maybe Kye's combo keyboard/mouse in one cog might be worth a look).

    As is usual with these things, there is a pile of spin code that has to go. Plotbox can go. DisplayClear can go. DisplayPointer might be the key to this, as this returns the location of the display buffer. Once C knows that, C can write directly to hub ram using a C function. DisplayState/DisplayRate/DisplayWait can go. DisplayColor can go. DisplayStart is needed.

    If you think a 64 color 160x120 color display can be added to Catalina, I can get to work on creating the IDE and making it easy to build programs.

    Your thoughts would be most appreciated.
    584 x 576 - 32K
    640 x 480 - 39K
  • jazzedjazzed Posts: 11,803
    edited 2010-11-22 22:17
    Dr_Acula wrote: »
    I'm thinking of ways to build a graphical IDE on the propeller. You know, drag and drop buttons and text boxes onto the screen, then glue them together with a bit of code.
    This will be the 3rd Propeller GUI IDE :D

    I started a similar project a few years ago. This year Rayman started one. Rayman's VisualSpin has some user following and can generate code.

    I do like the fact that you are using actual buttons, etc... from VB. Can you drag the elements around with the mouse?

    I could share my PropGUImaker project with you. It's all written in C# but can be converted to VB.net pretty easily except without comments.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2010-11-23 00:47
    Hi jazzed,

    With all the activity on graphics drivers, graphics GUI programs could be very interesting.

    What display engine are yours and Rayman's code using?

    Can you drag the elements around with the mouse?

    You set a hard challenge! Ok, I can't quite drag an element around, but I can click on a "move" button, then the mouse cursor changes to a cross, and then whereever you click the mouse, the element moves to there.

    Also can resize elements, though not quite as neatly as in the .net design view.

    I need to think about a way of having multiple elements on a form - probably need to have lots of invisible ones and make them visible as the user adds them. The prop screen is small so not many elements are going to fit on each screen.

    I'll do buttons/check boxes/radio boxes first.

    Picture boxes might need some code to turn bitmaps into a format that can be loaded quickly from an sd card (ie no processing). Using paintshop works but it is tedious.

    Text boxes will be the hardest one to code. Many different fonts, and the multiline version is almost a mini word processor. That implies a text buffer, which means more memory, and that is another reason to use Catalina rather than Spin.

    If this can run using Catalina XMM on the dracblade, it ought to also be possible to run on your 32mb board, right?
    492 x 274 - 24K
  • RossHRossH Posts: 5,580
    edited 2010-11-23 01:01
    Dr_Acula wrote: »
    Hi Ross,

    If you think a 64 color 160x120 color display can be added to Catalina, I can get to work on creating the IDE and making it easy to build programs.

    Your thoughts would be most appreciated.

    Hi Dr_Acula,

    I'm in the middle of porting the Parallax graphics driver and utilities to Catalina - I hope to be able to support a 256x192 color graphics display, and run the standard Parallax graphics demo (or rather its "C" equivalent). Space may be a problem in an LMM platform, since the graphics buffer takes so much - but it should run fine from XXM RAM.

    Here is the program I hope to run:
    #include "catalina_graphics.h"
    #include "catalina_hmi.h"
    
    #define x_tiles 16
    #define y_tiles 12
    
    #define lines 5
    #define thickness 2
    
    #define BITMAP_BASE  0x2000
    #define DISPLAY_BASE 0x5000
    
    
    #define limit(val, min, max) ((val)<(max)?((val)>(min)?(val):(min)):(max))
    
    #define sar(x,y) ((x)?(x>>y):-((-x)>>(y)))
    
    //#define sx7(x) ((x)&(0x80)?((x)|0xFFFFFF00):(x))
    //#define sx15(x) ((x)&(0x8000)?((x)|0xFFFF0000):(x))
    
    unsigned short vecdef[] = {
       0x4000+0x2000/3*0, // triangle
       50,
       0x8000+0x2000/3*1+1,
       50,
       0x8000+0x2000/3*2-1,
       50,
       0x8000+0x2000/3*0,
       50,
       0
    };
    
    unsigned short vecdef2[] = {
       0x4000+0x2000/12*0, // star
       50,
       0x8000+0x2000/12*1,
       20,
       0x8000+0x2000/12*2,
       50,
       0x8000+0x2000/12*3,
       20,
       0x8000+0x2000/12*4,
       50,
       0x8000+0x2000/12*5,
       20,
       0x8000+0x2000/12*6,
       50,
       0x8000+0x2000/12*7,
       20,
       0x8000+0x2000/12*8,
       50,
       0x8000+0x2000/12*9,
       20,
       0x8000+0x2000/12*10,
       50,
       0x8000+0x2000/12*11,
       20,
       0x8000+0x2000/12*0,
       50,
       0
    };
    
    unsigned short pixdef[] = {
       // byte    2,7,3,3
       (short)(2<<8 + 7), (short)(3<<8 + 3), // crosshair
       0x0FC0, 0x0000,
       0x3230, 0x0000,
       0xC20C, 0x0000,
       0xEAAC, 0x0000,
       0xC20C, 0x2000,
       0x3230, 0xA800,
       0x0FC0, 0x2000
    };
    
    unsigned short pixdef2[] = {
       // byte 1,4,0,3
       (short)(1<<8 + 4), (short)(0<<8 + 3), // dog
       0x800A,
       0x2AAA,
       0x2AA0,
       0x2020,
    };
    
    char pchip[] = "Propeller"; // text
    
    
    void main() {
    
      long mousex, mousey;
    
      unsigned short screen [x_tiles * y_tiles];
      unsigned long colors[64];
    
      signed char x[lines];
      signed char y[lines];
      signed char xs[lines];
      signed char ys[lines];
    
      union g_var gv;
      int i, j, k, kk, dx, dy, pp, pq, rr, numx, numchr;
    
    
      // init colors
      for (i = 0; i <= 63; i++) {
         colors[i] = 0x00001010 * (i+4) & 0xF + 0x2B060C02;
      }
    
      // init tile screen
      for (dx = 0; dx <= x_tiles - 1; dx++) {
         for (dy = 0; dy <= y_tiles - 1; dy++) {
            screen[dy * x_tiles + dx] 
               = DISPLAY_BASE >> 6 + dy + dx * y_tiles + ((dy & 0x3F) << 10);
         }
      }
    
      // init bouncing lines
      i = 1001;
      j = 123123;
      k = 8776434;
      for (i = 0; i <= lines - 1; i++) {
        x[i] = (j = _rand_forward(j)); // 64
        y[i] = (k = _rand_reverse(k)); // 48
        while (xs[i] != (k = sar(_rand_reverse(k), 29))) { };
        while (ys[i] != (j = sar(_rand_forward(j), 29))) { };
      }
    
      // setup graphics
      g_setup(&gv, 16, 12, 128, 96, (void *)BITMAP_BASE);
    
      while (1) {
    
        // clear bitmap
        g_clear(&gv);
    
        // draw spinning triangles
        g_colorwidth(&gv, 3,0);
        for (i = 1; i <= 8; i++) {
           g_vec(&gv, 0, 0, (k & 0x7F) << 3 + i << 5, k << 6 + i << 8, vecdef);
        }
    
        // draw expanding mouse crosshairs
        g_colorwidth(&gv, 2,k>>2);
        mousex = mousex + limit(m_delta_x(), -128, 127);
        mousey = mousey + limit(m_delta_y(), -96, 95);
        g_pix(&gv, mousex, mousey, k>>4 & 0x7, pixdef);
    
        // if left mouse button pressed, throw snowballs
        if (m_button(0)) {
          g_width(&gv, pq & 0xF);
          g_color(&gv, 2);
          pp = (pq & 0xF)*(pq & 0xF) + 5;
          pq++;
          g_arc(&gv, mousex, mousey, pp, pp>>1, -k * 200, 0x200, 8, 0);
        }
        else {
          pq = 0;
        }
    
        // if right mouse button pressed, pause
        while (m_button(1)) { }
    
        // draw expanding pixel halo
        g_colorwidth(&gv, 1,k);
        g_arc(&gv, 0,0,80,30,-k<<5,0x2000/9,9,0);
    
        // step bouncing lines
        for (i = 0; i <= lines - 1; i++) {
          if (abs(x[i]) > 60) {
            xs[i] = -xs[i];
          }
          if (abs(y[i]) > 40) {
            ys[i] = -ys[i];
          }
          x[i] += xs[i];
          y[i] += ys[i];
        }
    
        // draw bouncing lines
        g_colorwidth(&gv, 1,thickness);
        g_plot(&gv, x[0], y[0]);
        for (i = 1; i <= lines - 1; i++) {
           g_line(&gv, x[i],y[i]);
        }
        g_line(&gv, x[0], y[0]);
    
        // draw spinning stars and revolving crosshairs and dogs
        g_colorwidth(&gv, 2,0);
        for (i = 0; i <= 7; i++) {
           g_vecarc(&gv, 80,50,30,30,-(i<<10+k<<6),0x40,-(k<<7),vecdef2);
           g_pixarc(&gv, -80,-40,30,30,i<<10+k<<6,0,pixdef2);
           g_pixarc(&gv, -80,-40,20,20,-(i<<10+k<<6),0,pixdef);
        }
    
        // draw small box with text
        g_colorwidth(&gv, 1,14);
        g_box(&gv, 60,-80,60,16);
        g_textmode(&gv, 1,1,6,5);
        g_colorwidth(&gv, 2,0);
        g_text(&gv, 90,-72,pchip);
    
        // draw incrementing digit
        if (!(++numx & 7)) {
           numchr++;
        }
        if ((numchr < '0') || (numchr > '9')) {
           numchr = '0';
        }
        g_textmode(&gv, 8,8,6,5);
        g_colorwidth(&gv, 1,8);
        g_text(&gv, -90,50,&numchr);
    
        // copy bitmap to display
        g_copy(&gv, (void *)DISPLAY_BASE);
    
        // increment counter that makes everything change
        k++;
      }
    }
    
    Here is the Catalina's equvalent of the parallax "Graphics" object:
    #ifndef __CATALINA_GRAPHICS
    #define __CATALINA_GRAPHICS
    
    #define BLOCK_SIZE (28 + 32 + 64) // size in longs
    
    // We need this type since all variables MUST be allocated on the stack. We
    // pass a pointer to the allocated structure to all the functions that need 
    // access to the variables it contains
    typedef union g_var {
       long l[BLOCK_SIZE/4]; // longs
       short s[BLOCK_SIZE/2]; // shorts
    };
    
    #define _L_BITMAP_BASE  0  // long offset of BITMAP_BASE
    #define _L_BITMAP_LONGS 1  // long offset of BITMAP_LONGS
    #define _L_PIXEL_WIDTH  2  // long offset of BITMAP_WIDTH
    #define _L_TEXT_XS      3  // long offset of BITMAP_WIDTH
    #define _L_TEXT_YS      4  // long offset of BITMAP_WIDTH
    #define _L_TEXT_SP      5  // long offset of BITMAP_WIDTH
    #define _L_TEXT_JUST    6  // long offset of BITMAP_WIDTH
    #define _L_SLICES       7  // long offset of SLICES
    #define _S_BASES        30 // short offset of BASES
    
    // Set bitmap parameters
    //
    //   x_tiles        - number of x tiles (tiles are 16x16 pixels each)
    //   y_tiles        - number of y tiles
    //   x_origin       - relative-x center pixel
    //   y_origin       - relative-y center pixel
    //   base_ptr       - base address of bitmap
    //
    void g_setup(union g_var *gv, int x_tiles, int y_tiles, 
                 int x_org, int y_org, void *base_ptr);
       
    // Clear bitmap
    //
    void g_clear(union g_var *gv);
    
    // Copy bitmap
    // use for double-buffered display (flicker-free)
    //
    //   dest_ptr    - base address of destination bitmap
    //   
    void g_copy(union g_var *gv, void *dest_ptr);
    
    // Set pixel color to two-bit pattern
    //
    //   color       - color code in bits[1..0]
    //
    void g_color(union g_var *gv, int color); 
    
    // Set pixel width
    // actual width is w[3..0] + 1
    //
    //   width       - 0..15 for round pixels, 16..31 for square pixels
    //
    void g_width(union g_var *gv, int width);
    
    // Set pixel color and width
    //
    void g_colorwidth(union g_var *gv, int color, int width);
    
    // Plot point
    //
    //   x,y         - endpoint
    //
    void g_plot(union g_var *gv, int x, int y);
    
    // Draw a line to point
    //
    //   x,y         - endpoint
    //
    void g_line(union g_var *gv, int x, int y);
    
    // Draw an arc
    //
    //   x,y         - center of arc
    //   xr,yr       - radii of arc
    //   angle       - initial angle in bits[12..0] (0..$1FFF = 0°..359.956°)
    //   anglestep   - angle step in bits[12..0]
    //   steps       - number of steps (0 just leaves (x,y) at initial arc position)
    //   arcmode     - 0: plot point(s)
    //                 1: line to point(s)
    //                 2: line between points
    //                 3: line from point(s) to center
    //
    void g_arc(union g_var *gv, int x, int y, int xr, int yr, 
               int angle, int anglestep, int steps, int arcmode);
    
    // Draw a vector sprite
    //
    //   x,y         - center of vector sprite
    //   vecscale    - scale of vector sprite ($100 = 1x)
    //   vecangle    - rotation angle of vector sprite in bits[12..0]
    //   vecdef_ptr  - address of vector sprite definition
    //
    //
    // Vector sprite definition:
    //
    //   word $8000|$4000+angle  'vector mode + 13-bit angle 
    //                           '(mode: $4000=plot, $8000=line)
    //   word length             'vector length
    //   ...                     'more vectors
    //   ...
    //   word 0                  'end of definition
    //
    void g_vec(union g_var *gv, int x, int y, int vecscale, int vecangle, 
               void * vecdef_ptr);
    
    // Draw a vector sprite at an arc position
    //
    //   x,y         - center of arc
    //   xr,yr       - radii of arc
    //   angle       - angle in bits[12..0] (0..$1FFF = 0°..359.956°)
    //   vecscale    - scale of vector sprite ($100 = 1x)
    //   vecangle    - rotation angle of vector sprite in bits[12..0]
    //   vecdef_ptr  - address of vector sprite definition
    //
    void g_vecarc(union g_var *gv, int x, int y, int xr, int yr, int angle, 
                  int vecscale, int vecangle, void * vecdef_ptr);
          
    // Draw a pixel sprite
    //
    //   x,y         - center of vector sprite
    //   pixrot      - 0: 0°, 1: 90°, 2: 180°, 3: 270°, +4: mirror
    //   pixdef_ptr  - address of pixel sprite definition
    //
    //
    // Pixel sprite definition:
    //
    //    word    'word align, express dimensions and center, define pixels
    //    byte    xwords, ywords, xorigin, yorigin
    //    word    %%xxxxxxxx,%%xxxxxxxx
    //    word    %%xxxxxxxx,%%xxxxxxxx
    //    word    %%xxxxxxxx,%%xxxxxxxx
    //    ...
    //
    void g_pix(union g_var *gv, int x, int y, int pixrot, void *pixdef_ptr);
    
    // Draw a pixel sprite at an arc position
    //
    //   x,y         - center of arc
    //   xr,yr       - radii of arc
    //   angle       - angle in bits[12..0] (0..$1FFF = 0°..359.956°)
    //   pixrot      - 0: 0°, 1: 90°, 2: 180°, 3: 270°, +4: mirror
    //   pixdef_ptr  - address of pixel sprite definition
    //
    void g_pixarc(union g_var *gv, int x, int y, int xr, int yr, int angle, 
                  int pixrot, void *pixdef_ptr);
    
    // Draw text
    //
    //   x,y         - text position (see textmode for sizing and justification)
    //   string_ptr  - address of zero-terminated string (it may be necessary to 
    //                 call finish immediately afterwards to prevent subsequent 
    //                 code from clobbering the string as it is being drawn
    void g_text(union g_var *gv, int x, int y, void *string_ptr);
    
    // Draw text at an arc position
    //
    //   x,y         - center of arc
    //   xr,yr       - radii of arc
    //   angle       - angle in bits[12..0] (0..$1FFF = 0°..359.956°)
    //   string_ptr  - address of zero-terminated string (it may be necessary to 
    //                 call finish immediately afterwards to prevent subsequent 
    //                 code from clobbering the string as it is being drawn
    //
    void g_textarc(union g_var *gv, int x, int y, int xr, int yr, 
                   int angle, void *string_ptr);
    
    // Set text size and justification
    //
    //   x_scale        - x character scale, should be 1+
    //   y_scale        - y character scale, should be 1+
    //   spacing        - character spacing, 6 is normal
    //   justification  - bits[1..0]: 0..3 = left, center, right, left
    //                    bits[3..2]: 0..3 = bottom, center, top, bottom
    //
    void g_textmode(union g_var *gv, int x_scale, int y_scale, int spacing, int justification);
    
    // Draw a box with round/square corners, according to pixel width
    //
    //   x,y      - box left, box bottom
    //
    void g_box(union g_var *gv, int x, int y, int box_width, int box_height);
    
    
    // Draw a solid quadrilateral
    // vertices must be ordered clockwise or counter-clockwise
    //
    void g_quad(union g_var *gv, int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4);
    
    // Draw a solid triangle
    //
    void g_tri(union g_var *gv, int x1, int y1, int x2, int y2, int x3, int y3);
    
    // Wait for any current graphics command to finish
    // use this to insure that it is safe to manually manipulate the bitmap
    //
    void g_finish();
    
    #endif
    
    Note that neither of these files are yet working, and are still subject to change - but the final should not be too far removed from these, and it may be useful to compare them to their "SPIN" equivalents - they are pretty much line-for-line comparable.

    Ross.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2010-11-23 01:15
    Ross - that would be a truly amazing piece of work!

    256*192 is 4:3 so that would be sweet. How are you doing the magic of getting 256*192=49152 to fit in 32k of ram? Is that using tile drivers?

    If so, then if there was a "gray" tile and maybe a "white" one as well, then that would save a lot of ram. Hmm - would you need some code in an IDE that says "you are running out of tiles if you put any more elements on the screen". Maybe calculate the tiles needed on the fly as elements are added? (Buttons would be ok, it is pictureboxes that would use the tiles, but if we know the bitmap as it is added to the IDE, then you can check it will work before compiling).

    256x192 kind of blows 160x120 out of the water.

    From an IDE perspective, it is easy to change the size of the emulated screen.

    It sounds like you are already 10 steps ahead!

    Addit: based on your code, I figure that rather than load a predrawn bitmap of, say, a button, with the text on it, it may be quicker to take the information we know about the button (size, location, text) and use your drawing code to create the border, add the text etc. If you add one button, it adds code to draw a generic button and also to draw that particular button. If you add a second button, the generic button code is already there.

    This is going to be awesome! One cool thing about C compared with Spin is you can have huge data lists in the code and not have to worry about running out of code space. Especially with jazzed's 32mb. You could even choose in an IDE to turn a bitmap into a file on an SD card OR choose to turn it into data statements within C.

    Also, drawing in spin is just a fraction too slow. Catalina should be able to deliver the speed as well, so bitmaps load quicker. Especially if preloaded from sd card to external ram (which catalina can already do).

    Ok, back to coding. I need to look at pictureboxes next.
  • RossHRossH Posts: 5,580
    edited 2010-11-23 01:35
    Dr_Acula wrote: »
    Ross - that would be a truly amazing piece of work!

    256*192 is 4:3 so that would be sweet. How are you doing the magic of getting 256*192=49152 to fit in 32k of ram? Is that using tile drivers?

    You don't need a tile driver. 256*192*1 (i.e. 2 colors) = 49152 BITS, or 6k BYTES. If you want 4 colors it is 12k bytes, 8 colors is 24k bytes. The Parallax demo only uses 4 colors, plus some jiggery pokery in the background color to make it look like more. In SPIN you probably can't use 8 colors and have enough space left to do much useful processing - but I hope that Catalina (running a program from XMM) will be able to!

    It's just a matter of finding enough time ... sigh!

    Ross.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2010-11-23 01:50
    It's just a matter of finding enough time ... sigh!

    After careful consideration, I have made a clear and conscious decision to spend *more* time on the Propeller!

    Ah, so you are using bits. Kye's code is using bytes, so 160x120 in 64 bit color =19,200k of ram. (Technically you could get more as it is 6 bit not 8, but the TV driver has more colors).

    Still, if you go XMM you may as well use all the hub ram (once the stack is allocated). I think Baggers has a tile driver in full color. Once you get your code working we could maybe look at increasing the colors using the full color tiles?
  • PaxiPaxi Posts: 10
    edited 2010-11-23 03:20
    This really looks awesome! Hope you will be able to finish it soon.

    PS: I was a bit busy the last days not often at home. I still have to send you the gamepad driver
  • potatoheadpotatohead Posts: 10,261
    edited 2010-11-23 07:43
    I would like to point out the advantages of bits vs bytes.

    In a full color, byte per pixel driver, colors are absolute, so one needs tiles colored properly, and changing tile colors is either loading new images, or doing bitmasking on the tile data, using some compressed meta-data.

    With bits, colors are indexed into palettes, 4 colors per "tile" or screen region.

    The Parallax driver does this, and is very memory efficient because of that.

    With color redirection possible, only a "blank" tile is needed, for example, to cover the screen with any color, as the color drawn to the monitor is the product of the bit in the tile, which is indexed to sets of colors, where the bit selects a given color within that set, allowing for on the fly changes.

    It's possible, for example, to draw something on the screen slowly, then have it pop to being visible by just changing a color reference, where the full color driver must essentially have it all stored, and then all the tile addresses need to be written at one time for the "pop" to occur on screen.

    Finally, bits consume far less internal HUB to COG throughput. It's rather easy to get a 640 pixel screen with bits, because the video loops can be much longer, due to the longer waitvid frame time, and the ability to crunch more pixels per memory operation.
  • jazzedjazzed Posts: 11,803
    edited 2010-11-23 07:58
    Dr_Acula wrote: »
    What display engine are yours and Rayman's code using?
    I've not used Rayman's program, so he would need to answer that. I think he only supports only some VGA driver.

    My program provides lots of flexibility, but never matured to the point for code to be generated. I got stuck on the idea that perhaps a translator from other GUI IDEs might be better than making a new one from scratch. A new GUI IDE from scratch is a *lot* of work.

    I'm including a .net binary for you to play with so you can check the look and feel. The widget pane, property pane, and GUI canvas are the only functional parts. Click on form in the widget pane then click on the GUI canvas to get a new form. You can put buttons, etc on the form.

    I do believe a translator program is the best approach though. Many GUI IDEs can generate xml code. A plug-in or off-line program could translate elements and properties to driver interface code.
    Dr_Acula wrote: »
    If this can run using Catalina XMM on the dracblade, it ought to also be possible to run on your 32mb board, right?
    Yes. I'm starting back on my Catalina port today.

    Download the .binary and change it to .exe ... I've not included any of the other files from the bin directory, but that hasn't been a problem before - we'll see.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2010-11-23 18:22
    Hi Jazzed,

    Your program sounds very interesting. I tried renaming it to .exe but when I run it nothing happens. Maybe I am missing another file or something?

    The crazy idea I'm thinking of is to largely write a program by clicking things rather than by writing code.

    eg, add a button to a form. That simple task creates a whole lot of code. It creates a 'main'. The main calls a function 'check mouse'. When a mouseclick is detected, it calls another function, 'mouselocation' and that looks up a list of things on the display and works out which one has been clicked. If the mouseclick is inside the button, it calls another function 'button1click'. Like in .net, if you double click on the button on the screen view, I'd like to then change the view to the code layout with the cursor in the middle of a new function 'buttonclick'

    Then I'd like to copy something I already have with the sbasic IDE, which is to have a library of functions that you can select with a drop down menu.

    So you are in the middle of new code for the button click, and you could select a function from a list that is 'led_on' and paste that into the code.

    So you could potentially get a led to turn on without having to even know how to write C.

    If you are a beginner, each time you are doing this you are learning the language. For the seasoned programmers, they would probably write it in text rather than use the GUI.

    Much coding lies ahead of course!
  • jazzedjazzed Posts: 11,803
    edited 2010-11-23 18:49
    Dr_Acula wrote: »
    Your program sounds very interesting. I tried renaming it to .exe but when I run it nothing happens. Maybe I am missing another file or something?
    Most fascinating. I can run it fine under linux, but not on windows ! Whatever.

    Yes, I think I understand your crazy idea. It sounds the same as VB to me. That's where I was going originally.

    A translator would be less "one window", but would be about the same amount of work for a user with less developer work and more maintainable over time.
  • jazzedjazzed Posts: 11,803
    edited 2010-11-23 22:54
    I have finally Catalina ram_test working up to 32MB.

    Thanks.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2010-11-23 23:46
    32mb of ram for Catalina?!

    That is going to be awesome. What could you do with all that code space? You could run a whole operating system. Put huge amounts of graphics inline in the code for fast speed. Run big programs.

    This all very exciting!
  • RossHRossH Posts: 5,580
    edited 2010-11-24 00:34
    jazzed wrote: »
    I have finally Catalina ram_test working up to 8MB.
    What changes should I make and how many places do I need to do them to allow using 32MB?

    Thanks.

    Hi Jazzed - great work!

    There is nothing intrinsic in the RAM test program that should stop it working beyond 8Mb - how many of the 32 possible address bits actually get used by the XMM access routines is up to the routines themselves (I presume you have added yours to the ones in the file Catalina_XMM_RamTest_Input.spin?). As you've probably noticed, the existing ones differ for each platform, with some using only 19 bits, while others use 21, 22 or 24 bits.

    I assume you have set TEST_SIZE? - that's about the only configuration parameter there is - for 32mb it should be set to $800000 (test size is measured in LONGs, not BYTES).

    As far as I am aware the RAM test program itself should use 25 bits or even 32 bits quite happily. The program is relatively dumb - what output do you see?

    Ross.
  • jazzedjazzed Posts: 11,803
    edited 2010-11-24 08:08
    @RossH, Could you (or someone who uses Catalina) provide a very brief outline of loading/running an XMM program from SD CARD?

    "Getting Started with Catalina" talks about using SD card, but it's all a bit generalized and the XMM discussion seems incomplete.
    A step by step set of instructions would be greatly appreciated.

    Now that I'm fresh, I noticed the comment (number of LONGs). The test passes if TEST_SIZE = $80_0000, so I think it's working.
    TEST_SIZE  = $100_0000 ' number of LONGs to test - must be EVEN (due to address interleaving)
    
    $100_0000 longs = 64MB, so a test with that size failing is expected.

    I was getting this with TEST_SIZE = $100_0000.
    FAIL 00000000=00800000(01000000)
    FAIL 00000004=007FFFFF(00FFFFFF)
    FAIL 00000008=007FFFFE(00FFFFFE)
    FAIL 0000000C=007FFFFD(00FFFFFD)
    FAIL 00000010=007FFFFC(00FFFFFC)
    FAIL 00000014=007FFFFB(00FFFFFB)
    
  • jazzedjazzed Posts: 11,803
    edited 2010-11-24 10:39
    I decided to take the "easy path" and use Catalyst for now.
    It boots and I can run commands like CAT, DIR, and LS.

    Can't run VI just yet so I assume I still have some config issue.

    Just for sanity sake, tell me where I need to start the SdramCache COG.

    If I start it in Catalina_XMM_RAM_TEST_Input.spin, that works.
    But starting it in Catalina_XMM_Input.spin does not work.
    None of the other platforms use a COG for a memory driver, so there is no example to follow.

    I remember the email and the small list with xmm_*Input.spin, etc.... BUT it is of no help.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2010-11-24 14:57
    @RossH, Could you (or someone who uses Catalina) provide a very brief outline of loading/running an XMM program from SD CARD?

    I've automated the compile/download into one button as I can never remember all the switches for the command line.

    Using Payload works for loading to local memory but not for XMM.

    For XMM I am booting into Kyedos and then using the Xmodem feature in Kyedos to download the file, then using Kyedos to run Catalyst, and then using Catalyst to run the C program off the sd card. I have two versions of catalyst - one that talks to the local keyboard/vga display, and another that talks to the serial port. For automatic compiles the IDE uses the second one.

    The main routine is this:
            ResetPropeller() ' boot back into kyedos
            Sleep(2000) ' compile is faster than kyedos rebooting
            Compile_C() ' compile the program
            OpenSerialPort() ' open the serial port
            Download_C() ' download the file
            SerialPortName.Close() ' close the serial port
    

    Compile_C is the following and you can see the switches for compiling if XMM is selected:
        Private Sub Compile_C()
            ' compile the program - 
            Dim Location As New Process
            Dim filename1 As String
            Dim filename2 As String
            Dim filename_noextension As String
            Dim batchcommand As String
            Dim LineOfText As String
            Dim CommandLine As String
            SaveCatalina()
            filename1 = CatalinaFile
            filename_noextension = Strings.Left(filename1, Len(filename1) - 2)
            If Len(filename_noextension) > 8 Then
                MsgBox("Warning - filename is >8 characters long. Suggest renaming file")
            End If
            ' create a batch file in the demo folder
            'PrintLine(1, "catalina -lcx -x5 -M 128k -D DRACBLADE -D HIRES_VGA " + CatalinaFile)
            If XMM = "TRUE" Then
                CommandLine = "catalina -lcx -x5 -M " + MemSize + "k -D DRACBLADE -D " + VGAMode + " " + CatalinaFile
            Else
                CommandLine = "catalina -lc -D DEMO -D " + VGAMode + " " + CatalinaFile
            End If
            FileOpen(1, "C:\Program Files\Catalina\Demos\drac.bat", OpenMode.Output)
            PrintLine(1, "@echo off")
            PrintLine(1, "echo.")
            PrintLine(1, "echo    ===================")
            PrintLine(1, "echo    SETTING UP CATALINA")
            PrintLine(1, "echo    ===================")
            PrintLine(1, "echo.")
            PrintLine(1, "PATH=C:\Program Files\Catalina\bin;%PATH%")
            PrintLine(1, "Call catalina_env.bat()")
            PrintLine(1, CommandLine) ' see above
            PrintLine(1, "pause")
            'PrintLine(1, "pause") ' leaves batch file window open so can see errors
            FileClose(1)
            ' compile the program
            Location.StartInfo.FileName = "drac.bat"
            Location.StartInfo.WorkingDirectory = "C:\Program Files\Catalina\Demos"
            Location.Start() ' shell the startup file
            Do
                ' wait till batch file finishes
            Loop Until Location.HasExited = True
        End Sub
    

    Download_C is below, and it calls another routine that is a bit more complex that handles the xmodem transfer to Kyedos. I left in some comments from Ross regarding the download as this was a bit tricky to get working.
        Private Sub Download_C()
            Dim filename1 As String
            Dim filename_noextension As String
            Dim LineOfText As String
            Dim i As Integer
            filename1 = CatalinaFile
            filename_noextension = Strings.Left(filename1, Len(filename1) - 2)
            'MsgBox("Compiled")
            ' send the file
            'TabControl1.SelectedIndex = 0 ' display kyedos
            'TextBox3.Focus() 'display to kyedos
            ' rename .binary to .bin
            Try
                Kill("C:\Program Files\Catalina\Demos\" + filename_noextension + ".bin")
            Catch ex As Exception ' file didn't exist
            End Try
            Try
                Rename("C:\Program Files\Catalina\Demos\" + filename_noextension + ".binary", "C:\Program Files\Catalina\Demos\" + filename_noextension + ".bin")
                'TimerOff()
                Call XmodemSendKyeDOS("C:\Program Files\Catalina\Demos\" + filename_noextension + ".bin")
                'TimerOn()
                LineOfText = "Spin Catlyst2.bin" + vbCr ' run the serial version of catalyst
                Call StringToPacket(LineOfText)
                'The baud rate you are fiddling with is (as the comment implies) the loader baud rate. The baud rate you need to change to affect the PC HMI option are the ones in:
                'Catalina_PC_Text.spin()
                'Catalina_PC_Keyboard.spin()
                'Catalina_PC_Mouse.spin()
                ' and recompile with    build_all DRACBLADE              <-- to use local VGA and keyboard
                'or
                'build_all DRACBLADE PC VT100     <-- to use PC terminal emulator
                ' local version is catlyst1.bin and serial version is catlyst2.bin
                For i = 1 To 5
                    System.Windows.Forms.Application.DoEvents() ' update the label1 message
                    Sleep(1000) ' wait for reboot approx 5 seconds
                Next i
                LineOfText = UCase(filename_noextension) + vbCr ' and run the program
                Call StringToPacket(LineOfText)
            Catch ex As Exception
                MsgBox("Compile error, check batch file for error message(s)")
            End Try
        End Sub
    

    Kyedos runs programs with the "Spin" command, so once Kyedos has finished the download, 'type' the following command down the serial cable

    LineOfText = "Spin Catlyst2.bin" + vbCr ' run the serial version of catalyst

    and then type the program name

    LineOfText = UCase(filename_noextension) + vbCr ' and run the program

    which in the demo version types NEW<cr>

    RE None of the other platforms use a COG for a memory driver, so there is no example to follow.

    Are you looking for an example like the dracblade XMM driver code? That is hidden away in one of the subfolders, though it is eluding me for the moment.

    What I haven't coded yet is a way of automatically running a XMM program on startup. At the moment my board boots into Kydos, and Kyedos can be configured to autorun Catalyst say, if there is no keyboard input for a while, but one would need a version of Catalyst that autoruns a C program - possibly by reading a small text file off the sd card (if it exists). Or maybe there is another way eg, wrapping up catalyst as part of the C program so it ends up being one binary file that is self contained?
  • RossHRossH Posts: 5,580
    edited 2010-11-24 14:59
    jazzed wrote: »
    @RossH, Could you (or someone who uses Catalina) provide a very brief outline of loading/running an XMM program from SD CARD?

    Have you looked at the "technical notes" in the back of the Catalina manual - the section titled "A Description of the Generic SD Loader" talks about XMM loading, and the section before that talks about the various file formats (including XMM). These may help.
    jazzed wrote: »
    I decided to take the "easy path" and use Catalyst for now.
    It boots and I can run commands like CAT, DIR, and LS.

    Can't run VI just yet so I assume I still have some config issue.

    Just for sanity sake, tell me where I need to start the SdramCache COG.

    If I start it in Catalina_XMM_RAM_TEST_Input.spin, that works.
    But starting it in Catalina_XMM_Input.spin does not work.
    None of the other platforms use a COG for a memory driver, so there is no example to follow.

    I remember the email and the small list with xmm_*Input.spin, etc.... BUT it is of no help.

    When you run ls you are only running a SPIN program, and it uses Kye's SD card access (which is unavailable to Catalina once C has started). Possible causes of you being able to run ls (which uses Kye's SD card access and no XMM RAM access) but not vi (which uses Catalina's SD Card access and XMM RAM access) are:

    1. Your SD card itself - Catalina's code needs an SD card with an MBR, Kye's code does not. Also, check your SD card for file system integrity - Catalina's file functions will have problems if the SD Card has a corrupt file system on it (which I find is very common when you are developing, since you often reboot the Prop while a program is in the middle of file access).

    2. Your XMM access routines have not been copied into all the files that need them (since there is no #include option in Homespun, you have to physically copy the code to each file - but I have tried to separate out the "configuration" part from the "common" part). The common part must be copied to ALL of the following files (this is the list I sent you before):
    • Catalina_XMM_Input.spin
    • Catalina_XMM_SD_Loader_Input.spin
    • Catalina_XMM_EEPROM_Loader_Input.spin
    • Catalina_HUB_XMM_Loader_Input.spin
    • Catalina_XMM_SIO_Loader_Input.spin
    • Catalina_XMM_RamTest_Input.spin
    • Catalyst_XMM_SD_Loader_Input.spin
    The section you need to copy to each of these files is bounded by the following lines:
    '===============================================================================
    ' Beyond these lines, the code is common to all programs that need XMM support.
    
       << lots of code here >>>
    
    '==================== END OF PLATFORM SPECIFIC XMM SUPPORT CODE ================
    
    3. Your SdramCache is not being loaded everywhere it is needed. It must be loaded and started twice - first by the loader (Catalyst_XMM_SD_Loader_Input.spin) for use during the program load process, and then again by the target for use during program execution - (the default XMM target is called xmm_default_Input.spin). Loading it within the XMM kernel spin program (Catalina_XMM_Input.spin) will not work - this program is not "executed" in the normal way - it is simply compiled and included as a binary "blob" wherever the kernel is needed, and is loaded and executed later by the loader. Any SPIN code you add to this file will probably not be executed at the appropriate time.

    4. If you are trying to load your SdramCache in the right place but it won't start, it may be that you have simply run out of cogs. I don't recall how many cogs vi takes, but it may not have a spare cog left - are you (for example) using the HIRES_VGA option? If so, try using the VGA option instead, since this will free up a cog. A better idea may be to start with a much simpler program so you know you will have enough cogs - e.g. just try "hello_world" compiled as an XMM program (and loaded with Catalyst).

    Sorry if this seems confusing - but what you are attempting to do is even more complex than the standard Catalina program load - and that's already very complex :freaked:
    Ross.
  • jazzedjazzed Posts: 11,803
    edited 2010-11-24 15:36
    Thanks for your response.

    I've looked at the "technical notes" but the SD Loader is in the "internals" which I managed to miss :<

    Nice to know "ls" is a spin program. By the way, spinix has many worthwhile
    commands in it like "cd" and "rb" ... I am spoiled by that.

    I'm pretty sure my 2G SD card is well behaved.
    I don't know if it has a "Master Boot Record ?" though. How can I tell?

    I've copied the SDRAM routines into all the Catal*_XMM*Input.spin files

    I'm just trying to use the serial port for now. No VGA/TV or other drivers.
    My catalyst build is invoked thusly: ./build_all GG_SDRAM PC VT100 SDCARD

    Thanks for explaining Catalina_XMM_Input.spin ... I'll safely remove my code :D
    RossH wrote: »
    3. Your SdramCache is not being loaded everywhere it is needed. It must be loaded and started twice - first by the loader (Catalyst_XMM_SD_Loader_Input.spin) for use during the program load process, and then again by the target for use during program execution - (the default XMM target is called xmm_default_Input.spin). Loading it within the XMM kernel spin program
    This is the part where I'm mostly concerned. Start twice particularly bothers me because SDRAM as you know requires refresh. Stopping the driver then restarting will cause problems for sure if data from the first start needs to be there for the second start. This is not a problem with ZOG for example because the loader moves the image from SD straight to SDRAM and then launches the interpreter without restarting the driver. Any workaround?

    One thing that is very curious is the number of "start" like methods. I see Start and Run in some files, Run only in some files, and Execute in yet another file. Very confusing. This part is difficult.
  • RossHRossH Posts: 5,580
    edited 2010-11-24 18:04
    jazzed wrote: »
    Thanks for your response.

    This is the part where I'm mostly concerned. Start twice particularly bothers me because SDRAM as you know requires refresh. Stopping the driver then restarting will cause problems for sure if data from the first start needs to be there for the second start. This is not a problem with ZOG for example because the loader moves the image from SD straight to SDRAM and then launches the interpreter without restarting the driver. Any workaround?

    One thing that is very curious is the number of "start" like methods. I see Start and Run in some files, Run only in some files, and Execute in yet another file. Very confusing. This part is difficult.

    This may require some more work. I have one instance where I have to keep a cog alive between separate loader phases - this is the CogStore cog, which is used to store the command line while the initial Catalyst load (phase 1) is handed over to the internal program loader (phase 2). The way I do this is by always using cog 7 for this. If your SRAM driver cannot be stopped during the load process, a similar mechanism will be required.

    Look in Catalyst_XMM_SD_Loader_Input.spin and search for "cog 7".

    As for the number of "start" methods - this is partly just laziness on my part. In some cases it is because switched over to a different startup mechanism during development, and have either not gotten around to removing all the old ones, or I am preserving them in case I need them again. But there is generally some logic here:
    • the ones that have both Start and Run (like the Catalina_LMM.spin), the difference is that Start starts a new cog and returns, while Run overwrites the current cog and therefore never returns.
    • The ones that have both Start and Execute (like Catalyst_XMM_SD_Loader_Input.spin) it generally means that Start does the initial set up, and when that returns you must Execute to perform the action.
    Any that don't fit the above classficiations are simply due to inadequate levels of caffiene in the blood when coding :smilewinkgrin:

    Ross.
  • jazzedjazzed Posts: 11,803
    edited 2010-11-24 20:33
    So I have to use COGINIT with COG 6 for SdramCache and change the Catal*_XMM_SD_Loader_Input.spin (and others?) restart routines so that COG 6 (and 7) are not stopped.

    Still the question with a fixed COGINIT is "where is the best one place to do that?" I guess that would be the same place(s) that CogStore is started. Just using grep CogStore *Input.spin yields a familiar list.

    Is 5 COGs enough to do useful work?

    One COG can be used for Keyboard/Mouse (with the all-in-one SDRAM module, and the TinyTwoWire/SDRAM module combination) and 1 COG for TV video.

    I have other hardware/plans for VGA so COGs won't be an issue there.
  • jazzedjazzed Posts: 11,803
    edited 2010-11-24 20:38
    @Dr_A, Your VB code fragments were helpful. Thanks.
  • RossHRossH Posts: 5,580
    edited 2010-11-24 20:48
    Hi jazzed,

    You would need to permanenently allocate a cog to your cache anyway, so that's not an isssue. You effectively have a 7-cog Prop but with 32Mb RAM - seems an acceptable trade-off!

    By the way, the CogStore cog (7) is actually used only during the load process - it is stopped by the target (search for "CogStore.Stop") as part of the initialization process - once the target is in control it retrieves the command line from the CogStore and stores it in the appropriate place in Hub RAM. Then cog 7 can be re-used like any other cog. So that's not an issue.

    So the minimum cog usage you have is one cog for the kernel and one for the cache, instead of Catalina's normal minimum of one cog for the kernel - can you do useful things with the 6 other cogs? Of course!

    One day (sigh!) I had planned to add a combined keyboard/mouse driver to save a cog - if you generate one that would be great!

    By the way, the biggest cog-monster at the moment is the hires VGA display on the Morpheus (it takes 4 cogs just to generate the VGA signal!) - but even on that platform there are still plenty of cogs left to do useful things.

    Ross.
  • jazzedjazzed Posts: 11,803
    edited 2010-11-24 21:06
    RossH wrote: »
    You would need to permanenently allocate a cog to your cache anyway, so that's not an isssue. You effectively have a 7-cog Prop but with 32Mb RAM - seems an acceptable trade-off!
    Ok, so then CogStore will have to use COG 6.

    You still need to tell me where to start the "permanent" SdramCache COG.

    Please, pretty please ...

    Allowing for using Catalyst.bin OR booting by some other means seems troubling. I guess I can ping the driver to see if it's already running at startup via common#REQUESTS or that other mailbox you mentioned in email.
    RossH wrote: »
    One day (sigh!) I had planned to add a combined keyboard/mouse driver to save a cog - if you generate one that would be great!
    Well the one I'll be adding is kind of special. It is actually an I2C driver that talks to the Keyboard/Mouse (+other) via a separate controller. It's not exactly a Propeller combined keyboard/mouse driver.

    With continuing product line expansion a good VGA solution will be produced (it's on my desk now, but needs respin). I plan to have a separate Propeller for VGA and other functions, so if you like, you can have a 6 COG VGA driver if necessary. Don't worry, I won't be messing with a proxy loader.
Sign In or Register to comment.