Shop OBEX P1 Docs P2 Docs Learn Events
My first Propeller C program (if I can do it. . . ) — Parallax Forums

My first Propeller C program (if I can do it. . . )

Ken GraceyKen Gracey Posts: 7,401
edited 2011-11-23 19:50 in Propeller 1
Hey all,

I shouldn't have been so late to this party but I have to say I'm really excited about Propeller GCC. This afternoon I had a 15 minute break and I installed the 40 MB Propeller GCC compiler and sample programs.

Next I found the lmm_toggle directory and proceeded to modify toggle.c to look like this:
*/

#include "propeller.h"

int main(int argc, char* argv[])
{
    int mask = 0x3fffffff;
    int freq = CLKFREQ>>1;
    DIRA = mask;
    for(;;) {
      OUTA ^= 1<<0;
      OUTA ^= 1<<1;
      OUTA ^= 1<<2;
      OUTA ^= 1<<3;
      OUTA ^= 1<<4;
      OUTA ^= 1<<5;
      OUTA ^= 1<<6;
        waitcnt(freq+CNT);
    }    
}

Compiled the code and downloaded to RAM in a Propeller BOE. I was really excited to see the results! At least now I can run the demos that all of your are producing and do something beyond being the sideline cheerleader. Didn't want to wear a dress anyway.

I need to learn enough about C to port some of my simple projects from Spin. I need to find a C tutorial for business types (hah ha) - does such a book exist? Can somebody point me in the right direction so I can get a better feeling for the syntax? I have a whole week off over Thanksgiving and I think I should be able to come back here with some real questions and a demo of my own.

Nice work to the Propeller GCC developers!

Ken Gracey
«1

Comments

  • mindrobotsmindrobots Posts: 6,506
    edited 2011-11-15 21:04
    Ken, congrats!! Welcome to the newbie pool. The smart guys are pretty tolerant of the rest of us!

    I thought you were following the "business types" guide to C - set direction, hire consultants, concentrate on YOUR job until they are done! (kidding!)

    Hats off to all the developers!
  • Ken GraceyKen Gracey Posts: 7,401
    edited 2011-11-15 21:14
    Well, I am following the Business Types Guide to C but I don't want to be the normal sales ding-dong that shows up at Parallax and asks how many [thousands] we will be buying. If I can gain some intelligence about GCC's benefits and limitations in Propeller 1 then I'll be able to get more design-ins where we're not getting any attention.

    We still need to find a front-end Eclipse guru. Got a few tips from Captain Quirk but more options would be beneficial.

    And hats off to the volunteers, too. If any of them want anything we can provide (hardware, robots, sensors, etc.) please contact me. Your contributions are truly valuable.

    Ken Gracey
  • RonPRonP Posts: 384
    edited 2011-11-15 21:14
    Ken,

    In another thread a lot of people recomended "The C Programming Language(ANSI)" by Brian W. Kernighan and Dennis M. Ritchie. I picked up a copy at BN I just started to get into it. It assumes you have a little programming knowledge, but I understand it so far (I Think). As I go through it I am going to compile and run it on my computer and then the Propeller with PropGcc. Propgcc has compiled and ran the first two examples with no problems.

    Yeah, Great Job Propeller GCC Team.

    Ron
  • Ken GraceyKen Gracey Posts: 7,401
    edited 2011-11-15 21:21
    RonP, I'll pick up a copy of that book tomorrow on my way home from Parallax. Sounds like a better way for me to learn than the "go take a class" suggestion from Steve :)

    What I'm not sure about is how the Propeller's capabilities will shine through in C. For example, how can any standard C code run on a Propeller when syntax must be supplemented for cog launching, driving a VGA, etc. I guess everybody accepts that C must vary from what we've seen on a PC to be useful in embedded systems. Probably a very elementary concern. David Betz is porting the VGA from Spin to C/PASM blob so maybe that'll answer my questions.
  • RonPRonP Posts: 384
    edited 2011-11-15 21:38
    Ken,

    Forgot to mention the book is in its 2nd Edition. I also found this C Reference Card (ANSI) usefull makes a good book mark to.:cool:

    Ron
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-11-15 23:59
    For example, how can any standard C code run on a Propeller when syntax must be supplemented for cog launching, driving a VGA, etc. I guess everybody accepts that C must vary from what we've seen on a PC to be useful in embedded systems.

    Good points.

    I've experimented with two solutions. One involves writing an IDE that can detect pasm code and separate it out and compile it and then read it back in as a C array and copy it into a C program as a hex array.

    The second is to treat such compiled programs as something that can be loaded off an sd card.

    In both cases the C and the pasm have to be separated out and the only interaction between the two must be via the array passed by par. This means that not every piece of code in the Obex can be translated easily.

    Some work well though. The mouse for instance (this is Catalina code):

    At the beginning of the program, declare an array to store this. This works best for XMM so this array ends up in external memory rather than hub memory. This saves hub memory. You could also load directly from an sd card into the cog, but I have written this so there is a copy in external memory as reloads are then quicker. In terms of speed, you could put the cog data anywhere - fastest = in hub, medium =external ram, slowest = sd card. It depends if you will be loading and reloading cogs through the program or just loading them once at the beginning.
    	unsigned long cogject_mouse[512];					// external memory for mouse driver
    

    In the main, declare the common array between hub and spin. In Catalina, declaring an array in "main" means it is local and so ends up in hub rather than in external memory
    	unsigned long mouse_parameters[19];				// group of 7 plus 12 longs in par_x in the spin version
    

    Read the cog data from an sd card into the xmm array we declared earlier. The file "mouse.cog" is actually "mouse.bin" which is the pasm part of the standard Obex mouse driver that has been compiled without any Spin.
    	readcog("mouse.cog",cogject_mouse);
    

    which calls this code to read from the sd card
    void readcog(char *filename,unsigned long external_cog[])		// read in a .cog file into external memory array 
    {
    	int i;
    	FILE *FP1;
    	i = 0;
    	if((FP1=fopen(filename,"rb"))==0)					// open the file
       	{
      		fprintf(stderr,"Can't open file %s\n",filename);
    		exit(1);
       	}
      	fseek(FP1,0,0);
    	for(i=0;i<24;i++)
    	{
    		getc(FP1);							// read in the first 24 bytes and discard
    	}
    	i = 0;
      	while(!EoF(FP1) & (i<505))						// run until end of file or 511-6
    	{
    		external_cog[i] = getc(FP1) | (getc(FP1)<<8) | (getc(FP1)<<16) | (getc(FP1)<<24);	// get the long
    		i+=1;
    	}
    	if(FP1)
           {
         		fclose(FP1);							// close the file
         		FP1=NULL;
       	}
    	//printf("external array cog first long = 0x%x \n",external_cog[0]);	// hex value
    }
    

    Then fill up the array we pass to the cog with some parameters
    	mouse_engine_start(7, cogject_mouse, mouse_parameters, 24, 25);	// start the mouse driver (takes 2 secs to reply with the mouse type)
    

    which calls this routine
    void mouse_engine_start(int cognumber, unsigned long cogarray[], unsigned long mouse_parameters[], int dpin, int cpin)
    {
    	mouse_parameters[0] = (unsigned long) &mouse_parameters[0];	// the first long of the array points to the location of the array itself
    	mouse_parameters[5] = (unsigned long) dpin;			// data pin
    	mouse_parameters[6] = (unsigned long) cpin;
    	_cogstop(cognumber);							// stop this cog
    	external_memory_cog_load(cognumber,cogarray,mouse_parameters);			// load from external ram to this cog, pass location of the array
    }
    

    and which calls this routine to move data from an array in external memory into a cog:
    void external_memory_cog_load(int cognumber, unsigned long cogdata[], unsigned long parameters_array[])    	//  load a cog from external memory
    {
    	unsigned long hubcog[511];						// create a local array, this is in hub ram, not external ram	
    	int i;	
    	for(i=0;i<512;i++)								
    	{
    		hubcog[i]=cogdata[i];					// move from external memory to a local array in hub
    	}
     	_coginit((int)parameters_array>>2, (int)hubcog>>2, cognumber);		// load the cog
    }  
    

    That starts up the cog, and the mouse location and the buttons appear in the mouse_parameters array.

    This is a fragment of code to read the mouse pointer and check it is not off the screen and to see if a button has been pressed
    	{
    		if ((oldx != mouse_parameters[0]) | (oldy != mouse_parameters[1]))
    		{
    			mx = mouse_parameters[0];
    			my = mouse_parameters[1];
    			if (mx>0x80000000) mx = 0;				// x < 0 
    			if (mx > 307) mx = 307;				// x > 307
    			if (my>0x80000000) my = 0;				// y < 0
    			if (my>219) my=219;					// y > 219
    			gray_mousepointer(screen,mousebuffer,mx, 219-my); // move the pointer 
    			//gray_debug_hex(screen,mouse_parameters[1]);  // print the value
    			oldx = mouse_parameters[0];				// store the previous value
    			oldy = mouse_parameters[1];
    		}
    		new_button = mouse_parameters[3];				// in case state changes in the next few lines
    		if ((old_button == 0) & (new_button == 1))		// mouse has changed from zero to 1
    		{
    			mouse_button(screen, mouse_parameters);		// mouse down
    		}
    		old_button = new_button;					// store current state of buttons
    	}
    

    You can do the same thing with a VGA driver, eg this is a C translation of Kye's VGA driver. Separate out the pasm and the Spin. Convert the Spin to C. Compile the pasm part to a binary file, rename it as .cog and put it on an sd card
    void pix_clearscreen(unsigned long screen[])
    {
    	int i;
    	for (i=0;i<4800;i++)
    	{
    		screen[i] = 0x00000000;		// fill with black, use longs rather than bytes so 4 pixels per loop
    	}
    }
    
    void pix_pixel(unsigned long screen[], int x, int y, char color)
    {
    	poke((y*160+x+(unsigned long)&screen[0]),color);		
    }
    
    void pix_readscreen(char *filename, unsigned long screen[])		// read a full screen 19200 byte file into the screen
    {
    	int i;
    	FILE *FP1;
    	i = 0;
    	FP1=fopen(filename,"rb");					// open the file
      	fseek(FP1,0,0);
    	for(i=0;i<=4800;i++)
    	{
    		screen[i] = getc(FP1) | (getc(FP1)<<8) | (getc(FP1)<<16) | (getc(FP1)<<24);	// get the long
    	}
    	fclose(FP1);							// close the file
         	FP1=NULL;
    }
    
    char pix_color(char red,char green,char blue)				// pass red,green,blue 0-3, returns a combined value
    {
    	return ((red & 0x3) << 6 ) | ((green & 0x3) << 4) | ((blue & 0x3) << 2);
    }
    
    void pix_screengray(unsigned long screen[])				// whole screen gray
    {
    	int i;
    	for(i=0;i<4800;i++)
    	{
    		screen[i] = 0xa8a8a8a8;					// same as pix_color(2,2,2)
    	}
    }
    
    void pixenginestart(int cognumber, unsigned long cogarray[], unsigned long screen[], unsigned long pingroup, char color_parameters[])
    {
    	int i;
    	unsigned long frequencystate;
    	screen[2] = (0xff << (8*pingroup));
    	screen[3] = (0x300000ff | (pingroup << 9));      
    	frequencystate = ((25175000 + 1600) / 4);
    	screen[4] = 1;
    	for(i=0;i<32;i++)
    	{
    		frequencystate = frequencystate << 1;
    		screen[4] = (screen[4] << 1) | (screen[4] >> 31);
    		if (frequencystate >= _clockfreq())
    		{
    			frequencystate -= _clockfreq();
    			screen[4] += 1;
    		}
    	}
    	color_parameters[0] = 1;			// displayindicator
    	color_parameters[1] = 0;			// syncindicator
    	screen[0] = (unsigned long) &color_parameters[0]; // pointer to displayindicator
    	screen[1] = (unsigned long) &color_parameters[1]; // pointer to syncindicator
    	_cogstop(cognumber); 					// stop just before starting the next one
    	external_memory_cog_load(cognumber,cogarray,screen);		// load from external ram, pass some values in screen[]
    	//pix_clearscreen(screen);					// clear the screen to black
    	pix_screengray(screen);					// screen gray
    }
    
    void pix_colorbar(unsigned long screen[])
    {
    	int x;
    	int c;
    	x = 0;
    	for (c=0;c<64;c++)
    	{
    		pix_pixel(screen,x+10,6,(c<<2));			// print all the colors in a bar
    		x++;
    	}
    }
    
    void pix_line(unsigned long screen[], int startx, int starty, int endx, int endy, char color) 
    {
    	int row;								// also does an unfilled box
    	int col;
    	for(col=startx;col <= endx ;col++)
    	{
    		pix_pixel(screen,col,starty,color);			// horizontal lines
    		pix_pixel(screen,col,endy,color);
    	}
    	for(row=starty;row <= endy;row++)
    	{
    		pix_pixel(screen,startx,row,color);
    		pix_pixel(screen,endx,row,color);
    	}
    }
    
    void pix_box_fill(unsigned long screen[], int startx, int starty, int endx, int endy, char color) 
    {
    	int row;
    	int col;
    	for(row =starty;row <= endy; row++)
    	{
    		for(col=startx;col <=endx; col++)
    		{
    			pix_pixel(screen,col,row,color);			// horizontal line
    		}
    	}
    }
    
    
    void copyscreen(unsigned long source[],unsigned long destination[])
    {
    	memcpy(destination,source,19200);					// a strings.h function
    }
    
    void color_demo(unsigned long screen[],char color_parameters[],int cognumber)					// kye graphics demo
    {
           pixenginestart(cognumber,cogject_color,screen,2,color_parameters);				// start the driver
           pix_pixel(screen,3,3,0x44);
    	pix_pixel(screen,4,4,0xFF);
    	pix_pixel(screen,5,5,pix_color(1,2,3));				// rgb each 0,1,2 or 3
    	pix_line(screen,0,0,159,119,pix_color(3,0,0));			// red border for screen
    	pix_colorbar(screen);						// a color bar
    	pix_line(screen,10,10,30,30,pix_color(3,3,0));		// a yellow box
    	pix_box_fill(screen,10,50,40,60,pix_color(3,0,3));		// magenta filled rectangle
    	//pix_readscreen("wallaby.vga",screen);				// display whole screen image 
    	//copyscreen(screen,screen_external);				// copy to external ram
    	//pix_readscreen("Giraffe.vga",screen);				// display whole screen image 
    	//copyscreen(screen_external,screen);				// copy back to hub
    	//pix_readscreen("prop160.vga",screen);				// display whole screen image
    	//pix_box_fill(screen, 0, 0, 159,119,pix_color(2,2,2));		// whole screen gray	
    }
    

    and for reference, this was Kye's original Spin/Pasm VGA driver. Compare the function 'pixenginestart' in C and Spin
    {{
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // VGA64 6 Bits Per Pixel Engine
    //
    // Author: Kwabena W. Agyeman
    // Updated: 11/17/2010
    // Designed For: P8X32A
    // Version: 1.0
    //
    // Copyright (c) 2010 Kwabena W. Agyeman
    // See end of file for terms of use.
    //
    // Update History:
    //
    // v1.0 - Original release - 11/17/2009.
    //
    // For each included copy of this object only one spin interpreter should access it at a time.
    //
    // Nyamekye,
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Video Circuit:
    //
    //     0   1   2   3 Pin Group
    //
    //                     240OHM
    // Pin 0,  8, 16, 24 ----R-------- Vertical Sync
    //
    //                     240OHM
    // Pin 1,  9, 17, 25 ----R-------- Horizontal Sync
    //
    //                     470OHM
    // Pin 2, 10, 18, 26 ----R-------- Blue Video
    //                            |
    //                     240OHM |
    // Pin 3, 11, 19, 27 ----R-----
    //
    //                     470OHM
    // Pin 4, 12, 20, 28 ----R-------- Green Video
    //                            |
    //                     240OHM |
    // Pin 5, 13, 21, 29 ----R-----
    //
    //                     470OHM
    // Pin 6, 14, 22, 30 ----R-------- Red Video
    //                            |
    //                     240OHM |
    // Pin 7, 15, 23, 31 ----R-----
    //
    //                            5V
    //                            |
    //                            --- 5V
    //
    //                            --- Vertical Sync Ground
    //                            |
    //                           GND
    //
    //                            --- Hoirzontal Sync Ground
    //                            |
    //                           GND
    //
    //                            --- Blue Return
    //                            |
    //                           GND
    //
    //                            --- Green Return
    //                            |
    //                           GND
    //
    //                            --- Red Return
    //                            |
    //                           GND
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    }}
    
    CON
    
      #$FC, Light_Grey, #$A8, Grey, #$54, Dark_Grey
      #$C0, Light_Red, #$80, Red, #$40, Dark_Red
      #$30, Light_Green, #$20, Green, #$10, Dark_Green
      #$0C, Light_Blue, #$08, Blue, #$04, Dark_Blue
      #$F0, Light_Orange, #$A0, Orange, #$50, Dark_Orange
      #$CC, Light_Purple, #$88, Purple, #$44, Dark_Purple
      #$3C, Light_Teal, #$28, Teal, #$14, Dark_Teal
      #$FF, White, #$00, Black
    
    PUB plotBox(color, xPixelStart, yPixelStart, xPixelEnd, yPixelEnd) '' 8 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Plots a one color box of pixels on screen.
    '' //
    '' // Color - The color of the box of pixels to display on screen. A color byte (%RR_GG_BB_xx).
    '' // XPixelStart - The X cartesian pixel start coordinate. X between 0 and 159. Y between 0 and 119.
    '' // YPixelStart - The Y cartesian pixel start coordinate. Note that this axis is inverted like on all other graphics drivers.
    '' // XPixelEnd - The X cartesian pixel end coordinate. X between 0 and 159. Y between 0 and 119.
    '' // YPixelEnd - The Y cartesian pixel end coordinate. Note that this axis is inverted like on all other graphics drivers.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      xPixelEnd := ((xPixelEnd <# 159) #> 0)
      yPixelEnd := (((yPixelEnd <# 119) #> 0) * 160)
      xPixelStart := ((xPixelStart <# xPixelEnd) #> 0)
      yPixelStart := (((yPixelStart * 160) <# yPixelEnd) #> 0)
    
      yPixelEnd += xPixelStart
      yPixelStart += xPixelStart
      xPixelEnd -= --xPixelStart
    
      repeat result from yPixelStart to yPixelEnd step 160
        bytefill(@displayBuffer + result, (color | $3), xPixelEnd)
    
    PUB plotPixel(color, xPixel, yPixel) '' 6 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Plots a one color pixel on screen.
    '' //
    '' // Color - The color of the pixel to display on screen. A color byte (%RR_GG_BB_xx).
    '' // XPixel - The X cartesian pixel coordinate. X between 0 and 159. Y between 0 and 119.
    '' // YPixel - The Y cartesian pixel coordinate. Note that this axis is inverted like on all other graphics drivers.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      displayBuffer.byte[((xPixel <# 159) #> 0) + (160 * ((yPixel <# 119) #> 0))] := (color | $3)
    
    PUB displayClear '' 3 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Clears the screen to black.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      longfill(@displayBuffer, 0, constant((160 * 120) / 4))
    
    PUB displayPointer '' 3 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Returns a pointer to the display buffer.
    '' //
    '' // The display buffer is an array of 160 by 120 bytes. Each byte represents a pixel on the screen.
    '' //
    '' // Each pixel is a color byte (%RR_GG_BB_xx). Where RR, GG, and BB are the two bit values of red, green, blue respectively.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      return @displayBuffer
    
    PUB displayState(state) '' 4 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Enables or disables the PIX Driver's video output - turning the monitor off or putting it into standby mode.
    '' //
    '' // State - True for active and false for inactive.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      displayIndicator := state
    
    PUB displayRate(rate) '' 4 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Returns true or false depending on the time elasped according to a specified rate.
    '' //
    '' // Rate - A display rate to return at. 0=0.234375Hz, 1=0.46875Hz, 2=0.9375Hz, 3=1.875Hz, 4=3.75Hz, 5=7.5Hz, 6=15Hz, 7=30Hz.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      result or= (($80 >> ((rate <# 7) #> 0)) & syncIndicator)
    
    PUB displayWait(frames) '' 4 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Waits for the display vertical refresh.
    '' //
    '' // The best time to draw on screen for flicker free operation is right after this function returns.
    '' //
    '' // Frames - Number of vertical refresh frames to wait for.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      repeat (frames #> 0)
        result := syncIndicator
        repeat until(result <> syncIndicator)
    
    PUB displayColor(redAmount, greenAmount, blueAmount) '' 6 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Builds a color byte (%RR_GG_BB_xx) from red, green, and blue componets.
    '' //
    '' // RedAmount - The amount of red to add to the color byte. Between 0 and 3.
    '' // GreenAmount - The amount of green to add to the color byte. Between 0 and 3.
    '' // BlueAmount - The amount of blue to add to the color byte. Between 0 and 3.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      return ((((redAmount <# 3) #> 0) << 6) | (((greenAmount <# 3) #> 0) << 4) | (((blueAmount <# 3) #> 0) << 2) | $3)
    
    PUB PIXEngineStart(pinGroup) '' 7 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Starts up the PIX driver running on a cog.
    '' //
    '' // Returns true on success and false on failure.
    '' //
    '' // PinGroup - Pin group to use to drive the video circuit. Between 0 and 3.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      PIXEngineStop
      if(chipver == 1)
    
        pinGroup := ((pinGroup <# 3) #> 0)
        directionState := ($FF << (8 * pinGroup))
        videoState := ($30_00_00_FF | (pinGroup << 9))
    
        pinGroup := constant((25_175_000 + 1_600) / 4)
        frequencyState := 1
    
        repeat 32
          pinGroup <<= 1
          frequencyState <-= 1
          if(pinGroup => clkfreq)
            pinGroup -= clkfreq
            frequencyState += 1
    
        displayIndicatorAddress := @displayIndicator
        syncIndicatorAddress := @syncIndicator
        cogNumber := cognew(@initialization, @displayBuffer)
        result or= ++cogNumber
    
    PUB PIXEngineStop '' 3 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Shuts down the PIX driver running on a cog.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      if(cogNumber)
        cogstop(-1 + cogNumber~)
    
    DAT
    
    ' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '                       PIX Driver
    ' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
                            org     0
    
    ' //////////////////////Initialization/////////////////////////////////////////////////////////////////////////////////////////
    
    initialization          mov     vcfg,           videoState                 ' Setup video hardware.
                            mov     frqa,           frequencyState             '
                            movi    ctra,           #%0_00001_101              '
    
    ' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '                       Active Video
    ' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    loop                    mov     displayCounter, par                        ' Set/Reset tiles fill counter.
                            mov     tilesCounter,   #120                       '
    
    tilesDisplay            mov     tileCounter,    #4                         ' Set/Reset tile fill counter.
    
    tileDisplay             mov     vscl,           visibleScale               ' Set/Reset the video scale.
                            mov     counter,        #40                        '
    
    ' //////////////////////Visible Video//////////////////////////////////////////////////////////////////////////////////////////
    
    videoLoop               rdlong  buffer,         displayCounter             ' Download new pixels.
                            add     displayCounter, #4                         '
    
                            or      buffer,         HVSyncColors               ' Update display scanline.
                            waitvid buffer,         #%%3210                    '
    
                            djnz    counter,        #videoLoop                 ' Repeat.
    
    ' //////////////////////Invisible Video////////////////////////////////////////////////////////////////////////////////////////
    
                            mov     vscl,           invisibleScale             ' Set/Reset the video scale.
    
                            waitvid HSyncColors,    syncPixels                 ' Horizontal Sync.
    
    ' //////////////////////Repeat/////////////////////////////////////////////////////////////////////////////////////////////////
    
                            sub     displayCounter, #160                       ' Repeat.
                            djnz    tileCounter,    #tileDisplay               '
    
                            add     displayCounter, #160                       ' Repeat.
                            djnz    tilesCounter,   #tilesDisplay              '
    
    ' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '                       Inactive Video
    ' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
                            add     refreshCounter, #1                         ' Update sync indicator.
                            wrbyte  refreshCounter, syncIndicatorAddress       '
    
    ' //////////////////////Front Porch////////////////////////////////////////////////////////////////////////////////////////////
    
                            mov     counter,        #11                        ' Set loop counter.
    
    frontPorch              mov     vscl,           blankPixels                ' Invisible lines.
                            waitvid HSyncColors,    #0                         '
    
                            mov     vscl,           invisibleScale             ' Horizontal Sync.
                            waitvid HSyncColors,    syncPixels                 '
    
                            djnz    counter,        #frontPorch                ' Repeat # times.
    
    ' //////////////////////Vertical Sync//////////////////////////////////////////////////////////////////////////////////////////
    
                            mov     counter,        #(2 + 2)                   ' Set loop counter.
    
    verticalSync            mov     vscl,           blankPixels                ' Invisible lines.
                            waitvid VSyncColors,    #0                         '
    
                            mov     vscl,           invisibleScale             ' Vertical Sync.
                            waitvid VSyncColors,    syncPixels                 '
    
                            djnz    counter,        #verticalSync              ' Repeat # times.
    
    ' //////////////////////Back Porch/////////////////////////////////////////////////////////////////////////////////////////////
    
                            mov     counter,        #31                        ' Set loop counter.
    
    backPorch               mov     vscl,           blankPixels                ' Invisible lines.
                            waitvid HSyncColors,    #0                         '
    
                            mov     vscl,           invisibleScale             ' Horizontal Sync.
                            waitvid HSyncColors,    syncPixels                 '
    
                            djnz    counter,        #backPorch                 ' Repeat # times.
    
    ' //////////////////////Update Display Settings////////////////////////////////////////////////////////////////////////////////
    
                            rdbyte  buffer,         displayIndicatorAddress wz ' Update display settings.
                            muxnz   dira,           directionState             '
    
    ' //////////////////////Loop///////////////////////////////////////////////////////////////////////////////////////////////////
    
                            jmp     #loop                                      ' Loop.
    
    ' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '                       Data
    ' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    invisibleScale          long    (16 << 12) + 160                           ' Scaling for inactive video.
    visibleScale            long    (4 << 12) + 16                             ' Scaling for active video.
    blankPixels             long    640                                        ' Blank scanline pixel length.
    syncPixels              long    $00_00_3F_FC                               ' F-porch, h-sync, and b-porch.
    HSyncColors             long    $01_03_01_03                               ' Horizontal sync color mask.
    VSyncColors             long    $00_02_00_02                               ' Vertical sync color mask.
    HVSyncColors            long    $03_03_03_03                               ' Horizontal and vertical sync colors.
    
    ' //////////////////////Configuration Settings/////////////////////////////////////////////////////////////////////////////////
    
    directionState          long    0
    videoState              long    0
    frequencyState          long    0
    
    ' //////////////////////Addresses//////////////////////////////////////////////////////////////////////////////////////////////
    
    displayIndicatorAddress long    0
    syncIndicatorAddress    long    0
    
    ' //////////////////////Run Time Variables/////////////////////////////////////////////////////////////////////////////////////
    
    counter                 res     1
    buffer                  res     1
    
    tileCounter             res     1
    tilesCounter            res     1
    
    refreshCounter          res     1
    displayCounter          res     1
    
    ' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
                            fit     496
    
    DAT
    
    ' //////////////////////Variable Arrary////////////////////////////////////////////////////////////////////////////////////////
    
    displayBuffer           long    0[(160 * 120) / 4]                         ' Display buffer.
    displayIndicator        byte    1                                          ' Video output control.
    syncIndicator           byte    0                                          ' Video update control.
    cogNumber               byte    0                                          ' Cog ID.
    
    ' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    {{
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //                                                  TERMS OF USE: MIT License
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
    // files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
    // modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
    // Software is furnished to do so, subject to the following conditions:
    //
    // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
    // Software.
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
    // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
    // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
    // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    }}
    
  • RossHRossH Posts: 5,513
    edited 2011-11-16 01:18
    Ken Gracey wrote: »
    What I'm not sure about is how the Propeller's capabilities will shine through in C. For example, how can any standard C code run on a Propeller when syntax must be supplemented for cog launching, driving a VGA, etc. I guess everybody accepts that C must vary from what we've seen on a PC to be useful in embedded systems.

    I beg to differ - Catalina allows you to run exactly the same C code you run on your PC on your Propeller!

    Catalina supports launching C (or Spin or PASM for that matter) in multiple cogs using syntax that will be very familiar to anyone who has ever used Posix threads, plus it has full VGA, TV, serial device, file system support using standard C syntax, plus it gives you access to all the unique facilities of the Propeller.

    Yes, I expect GCC may catch up eventually ... but why wait?

    Ross.

    P.S. Sorry, Ken - but you asked for this one :lol:
  • Heater.Heater. Posts: 21,230
    edited 2011-11-16 02:18
    Ken,
    For example, how can any standard C code run on a Propeller when syntax must be supplemented for

    Just a little clarification here. Technically as far as syntax goes C is C is C...That is to say that Catalina or ICC or propgcc or whatever C are designed to support the same standardized C syntax. (Give or take a few standard revisions). The syntax is not modified to support Propeller features.

    Next up we have to consider the environment your C code runs in. One of the reasons C became so popular is that it did specify a minimal input output system based on library functions. Old languages like Algol did not do that and every "Hello world" program ended up using some weird IO system local to that compiler or that machine. Things were very unportable. (N.B. Spin is still in that era). So C has things like printf for dealing with the console and fopen, fclose, fprintf, fscanf etc etc for dealing with files and so on.

    So yes any standard code can run on any machine supporting the standard without modification. As Catalina does and propgcc surely will.

    Next up we come to all those features of embedded devices that are not mentioned in any standard. The classic simple case being how to set a pin to input or out put and how to read and write it's state. For sure every compiler and every system does this a different way. Remember the C syntax is not changed to do this but different library functions or macros may be supplied to do it. Or perhaps you are just left to know the address of the register that drives that pin and have to figure out how to read/write it your self. (Much like Spin). In the extreme on something like a Linux system or Windows you may end up having to write an entire device driver to connect your user application to the hardware!

    In the embedded world all this customization of I/O and special device features is pretty much taken for granted.

    I have to take issue with RossH though, the vast majority of C programs that will run on a PC will not run on your embedded system just because your compiler supports the C standard libraries. There is always a pile of operating system and or hardware dependencies that make it unlikely your code will work with out modification or perhaps porting the OS interface from one OS to another. Why do we need things like cygwin and mingw otherwise?

    Having said all that. GCC does have a pile of non-standard extensions to the actual C syntax. A wise programmer wanting to create cross-platform code would not use such extensions. I am guilty of using one such extension in order to get my full duplex serial driver compiled into native COG code to run at 115200 baud.
  • RossHRossH Posts: 5,513
    edited 2011-11-16 03:12
    Heater. wrote: »
    I have to take issue with RossH though, the vast majority of C programs that will run on a PC will not run on your embedded system just because your compiler supports the C standard libraries.
    Numerically, what you say may be true - because many C programs are intentionally platform-specific and would never be able run on any platform other than the one for which they were specifically designed.

    But if you restrict yourself to ANSI C programs (i.e. C programs written in the last 20 years or so) then yes they will - provided (of course) that there is enough RAM space for them to do so.
    Heater. wrote: »
    There is always a pile of operating system and or hardware dependencies that make it unlikely your code will work with out modification or perhaps porting the OS interface from one OS to another.
    Ummm. This is also a bit of a red herring. Yes, if I write a program that uses some OS-specific libraries, then it will probably not work on another OS. But this has nothing to do with C itself - it is true in any language.
    Heater. wrote: »
    Why do we need things like cygwin and mingw otherwise?
    A good question - but I'm not sure I see the relevance to this particular argument. Cygwin and/or MinGW are required by GCC because GCC is specifically intended to run in a Linux-like OS environment, not a Windows one. This is not true of other C compilers (including Catalina), and it also has nothing to do with the language supported by the compiler.

    Ross.
  • Heater.Heater. Posts: 21,230
    edited 2011-11-16 03:40
    RossH,
    But if you restrict yourself to ANSI C programs...then yes they will...
    True, no argument there. But of course programs with those restrictions are
    basically useless on most MCU systems. Take that simple I/O pin access for
    example. I have an application that uses a lot of general purpose I/O bits
    running on an industrial PC under Linux. We created a Linux device driver for
    those I/O's. So yes, the app can use standard functions to access those I/Os
    now. But would you really want to carry all that baggage to a small system
    where INA/OUTA would do?
    This is also a bit of a red herring.

    Yes it is. OS specific or hardware specific the problem is always there.
    I'm just hinting that on a Propeller or other MCU we don't really need all those
    standard libs. Spin users have not missed such luxuries so far.
    Cygwin and/or MinGW are required by GCC because GCC is specifically intended to
    run in a Linux-like OS environment, not a Windows one

    A very good point. Given a standardized C language which also standardizes the
    I/O and such, the run time environment. How the hell did the GNU guys come
    up with a compiler that doesn't just compile anywhere that has a similarly
    standardized compiler to start with? After all when all is said and done it's
    just read text in, write binary out.
  • Andrey DemenevAndrey Demenev Posts: 377
    edited 2011-11-16 03:44
    Could not find a more relevant topic to post in ... Though I did not search hard...

    It's been long time since I've been here, and now I see this. However it comes out, my opinion is that C on the Prop is .... hmmmmmmmmm..... unnecessary. You are killing what Prop can do with this. I never could understand all these *MM things. And over 5 KB "Hello world" .... Nothing good.

    Bad direction. I have nothing more to say.
  • David BetzDavid Betz Posts: 14,516
    edited 2011-11-16 03:56
    Hi Ken,

    Congratulations on writing your first C program! I think you'll find that most fairly generic C code will run on the PropBOE as long as it fits into hub memory. Also, I've just finished an SD cache driver that will allow larger programs to run on the PropBOE or any Propeller board with an SD card interface. This gives an almost limitless amount of code space but data will still be restricted to hub memory since the SD card is currently treated as read-only. Of course, programs will run much slower from the SD card but performance may be good enough for a non-time-critical main program. Anyway, have fun with C on the Propeller and feel free to ask questions if you find yourself getting into difficulties.

    David
  • RossHRossH Posts: 5,513
    edited 2011-11-16 04:54
    Heater. wrote: »
    True, no argument there. But of course programs with those restrictions are
    basically useless on most MCU systems. Take that simple I/O pin access for
    example. I have an application that uses a lot of general purpose I/O bits
    running on an industrial PC under Linux. We created a Linux device driver for
    those I/O's. So yes, the app can use standard functions to access those I/Os
    now.
    I guess real the answer is that it depends on what you want to do.

    You can use C as a kind of "structured assembler" and write programs that will never be portable, were never intended to be portable, and would generally be better off actually written in assembler if you could be bothered to do so - Dr_A just posted a perfect example in the Catalina 3.4 thread (a driver for an LCD display).

    Or you can use C and write extremely portable programs, but at the cost of efficiency. Rayman's chess program was a good exampe of the latter, also posted in the same thread.

    But you also find programs designed to be embedded that are written in ANSI C. Take the Lua scripting language - 100% ANSI C, runs fine on the Propeller (well, a little slow on the Prop 1 perhaps - but it will be perfect for the Prop 2!).

    However, most C programs (ANSI or not) fall somewhere in between. A well structured C program would typically have >95% completely portable C that will compile correctly on any C compiler, and <5% platform (or OS) specific C that won't. Good examples are the xvi text editor, or David Betz' xbasic. In both these examples the platform specific code limited to a single file of no more than a couple of dozen lines of code - and both run fine on the Propeller. Are these programs "useless" on an MCU? Well, for you perhaps they are - but for others they most definitely are not!
    Heater. wrote: »
    But would you really want to carry all that baggage to a small system where INA/OUTA would do?
    What baggage? If you don't use any of the standard library functions, they cost you nothing.

    Ross.
  • ersmithersmith Posts: 6,100
    edited 2011-11-16 04:56
    I'll second the recommendation of Kernighan & Ritchie. It's pretty much the canonical C book, since they're the guys who invented the language. For someone who knows programming (but not C) already it's a good introduction. Even if you decide later to get another book as well, it's a great reference.

    (And congratulations on joining the ranks of C programmers, Ken!)

    Eric
  • ersmithersmith Posts: 6,100
    edited 2011-11-16 05:09
    RossH wrote: »
    I beg to differ - Catalina allows you to run exactly the same C code you run on your PC on your Propeller!
    I think Ken was talking about hardware access -- things like programming cogs, driving a VGA, and so forth. Low level hardware access on *any* machine is not covered by the ANSI standard, and it's not going to be the same on the Propeller as on a PC. You can't take a Linux device driver and recompile it with Catalina!
    Catalina supports launching C (or Spin or PASM for that matter) in multiple cogs using syntax that will be very familiar to anyone who has ever used Posix threads, plus it has full VGA, TV, serial device, file system support using standard C syntax, plus it gives you access to all the unique facilities of the Propeller.
    If we're going to be pedantic "syntax that will be very familiar" is not "exactly the same"! Propgcc actually has a pthreads library. It's still a work in progress, but you can launch threads on other cogs in propgcc using standard pthreads functions, not "pthreads-like" functions.

    Of course Catalina could adopt the same library -- it's a fine compiler. But none of us are in a position to throw stones about who is "most standards compliant". Neither Catalina nor the current propgcc distribution is fully compliant with the latest C standard (C99). I daresay propgcc is closer to compliant with C99, and Catalina is probably closer to compliant with the previous C89 standard.
    P.S. Sorry, Ken - but you asked for this one :lol:

    As did you :smile:.

    Eric
  • ersmithersmith Posts: 6,100
    edited 2011-11-16 05:18
    Dr_Acula wrote: »
    I've experimented with two solutions. One involves writing an IDE that can detect pasm code and separate it out and compile it and then read it back in as a C array and copy it into a C program as a hex array.

    The second is to treat such compiled programs as something that can be loaded off an sd card.

    In both cases the C and the pasm have to be separated out and the only interaction between the two must be via the array passed by par. This means that not every piece of code in the Obex can be translated easily.

    If you use only gcc (and it's assembler gas) then code in cogs can communicate with the main code -- they can share variables in hub ram on so forth. And in fact you can often write the cog code in C, which is certainly easier than PASM (but a little bigger and slower).

    For many drivers restricting the interaction to a memory block pointed to by PAR makes sense, and it does make it easier to port the code between compilers (and lets you do neat things like loading the driver from an sd card, as you showed). So that's probably the preferred way to do it wherever possible.

    Eric
  • __red____red__ Posts: 470
    edited 2011-11-16 07:48
    Could not find a more relevant topic to post in ... Though I did not search hard...

    It's been long time since I've been here, and now I see this. However it comes out, my opinion is that C on the Prop is .... hmmmmmmmmm..... unnecessary. You are killing what Prop can do with this. I never could understand all these *MM things. And over 5 KB "Hello world" .... Nothing good.

    Bad direction. I have nothing more to say.

    Your post is based on the premise that there is one direction and that implementing a C compiler for the prop in some way removes all the other methods of programming the device.

    It doesn't.

    What it does do is reduce the investment required for an embedded development shop to start using the propeller. They no longer have to learn a chip-specific language or asm, they can use the most commonly used language in the world. C.

    So, keep on using SPIN, keep on using PASM. C just opens up our influence to a whole other world of developers and existing code.
  • ReinhardReinhard Posts: 489
    edited 2011-11-16 09:30
    __red__ wrote: »
    C just opens up our influence to a whole other world of developers and existing code.

    Yeep, I guess 99% of embedded Software worldwide is written in C.

    For my point of view : THANKS to all the people, they developed Catalina, ICCv7 and now propgcc.

    best regards,
    Reinhard
  • KyeKye Posts: 2,200
    edited 2011-11-16 09:40
    @Andrey Demenev

    The point of C on the propeller chip is to prepare for C on the propeller 2. Alot of bugs and how to do things can be worked out now and then port to the new hardware when it comes out.

    @ Ken

    If people want ultra portable C code that works on any platform then they must have functions that must be called for any device specific functionality not in the C library or standard. This isn't really a huge issue. Any developer would just have to write the code more carfully and not use DIRA and OUTA but a function that could be replaced that sets DIRA or OUTA to hide the details of the underlying hardware.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-11-16 09:55
    Can't ... control ... typing ... hand ... must not ... type ... ken ... c ... darkside .... nnngh! ... nono ... must ... repeat ... c good ... not darkside .... nnngh! ... brain ... exploding ... need ... spin fix
  • Kevin WoodKevin Wood Posts: 1,266
    edited 2011-11-16 11:58
    One book that I recommend having is C in a Nutshell, published by O'Reilly.
  • Roy ElthamRoy Eltham Posts: 3,000
    edited 2011-11-16 14:50
    Since this came out well after I started using and learning C/C++, I can't vouch for it directly, but several friends have told me it's great. Also, it's free.

    http://mindview.net/CDs/ThinkingInC/beta3

    There is also a free version of the book "Thinking in C++" in pdf form available here: http://www.lib.ru.ac.th/download/e-books/TIC2Vone.pdf
    Volume two is available here: http://www.lib.ru.ac.th/download/e-books/Tic2Vtwo.pdf
    However, volume two is less interesting for Microcontroller use.

    propgcc does support C++, and we will use it to great effect in the long run.
  • jazzedjazzed Posts: 11,803
    edited 2011-11-16 15:53
    Kevin Wood wrote: »
    One book that I recommend having is C in a Nutshell, published by O'Reilly.
    That's a very good book. Nice that it's online. It also talks about GCC and make.

    This on-line tutorial is pretty good: http://www.cprogramming.com/tutorial/c/lesson1.html

    Bob Lawrence recommended this book: http://publications.gbdirect.co.uk/c_book/ It is a good reference.
  • RossHRossH Posts: 5,513
    edited 2011-11-16 16:32
    ersmith wrote: »
    You can't take a Linux device driver and recompile it with Catalina!
    Of course not - in fact I'd be very surprised if you could take a Linux device driver and recompile it with any other compiler, or on any other platform, than GCC on Linux. this is a perfect example of the class of C programs that is completely non-portable - by design! Also, while you could implement a device driver with Catalina (I have done so) I readily acknowledge propGCC will be better for this since it can generate cog-based PASM - but it is too early to tell whether this will be the way people choose to to write their device drivers on the Propeller. Also, is propGCC really using C here? - my understanding is that when generating cog-based PASM, propGCC supports only a subset of C, plus some propeller-specific extensions - but I have to admit am not all that familiar with it, so correct me if I have misunderstood this.
    ersmith wrote: »
    If we're going to be pedantic "syntax that will be very familiar" is not "exactly the same"! Propgcc actually has a pthreads library. It's still a work in progress, but you can launch threads on other cogs in propgcc using standard pthreads functions, not "pthreads-like" functions.
    I love being pedantic! I could have elected for syntactical compliance with pthreads (probably still could in fact, with the inclusion of a few macro definitions) - but in my view this is worse than not being compliant, since I think the pthreads semantics are too expensive to implement on the Prop 1 - which would mean programs might compile, but not run correctly.

    But I'll be quite impressed if propGCC can actually support pthreads (in its entirety) on the Prop 1!
    ersmith wrote: »
    Of course Catalina could adopt the same library -- it's a fine compiler. But none of us are in a position to throw stones about who is "most standards compliant". Neither Catalina nor the current propgcc distribution is fully compliant with the latest C standard (C99). I daresay propgcc is closer to compliant with C99, and Catalina is probably closer to compliant with the previous C89 standard.
    I'm not throwing stones - and certainly not about C99 - neither Catalina nor GCC claim to be C99 compliant, and I don't think C99 is all that relevant for embedded systems anyway - but I do think C89 compliance is important, and I have already said I expect GCC to become more C89 compliant over time. The main point (to bring this back to Ken's original posts) is that I believe such compliance to be necessary to the success of C on the Propeller, whereas some others obviously don't. But that's fine - everyone is entitled to their opinion, no matter how muddle-headed it may be :)

    I guess we should let Ken have his thread back at this point - but I'd be happy to carry on this discussion in another thread.

    Ross.
  • jazzedjazzed Posts: 11,803
    edited 2011-11-16 17:05
    RossH wrote: »
    I guess we should let Ken have his thread back at this point ...
    Yes, this forum is about alpha testing Propeller-GCC. It is not a free-for-all. Moderation has been restrained so far.
  • RossHRossH Posts: 5,513
    edited 2011-11-16 17:14
    Kye wrote: »
    The point of C on the propeller chip is to prepare for C on the propeller 2.

    Say what? Surely the point of the propGCC project is to be able to offer C on both the Propeller 1 and the Propeller 2 ???? Or is propGCC on the Prop 1 just going to stay in alpha mode?

    Ross.
  • ersmithersmith Posts: 6,100
    edited 2011-11-16 17:20
    RossH wrote: »
    Also, is propGCC really using C here? - my understanding is that when generating cog-based PASM, propGCC supports only a subset of C, plus some propeller-specific extensions - but I have to admit am not all that familiar with it, so correct me if I have misunderstood this.
    Propgcc allows for any C (or C++) code that will fit to be compiled to run in a cog. The "that will fit" is a serious constraint, of course, given the small size of cog memory, but there is no compiler based restriction on what you can do.

    I think we'll leave the rest to another thread and/or another time.

    Eric
  • TorTor Posts: 2,010
    edited 2011-11-17 01:05
    RossH wrote: »
    [..] but I do think C89 compliance is important,]..}
    I totally agree there. I only write C89. At work we produce software for many platforms and many compilers, thus everything (if written in C) is always written as C89. We don't accept '//' comments (so-called C++ comments), for example. We don't use GCC extensions. This goes for a couple of open source projects I'm working for as well: Always C89.
    All my private hobby code is also following C89. There's very little in C99 that I find particularly useful, with the exception of the occasional need for declarations-following-code, but that's often a mis-used feature anyway and all in all it's better without it.

    -Tor
  • Daniel HarrisDaniel Harris Posts: 207
    edited 2011-11-17 11:01
    Hey guys, lets try and keep this thread on topic. I know there is alot of discussion about the point of PropGCC and its point for Parallax - this is not the topic of this thread.

    Thanks!
  • RaymanRayman Posts: 14,851
    edited 2011-11-17 19:07
    Hey, I noticed Ken said "Propeller 1" yesterday. Does that imply the next chip will be called Propeller 2?

    BTW: I think GCC and Catalina will both be important for whatever Prop2 is called....
Sign In or Register to comment.