home *** CD-ROM | disk | FTP | other *** search
- /**
- ** BITDRAW.H
- **
- ** Copyright (C) 1992, Csaba Biegl
- ** 820 Stirrup Dr, Nashville, TN, 37221
- ** csaba@vuse.vanderbilt.edu
- **
- ** This file is distributed under the terms listed in the document
- ** "copying.cb", available from the author at the address above.
- ** A copy of "copying.cb" should accompany this file; if not, a copy
- ** should be available from where this file was obtained. This file
- ** may not be distributed without a verbatim copy of "copying.cb".
- ** You should also have received a copy of the GNU General Public
- ** License along with this program (it is in the file "copying");
- ** if not, write to the Free Software Foundation, Inc., 675 Mass Ave,
- ** Cambridge, MA 02139, USA.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **/
-
- #ifndef _BITDRAW_H_
- #define _BITDRAW_H_
-
- #ifdef __TURBOC__
- #pragma inline
- #endif
-
- /*
- * utilities -- other files may define them too
- */
- #ifndef _SaveDS
-
- #ifdef __TURBOC__
- #define _ClrDir() asm cld
- #define _SetDir() asm std
- #define _SaveDS() asm push ds
- #define _RestoreDS() asm pop ds
- #endif
-
- #ifdef __GNUC__
- #define _ASV asm volatile
- #define _ClrDir() _ASV("cld")
- #define _SetDir() _ASV("std")
- #define _SaveDS()
- #define _RestoreDS()
- #endif
-
- #endif /* _SaveDS */
-
- /*
- * instruction fragment to set up the EGA or VGA for subsequent
- * bit mask register writes (__EGAINIT__) or just set up DX
- * for the correct address (__EGAINITADDR__)
- */
- #ifdef __TURBOC__
- #define __EGAINIT__ \
- asm mov dx,VGA_GR_CTRL_PORT; \
- asm mov al,VGA_BIT_MASK_REG; \
- asm out dx,al; \
- asm inc dx
- #define __EGAINITADDR__ \
- asm mov dx,VGA_GR_CTRL_PORT+1;
- #endif
- #ifdef __GNUC__
- #define __EGAINIT__ "\n\
- movl $L_VGA_GR_CTRL_PORT,%%edx \n\
- movb $L_VGA_BIT_MASK_REG,%%al \n\
- outb %%al,%%dx \n\
- incl %%edx "
- #define __EGAINITADDR__ "\n\
- movl $L_VGA_GR_CTRL_PORT+1,%%edx "
- #endif
-
- /*
- * mask and data output instruction fragments for line and font drawing
- * mask in al, data address in es:[di] (edi)
- * (ANDBYTE1: can destroy mask)
- * (ANDBYTE2: can use ah for temporary)
- */
- #ifdef __TURBOC__
- #define __INVMASK__ asm not al
- #define __EGAMASK__ asm out dx,al
- #define __EGABYTE__ asm inc BYTE PTR es:[di]
- #define __VGABYTE__ asm and BYTE PTR es:[di],al
- #define __XORBYTE__ asm xor BYTE PTR es:[di],al
- #define __ORBYTE__ asm or BYTE PTR es:[di],al
- #define __ANDBYTE1__ \
- asm not al; \
- asm and BYTE PTR es:[di],al
- #define __ANDBYTE2__ \
- asm mov ah,al; \
- asm not ah; \
- asm and BYTE PTR es:[di],ah
- #endif
- #ifdef __GNUC__
- #define __INVMASK__ "notb %%al"
- #define __EGAMASK__ "outb %%al,%%dx"
- #define __EGABYTE__ "incb (%%edi)"
- #define __VGABYTE__ "andb %%al,(%%edi)"
- #define __XORBYTE__ "xorb %%al,(%%edi)"
- #define __ORBYTE__ "orb %%al,(%%edi)"
- #define __ANDBYTE1__ "\n\
- notb %%al \n\
- andb %%al,(%%edi) "
- #define __ANDBYTE2__ "\n\
- movb %%al,%%ah \n\
- notb %%ah \n\
- andb %%ah,(%%edi) "
- #endif
-
- /*
- * line drawing, X major
- * putmask: how to output the mask
- * putbyte: how to output the current byte
- * init: what to do before starting
- */
- #ifdef __TURBOC__
- #define __XLINE__(addr,offs,deltx,delty,mask,putbyte,putmask,init) do { \
- init; \
- asm les di,DWORD PTR addr; \
- asm mov si,WORD PTR delty; \
- asm mov ax,WORD PTR mask; \
- asm mov cx,WORD PTR deltx; \
- asm mov bx,cx; \
- asm shr bx,1; \
- asm inc cx; \
- Xline##putbyte##Loop: \
- putmask; \
- putbyte; \
- asm ror al,1; \
- asm adc di,0; \
- asm sub bx,si; \
- asm jnc Xline##putbyte##NoAdjust; \
- asm add bx,deltx; \
- asm add di,offs; \
- Xline##putbyte##NoAdjust: \
- asm loop Xline##putbyte##Loop; \
- } while(0)
- #endif
- #ifdef __GNUC__
- #define __XLINE__(adr,ofs,deltx,delty,msk,putbyte,putmask,init) _ASV( "\n\
- "init" \n\
- movl %0,%%edi \n\
- movl %3,%%esi \n\
- movl %4,%%eax \n\
- movl %2,%%ecx \n\
- movl %%ecx,%%ebx \n\
- shrl $1,%%ebx \n\
- incl %%ecx \n\
- L_Xline"#putbyte"Loop: \n\
- "putmask" \n\
- "putbyte" \n\
- rorb $1,%%al \n\
- adcl $0,%%edi \n\
- subl %%esi,%%ebx \n\
- jnc L_Xline"#putbyte"NoAdjust \n\
- addl %2,%%ebx \n\
- addl %1,%%edi \n\
- L_Xline"#putbyte"NoAdjust: \n\
- loop L_Xline"#putbyte"Loop "\
- : /* NOTHING */ \
- : "g" (adr), "g" (ofs), "g" (deltx), "g" (delty), "g" (msk) \
- : "di", "si", "dx", "cx", "bx", "ax" \
- )
- #endif
-
- /*
- * line drawing, Y major
- * putmask: how to output the mask
- * putbyte: how to output the current byte
- * init: what to do before starting
- */
- #ifdef __TURBOC__
- #define __YLINE__(addr,offs,deltx,delty,mask,putbyte,putmask,init) do { \
- init; \
- asm mov al,BYTE PTR mask; \
- asm les di,DWORD PTR addr; \
- asm mov si,WORD PTR offs; \
- asm mov cx,WORD PTR delty; \
- asm mov bx,cx; \
- asm shr bx,1; \
- asm inc cx; \
- putmask; \
- Yline##putbyte##Loop: \
- putbyte; \
- asm sub bx,deltx; \
- asm jnc Yline##putbyte##NoAdjust; \
- asm add bx,delty; \
- asm ror al,1; \
- asm adc di,0; \
- putmask; \
- Yline##putbyte##NoAdjust: \
- asm add di,si; \
- asm loop Yline##putbyte##Loop; \
- } while(0)
- #endif
- #ifdef __GNUC__
- #define __YLINE__(adr,ofs,deltx,delty,msk,putbyte,putmask,init) _ASV( "\n\
- "init" \n\
- movl %0,%%edi \n\
- movl %1,%%esi \n\
- movl %4,%%eax \n\
- movl %3,%%ecx \n\
- movl %%ecx,%%ebx \n\
- shrl $1,%%ebx \n\
- incl %%ecx \n\
- "putmask" \n\
- L_Yline"#putbyte"Loop: \n\
- "putbyte" \n\
- subl %2,%%ebx \n\
- jnc L_Yline"#putbyte"NoAdjust \n\
- addl %3,%%ebx \n\
- rorb $1,%%al \n\
- adcl $0,%%edi \n\
- "putmask" \n\
- L_Yline"#putbyte"NoAdjust: \n\
- addl %%esi,%%edi \n\
- loop L_Yline"#putbyte"Loop "\
- : /* NOTHING */ \
- : "g" (adr), "g" (ofs), "g" (deltx), "g" (delty), "g" (msk) \
- : "di", "si", "dx", "cx", "bx", "ax" \
- )
- #endif
-
- #define _DrawLineEGA(AD,OF,X,Y,MS) do { \
- if(X > Y) __XLINE__(AD,OF,X,Y,MS,__EGABYTE__,__EGAMASK__,__EGAINIT__); \
- else __YLINE__(AD,OF,X,Y,MS,__EGABYTE__,__EGAMASK__,__EGAINIT__); \
- } while(0)
-
- #define _DrawLineVGA(AD,OF,X,Y,MS) do { \
- if(X > Y) __XLINE__(AD,OF,X,Y,MS,__VGABYTE__,,); \
- else __YLINE__(AD,OF,X,Y,MS,__VGABYTE__,,); \
- } while(0)
-
- #define _DrawLineXor(AD,OF,X,Y,MS) do { \
- if(X > Y) __XLINE__(AD,OF,X,Y,MS,__XORBYTE__,,); \
- else __YLINE__(AD,OF,X,Y,MS,__XORBYTE__,,); \
- } while(0)
-
- #define _DrawLineOr(AD,OF,X,Y,MS) do { \
- if(X > Y) __XLINE__(AD,OF,X,Y,MS,__ORBYTE__,,); \
- else __YLINE__(AD,OF,X,Y,MS,__ORBYTE__,,); \
- } while(0)
-
- #define _DrawLineAnd(AD,OF,X,Y,MS) do { \
- if(X > Y) __XLINE__(AD,OF,X,Y,MS,__ANDBYTE2__,,); \
- else __YLINE__(AD,OF,X,Y,MS,__ANDBYTE2__,,); \
- } while(0)
-
- /*
- * font drawing
- */
- #ifdef __TURBOC__
- #define __FNTROW__(adr,bits,wdt,shft,mask,putbyte,putmask,init,inv) do { \
- init; \
- asm les di,DWORD PTR adr; \
- asm lds si,DWORD PTR bits; \
- asm mov cx,WORD PTR shft; \
- asm jcxz FontNS##putbyte##inv##Init; \
- asm mov bx,WORD PTR wdt; \
- asm or bx,bx; \
- asm jz FontSFT##putbyte##inv##TestMask; \
- FontSFT##putbyte##inv##Loop: \
- asm lodsb; \
- inv; \
- asm xor ah,ah; \
- asm ror ax,cl; \
- asm or al,ch; \
- asm mov ch,ah; \
- putmask; \
- putbyte; \
- asm inc di; \
- asm dec bx; \
- asm jnz FontSFT##putbyte##inv##Loop; \
- FontSFT##putbyte##inv##TestMask: \
- asm or bx,WORD PTR mask; \
- asm jz Font##putbyte##inv##End; \
- asm lodsb; \
- inv; \
- asm shr al,cl; \
- asm or al,ch; \
- asm and al,bl; \
- asm jmp Font##putbyte##inv##LastByte; \
- FontNS##putbyte##inv##Init: \
- asm mov cx,WORD PTR wdt; \
- asm jcxz FontNS##putbyte##inv##TestMask; \
- FontNS##putbyte##inv##Loop: \
- asm lodsb; \
- inv; \
- putmask; \
- putbyte; \
- asm inc di; \
- asm loop FontNS##putbyte##inv##Loop; \
- FontNS##putbyte##inv##TestMask: \
- asm or cx,WORD PTR mask; \
- asm jz Font##putbyte##inv##End; \
- asm lodsb; \
- inv; \
- asm and al,cl; \
- Font##putbyte##inv##LastByte: \
- putmask; \
- putbyte; \
- Font##putbyte##inv##End: ; \
- } while(0)
- #endif
- #ifdef __GNUC__
- #define __FNTROW__(adr,bits,wdt,shft,mask,putbyte,putmask,init,inv) _ASV("\n\
- "init" \n\
- movl %0,%%edi \n\
- movl %1,%%esi \n\
- movl %3,%%ecx \n\
- jecxz L_FontNS"#putbyte #inv"Init \n\
- movl %2,%%ebx \n\
- orl %%ebx,%%ebx \n\
- jz L_FontSFT"#putbyte #inv"TestMask \n\
- L_FontSFT"#putbyte #inv"Loop: \n\
- lodsb \n\
- "inv" \n\
- xorb %%ah,%%ah \n\
- rorw %%cl,%%ax \n\
- orb %%ch,%%al \n\
- movb %%ah,%%ch \n\
- "putmask" \n\
- "putbyte" \n\
- incl %%edi \n\
- decl %%ebx \n\
- jnz L_FontSFT"#putbyte #inv"Loop \n\
- L_FontSFT"#putbyte #inv"TestMask: \n\
- orl %4,%%ebx \n\
- jz L_Font"#putbyte #inv"End \n\
- lodsb \n\
- "inv" \n\
- shrb %%cl,%%al \n\
- orb %%ch,%%al \n\
- andb %%bl,%%al \n\
- jmp L_Font"#putbyte #inv"LastByte \n\
- L_FontNS"#putbyte #inv"Init: \n\
- movl %2,%%ecx \n\
- jcxz L_FontNS"#putbyte #inv"TestMask \n\
- L_FontNS"#putbyte #inv"Loop: \n\
- lodsb \n\
- "inv" \n\
- "putmask" \n\
- "putbyte" \n\
- incl %%edi \n\
- loop L_FontNS"#putbyte #inv"Loop \n\
- L_FontNS"#putbyte #inv"TestMask: \n\
- orl %4,%%ecx \n\
- jz L_Font"#putbyte #inv"End \n\
- lodsb \n\
- "inv" \n\
- andb %%cl,%%al \n\
- L_Font"#putbyte #inv"LastByte: \n\
- "putmask" \n\
- "putbyte" \n\
- L_Font"#putbyte #inv"End: "\
- : /* NOTHING */ \
- : "g" (adr), "g" (bits), "g" (wdt), "g" (shft), "g" (mask) \
- : "di", "si", "dx", "cx", "bx", "ax" \
- )
- #endif
-
- #define _CharFGRowEGA(A,B,W,S,M) __FNTROW__(A,B,W,S,M,__EGABYTE__,__EGAMASK__,__EGAINITADDR__,)
- #define _CharFGRowVGA(A,B,W,S,M) __FNTROW__(A,B,W,S,M,__VGABYTE__,,,)
- #define _CharFGRowXor(A,B,W,S,M) __FNTROW__(A,B,W,S,M,__XORBYTE__,,,)
- #define _CharFGRowOr(A,B,W,S,M) __FNTROW__(A,B,W,S,M,__ORBYTE__,,,)
- #define _CharFGRowAnd(A,B,W,S,M) __FNTROW__(A,B,W,S,M,__ANDBYTE1__,,,)
-
- #define _CharBGRowEGA(A,B,W,S,M) __FNTROW__(A,B,W,S,M,__EGABYTE__,__EGAMASK__,__EGAINITADDR__,__INVMASK__)
- #define _CharBGRowVGA(A,B,W,S,M) __FNTROW__(A,B,W,S,M,__VGABYTE__,,,__INVMASK__)
- #define _CharBGRowXor(A,B,W,S,M) __FNTROW__(A,B,W,S,M,__XORBYTE__,,,__INVMASK__)
- #define _CharBGRowOr(A,B,W,S,M) __FNTROW__(A,B,W,S,M,__ORBYTE__,,,__INVMASK__)
- #define _CharBGRowAnd(A,B,W,S,M) __FNTROW__(A,B,W,S,M,__ANDBYTE1__,,,__INVMASK__)
-
- #endif /* whole file */
-