Shop OBEX P1 Docs P2 Docs Learn Events
First Trial of a C - Interface to the VGA 64 Driver from OBEX — Parallax Forums

First Trial of a C - Interface to the VGA 64 Driver from OBEX

ReinhardReinhard Posts: 489
edited 2012-01-04 02:00 in Propeller 1
Hi,
Try to built a C interface to the VGA64 driver from OBEX
( the origin author will forgive me ;-)

Basicly works and my first goal was a closer understand of the mailbox interface to pasm code.
/**
    Trial of a C - Interface to the VGA 64 Driver from     OBEX
    VGA64 6 Bits Per Pixel Engine

ORIGIN:
    Author: Kwabena W. Agyeman
    Updated: 11/17/2010
    Designed For: P8X32A
    Version: 1.0

    Copyright (c) 2010 Kwabena W. Agyeman
--------------------------------------------------
    Code from PUB PIXEngineStart(pinGroup) 
    is go to main
    
    very experimental, basicly works
    
*/

#include <stdlib.h>
#include <propeller.h>                   
////////////////////////////////////////////////////////////////////////
//  Mailbox
////////////////////////////////////////////////////////////////////////
static unsigned int directionState; 
static unsigned int videoState;
static unsigned int frequencyState;
static unsigned int * displayPtr;

static unsigned int *syncIndicatorAdress;
static unsigned int *displayIndicatorAdress;
////////////////////////////////////////////////////////////////////////
unsigned int DISPLAY_BUFFER[(160 * 120) / 4];
unsigned int sync_indi;
unsigned int display_indi;
////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////
unsigned int _rotl( unsigned int value, int shift) 
{
    if ((shift &= sizeof(value)*8 - 1) == 0)
      return value;
    return (value << shift) | (value >> (sizeof(value)*8 - shift));
}
////////////////////////////////////////////////////////////////////////
int start(unsigned int *ptr)  
{
    extern unsigned int binary_vga64_pix_dat_start[];
    return cognew(&binary_vga64_pix_dat_start, ptr);
}
////////////////////////////////////////////////////////////////////////
void usleep(int t)
{
    if(t < 10)  // very small t values will cause a hang
        return; // don't bother function delay is likely enough
    waitcnt((CLKFREQ/1000000)*t+CNT);
}
////////////////////////////////////////////////////////////////////////
void main (void)
{
    int tmp,i,x,y;
    
    // Preset the mailbox parameters

    directionState = 0xFF << 16;
    
    videoState = (0x300000FF | (2 << 9));

    tmp = (25175000 + 1600) / 4;
    frequencyState = 1 ;

    for(i = 0; i < 32; i++)
    {
        tmp = tmp << 1;
        frequencyState = _rotl(frequencyState,1);
        if(tmp >= _clkfreq)
        {
            tmp = tmp - _clkfreq;
            frequencyState += 1;
        }
        
    }
    
    displayPtr = DISPLAY_BUFFER;
    
    syncIndicatorAdress = &sync_indi;
    
    displayIndicatorAdress = &display_indi;
    
    // start the Driver
    
    start(&directionState);
    
    while(1)
    {
        for (y = 0; y < 120;y++)
        {
          for (x = 0; x < 160;x++)
          {
            while((0x80 >> 5) & sync_indi);
            //DISPLAY_BUFFER[x + 160 * y] = 0xFF; // set a white pixel at (x,y)
            *(unsigned char *)(DISPLAY_BUFFER + x + 160 * y) = 0x30; // Lightgreen
          }
        }
    }
}
////////////////////////////////////////////////////////////////////////



Reinhard

Comments

  • ReinhardReinhard Posts: 489
    edited 2011-12-30 12:28
    ups, I was to fast....

    there is a bug in my program near the DISPLAY_BUFFER size

    seems a problem with int/byte access.

    work on it, sorry

    Reinhard
  • KyeKye Posts: 2,200
    edited 2011-12-30 13:22
    Shouldn't there be a builtin rotl function?
  • mindrobotsmindrobots Posts: 6,506
    edited 2011-12-30 14:11
    @kye, that surprised me to as I've been trying to learn c and try to be helpful to the propgcc project. Before the holidays, I was trying to port some I2C routines and needed the rotr and rotl functions and all my searching led to user provided functions like Reinhard used. It seems to be a common standard solution that everybody provides in their own code.
  • Heater.Heater. Posts: 21,230
    edited 2011-12-30 14:22
    Shouldn't that:
     if ((shift &= sizeof(value)*8 - 1) == 0)
    
    be:
     if ((shift &= sizeof(value)*4 - 1) == 0)
    
    As value is an int which is 32 bits which is 4 bytes.
  • ReinhardReinhard Posts: 489
    edited 2011-12-30 15:57
    I translate the spin code step by step into C.
    If I come to the rotl operator I searched for builtins, but do not found.
    So I get the rotl function with a short web search and take it as it is, without censorious check.

    Heater, what you write make sense, I changed it.

    On the screen I see the green stripes, with black spaces between.
    My expectation is a full green screen.

    I guess the problem is my write into the DISPLAY_BUFFER is different to the spin code:
    displayBuffer.byte[.....] I think only 1/4 from Buffer is used by my C program ?!

    Try tomorrow a solution.

    Reinhard
  • ReinhardReinhard Posts: 489
    edited 2011-12-30 19:53
    Kye wrote: »
    Shouldn't there be a builtin rotl function?

    found " Nyamekye " also in the origin VGA - sourcecode

    hi Kye, nice to meet you

    feel a little bit like this ...

    http://german.about.com/library/blgzauberl.htm

    Reinhard
  • ReinhardReinhard Posts: 489
    edited 2012-01-01 05:52
    seems my theory is right

    if I replace the line:

    DISPLAY_BUFFER[x + 160 * y] = 0x30; with DISPLAY_BUFFER[x + 160 * y] = 0x30303030;

    the screen is filled full green,

    because the pasm read a long ( I mean this is a int32 in C )

    and if I write only 8 Bit into Buffer, the remaining 24 Bits are unused.

    So with a little workaround in the interface, the proper setting can done.

    Reinhard
  • ersmithersmith Posts: 6,099
    edited 2012-01-02 05:07
    Kye wrote: »
    Shouldn't there be a builtin rotl function?

    Oddly enough there isn't; but the compiler is smart enough to compile
    a = (a << b) | (a >> (32-b))
    
    into a single rotl instruction.

    Eric
  • ReinhardReinhard Posts: 489
    edited 2012-01-03 07:11
    Ready.
    Was a long way, but now I have what I want.
    A simple Graphic Interface , like at the good old TurboC Times.
    /**
      VGA Graphic Demo with Parallax VGA_512x384_Bitmap Interface
      
      for DemoBoard Wiring
      
      reimay / January 2012
     
    */
    
    #include <propeller.h>                   
    ////////////////////////////////////////////////////////////////////////
    //  Mailbox
    ////////////////////////////////////////////////////////////////////////
    static unsigned int sync; 
    static unsigned int reg_dira;
    static unsigned int reg_vcfg;
    static unsigned int * pixel_ptr;
    static unsigned short * color_ptr;
    ////////////////////////////////////////////////////////////////////////
    unsigned int   PIXEL_BUFFER[6144];
    unsigned short COLOR_BUFFER[192];
    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    void plot( unsigned int x, unsigned int y)
    {
     int tmp = x % 32;
     if(x >= 0 && x < 512 && y >= 0 && y < 384)
     {
       PIXEL_BUFFER[(x/32) + (y*16)] |=  1<<tmp; 
     }
    }
    ////////////////////////////////////////////////////////////////////////
    int start(unsigned int *ptr)  
    {
        extern unsigned int binary_vga_dat_start[];
        return cognew(&binary_vga_dat_start, ptr);
    }
    ////////////////////////////////////////////////////////////////////////
    void main (void)
    {
      unsigned int z,i,x,y;
     
     // Preset the mailbox parameters
      sync = 0;
     
     reg_dira = 0x00FF0000;
     
     reg_vcfg = 0x200000FF + (16 << 6);  
      // Fill Color Buffer
     for(i = 0; i < 192; i++)
     {
      COLOR_BUFFER[i] = 0x2804 ;
     }
     
      pixel_ptr = PIXEL_BUFFER;
     color_ptr = COLOR_BUFFER;
     
     // start the Driver
     start(&sync);
    /*
      Graphic Demo :
      plot the sierpinsky triangel with binary adresses
    */
      for( y = 0; y <= 255; y++)
        for(x = 0;x <= y;x++)
        {
         z = x & ( y -x) ;
         if(z==0)
          plot(x+ (256-y/2),y+30);
        }
     
    }
    ////////////////////////////////////////////////////////////////////////
     
    

    Reinhard
  • ReinhardReinhard Posts: 489
    edited 2012-01-03 14:04
    Hi,
    have now combined the sigma_delta driver with the vga driver, similar to the microphoneToVGA Demo in the spin example package from parallax.

    Basicly works, but I have no idea how to clear the screen.

    thanks for any suggestions

    Reinhard
  • jazzedjazzed Posts: 11,803
    edited 2012-01-03 15:33
    Reinhard wrote: »
    Basicly works, but I have no idea how to clear the screen.

    Hi Reinhard! Happy New Year.

    Some drivers use double buffering. That is, divide a big buffer in half to make 2 screens, draw to each screen, and just change the pointer to display a new screen. The graphics demo does that.

    Cheers.
    --Steve
  • plainsteveplainsteve Posts: 33
    edited 2012-01-03 19:00
    Reinhard said:
    seems my theory is right

    if I replace the line:

    DISPLAY_BUFFER[x + 160 * y] = 0x30; with DISPLAY_BUFFER[x + 160 * y] = 0x30303030;

    the screen is filled full green,

    Oh, man. I did the exact same thing when I was learning 32-bit x86 assembly code when I was a teenager. I loaded a 32-bit register with a byte value and expected 32-bit memcpy()-style code to "just work" and got vertical stripes down the screen. :D Thanks, Reinhard, for digging up a fun memory; I haven't thought about those times in a while.
  • ReinhardReinhard Posts: 489
    edited 2012-01-04 02:00
    @jazzed: Hi Steve, thank's for your response.
    I get to study the graphic demos with double buffering !


    @plainsteve: Hi, was also a learning process for me.
    Interesting to see on neptun are the same pitfalls . . . :smile:

    Reinhard
Sign In or Register to comment.