Video and other misc. routines for in-line Assembly.  These are especially
handy because you can just cut-and-paste them between languages on the PC;
I developed/rounded up many of these when I was programming in Pascal, and
when I turned to C, they were easily ported.  


To use the virtual screens, declare global pointers like this:

   unsigned char far *VS1 = NULL;          // pointer to virtual screen.

Then from main(), allocate the memory for them like this:

   VS1 = new far unsigned char[64000];

You can then access it like an array, and use Buffer_Paste(VS1) to paste it
to the screen and Buffer_Clear(VS1) to clear it.

Sorry about putpixel() and getpixel() - they're extremely sloppily-written -
but I never use them anymore, and if you need speed, don't look to making
function calls anyway!





//These macros will be needed for the palette functions.

#define COLOR_MASK         0x3C6        // the bit mask register
#define COLOR_REGISTER_RD  0x3C7        // set read index at this I/O
#define COLOR_REGISTER_WR  0x3C8        // set write index at this I/O
#define COLOR_DATA         0x3C9        // the R/W data is here




void set13()
{
   asm 
   {
      mov       ax, 0013h;              // set video mode
      int       10h;                    // to 320x200x256
   }
}


void settext()
{
   asm
   {
      mov       ax, 0003h;
      int       10h;
   }   
}


void wait_refresh()               // (...this one I stole from the web)
{
   asm 
   {
         mov     dx,3dah         //wait for vertical retrace
      NoVrt:
         in      al,dx
         test    al,8             //Test 3rd bit again
         jz      NoVrt           //Wait until Verticle Retrace ends
   }
}


void putpixel(int x, int y, unsigned char c)
{
   asm 
   {
       mov      bx, 40960
       mov       ax, 320
       mul       y
       add       ax, x
       mov       di, ax
       mov      es, bx

       mov       al, c

       stosb                             // moves al to es:di
   }
}

unsigned char getpixel(int x, int y)
{
   unsigned char c;
   asm 
   {
       push ds

       mov       cx, y
       mov      ax, 40960
       mov       bx, cx
       mov      ds, ax
       shl       bx, 2
       add       bx, cx
       shl       bx, 6
       add       bx, x
       mov       si, bx
       lodsb                             // moves [ds:si] to al
       mov       c, al

       pop ds
   }
   return c;
}

unsigned char getsubpixel(unsigned char far *buffer, float x, float y)
{
   int x2, y2;
   static float dx, dy, dx_invert, dy_invert, e;
   unsigned char a, b, c, d;
   
   x2 = x;
   y2 = y;
   dx = x - (float)x2;      // 0..1
   dy = y - (float)y2;      // 0..1
   dx_invert = 1-dx;
   dy_invert = 1-dy;


   asm 
   {
       push ds                           

       lds si, buffer

       mov       ax, 320
       mul       y2
       add       ax, x2
       mov       si, ax

       add       si, 4   ;// crackhead patch alert!

       lodsb                             // moves [ds:si] to al (1 byte) & inc. si
       mov       a, al

    
       lodsb                             // moves [ds:si] to al
       mov       b, al
      
       add       si, 318
       lodsb                             // moves [ds:si] to al
       mov       c, al

       
       lodsb                             // moves [ds:si] to al
       mov       d, al

       pop ds
   }
   
   e =  a*dx_invert*dy_invert; 
   e += c*dx_invert*dy;
   e += b*dy_invert*dx; 
   e += d*dx*dy;

   return (unsigned char)e;
}


   
void setRGB(unsigned char co,unsigned char r,unsigned char g,unsigned char b)
{
   asm
   {
      mov   al, co

      mov   dx, COLOR_REGISTER_WR
      cli                                       // disable interrupts
      out   dx, al


      mov   dx, COLOR_DATA

      mov   al, r
      out   dx, al

      mov   al, g
      out   dx, al

      mov   al, b
      out   dx, al

      sti                                       // re-enable interrupts
   }

   //outp(COLOR_REGISTER_WR, co);
   //outp(COLOR_DATA, r);
   //outp(COLOR_DATA, g);
   //outp(COLOR_DATA, b);
}

void getRGB(unsigned char co,unsigned char *r,unsigned char *g,unsigned char *b)
{
   asm
   {
      mov   al, co

      mov   dx, COLOR_REGISTER_RD
      cli
      out   dx, al


      mov   dx, COLOR_DATA

      in    al, dx
      mov   bx, r
      mov   [bx], al   // if this won't compile use BYTE PTR [bx].

      in    al, dx
      mov   bx, g
      mov   [bx], al

      in    al, dx
      mov   bx, b
      mov   [bx], al

      sti
   }

   //outp(COLOR_REGISTER_RD, co);
   //outp(COLOR_DATA, *r);
   //outp(COLOR_DATA, *g);
   //outp(COLOR_DATA, *b);
}


void Buffer_Paste(unsigned char far *buffer)
{
  asm                   // "rep movsd" moves ecx dwords from ds:si to es:di
  {
    push ds;
    mov ax, 40960;              
    mov di, 0;                  // es:di is the dest of memory to move to
    mov ecx, 16000;             // size of buffer in DWORDS (# of reps)
    mov es, ax;                 
    lds si, buffer;             // ds:si is the source
    rep movsd;                  // move 16000 dwords (64000 bytes)
    pop ds;   
  }  
}




void Buffer_Clear(unsigned char far *buffer)
{
  asm                   // "rep movsd" moves ecx dwords from ds:si to es:di
  {
    push ds;
    mov ecx, 16000;             // size of buffer in DWORDS (# of reps)
    mov eax, 0;
    les di, buffer;             // es:di is the dest
    rep stosd;                  // move 16000 dwords (64000 bytes)
    pop ds;   
  }
}



void Buffer_Copy(unsigned char far *buffer1, unsigned char far *buffer2)
{                        // copies second buffer to first buffer.
  asm                   // "rep movsd" moves ecx dwords from ds:si to es:di
  {
    push ds;
    mov ecx, 16000;             // size of buffer in DWORDS (# of reps)
    les di, buffer1;              // es:di is the dest
    lds si, buffer2;            // ds:si is the source
    rep movsd;                  // move 16000 dwords (64000 bytes)
    pop ds;   
  }  
}



void waitkey()
{
   asm 
   {
      mov   ah, 1                        //DOS: get a character (puts it in AL)
      int   21h
   }
}





This document copyright (c)1998+ Ryan M. Geiss.
Return to FAQ page