Shop OBEX P1 Docs P2 Docs Learn Events
Kwabena W. Agyeman's VGA64 driver in XMMC memory model? — Parallax Forums

Kwabena W. Agyeman's VGA64 driver in XMMC memory model?

vencejovencejo Posts: 7
edited 2012-11-19 10:01 in Propeller 1
Hi, Greetings to all from Spain.

I'm trying to make a program in XMMC memory model . This program uses the Kwabena W. Agyeman's VGA driver .

Unfortunately, it appears that the driver only operates in the LMM.

Anyone know how to modify the driver to work in XMMC mode?

Thank´s.

Comments

  • jazzedjazzed Posts: 11,803
    edited 2012-11-15 11:15
    Hello. Welcome to the propeller forum.

    Is there a demo or other example where you are having trouble? Post the code here if you can.

    I have many drivers that run fine with XMMC mode. What simpleide/gcc version are you using?

    Thanks,
    --Steve
  • vencejovencejo Posts: 7
    edited 2012-11-16 02:03
    Well, I've been trying to expand the kamil´s program on Conway's Game of Life .

    The program works perfectly on LMM mode.

    Unfortunately when I try to add more rows or columns to the grid I get the message "Your program is too big for the memory" and when I change the memory mode to XMMC the program no longer works.

    This is the code:


    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include "vga.h"
    #include "propeller.h"

    #define GRID_X 78
    #define GRID_Y 55

    #define MAX_GENERATIONS 350

    uint8_t grid[2][GRID_X][GRID_Y];
    uint8_t current_grid = 0;
    uint8_t generations = 0;


    volatile struct {
    unsigned stack[16];
    struct vga_param v;
    } par;


    void startvga(volatile void *parptr)
    {
    extern unsigned int _load_start_vga_cog[];
    int r;
    r = cognew(_load_start_vga_cog, parptr);
    }

    #define COLS 160
    #define ROWS 120
    #define PINGROUP 2

    unsigned char framebuffer[ROWS*COLS];


    void hline(unsigned char *frame, int x, int y, unsigned char color)
    {
    int i;
    frame += (y*COLS) + x;
    *frame++ = color;
    }


    int cmpGrid()
    {
    int i, j;
    for (i=0; i < GRID_Y; i++) {
    for (j=0; j < GRID_X; j++) {
    if (grid[0][j] != grid[1][j]) { return 0; }
    }
    }
    return 1;
    }

    void initGrid()
    {
    int i, j;
    int t;
    memset(framebuffer, Black, ROWS*COLS);
    current_grid = 0;
    for (i = 0; i < GRID_X; i++) {
    for (j = 0; j < GRID_Y; j++) {

    if ((uint8_t)rand() % 3 == 0) {
    grid[0][j] = 1;
    } else {
    grid[0][j] = 0;
    }
    }
    }
    }

    int count_neighbours(int x, int y)
    {
    int i, j;
    int sx;
    int result = 0;

    x--;
    y--;
    for (i = 0; i < 3; i++) {
    if (y < 0 || y > (GRID_Y - 1)) { continue; }
    for (j = 0; j < 3; j++) {
    if (x < 0 || x > (GRID_X - 1)) { continue; }
    if (i==1 && j == 1) { x++; continue; }
    if (grid[current_grid][x][y]) { result++; }
    x++;
    }
    y++;
    x -= 3;
    }
    return result;
    }

    void runGrid()
    {
    uint8_t x, y;
    int count;
    char string[2] = {0,0};
    uint8_t value = 0;
    uint8_t new_grid;

    new_grid = 1 - current_grid;
    for (y = 0; y < GRID_Y; y++) {
    for (x = 0; x < GRID_X; x++) {
    count = count_neighbours(x, y);
    string[0] = count+48;
    if (count < 2 || count > 3) { value = 0; }
    else if (count == 3) { value = 3; }
    else { value = grid[current_grid][x][y]; }
    grid[new_grid][x][y] = value;
    }
    }
    current_grid = new_grid;
    }



    void drawGrid()
    {
    uint8_t x, y;
    uint8_t cx, cy;
    uint8_t grid_next_colour = 0;
    cx = 0;
    cy = 0;
    for (y = 0; y < GRID_Y; y++) {
    cx = 0;
    for (x = 0; x < GRID_X; x++) {
    if (grid[1-current_grid][x][y] != grid[current_grid][x][y]) {
    if(grid[current_grid][x][y]) {

    hline(framebuffer, 1+cx, 3+cy,rand()%255);
    }
    else {

    hline(framebuffer, 1+cx, 3+cy, Black);
    }
    }
    cx += 2;
    }
    cy += 2;
    }
    }

    int main()
    {
    unsigned int frequency, i, testval;
    unsigned int clkfreq = _CLKFREQ;

    _DIRA = (1<<15);
    _OUTA = 0;

    par.v.displayBuffer = framebuffer;
    par.v.directionState = (0xff << (8*PINGROUP));
    par.v.videoState = 0x300000FF | (PINGROUP<<9);
    testval = (25175000 + 1600) / 4;
    frequency = 1;
    for (i = 0; i < 32; i++) {
    testval = testval << 1;
    frequency = (frequency << 1) | (frequency >> 31);
    if (testval >= clkfreq) {
    testval -= clkfreq;
    frequency++;
    }
    }
    par.v.frequencyState = frequency;
    par.v.enabled = 1;

    // start up the video cog
    memset(framebuffer, Black, ROWS*COLS);
    startvga(&par.v);

    srand(_CNT);

    initGrid();
    drawGrid();


    for(;;) {

    runGrid();
    drawGrid();
    generations++;
    if (generations > MAX_GENERATIONS) { // || cmpGrid()
    generations = 0;
    initGrid();
    }


    }
    }
  • ersmithersmith Posts: 6,054
    edited 2012-11-16 08:41
    The problem is in the startvga() function. cognew() does not work in XMMC mode. You'll have to use load_cog_driver_xmm in XMM or XMMC mode, like this:
    void startvga(volatile void *parptr)
    {
       extern unsigned int _load_start_vga_cog[];
      
    #if defined(__PROPELLER_XMM__) || defined(__PROPELLER_XMMC__)
       load_cog_driver_xmm(_load_start_toggle_fw_cog, 496, (uint32_t *)parptr);
    #else
       cognew(_load_start_vga_cog, parptr);
    #endif
    }
    
    

    PS: A tip for the future: if you put your code inside [ code ] and [ /code ] (no spaces) then it'll be much more legible.
  • vencejovencejo Posts: 7
    edited 2012-11-19 04:59
    ok, now it works, thank you very much.
    As you said, the startvga function's code had to be changed :
    void startvga(volatile void *parptr)
    {
       extern unsigned int _load_start_vga_cog[];
      
    #if defined(__PROPELLER_XMM__) || defined(__PROPELLER_XMMC__)
       load_cog_driver_xmm(_load_start_vga_cog, 496, (uint32_t *)parptr);
    #else
       cognew(_load_start_vga_cog, parptr);
    #endif
    }
    
  • RaymanRayman Posts: 14,669
    edited 2012-11-19 10:01
    I'll have to remember this...
    Does Spin2Cpp include this automatically? Or, will Spin2Cpp code require this change to run in XMM mode?
Sign In or Register to comment.