/* Copyright (C) 1998 BJ Eirich (aka vecna) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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 Lic See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include "verge.h" // ================================= Data ==================================== #define SEQU_ADDR 0x3c4 #define CRTC_ADDR 0x3d4 #define MISC_OUTPUT 0x3c2 byte *screenbase; // ptr to A000:0000 int endcol,nextl; // end column number thingy | next line int winofs; // ================================= Code ==================================== void ModeXSetMode(int mode) { REGISTERS r; SET_AX(r, mode); INTERRUPT(0x10, r); } void plane(byte p) { int hi=1<> 8) | 0x0c); outportb(0x3d4, (offset & 0xff) | 0x0d); _enable(); } int ModeXShowPage() { byte *s,*d; int x,y,k; int sx2; int b; RenderGUI(); cpubyte=PFLIP; //s=screen+(16*tsx)+16; b=(16*tsx)+16; d=screenbase; sx2=sx>>2; //while (!(inp(986) & 8)); for (y=0; ycx2 || y>cy2 || x+xl cx2) xl=cx2-x+1; if (y+yl > cy2) yl=cy2-y+1; if (xcx2 || y>cy2 || x+xl cx2) xl=cx2-x+1; if (y+yl > cy2) yl=cy2-y+1; if (x0 && th>0) dys=tsx-xm; else if (tw>0 && th<0) dys=(0-tsx)-xm; else if (tw<0 && th>0) dys=tsx+xm; else if (tw<0 && th<0) dys=(0-tsx)+xm; d = screen+(y*tsx)+x; for (i=0;i>16)]; d+=xd; sx+=xs; } d+=dys; sy+=ys; s+=(sy>>16)*w; sy&=0xffff; } cpubyte=ETC; return 0; } int ModeXRenderMAPLine(int x, int y, int yofs, word *map) { cpubyte=RENDER; asm("movl %1, %%edi \n\t" "imul _tsx, %%edi \n\t" "addl %0, %%edi \n\t" "addl _screen, %%edi \n\t" "movl _tx, %%ebx \n\t" "incl %%ebx \n\t" "movl %3, %%ecx \n\t" "tileloop: \n\t" "movw (%%ecx), %%ax \n\t" "movzwl %%ax, %%edx \n\t" "shll $1, %%edx \n\t" "addl _tileidx, %%edx \n\t" "movw (%%edx), %%ax \n\t" "movzwl %%ax, %%esi \n\t" "shll $8, %%esi \n\t" "addl _vsp, %%esi \n\t" "movl %2, %%eax \n\t" "shll $4, %%eax \n\t" "addl %%eax, %%esi \n\t" "movl (%%esi), %%eax \n\t" "movl %%eax, (%%edi) \n\t" "movl 4(%%esi), %%eax \n\t" "movl %%eax, 4(%%edi) \n\t" "movl 8(%%esi), %%eax \n\t" "movl %%eax, 8(%%edi) \n\t" "movl 12(%%esi), %%eax \n\t" "movl %%eax, 12(%%edi) \n\t" "addl $16, %%edi \n\t" "addl $2, %%ecx \n\t" "decl %%ebx \n\t" "jnz tileloop \n\t" : : "m" (x), "m" (y), "m" (yofs), "m" (map) : "eax","ebx","ecx","edx","esi","edi","cc" ); cpubyte=ETC; return 0; } int ModeXTRenderMAPLine(int x, int y, int yofs, word *map) { cpubyte=RENDER; asm("movl %1, %%edi \n\t" "imul _tsx, %%edi \n\t" "addl %0, %%edi \n\t" "addl _screen, %%edi \n\t" "movl _tx, %%ebx \n\t" "incl %%ebx \n\t" "movl %3, %%ecx \n\t" "tileloop1: \n\t" "movw (%%ecx), %%ax \n\t" "movzwl %%ax, %%edx \n\t" "shll $1, %%edx \n\t" "addl _tileidx, %%edx \n\t" "movw (%%edx), %%ax \n\t" "orw %%ax, %%ax \n\t" "jz next1 \n\t" "movzwl %%ax, %%esi \n\t" "shll $8, %%esi \n\t" "movl %%esi, %%edx \n\t" "addl _vspmask, %%edx \n\t" "addl _vsp, %%esi \n\t" "movl %2, %%eax \n\t" "shll $4, %%eax \n\t" "addl %%eax, %%esi \n\t" "addl %%eax, %%edx \n\t" "movl (%%edi), %%eax \n\t" "andl (%%edx), %%eax \n\t" "orl (%%esi), %%eax \n\t" "movl %%eax, (%%edi) \n\t" "movl 4(%%edi), %%eax \n\t" "andl 4(%%edx), %%eax \n\t" "orl 4(%%esi), %%eax \n\t" "movl %%eax, 4(%%edi) \n\t" "movl 8(%%edi), %%eax \n\t" "andl 8(%%edx), %%eax \n\t" "orl 8(%%esi), %%eax \n\t" "movl %%eax, 8(%%edi) \n\t" "movl 12(%%edi), %%eax \n\t" "andl 12(%%edx), %%eax \n\t" "orl 12(%%esi), %%eax \n\t" "movl %%eax, 12(%%edi) \n\t" "next1: \n\t" "addl $16, %%edi \n\t" "addl $2, %%ecx \n\t" "decl %%ebx \n\t" "jnz tileloop1 \n\t" : : "m" (x), "m" (y), "m" (yofs), "m" (map) : "eax","ebx","ecx","edx","esi","edi","cc" ); cpubyte=ETC; return 0; } int ModeXColorField(int x, int y, byte c) { cpubyte=RENDER; asm("movl %1, %%eax \n\t" "imul _tsx, %%eax \n\t" "addl %0, %%eax \n\t" "addl _screen, %%eax \n\t" "movl %%eax, %%edi \n\t" "movl $8, %%ecx \n\t" "movb %2, %%al \n\t" "lineloop1: \n\t" "stosb \n\t" "incl %%edi \n\t" "stosb \n\t" "incl %%edi \n\t" "stosb \n\t" "incl %%edi \n\t" "stosb \n\t" "incl %%edi \n\t" "stosb \n\t" "incl %%edi \n\t" "stosb \n\t" "incl %%edi \n\t" "stosb \n\t" "incl %%edi \n\t" "stosb \n\t" "incl %%edi \n\t" "addl _sx, %%edi \n\t" "addl $16, %%edi \n\t" "incl %%edi \n\t" "stosb \n\t" "incl %%edi \n\t" "stosb \n\t" "incl %%edi \n\t" "stosb \n\t" "incl %%edi \n\t" "stosb \n\t" "incl %%edi \n\t" "stosb \n\t" "incl %%edi \n\t" "stosb \n\t" "incl %%edi \n\t" "stosb \n\t" "incl %%edi \n\t" "stosb \n\t" "addl _sx, %%edi \n\t" "addl $16, %%edi \n\t" "decl %%ecx \n\t" "jnz lineloop1 \n\t" : : "m" (x), "m" (y), "m" (c) : "eax","edi","ecx","cc" ); cpubyte=ETC; return 0; } int ModeXClearScreen() { cpubyte=RENDER; memset(screen+(tsx*16)+16,0,(tsx*sy)); cpubyte=ETC; return 0; } int ModeXPutPixel(int x, int y, int color) { cpubyte=RENDER; if (xcx2 || y>cy2) { cpubyte=ETC; return 0; } x+=16; y+=16; screen[(y*tsx)+x]=color; cpubyte=ETC; return 0; } int ModeXGetPixel(int x, int y) { cpubyte=RENDER; if (xcx2 || y>cy2) { cpubyte=ETC; return 0; } x+=16; y+=16; cpubyte=ETC; return screen[(y*tsx)+x]; } int ModeXHLine(int x, int y, int x2, int color) { byte *d; int width; cpubyte=RENDER; // swap? if (x2cx2 || y>cy2 || x+width cx2) width=cx2-x+1; if (xcx2 || y>cy2 || x cy2) height=cy2-y+1; if (ycx2 && x2>cx2) || (y1cy2 && y2>cy2)) { cpubyte=ETC; return 0; } if (x1>x2) { i=x1; x1=x2; x2=i; i=y1; y1=y2; y2=i; } // clip the left side if (x1cx2) { int myy=(y2-y1); int mxx=(x2-x1),b; if (!mxx) { cpubyte=ETC; return 0; } if (myy) { b=y1-(y2-y1)*x1/mxx; y2=myy*cx2/mxx+b; x2=cx2; } else x2=cx2; } if (y1>y2) { i=x1; x1=x2; x2=i; i=y1; y1=y2; y2=i; } // clip the bottom if (y2>cy2) { int mxx=(x2-x1); int myy=(y2-y1),b; if (!myy) { cpubyte=ETC; return 0; } if (mxx) { b=y1-(y2-y1)*x1/mxx; x2=(cy2-b)*mxx/myy; y2=cy2; } else y2=cy2; } // clip the top if (y1cx2 || x2>cx2 || y1cy2 || y2>cy2) { cpubyte=ETC; return 0; } if (x1>x2) { xc=x2; xi=x1; } else { xi=x2; xc=x1; } x1+=16;y1+=16; // aen; adjust these here?? x2+=16;y2+=16; // assume y1<=y2 from above swap operation yi=y2; yc=y1; dcx=x1; dcy=y1; xc=(x2-x1); yc=(y2-y1); if (xc<0) xi=-1; else xi=1; if (yc<0) yi=-1; else yi=1; n=abs(xc); m=abs(yc); ycyi=abs(2*yc*xi); er=0; if (n>m) { xcxi=abs(2*xc*xi); for (i=0;i<=n;i++) { screen[(dcy*tsx)+dcx]=color; if (er>0) { dcy+=yi; er-=xcxi; } er+=ycyi; dcx+=xi; } } else { xcyi=abs(2*xc*yi); for (i=0;i<=m;i++) { screen[(dcy*tsx)+dcx]=color; if (er>0) { dcx+=xi; er-=ycyi; } er+=xcyi; dcy+=yi; } } cpubyte=ETC; return 0; } int ModeXCircle(int x, int y, int radius, int color) { int cx=0; int cy=radius; int df=1-radius; int d_e=3; int d_se=-2*radius+5; cpubyte=RENDER; do { ModeXPutPixel(x+cx,y+cy,color); if (cx) ModeXPutPixel(x-cx,y+cy,color); if (cy) ModeXPutPixel(x+cx,y-cy,color); if ((cx) && (cy)) ModeXPutPixel(x-cx,y-cy,color); if (cx != cy) { ModeXPutPixel(x+cy,y+cx,color); if (cx) ModeXPutPixel(x+cy,y-cx,color); if (cy) ModeXPutPixel(x-cy,y+cx,color); if (cx && cy) ModeXPutPixel(x-cy,y-cx,color); } if (df<0) { df+=d_e; d_e+=2; d_se+=2; } else { df+=d_se; d_e+=2; d_se+=4; cy--; } cx++; } while (cx <= cy); cpubyte=ETC; return 0; } int ModeXCircleFill(int x, int y, int radius, int color) { int cx=0; int cy=radius; int df=1-radius; int d_e=3; int d_se=-2*radius+5; cpubyte=RENDER; do { ModeXHLine(x-cy,y-cx,x+cy,color); if (cx) ModeXHLine(x-cy,y+cx,x+cy,color); if (df<0) { df+=d_e; d_e+=2; d_se+=2; } else { if (cx != cy) { ModeXHLine(x-cx,y-cy,x+cx,color); if (cy) ModeXHLine(x-cx,y+cy,x+cx,color); } df+=d_se; d_e+=2; d_se+=4; cy--; } cx++; } while (cx <= cy); cpubyte=ETC; return 0; } int ModeXRect(int x, int y, int x2, int y2, int color) { ModeXHLine(x,y,x2,color); ModeXHLine(x,y2,x2,color); ModeXVLine(x,y+1,y2-1,color); ModeXVLine(x2,y+1,y2-1,color); return 0; } int ModeXRectFill(int x, int y, int x2, int y2, int color) { cpubyte=RENDER; if (y2