VGA mode 12h - Programmers Heaven

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

VGA mode 12h



hey, does anybody know how to program the video card directly

in VGA mode 12h (640x480, 16 colors)? just something simple, like

plotting a pixel..


-Assassin




Comments

  • : The same way you program the 320x200x256....

    : But with the figures 640x480x16....

    : Pretty basic.....


    uhh.. they're actually a lot different to program.

    640x480x16 is not nearly as "basic" as mode 13h..




  • MichaelJensenMichaelJensen Posts: 2Member
    : : The same way you program the 320x200x256....
    : : But with the figures 640x480x16....
    : : Pretty basic.....


    : uhh.. they're actually a lot different to program.
    : 640x480x16 is not nearly as "basic" as mode 13h..
    :
    :
    :
    :

    ok well, I've collected a lot of code, some from here, some from other places, and I'm trying to write an EGA graphics library, well I stole a pixel plotting routine from one of this sites messages the other night for mode 0x12 (12H) and changed it for mode 0xD (mode DH? heh) anyways, heres the converted back version that will work on mode 12H: (I use DJGPP for a compiler by the way.)

    (ps. some of the code is larger than will fit on the line in this post, so you may want to copy it to notepad and save it to a file) I HOPE THIS HELPS! :)

    (ps #2, I have no clue how the setpixel routine really works, I just use it.)

    ///////////////////////////////////////////////////////////////
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include

    #include
    #include
    //#include
    #include
    //#include
    #include

    //0xD = 320 x 200 (ega)
    //0xE = 640 x 200 (ega)
    //0x10 = 640 x 350 (ega/vga)? (might not work on some ega boards)
    //0x12 = 640 x 480 (vga)
    //0x13 will work if you change the setpixel routines

    #define SCREEN_WIDTH 640
    #define SCREEN_HEIGHT 480
    #define SCREEN_SAFE TRUE
    #define SCREEN_MODE 0x12 //:)

    void SetGfxMode(int mode);
    void setpixel(int x, int y, int col);
    int InitGfx(void);
    void ShutDownGfx(void);
    void DrawLine(int Ax, int Ay, int Bx, int By, unsigned char Color);
    //void DrawCircleFill(int x, int y, int c, int r);

    char * screen;

    long int setpixel_i[SCREEN_WIDTH][SCREEN_HEIGHT];
    unsigned char setpixel_b[SCREEN_WIDTH];
    long int setpixel_ti;
    unsigned char setpixel_tb;



    int main(void)
    {
    srand(time(0));
    if (InitGfx()) {return 1;} //error
    SetGfxMode(SCREEN_MODE);


    for (int i=0; i<1000; i++)
    {
    DrawLine(rand()%SCREEN_WIDTH, rand()%SCREEN_HEIGHT, rand()%SCREEN_WIDTH, rand()%SCREEN_HEIGHT, rand()%16);
    }


    getch();
    SetGfxMode(0x3);
    clrscr();
    printf("Bye.
    ");
    ShutDownGfx();
    return 0;
    }
















    //THE FOLLOWING SHOULD WORK WITH 16 COLOR VGA AS WELL, IT DID FOR ME

    /////////////////////////////////////////////////////////////////////////////
    // EGA Graphics Library Follows, Started around 11-27-01, belive it or not //
    /////////////////////////////////////////////////////////////////////////////


    void ShutDownGfx(void)
    {
    __djgpp_nearptr_disable();
    }

    int InitGfx(void)
    {
    if (__djgpp_nearptr_enable()==0) return 1; //could happen
    return 0;
    }

    void SetGfxMode(int mode)
    {
    __dpmi_regs regs;
    memset(&regs,0, sizeof(regs));
    regs.x.ax=mode;
    //regs.x.ax=0xD; //screen mode (EGA)
    //regs.x.ax=0x13; //screen mode (VGA)
    __dpmi_int(0x10,&regs);
    //_farsetsel(_dos_ds);
    screen=(char *)0xA0000 + __djgpp_conventional_base;

    unsigned char weird_number=(SCREEN_WIDTH/8);
    for (int x=0; x<SCREEN_WIDTH; x++)
    {
    for (int y=0; y<SCREEN_HEIGHT; y++)
    {
    setpixel_i[x][y] = y*weird_number + x/8; /* Memory Location */
    }
    setpixel_b[x] = (0x80)>>(x%8); /* compute Bit Mask */
    }


    return;
    }


    void setpixel(int x, int y, int col)
    {
    #ifdef SCREEN_SAFE
    if ((x<0) && (x>=SCREEN_WIDTH) && (y<0) && (y>=SCREEN_HEIGHT))
    {return;}
    #endif



    //char far *screen = (char far *)0xA0000000; //djgpp doesn't understand far for some reason, maybe it's just me! heh
    //long int i;
    //unsigned char b;

    outp(0x3ce,0x05); /* Graphics Mode */
    outp(0x3cf,0x02); /* Write Mode 2 */

    setpixel_ti=setpixel_i[x][y];
    setpixel_tb=setpixel_b[x];
    //i = y*40 + x/8; /* Memory Location */
    //b = (0x80)>>(x%8); /* compute Bit Mask */

    outp(0x3ce,0x08); /* Bit Mask Register */
    outp(0x3cf,setpixel_tb); /* Bit Mask */
    outp(0x3ce,0x03); /* Function Select Register */
    outp(0x3cf,0x00); /* Replace Pixel */
    setpixel_tb = screen[setpixel_ti]; /* Dummy Read to refresh latch registers (THIS IS *VERY* IMPORTANT)*/
    screen[setpixel_ti] = col; /* Set Pixel */

    }


    //DrawLine was origonally BresLine, and I got this from http://www.cs.unc.edu/~hoff/projects/comp235/bresline/perform0.html
    //
    //============================================================================
    // Fills the intermediate points along a line between the two given endpoints
    // using Bresenham's line drawing algorithm. NOTE: this routine does no clipping
    // so the coordinate values must be within the FrameBuffer bounds.
    // NOTE: USE (Ax,Ay) as the starting point (values that are incremented)
    //============================================================================
    void DrawLine(int Ax, int Ay, int Bx, int By, unsigned char Color)
    {
    //------------------------------------------------------------------------
    // INITIALIZE THE COMPONENTS OF THE ALGORITHM THAT ARE NOT AFFECTED BY THE
    // SLOPE OR DIRECTION OF THE LINE
    //------------------------------------------------------------------------
    int dX = abs(Bx-Ax); // store the change in X and Y of the line endpoints
    int dY = abs(By-Ay);

    //------------------------------------------------------------------------
    // DETERMINE "DIRECTIONS" TO INCREMENT X AND Y (REGARDLESS OF DECISION)
    //------------------------------------------------------------------------
    int Xincr, Yincr;
    if (Ax > Bx) { Xincr=-1; } else { Xincr=1; } // which direction in X?
    if (Ay > By) { Yincr=-1; } else { Yincr=1; } // which direction in Y?

    //------------------------------------------------------------------------
    // DETERMINE INDEPENDENT VARIABLE (ONE THAT ALWAYS INCREMENTS BY 1 (OR -1) )
    // AND INITIATE APPROPRIATE LINE DRAWING ROUTINE (BASED ON FIRST OCTANT
    // ALWAYS). THE X AND Y'S MAY BE FLIPPED IF Y IS THE INDEPENDENT VARIABLE.
    //------------------------------------------------------------------------
    if (dX >= dY) // if X is the independent variable
    {
    int dPr = dY<<1; // amount to increment decision if right is chosen (always)
    int dPru = dPr - (dX<<1); // amount to increment decision if up is chosen
    int P = dPr - dX; // decision variable start value

    for (; dX>=0; dX--) // process each point in the line one at a time (just use dX)
    {
    setpixel(Ax, Ay, Color); // plot the pixel
    if (P > 0) // is the pixel going right AND up?
    {
    Ax+=Xincr; // increment independent variable
    Ay+=Yincr; // increment dependent variable
    P+=dPru; // increment decision (for up)
    }
    else // is the pixel just going right?
    {
    Ax+=Xincr; // increment independent variable
    P+=dPr; // increment decision (for right)
    }
    }
    }
    else // if Y is the independent variable
    {
    int dPr = dX<<1; // amount to increment decision if right is chosen (always)
    int dPru = dPr - (dY<<1); // amount to increment decision if up is chosen
    int P = dPr - dY; // decision variable start value

    for (; dY>=0; dY--) // process each point in the line one at a time (just use dY)
    {
    setpixel(Ax, Ay, Color); // plot the pixel
    if (P > 0) // is the pixel going up AND right?
    {
    Ax+=Xincr; // increment dependent variable
    Ay+=Yincr; // increment independent variable
    P+=dPru; // increment decision (for up)
    }
    else // is the pixel just going up?
    {
    Ay+=Yincr; // increment independent variable
    P+=dPr; // increment decision (for right)
    }
    }
    }
    }


    /* //I made this function but it doesn't work, oh well, would have probably been slow anyways
    void DrawCircleFill(int x, int y, int c, int r)
    {
    int DCF_x1=(x-(r+1));
    int DCF_y1=(y-(r+1));
    int DCF_x2=(x+(r+2));
    int DCF_y2=(y+(r+2));
    int DCF_sr=r*r;
    int DCF_dx;
    int DCF_dy;
    int DCF_dist;
    int DCF_cx;
    int DCF_cy;

    for (DCF_cx=DCF_x1; DCF_cx<DCF_x2; DCF_cx++)
    {
    for (DCF_cy=DCF_y1; DCF_cy<DCF_y1; DCF_cy++)
    {

    DCF_dx=abs(DCF_cx-x);
    DCF_dy=abs(DCF_cy-y);
    DCF_dx *=DCF_dx;
    DCF_dy *=DCF_dy;

    DCF_dist=DCF_dx+DCF_dy;
    if (DCF_dist<=DCF_sr)
    {setpixel(DCF_cx,DCF_cy,c);}
    }
    }
    return;
    }
    */




  • assassinassassin Posts: 21Member
    hehe, thanks.. since then i've learned and forgotten how mode 12h works -- a couple times.

    never expected to get a reply 3.5 years later :)


    : : : The same way you program the 320x200x256....
    : : : But with the figures 640x480x16....
    : : : Pretty basic.....


    : : uhh.. they're actually a lot different to program.
    : : 640x480x16 is not nearly as "basic" as mode 13h..
    : :
    : :
    : :
    : :
    :
    : ok well, I've collected a lot of code, some from here, some from other places, and I'm trying to write an EGA graphics library, well I stole a pixel plotting routine from one of this sites messages the other night for mode 0x12 (12H) and changed it for mode 0xD (mode DH? heh) anyways, heres the converted back version that will work on mode 12H: (I use DJGPP for a compiler by the way.)
    :
    : (ps. some of the code is larger than will fit on the line in this post, so you may want to copy it to notepad and save it to a file) I HOPE THIS HELPS! :)
    :
    : (ps #2, I have no clue how the setpixel routine really works, I just use it.)
    :
    : ///////////////////////////////////////////////////////////////
    : #include
    : #include
    : #include
    : #include
    : #include
    : #include
    : #include
    : #include
    : #include
    : #include
    :
    : #include
    : #include
    : //#include
    : #include
    : //#include
    : #include
    :
    : //0xD = 320 x 200 (ega)
    : //0xE = 640 x 200 (ega)
    : //0x10 = 640 x 350 (ega/vga)? (might not work on some ega boards)
    : //0x12 = 640 x 480 (vga)
    : //0x13 will work if you change the setpixel routines
    :
    : #define SCREEN_WIDTH 640
    : #define SCREEN_HEIGHT 480
    : #define SCREEN_SAFE TRUE
    : #define SCREEN_MODE 0x12 //:)
    :
    : void SetGfxMode(int mode);
    : void setpixel(int x, int y, int col);
    : int InitGfx(void);
    : void ShutDownGfx(void);
    : void DrawLine(int Ax, int Ay, int Bx, int By, unsigned char Color);
    : //void DrawCircleFill(int x, int y, int c, int r);
    :
    : char * screen;
    :
    : long int setpixel_i[SCREEN_WIDTH][SCREEN_HEIGHT];
    : unsigned char setpixel_b[SCREEN_WIDTH];
    : long int setpixel_ti;
    : unsigned char setpixel_tb;
    :
    :
    :
    : int main(void)
    : {
    : srand(time(0));
    : if (InitGfx()) {return 1;} //error
    : SetGfxMode(SCREEN_MODE);
    :
    :
    : for (int i=0; i<1000; i++)
    : {
    : DrawLine(rand()%SCREEN_WIDTH, rand()%SCREEN_HEIGHT, rand()%SCREEN_WIDTH, rand()%SCREEN_HEIGHT, rand()%16);
    : }
    :
    :
    : getch();
    : SetGfxMode(0x3);
    : clrscr();
    : printf("Bye.
    ");
    : ShutDownGfx();
    : return 0;
    : }
    :
    :
    :
    :
    :
    :
    :
    :
    :
    :
    :
    :
    :
    :
    :
    :
    : //THE FOLLOWING SHOULD WORK WITH 16 COLOR VGA AS WELL, IT DID FOR ME
    :
    : /////////////////////////////////////////////////////////////////////////////
    : // EGA Graphics Library Follows, Started around 11-27-01, belive it or not //
    : /////////////////////////////////////////////////////////////////////////////
    :
    :
    : void ShutDownGfx(void)
    : {
    : __djgpp_nearptr_disable();
    : }
    :
    : int InitGfx(void)
    : {
    : if (__djgpp_nearptr_enable()==0) return 1; //could happen
    : return 0;
    : }
    :
    : void SetGfxMode(int mode)
    : {
    : __dpmi_regs regs;
    : memset(&regs,0, sizeof(regs));
    : regs.x.ax=mode;
    : //regs.x.ax=0xD; //screen mode (EGA)
    : //regs.x.ax=0x13; //screen mode (VGA)
    : __dpmi_int(0x10,&regs);
    : //_farsetsel(_dos_ds);
    : screen=(char *)0xA0000 + __djgpp_conventional_base;
    :
    : unsigned char weird_number=(SCREEN_WIDTH/8);
    : for (int x=0; x<SCREEN_WIDTH; x++)
    : {
    : for (int y=0; y<SCREEN_HEIGHT; y++)
    : {
    : setpixel_i[x][y] = y*weird_number + x/8; /* Memory Location */
    : }
    : setpixel_b[x] = (0x80)>>(x%8); /* compute Bit Mask */
    : }
    :
    :
    : return;
    : }
    :
    :
    : void setpixel(int x, int y, int col)
    : {
    : #ifdef SCREEN_SAFE
    : if ((x<0) && (x>=SCREEN_WIDTH) && (y<0) && (y>=SCREEN_HEIGHT))
    : {return;}
    : #endif
    :
    :
    :
    : //char far *screen = (char far *)0xA0000000; //djgpp doesn't understand far for some reason, maybe it's just me! heh
    : //long int i;
    : //unsigned char b;
    :
    : outp(0x3ce,0x05); /* Graphics Mode */
    : outp(0x3cf,0x02); /* Write Mode 2 */
    :
    : setpixel_ti=setpixel_i[x][y];
    : setpixel_tb=setpixel_b[x];
    : //i = y*40 + x/8; /* Memory Location */
    : //b = (0x80)>>(x%8); /* compute Bit Mask */
    :
    : outp(0x3ce,0x08); /* Bit Mask Register */
    : outp(0x3cf,setpixel_tb); /* Bit Mask */
    : outp(0x3ce,0x03); /* Function Select Register */
    : outp(0x3cf,0x00); /* Replace Pixel */
    : setpixel_tb = screen[setpixel_ti]; /* Dummy Read to refresh latch registers (THIS IS *VERY* IMPORTANT)*/
    : screen[setpixel_ti] = col; /* Set Pixel */
    :
    : }
    :
    :
    : //DrawLine was origonally BresLine, and I got this from http://www.cs.unc.edu/~hoff/projects/comp235/bresline/perform0.html
    : //
    : //============================================================================
    : // Fills the intermediate points along a line between the two given endpoints
    : // using Bresenham's line drawing algorithm. NOTE: this routine does no clipping
    : // so the coordinate values must be within the FrameBuffer bounds.
    : // NOTE: USE (Ax,Ay) as the starting point (values that are incremented)
    : //============================================================================
    : void DrawLine(int Ax, int Ay, int Bx, int By, unsigned char Color)
    : {
    : //------------------------------------------------------------------------
    : // INITIALIZE THE COMPONENTS OF THE ALGORITHM THAT ARE NOT AFFECTED BY THE
    : // SLOPE OR DIRECTION OF THE LINE
    : //------------------------------------------------------------------------
    : int dX = abs(Bx-Ax); // store the change in X and Y of the line endpoints
    : int dY = abs(By-Ay);
    :
    : //------------------------------------------------------------------------
    : // DETERMINE "DIRECTIONS" TO INCREMENT X AND Y (REGARDLESS OF DECISION)
    : //------------------------------------------------------------------------
    : int Xincr, Yincr;
    : if (Ax > Bx) { Xincr=-1; } else { Xincr=1; } // which direction in X?
    : if (Ay > By) { Yincr=-1; } else { Yincr=1; } // which direction in Y?
    :
    : //------------------------------------------------------------------------
    : // DETERMINE INDEPENDENT VARIABLE (ONE THAT ALWAYS INCREMENTS BY 1 (OR -1) )
    : // AND INITIATE APPROPRIATE LINE DRAWING ROUTINE (BASED ON FIRST OCTANT
    : // ALWAYS). THE X AND Y'S MAY BE FLIPPED IF Y IS THE INDEPENDENT VARIABLE.
    : //------------------------------------------------------------------------
    : if (dX >= dY) // if X is the independent variable
    : {
    : int dPr = dY<<1; // amount to increment decision if right is chosen (always)
    : int dPru = dPr - (dX<<1); // amount to increment decision if up is chosen
    : int P = dPr - dX; // decision variable start value
    :
    : for (; dX>=0; dX--) // process each point in the line one at a time (just use dX)
    : {
    : setpixel(Ax, Ay, Color); // plot the pixel
    : if (P > 0) // is the pixel going right AND up?
    : {
    : Ax+=Xincr; // increment independent variable
    : Ay+=Yincr; // increment dependent variable
    : P+=dPru; // increment decision (for up)
    : }
    : else // is the pixel just going right?
    : {
    : Ax+=Xincr; // increment independent variable
    : P+=dPr; // increment decision (for right)
    : }
    : }
    : }
    : else // if Y is the independent variable
    : {
    : int dPr = dX<<1; // amount to increment decision if right is chosen (always)
    : int dPru = dPr - (dY<<1); // amount to increment decision if up is chosen
    : int P = dPr - dY; // decision variable start value
    :
    : for (; dY>=0; dY--) // process each point in the line one at a time (just use dY)
    : {
    : setpixel(Ax, Ay, Color); // plot the pixel
    : if (P > 0) // is the pixel going up AND right?
    : {
    : Ax+=Xincr; // increment dependent variable
    : Ay+=Yincr; // increment independent variable
    : P+=dPru; // increment decision (for up)
    : }
    : else // is the pixel just going up?
    : {
    : Ay+=Yincr; // increment independent variable
    : P+=dPr; // increment decision (for right)
    : }
    : }
    : }
    : }
    :
    :
    : /* //I made this function but it doesn't work, oh well, would have probably been slow anyways
    : void DrawCircleFill(int x, int y, int c, int r)
    : {
    : int DCF_x1=(x-(r+1));
    : int DCF_y1=(y-(r+1));
    : int DCF_x2=(x+(r+2));
    : int DCF_y2=(y+(r+2));
    : int DCF_sr=r*r;
    : int DCF_dx;
    : int DCF_dy;
    : int DCF_dist;
    : int DCF_cx;
    : int DCF_cy;
    :
    : for (DCF_cx=DCF_x1; DCF_cx<DCF_x2; DCF_cx++)
    : {
    : for (DCF_cy=DCF_y1; DCF_cy<DCF_y1; DCF_cy++)
    : {
    :
    : DCF_dx=abs(DCF_cx-x);
    : DCF_dy=abs(DCF_cy-y);
    : DCF_dx *=DCF_dx;
    : DCF_dy *=DCF_dy;
    :
    : DCF_dist=DCF_dx+DCF_dy;
    : if (DCF_dist<=DCF_sr)
    : {setpixel(DCF_cx,DCF_cy,c);}
    : }
    : }
    : return;
    : }
    : */
    :
    :
    :
    :
    :

Sign In or Register to comment.