📄 ark.c
字号:
#define WRITEPLANEMASK 0x1A#define STENCILPITCH 0x60#define SOURCEPITCH 0x62#define DESTPITCH 0x64#define STENCILADDR 0x68#define STENCILX 0x68#define STENCILY 0x6A#define SOURCEADDR 0x6C#define SOURCEX 0x6C#define SOURCEY 0x6E#define DESTADDR 0x70#define DESTX 0x70#define DESTY 0x72#define WIDTH 0x74#define HEIGHT 0x76#define BITMAPCONFIG 0x7C#define COMMAND 0x7E/* Flags for COMMAND register. */#define DRAWNSTEP 0x0000#define LINEDRAW 0x1000#define BITBLT 0x2000#define TEXTBITBLT 0x3000#define USEPLANEMASK 0x0000#define DISABLEPLANEMASK 0x0800#define PATTERN8X8 0x0400#define SELECTBGCOLOR 0x0000#define BACKGROUNDBITMAP 0x0200#define SELECTFGCOLOR 0x0000#define FOREGROUNDBITMAP 0x0100#define STENCILONES 0x0000#define STENCILGENERATED 0x0040#define STENCILBITMAP 0x0080#define LINEDRAWALL 0x0000#define LINESKIPFIRST 0x0010#define LINESKIPLAST 0x0020#define ENABLECLIPPING 0x0000#define DISABLECLIPPING 0x0008#define RIGHTANDDOWN 0x0000#define RIGHTANDUP 0x0002#define LEFTANDDOWN 0x0004#define LEFTANDUP 0x0006/* Flags for Bitmap Configuration register. */#define SWAPNIBLES 0x2000#define SWAPBITS 0x1000#define SYSTEMSTENCIL 0x0200#define LINEARSTENCILADDR 0x0100#define SYSTEMSOURCE 0x0020#define LINEARSOURCEADDR 0x0010#define SYSTEMDEST 0x0002#define LINEARDESTADDR 0x0001#define SETBACKGROUNDCOLOR(c) \ *(unsigned short *)(mmio_base + BACKGROUNDCOLOR) = c;#define SETFOREGROUNDCOLOR(c) \ *(unsigned short *)(mmio_base + FOREGROUNDCOLOR) = c;#define SETCOLORMIXSELECT(m) \ *(unsigned short *)(mmio_base + COLORMIXSELECT) = m;#define SETWRITEPLANEMASK(m) \ *(unsigned short *)(mmio_base + WRITEPLANEMASK) = m;#define SETSTENCILPITCH(p) \ *(unsigned short *)(mmio_base + STENCILPITCH) = p;#define SETSOURCEPITCH(p) \ *(unsigned short *)(mmio_base + SOURCEPITCH) = p;#define SETDESTPITCH(p) \ *(unsigned short *)(mmio_base + DESTPITCH) = p;#define SETSTENCILADDR(p) \ *(unsigned int *)(mmio_base + STENCILADDR) = p;#define SETSOURCEADDR(p) \ *(unsigned int *)(mmio_base + SOURCEADDR) = p;#define SETSOURCEXY(x, y) \ *(unsigned int *)(mmio_base + SOURCEADDR) = (y << 16) + x;#define SETSOURCEX(x) \ *(unsigned short *)(mmio_base + SOURCEX) = x;#define SETSOURCEY(y) \ *(unsigned short *)(mmio_base + SOURCEY) = y;#define SETDESTADDR(p) \ *(unsigned int *)(mmio_base + DESTADDR) = p;#define SETDESTXY(x, y) \ *(unsigned int *)(mmio_base + DESTADDR) = (y << 16) + x;#define SETDESTX(x) \ *(unsigned short *)(mmio_base + DESTX) = x;#define SETDESTY(y) \ *(unsigned short *)(mmio_base + DESTY) = y;#define SETWIDTH(p) \ *(unsigned short *)(mmio_base + WIDTH) = p - 1;#define SETHEIGHT(p) \ *(unsigned short *)(mmio_base + HEIGHT) = p - 1;#define SETBITMAPCONFIG(p) \ *(unsigned short *)(mmio_base + BITMAPCONFIG) = p;#define SETCOMMAND(p) \ *(unsigned short *)(mmio_base + COMMAND) = p;#define COPISBUSY() (inb(0x3CB) & 0x40)#define WAITUNTILFINISHED() \ for (;;) { \ if (!COPISBUSY()) \ break; \ }static void arkaccel_init(AccelSpecs * accelspecs, int bpp, int width_in_pixels){#ifdef COORDINATES int pitch;#endif SETCOLORMIXSELECT(0x0303); /* Copy source. */ SETWRITEPLANEMASK(0xFFFF); SETSTENCILPITCH(width_in_pixels); SETSOURCEPITCH(width_in_pixels); SETDESTPITCH(width_in_pixels);#ifdef COORDINATES SETBITMAPCONFIG(0); switch (width_in_pixels) { case 640: pitch = 0; break; case 800: pitch = 1; break; case 1024: pitch = 2; break; case 1280: pitch = 4; break; case 1600: pitch = 5; break; case 2048: pitch = 6; break; } __svgalib_outSR(0x17, (__svgalib_inSR(0x17) & ~0x07) | pitch);#else SETBITMAPCONFIG(LINEARSTENCILADDR | LINEARSOURCEADDR | LINEARDESTADDR);#endif}#define FINISHBACKGROUNDBLITS() \ if (__svgalib_accel_mode & BLITS_IN_BACKGROUND) \ WAITUNTILFINISHED();void __svgalib_arkaccel_FillBox(int x, int y, int width, int height){ int destaddr; destaddr = BLTPIXADDRESS(x, y); FINISHBACKGROUNDBLITS(); SETDESTADDR(destaddr); SETWIDTH(width); SETHEIGHT(height); SETCOMMAND(SELECTBGCOLOR | SELECTFGCOLOR | STENCILONES | DISABLEPLANEMASK | DISABLECLIPPING | BITBLT); if (!(__svgalib_accel_mode & BLITS_IN_BACKGROUND)) WAITUNTILFINISHED();}void __svgalib_arkaccel_coords_FillBox(int x, int y, int width, int height){ FINISHBACKGROUNDBLITS(); SETDESTXY(x, y); SETWIDTH(width); SETHEIGHT(height); SETCOMMAND(SELECTBGCOLOR | SELECTFGCOLOR | STENCILONES | DISABLEPLANEMASK | DISABLECLIPPING | BITBLT); if (!(__svgalib_accel_mode & BLITS_IN_BACKGROUND)) WAITUNTILFINISHED();}void __svgalib_arkaccel_ScreenCopy(int x1, int y1, int x2, int y2, int width, int height){ int srcaddr, destaddr, dir; srcaddr = BLTPIXADDRESS(x1, y1); destaddr = BLTPIXADDRESS(x2, y2); dir = RIGHTANDDOWN; if ((y1 < y2 || (y1 == y2 && x1 < x2)) && y1 + height > y2) { srcaddr += (height - 1) * __svgalib_accel_screenpitch + width - 1; destaddr += (height - 1) * __svgalib_accel_screenpitch + width - 1; dir = LEFTANDUP; } FINISHBACKGROUNDBLITS(); SETSOURCEADDR(srcaddr); SETDESTADDR(destaddr); SETWIDTH(width); SETHEIGHT(height); SETCOMMAND(BACKGROUNDBITMAP | FOREGROUNDBITMAP | STENCILONES | DISABLEPLANEMASK | DISABLECLIPPING | BITBLT | dir); if (!(__svgalib_accel_mode & BLITS_IN_BACKGROUND)) WAITUNTILFINISHED();}void __svgalib_arkaccel_coords_ScreenCopy(int x1, int y1, int x2, int y2, int width, int height){ int dir; dir = RIGHTANDDOWN; if ((y1 < y2 || (y1 == y2 && x1 < x2)) && y1 + height > y2) { y1 += height - 1; y2 += height - 1; x1 += width - 1; x2 += width - 1; dir = LEFTANDUP; } FINISHBACKGROUNDBLITS(); SETSOURCEXY(x1, y1); SETDESTXY(x2, y2); SETWIDTH(width); SETHEIGHT(height); SETCOMMAND(BACKGROUNDBITMAP | FOREGROUNDBITMAP | STENCILONES | DISABLEPLANEMASK | DISABLECLIPPING | BITBLT | dir); if (!(__svgalib_accel_mode & BLITS_IN_BACKGROUND)) WAITUNTILFINISHED();}void __svgalib_arkaccel_DrawHLineList(int ymin, int n, int *xmin, int *xmax){ int y, destaddr; FINISHBACKGROUNDBLITS(); SETHEIGHT(1); y = ymin; destaddr = BLTPIXADDRESS(0, ymin); while (n > 0) { /* * We don't wait for previous commands to finish. * The ARK databook isn't specific on this, but * I assume the chip will correctly force waits when * the command FIFO is full. */ int x, w; x = *xmin; SETDESTADDR(destaddr + x); w = *xmax - x; if (w > 0) { SETWIDTH(w); SETCOMMAND(SELECTBGCOLOR | SELECTFGCOLOR | STENCILONES | DISABLEPLANEMASK | DISABLECLIPPING | BITBLT); } xmin++; xmax++; destaddr += __svgalib_accel_screenpitch; n--; } if (!(__svgalib_accel_mode & BLITS_IN_BACKGROUND)) WAITUNTILFINISHED();}void __svgalib_arkaccel_coords_DrawHLineList(int ymin, int n, int *xmin, int *xmax){ int y; FINISHBACKGROUNDBLITS(); SETHEIGHT(1); y = ymin; while (n > 0) { /* * We don't wait for previous commands to finish. * The ARK databook isn't specific on this, but * I assume the chip will correctly force waits when * the command FIFO is full. */ int x, w; x = *xmin; SETDESTXY(x, y); w = *xmax - x; if (w > 0) { SETWIDTH(w); SETCOMMAND(SELECTBGCOLOR | SELECTFGCOLOR | STENCILONES | DISABLEPLANEMASK | DISABLECLIPPING | BITBLT); } xmin++; xmax++; n--; } if (!(__svgalib_accel_mode & BLITS_IN_BACKGROUND)) WAITUNTILFINISHED();}void __svgalib_arkaccel_SetFGColor(int fg){ SETFOREGROUNDCOLOR(fg);}void __svgalib_arkaccel_SetBGColor(int fg){ SETBACKGROUNDCOLOR(fg);}void __svgalib_arkaccel_PutBitmap(int x, int y, int w, int h, void *bitmap){ int destaddr, count;#ifndef COORDINATES destaddr = BLTPIXADDRESS(x, y);#endif /* * Calculate number of bytes to transfer. * The ARK chip requires the bitmap scanlines to be aligned * to 32-bit words, with correct bit order, so no conversion * is required. */ count = (((w + 31) & ~0x1F) / 8) * h; FINISHBACKGROUNDBLITS();#ifdef COORDINATES SETDESTXY(x, y);#else SETDESTADDR(destaddr);#endif SETWIDTH(w); SETHEIGHT(h); SETBITMAPCONFIG(LINEARSTENCILADDR | LINEARSOURCEADDR | LINEARDESTADDR | SYSTEMSTENCIL); SIGNALBLOCK; SETCOMMAND(SELECTBGCOLOR | SELECTFGCOLOR | STENCILBITMAP | DISABLEPLANEMASK | DISABLECLIPPING | BITBLT); while (count >= 65536) { memcpy(__svgalib_graph_mem, bitmap, 65536); count -= 65536; bitmap += 65536; } if (count > 0) memcpy(__svgalib_graph_mem, bitmap, count); SIGNALUNBLOCK; WAITUNTILFINISHED();}static unsigned char ark_rop_map[] ={ 0x3, /* COPY */ 0x7, /* OR */ 0x1, /* AND */ 0x6, /* XOR */ 0xA /* INVERT */};void __svgalib_arkaccel_SetRasterOp(int r){ /* Write rop at bits 0-3 and 8-11. */ SETCOLORMIXSELECT((int) ark_rop_map[r] * 0x0101);}void __svgalib_arkaccel_Sync(void){ WAITUNTILFINISHED();}/* * Set up accelerator interface for pixels of size bpp and scanline width * of width_in_pixels. */static void init_acceleration_specs_for_mode(AccelSpecs * accelspecs, int bpp, int width_in_pixels){ accelspecs->operations = 0; accelspecs->ropOperations = 0; accelspecs->transparencyOperations = 0; accelspecs->ropModes = (1<<ROP_COPY) | (1<<ROP_OR) | (1<<ROP_AND) | (1<<ROP_XOR) | (1<<ROP_INVERT); accelspecs->transparencyModes = 0;#ifdef COORDINATES if (width_in_pixels != 640 && width_in_pixels != 800 && width_in_pixels != 1024 && width_in_pixels != 1280 && width_in_pixels != 1600 && width_in_pixels != 2048) return;#endif accelspecs->operations |= ACCELFLAG_SETMODE | ACCELFLAG_SYNC | ACCELFLAG_SETRASTEROP; if (bpp == 8 || bpp == 16) { accelspecs->operations |= ACCELFLAG_FILLBOX | ACCELFLAG_SETFGCOLOR | ACCELFLAG_SCREENCOPY | ACCELFLAG_SETBGCOLOR | ACCELFLAG_PUTBITMAP; accelspecs->ropOperations |= ACCELFLAG_FILLBOX | ACCELFLAG_SCREENCOPY; } /* Set the function pointers; availability is handled by flags. */#ifdef COORDINATES accelspecs->FillBox = __svgalib_arkaccel_coords_FillBox; accelspecs->ScreenCopy = __svgalib_arkaccel_coords_ScreenCopy;#else accelspecs->FillBox = __svgalib_arkaccel_FillBox; accelspecs->ScreenCopy = __svgalib_arkaccel_ScreenCopy;#endif accelspecs->SetFGColor = __svgalib_arkaccel_SetFGColor; accelspecs->SetRasterOp = __svgalib_arkaccel_SetRasterOp; accelspecs->Sync = __svgalib_arkaccel_Sync; accelspecs->SetBGColor = __svgalib_arkaccel_SetBGColor; accelspecs->PutBitmap = __svgalib_arkaccel_PutBitmap;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -