home *** CD-ROM | disk | FTP | other *** search
- /*
- Filename : ixeblit.c
- Author : Ray E. Bornert II
- Date : 1993-APR-09
-
- Copyright (C) 1993 HixoxiH Software. All rights reserved.
- */
-
- //compile line:
- // bcc -ml -c -B ixeblit.c
-
- #include "ixeblit.h"
- #include <dos.h>
-
- /*
- This routine good on 80386's and above for all IXE supported video modes
- */
- asm P386
- void ixeBlitXY32 //very fast and exclusive
- (
- unsigned char *dest, //MUST be paragraph aligned for planar mode
- void *ixeCode, //address of the precompiled icon
- unsigned long DestWidth, //byte width of destination buffer
- unsigned long x, //horizontal coordinate based at 0
- unsigned long y //vertical coordinate based at 0
- )
- {
- asm {
- push ds; //save segment
- pushad;
-
- xor edi,edi; //edi=0
- lds di,dest; //point ds:di to dest
-
- mov ebx,DestWidth; //load the destination width
- mov eax,y; //load the y coordinate
- mul ebx; //
- add eax,x; //
- add edi,eax; //offset += y*DestWidth+x
- call dword ptr ixeCode; //goto ixe code
-
- popad;
- pop ds; //restore segment
- }
- }
-
- /*
- This routine good on 80286's and above for all IXE supported video modes
- where screen size in pixels is less than 65536.
-
- NOTE:
- This routine SHOULD NOT be used with video modes
- where Pixel ScreenWidth * Pixel ScreenHeight > 65536
- Mode 320x200 is okay because 320*200=64000 and is less than 65536
- The reason for all of this is that 16bit unsigned math wraps at 65535
- For example in mode 320x240 the offset for screen coordinate y=204,x=256
- is 320*204+256=65536 but a 16bit unsigned value with all bits on is 65535
- If the cpu is allowed to perform 320*204+256 the result will be zero and
- 320*204+257 will equal 1 and so forth and so on. 16bit math wraps at 65535.
- If you are using a video mode with a screen size > 65535 and
- you must use 16 bit code then you should use the slower yet reliable
- plain jane ixeBlitXY below.
- */
- asm P286
- void ixeBlitXY16 //fast and restricted
- (
- unsigned char *dest, //MUST be paragraph aligned for planar mode
- void *ixeCode, //address of the precompiled icon
- unsigned short DestWidth, //byte width of destination buffer
- unsigned short x, //horizontal coordinate based at 0
- unsigned short y //vertical coordinate based at 0
- )
- {
- asm {
- push ds; //save segment
- pusha;
-
- xor di,di; //edi=0
- lds di,dest; //point ds:di to dest
-
- mov bx,DestWidth; //load the destination width
- mov ax,y; //load the y coordinate
- mul bx; //
- add ax,x; //
- add di,ax; //offset += y*DestWidth+x
- call dword ptr ixeCode; //goto ixe code
-
- popa;
- pop ds; //restore segment
- }
- }
-
- /*
- This routine good on 80286's and above for all IXE supported video modes
- */
- asm P286
- void ixeBlitXY //slowest and most generic
- (
- unsigned char *dest, //MUST be paragraph aligned for planar mode
- void *ixeCode, //address of the precompiled icon
- unsigned int DestWidth, //byte width of destination buffer
- unsigned int x, //horizontal coordinate based at 0
- unsigned int y //vertical coordinate based at 0
- )
- {
- //this stuff is slow but we gotta do it to be generic
- unsigned short s=FP_SEG(dest);
- unsigned short o=FP_OFF(dest);
- unsigned long u,adjust;
- u=(long)o+((long)y*(long)DestWidth+(long)x);
- if (*((unsigned short *)ixeCode) == 0xCF8B)
- adjust=64; else
- adjust=16;
- o = (unsigned short)(u%adjust);
- s+= (u/adjust);
- dest = (unsigned char *)MK_FP(s,o);
-
- asm {
- push ds;
- pusha;
- lds di,dest;
- mov bx,DestWidth;
- call dword ptr ixeCode;
- popa;
- pop ds;
- }
- }
-
- /*
- The code below is desinged to sidestep Interrupt 13 which occurs when the
- CPU encounters the following:
- mov word ptr [FFFFh], <any 16bit or 32bit operand> or
- mov dword ptr [FFFFh], <any 16bit or 32bit operand> or
- mov dword ptr [FFFEh], <any 32bit operand> or
- mov dword ptr [FFFDh], <any 32bit operand>
- */
- #ifdef __cplusplus
- #define __CPPARGS ...
- #else
- #define __CPPARGS
- #endif
- void interrupt ( *oldInt13)(__CPPARGS);
- unsigned char far newInt13[256]=
- {
- 0x89,0xDA, //mov dx,bx
- 0x5B, //pop bx
- 0x07, //pop es
- 0x26, //es:
- 0x80,0x3F,0x66, //cmp byte ptr [bx],66
- 0x75,0x03, //jne $+5
- 0x83,0xC3,0x02, //add bx,2
- 0x83,0xC3,0x06, //add bx,6
- 0x06, //push es
- 0x53, //push bx
- 0x89,0xD3, //mov bx,dx
- 0xCF //iret
- };
-
- /*
- This routine saves the current Interrupt Vector for Interrupt 13
- and then sets Interrupt Vector 13 to point to newInt13 above.
- */
- void disableInt13(void)
- {
- oldInt13 = getvect(13);
- setvect(13,(void interrupt (*)(__CPPARGS)) newInt13);
- }
-
- /*
- This routine restores the original value of Interrupt Vector 13
- */
- void enableInt13(void)
- {
- setvect(13,oldInt13);
- }
-