*\r
* Simple graphics library to accompany the article\r
* \r
- * INTRODUCTION TO MODE X.\r
+ * INTRODUCTION TO MODE X.\r
* \r
* This library provides the basic functions for initializing and using\r
* unchained (planar) 256-color VGA modes. Currently supported are:\r
*\r
- * - 320x200\r
- * - 320x240\r
+ * - 320x200\r
+ * - 320x240\r
*\r
* Functions are provided for:\r
*\r
- * - initializing one of the available modes\r
- * - setting the start address of the VGA refresh data\r
- * - setting active and visible display pages\r
- * - writing and reading a single pixel to/from video memory\r
+ * - initializing one of the available modes\r
+ * - setting the start address of the VGA refresh data\r
+ * - setting active and visible display pages\r
+ * - writing and reading a single pixel to/from video memory\r
*\r
* The library is provided as a demonstration only, and is not claimed\r
* to be particularly efficient or suited for any purpose. It has only\r
//code from old library!\r
/*src\lib\*/\r
#include "dos_gfx.h"\r
-//#include "lib\x\modex.h"\r
-//#include "XPRIM.HPP"\r
\r
int old_mode;\r
//color \82Ä\82·\82Æ\r
/*\r
* Define the port addresses of some VGA registers.\r
*/\r
-#define CRTC_ADDR 0x3d4 /* Base port of the CRT Controller (color) */\r
+#define CRTC_ADDR 0x3d4 /* Base port of the CRT Controller (color) */\r
\r
-#define SEQU_ADDR 0x3c4 /* Base port of the Sequencer */\r
-#define GRAC_ADDR 0x3ce /* Base port of the Graphics Controller */\r
+#define SEQU_ADDR 0x3c4 /* Base port of the Sequencer */\r
+#define GRAC_ADDR 0x3ce /* Base port of the Graphics Controller */\r
#define STATUS_ADDR 0x3DA\r
\r
unsigned char *RowsX[600];\r
unsigned char write_plane, read_plane;\r
unsigned short text_mask[16] = { 0x0002, 0x0102, 0x0202, 0x0302,\r
- 0x0402, 0x0502, 0x0602, 0x0702,\r
- 0x0802, 0x0902, 0x0A02, 0x0B02,\r
- 0x0C02, 0x0D02, 0x0E02, 0x0F02 };\r
+ 0x0402, 0x0502, 0x0602, 0x0702,\r
+ 0x0802, 0x0902, 0x0A02, 0x0B02,\r
+ 0x0C02, 0x0D02, 0x0E02, 0x0F02 };\r
\r
\r
/*\r
\r
/*\r
* set320x200x256_X()\r
- * sets mode 13h, then turns it into an unchained (planar), 4-page\r
- * 320x200x256 mode.\r
+ * sets mode 13h, then turns it into an unchained (planar), 4-page\r
+ * 320x200x256 mode.\r
*/\r
void set320x200x256_X(void)\r
{\r
\r
/* Update the global variables to reflect dimensions of this\r
mode. This is needed by most future drawing operations. */\r
- width = 320;\r
+ width = 320;\r
height = 200;\r
\r
/* Each byte addresses four pixels, so the width of a scan line\r
-----------------------------------------------\r
*/\r
\r
-//mxSetVirtualScreen(480,360);\r
}\r
\r
/*\r
void setVisibleStart(unsigned offset)\r
{\r
visStart = offset;\r
- outpw(CRTC_ADDR, 0x0C); /* set high byte */\r
+ outpw(CRTC_ADDR, 0x0C); /* set high byte */\r
outpw(CRTC_ADDR+1, visStart >> 8);\r
- outpw(CRTC_ADDR, 0x0D); /* set low byte */\r
+ outpw(CRTC_ADDR, 0x0D); /* set low byte */\r
outpw(CRTC_ADDR+1, visStart & 0xff);\r
}\r
\r
/* Modify the vertical timing registers to reflect the increased\r
vertical resolution, and to center the image as good as\r
possible: */\r
- outpw(0x3D4, 0x2C11); /* turn off write protect */\r
- outpw(0x3D4, 0x0D06); /* vertical total */\r
- outpw(0x3D4, 0x3E07); /* overflow register */\r
- outpw(0x3D4, 0xEA10); /* vertical retrace start */\r
- outpw(0x3D4, 0xAC11); /* vertical retrace end AND wr.prot */\r
- outpw(0x3D4, 0xDF12); /* vertical display enable end */\r
- outpw(0x3D4, 0xE715); /* start vertical blanking */\r
- outpw(0x3D4, 0x0616); /* end vertical blanking */\r
+ outpw(0x3D4, 0x2C11); /* turn off write protect */\r
+ outpw(0x3D4, 0x0D06); /* vertical total */\r
+ outpw(0x3D4, 0x3E07); /* overflow register */\r
+ outpw(0x3D4, 0xEA10); /* vertical retrace start */\r
+ outpw(0x3D4, 0xAC11); /* vertical retrace end AND wr.prot */\r
+ outpw(0x3D4, 0xDF12); /* vertical display enable end */\r
+ outpw(0x3D4, 0xE715); /* start vertical blanking */\r
+ outpw(0x3D4, 0x0616); /* end vertical blanking */\r
\r
/* Update mode info, so future operations are aware of the\r
resolution */\r
height = 240;\r
\r
+//*$pragma aux mxSetVirtualScreen "MXSETVIRTUALSCREEN"\r
+//mxSetVirtualScreen(480,360);\r
}\r
\r
\r
/*-----------XXXX-------------*/\r
\r
/////////////////////////////////////////////////////////////////////////////\r
-// //\r
-// WaitRetrace() - This waits until you are in a Verticle Retrace. //\r
-// //\r
+// //\r
+// WaitRetrace() - This waits until you are in a Verticle Retrace. //\r
+// //\r
/////////////////////////////////////////////////////////////////////////////\r
void wait_for_retrace(void)\r
{\r
}\r
\r
/////////////////////////////////////////////////////////////////////////////\r
-// //\r
-// MoveTo() - This moves to position X*4 on a chain 4 screen. //\r
-// Note: As soon as I find documentation, this function //\r
-// will be better documented. - Snowman //\r
-// //\r
+// //\r
+// MoveTo() - This moves to position X*4 on a chain 4 screen. //\r
+// Note: As soon as I find documentation, this function //\r
+// will be better documented. - Snowman //\r
+// //\r
/////////////////////////////////////////////////////////////////////////////\r
/*\r
void MoveTo (word X, word Y) {\r
;\r
;-----------------------------------------------------------\r
;WARN PRO\r
-INCLUDE MODEX.DEF\r
-\r
-PUBLIC mxPan\r
-\r
-EXTRN mxWaitDisplay : FAR\r
-EXTRN mxStartAddress : FAR\r
-\r
-MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
- ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
-\r
-EXTRN mx_BytesPerLine : WORD\r
-\r
-;-----------------------------------------------------------\r
-;\r
-; Moves the screen.\r
-;\r
-; Input:\r
-; X, Y = new X, Y coordinates of view screen\r
-; Output:\r
-; none\r
-;\r
-mxPan PROC FAR\r
- ARG Y:WORD, \\r
- X:WORD = ARG_SIZE\r
- ASSUME ds:NOTHING\r
- .enter 0\r
-\r
- mov ax, [Y]\r
- mul [mx_BytesPerLine]\r
- mov dx, [X]\r
- shr dx, 1\r
- shr dx, 1\r
- add ax, dx\r
- push ax ; Push the start address\r
- call mxWaitDisplay\r
- call mxStartAddress\r
-\r
- mov dx, 03DAh ; Set the pixel pan register\r
- in al, dx\r
- mov dx, 03C0h\r
- mov al, 33h\r
- out dx, al\r
- mov al, BYTE PTR [X]\r
- and al, 3\r
- shl al, 1\r
- out dx, al\r
-\r
- xor ax, ax\r
- .leave ARG_SIZE\r
-mxPan ENDP\r
-\r
-MX_TEXT ENDS\r
+#pragma aux mxPan = \\r
+"INCLUDE MODEX.DEF" \\r
+\r
+\r
+\r
+"EXTRN mxWaitDisplay : FAR" \\r
+"EXTRN mxStartAddress : FAR" \\r
+\r
+"MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
+ ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING" \\r
+\r
+"EXTRN mx_BytesPerLine : WORD" \\r
+\r
+//;-----------------------------------------------------------\r
+//;\r
+//; Moves the screen.\r
+//;\r
+//; Input:\r
+//; X, Y = new X, Y coordinates of view screen\r
+//; Output:\r
+//; none\r
+//;\r
+mxPan PROC FAR\r
+ ARG Y:WORD, \\r
+ X:WORD = ARG_SIZE\r
+ ASSUME ds:NOTHING\r
+ .enter 0\r
+\r
+ mov ax, [Y]\r
+ mul [mx_BytesPerLine]\r
+ mov dx, [X]\r
+ shr dx, 1\r
+ shr dx, 1\r
+ add ax, dx\r
+ push ax ; Push the start address\r
+ call mxWaitDisplay\r
+ call mxStartAddress\r
+\r
+ mov dx, 03DAh ; Set the pixel pan register\r
+ in al, dx\r
+ mov dx, 03C0h\r
+ mov al, 33h\r
+ out dx, al\r
+ mov al, BYTE PTR [X]\r
+ and al, 3\r
+ shl al, 1\r
+ out dx, al\r
+\r
+ xor ax, ax\r
+ .leave ARG_SIZE\r
+mxPan ENDP\r
+\r
+MX_TEXT ENDS\r
END\r
\r
\r
\r
// for(loop1=0;loop1<=3;loop1++)\r
// for(loop2=0;loop2<=5;loop2++)\r
-// Putpic (loop1*160,loop2*66); // { This places the picture all over the\r
- // chain-4 screen }\r
+// Putpic (loop1*160,loop2*66); // { This places the picture all over the\r
+ // chain-4 screen }\r
// getch();\r
// ch=0x0;\r
// xpos=rand (78)+1;\r
ypos=ypos+ydir;\r
if( (xpos>79) || (xpos<1))xdir=-xdir;\r
if( (ypos>199) || (ypos<1))ydir=-ydir; // { Hit a boundry, change\r
- // direction! }\r
+ // direction! }\r
// if(_bios_keybrd(_KEYBRD_READY))ch=getch();\r
// if(ch==0x71)break; // 'q'\r
// if(ch==0x1b)break; // 'ESC'\r
Perhaps a little diagram will clarify it. The following picture is of a\r
standard X-mode addressing scheme with the OFFSET register set to 80.\r
\r
- ROW OFFSET\r
- 0 0 ========================\r
- 1 80 [ ]\r
- 2 160 [ ]\r
- .. .. [ VISIBLE ]\r
- [ SCREEN ]\r
- [ ]\r
- [ ]\r
- .. .. [ ]\r
- 199 15920 ========================\r
+ ROW OFFSET\r
+ 0 0 ========================\r
+ 1 80 [ ]\r
+ 2 160 [ ]\r
+ .. .. [ VISIBLE ]\r
+ [ SCREEN ]\r
+ [ ]\r
+ [ ]\r
+ .. .. [ ]\r
+ 199 15920 ========================\r
\r
and the next diagram is of a modified addressing scheme with the OFFSET\r
register set to 82 (to give us 4 extra pixels on each side of the screen)\r
\r
ROW OFFSET\r
-0 0 ------========================------\r
-1 82 | V [ ] V |\r
-2 164 | I [ ] I |\r
-.. .. | N S [ VISIBLE ] N S |\r
- | O I [ SCREEN ] O I |\r
- | T B [ ] T B |\r
- | L [ ] L |\r
-.. .. | E [ ] E |\r
+0 0 ------========================------\r
+1 82 | V [ ] V |\r
+2 164 | I [ ] I |\r
+.. .. | N S [ VISIBLE ] N S |\r
+ | O I [ SCREEN ] O I |\r
+ | T B [ ] T B |\r
+ | L [ ] L |\r
+.. .. | E [ ] E |\r
199 16318 ------========================------\r
\r
Beautiful!!!\r
}\r
\r
/////////////////////////////////////////////////////////////////////////////\r
-// //\r
-// setvideo() - This function Manages the video modes //\r
-// //\r
+// //\r
+// setvideo() - This function Manages the video modes //\r
+// //\r
/////////////////////////////////////////////////////////////////////////////\r
void setvideo(/*byte mode, */int vq){\r
union REGS in, out;\r
/////////////////////////////////////////////////////////////////////////////\r
// //\r
// cls() - This clears the screen to the specified color, on the VGA or on //\r
-// the Virtual screen. //\r
+// the Virtual screen. //\r
// //\r
/////////////////////////////////////////////////////////////////////////////\r
void cls(byte color, byte *Where){\r
//color \82Ä\82·\82Æ\r
int colorz(){\r
if(gq < HGQ){\r
-//---- cls(gq, vaddr);\r
+//---- cls(gq, vaddr);\r
cls(gq, vga);\r
gq++;\r
}else gq = LGQ;\r
if((q == 2\r
||q==4\r
||q==16\r
- ) && gq == BONK-1){\r
+ ) && gq == BONK){\r
if(coor < HGQ && coor < LGQ) coor = LGQ;\r
- if(coor < HGQ){\r
+ if(coor < HGQ-1){\r
coor++;\r
}else{ coor = LGQ;\r
bakax = rand()%3; bakay = rand()%3;\r
}\r
}\r
\r
- if(q == 8){ colorz(); return gq; }else\r
- if(q == 10){ ssd(q); /*printf("%d\n", coor);*/ }else\r
- if(q == 5){ colortest(); return gq; }else\r
- if(q == 11){ colorz(); delay(100); return gq; }\r
- if(q == 6){\r
+ if(q==8){ colorz(); return gq; }else\r
+ if(q==10){ ssd(q); /*printf("%d\n", coor);*/ }else\r
+ if(q==5){ colortest(); return gq; }else\r
+ if(q==11){ colorz(); delay(100); return gq; }\r
+ if(q==6){\r
coor = rand()%NUM_COLORS;\r
-//---- cls(coor, vaddr);\r
+//---- cls(coor, vaddr);\r
cls(coor, vga);\r
//updatevbuff();\r
}\r
\r
- if(q == 7 || q== 9){\r
+ if(q==7||q==9){\r
if(gq < HGQ){\r
if(q == 7) ssd(q);\r
if(q == 9){ ssd(q); coor++; }\r
// fixer\r
// if(q!=16){\r
//if(q!=16)\r
- if(xx<(0/*-TILEWH*/)) xx=(width/*+TILEWH*/);\r
+// if(xx<(0/*-(TILEWH/2)*/)) xx=(width/*+(TILEWH)*/);\r
if(yy<0) yy=(height*3);\r
- if(xx>(width/*+TILEWH*/)) xx=(0/*-TILEWH*/);\r
+// if(xx>(width/*+(TILEWH)*/)) xx=(0/*-(TILEWH/2)*/);\r
if(yy>(height*3)) yy=0;\r
// }\r
\r
//printf("%d %d %d %d %d %d\n", xx, yy, tx, ty, TILEWH);\r
\r
// plot the pixel\r
-//---- ppf(xx, yy, coor, vga);\r
+//---- ppf(xx, yy, coor, vga);\r
}else /*if(xx>=0 && xx<width && yy>=0 && yy<(height*3))*/{\r
// putColorBox_X(xx, yy, TILEWH, TILEWH, coor);\r
//++++0000\r
putPixel_X(xx, yy, coor);\r
} \r
\r
-//---- if(q==2) ppf(rand()%, rand()%height, 0, vga);\r
+//---- if(q==2) ppf(rand()%, rand()%height, 0, vga);\r
// if(q==2) putColorBox_X(rand()%width, rand()%(height*3), TILEWH, TILEWH, 0);\r
//++++0000\r
if(q==2) putPixel_X(rand()%width, rand()%(height*3), 0);\r
if(q==2||q==4||q==16){ bakax = rand()%3; bakay = rand()%3; }\r
gq++;\r
//if(xx<0||xx>320||yy<0||yy>(height*3))\r
-// printf("%d %d %d %d %d %d\n", xx, yy, coor, bakax, bakay, getPixel_X(xx,yy));\r
-// printf("%d\n", getPixel_X(xx,yy));\r
+// printf("%d %d %d %d %d %d\n", xx, yy, coor, bakax, bakay, getPixel_X(xx,yy));\r
+// printf("%d\n", getPixel_X(xx,yy));\r
//0000\r
-// drawText(0, 0, 15, getPixel_X(xx,yy));\r
+// drawText(0, 0, 15, getPixel_X(xx,yy));\r
}else gq = LGQ;\r
return gq;\r
}\r
\r
/* This is the way to calculate the number of pages available. */\r
pages = 65536L/(widthBytes*height); // apparently this takes the A000 address\r
+// if(height==240) pages++;\r
\r
- printf("%d\n", pages);\r
+// printf("%d\n", pages);\r
\r
for (p = 0; p <= pages; ++p)\r
{\r
{\r
putPixel_X(x, 0, p+1);\r
if(p!=pages) putPixel_X(x, height-1, p+1);\r
- else putPixel_X(x, 99-1, p+1);\r
+ else if(height==240) putPixel_X(x, 99-1, p+1);\r
}\r
\r
for (y = 0; y <= height; ++y)\r
{\r
putPixel_X(0, y, p+1);\r
if(p!=pages) putPixel_X(width-1, y, p+1);\r
- else putPixel_X(width-1, y, p+1);\r
+ else if(height==240) putPixel_X(width-1, y, p+1);\r
}\r
\r
- for (x = 0; x < 16; ++x)\r
- for (y = 0; y < 16; ++y)\r
- putPixel_X(x+(p+2)*16, y+(p+2)*16, x + y*16);\r
+ for (x = 0; x < TILEWH; ++x)\r
+ for (y = 0; y < TILEWH; ++y)\r
+ putPixel_X(x+(p+2)*16, y+(p+2)*TILEWH, x + y*TILEWH);\r
//}\r
\r
-// drawText(0, 0, 15, p);\r
-\r
}\r
\r
/* Each pages will now contain a different image. Let the user cycle\r
through all the pages by pressing a key. */\r
- for (p = 0; p <= pages; ++p)\r
+ for (p = 0; p < pages; ++p)\r
{\r
setVisiblePage(p);\r
- //drawText(0, 240, 15, "bakapi");\r
getch();\r
}\r
\r
// main variables\r
d=1; // switch variable\r
key=4; // default screensaver number\r
-// puts("First, have a look at the 320x200 mode. I will draw some rubbish");\r
-// puts("on all of the four pages, then let you cycle through them by");\r
-// puts("hitting a key on each page.");\r
-// puts("Press a key when ready...");\r
-// getch();\r
+// puts("First, have a look at the 320x200 mode. I will draw some rubbish");\r
+// puts("on all of the four pages, then let you cycle through them by");\r
+// puts("hitting a key on each page.");\r
+// puts("Press a key when ready...");\r
+// getch();\r
\r
-// doTest();\r
+// doTest();\r
\r
-// puts("Then, check out Mode X, 320x240 with 3 (and a half) pages.");\r
-// puts("Press a key when ready...");\r
-// getch();\r
+// puts("Then, check out Mode X, 320x240 with 3 (and a half) pages.");\r
+// puts("Press a key when ready...");\r
+// getch();\r
\r
//++++0000\r
setvideo(1);\r
}\r
}*/ // else off\r
while(!kbhit()){ // conditions of screen saver\r
- ding(2);\r
+ ding(4);\r
}\r
//end of screen savers\r
-// doTest();\r
- getch();\r
+ doTest();\r
+// getch();\r
\r
while(!kbhit()){ // conditions of screen saver\r
-// hScroll(1);\r
- scrolly(1);\r
- delay(100);\r
+ hScroll(1);\r
+// scrolly(1);\r
+// vScroll(1);\r
+// delay(100);\r
// Play();\r
}\r
//++++0000\r
setvideo(0);\r
+ printf("Resolution:\n[%d][%d]\n", width,height);\r
+// setvideo(0);\r
//mxTerm();\r
-//mxGetVersion();\r
- puts("Where to next? It's your move! wwww");\r
+//mxGetVersion();
+
+ printf("[%d]\n", mxGetVersion());\r
+ puts("where to next? It's your move! wwww");\r
printf("bakapi ver. 1.04.09.03\nis made by sparky4\81i\81\86\83Ö\81\85\81j feel free to use it ^^\nLicence: GPL v2\n");\r
return 0;\r
}\r