+++ /dev/null
-/* VERY QUICK AND ULTRA-DIRTY DEMO USING XLIB */\r
-\r
-/* Simple Demo of MODE X Split screen and panning */\r
-/* Compile using Turbo C and Tasm */\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <conio.h>\r
-#include <ctype.h>\r
-#include <alloc.h>\r
-#include <dos.h>\r
-#include "Xlib_all.h"\r
-\r
-#define MAX_OBJECTS 10\r
-\r
-static char *texttest[6] =\r
- {"This is a demonstration of the fonts ",\r
- "available in XLIB. Notice fixed and ",\r
- "variabe spaced fonts are supported but",\r
- "are limited to a maximum of 8 pixels in",\r
- "width. Height of the characters is ",\r
- "ofcourse unlimited..."};\r
-\r
-typedef struct {\r
- int X,Y,Width,Height,XDir,YDir,XOtherPage,YOtherPage;\r
- char far * Image;\r
- char far * bg;\r
- char far * bgOtherPage;\r
-} AnimatedObject;\r
-\r
-AnimatedObject objects[MAX_OBJECTS];\r
-int object_count=0;\r
-\r
-static char bm[] = {4,12,\r
- /* plane 0 */\r
- 2,2,2,2,2,1,1,1,2,1,1,1,2,3,3,1,\r
- 2,0,0,3,2,0,0,3,2,0,0,3,2,0,0,3,\r
- 2,3,3,1,2,1,1,1,2,1,1,1,2,2,2,2,\r
- /* plane 1 */\r
- 2,2,2,2,1,1,1,1,1,1,1,1,1,3,3,1,\r
- 1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,\r
- 1,3,3,1,1,1,1,1,1,1,1,1,2,2,2,2,\r
- /* plane 2 */\r
- 2,2,2,2,1,1,1,1,1,1,1,1,1,3,3,1,\r
- 1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,\r
- 1,3,3,1,1,1,1,1,1,1,1,1,2,2,2,2,\r
- /* plane 3 */\r
- 2,2,2,2,1,1,1,2,1,1,1,2,1,3,3,2,\r
- 3,0,0,2,3,0,0,2,3,0,0,2,3,0,0,2,\r
- 1,3,3,2,1,1,1,2,1,1,1,2,2,2,2,2};\r
-\r
-static char bm2[] = {4,12,\r
- /* plane 0 */\r
- 2,2,2,2,2,4,4,4,2,4,4,4,2,2,2,4,\r
- 2,0,0,2,2,0,0,2,2,0,0,2,2,0,0,2,\r
- 2,2,2,4,2,4,4,4,2,4,4,4,2,2,2,2,\r
- /* plane 1 */\r
- 2,2,2,2,4,4,4,4,4,4,4,4,4,2,2,4,\r
- 4,0,0,4,4,0,0,4,4,0,0,4,4,0,0,4,\r
- 4,2,2,4,4,4,4,4,4,4,4,4,2,2,2,2,\r
- /* plane 2 */\r
- 2,2,2,2,4,4,4,4,4,4,4,4,4,2,2,4,\r
- 4,0,0,4,4,0,0,4,4,0,0,4,4,0,0,4,\r
- 4,2,2,4,4,4,4,4,4,4,4,4,2,2,2,2,\r
- /* plane 2 */\r
- 2,2,2,2,4,4,4,2,4,4,4,2,4,2,2,2,\r
- 2,0,0,2,2,0,0,2,2,0,0,2,2,0,0,2,\r
- 4,2,2,2,4,4,4,2,4,4,4,2,2,2,2,2};\r
-\r
-int textwindow_x=0,textwindow_y=0;\r
-char far * pal,far * pal2;\r
-char palscrolldir=1;\r
-char far * userfnt1;\r
-\r
-\r
-\r
-void drawtext(int height){\r
- int i;\r
- for (i=0;i<6;i++)\r
- x_printf(textwindow_x+5,50+i*(height+2),VisiblePageOffs,9,texttest[i]);\r
-}\r
-\r
-/* initialize a new object */\r
-void init_object(int x,int y,int width, int height, int xdir, int ydir,\r
- char far * image){\r
- int i;\r
- objects[object_count].X = objects[object_count].XOtherPage = x;\r
- objects[object_count].Y = objects[object_count].YOtherPage = y;\r
- objects[object_count].Width = width;\r
- objects[object_count].Height = height;\r
- objects[object_count].XDir = xdir;\r
- objects[object_count].YDir = ydir;\r
- objects[object_count].Image = image;\r
- objects[object_count].bg = (char far *) farmalloc(4*width*height+20);\r
- objects[object_count].bgOtherPage = (char far *) farmalloc(4*width*height+20);\r
- x_get_pbm(x,y,(unsigned)width,height,VisiblePageOffs,\r
- objects[object_count].bg);\r
- x_get_pbm(x,y,(unsigned)width,height,HiddenPageOffs,\r
- objects[object_count].bgOtherPage);\r
- object_count++;\r
-}\r
-\r
-/* Move the specified object, bouncing at the edges of the screen and\r
- remembering where the object was before the move for erasing next time */\r
-void MoveObject(AnimatedObject * ObjectToMove) {\r
- int X, Y;\r
- char far *cptr;\r
- X = ObjectToMove->X + ObjectToMove->XDir;\r
- Y = ObjectToMove->Y + ObjectToMove->YDir;\r
- if ((X < 0) || (X > (ScrnLogicalPixelWidth-((ObjectToMove->Width)<<2)))) {\r
- ObjectToMove->XDir = -ObjectToMove->XDir;\r
- X = ObjectToMove->X + ObjectToMove->XDir;\r
- }\r
- if ((Y < 0) || (Y > (ScrnLogicalHeight-ObjectToMove->Height))) {\r
- ObjectToMove->YDir = -ObjectToMove->YDir;\r
- Y = ObjectToMove->Y + ObjectToMove->YDir;\r
- }\r
- /* Remember previous location for erasing purposes */\r
- ObjectToMove->XOtherPage = ObjectToMove->X;\r
- ObjectToMove->YOtherPage = ObjectToMove->Y;\r
- ObjectToMove->X = X; /* set new location */\r
- ObjectToMove->Y = Y;\r
- cptr = ObjectToMove->bg;\r
- ObjectToMove->bg = ObjectToMove->bgOtherPage;\r
- ObjectToMove->bgOtherPage = cptr;\r
-}\r
-\r
-void animate(void){\r
- int i;\r
- for(i=object_count-1;i>=0;i--){\r
- x_put_pbm(objects[i].XOtherPage,objects[i].YOtherPage,\r
- HiddenPageOffs,objects[i].bgOtherPage);\r
- }\r
- for(i=0;i<object_count;i++){\r
- MoveObject(&objects[i]);\r
-\r
- x_get_pbm(objects[i].X,objects[i].Y,\r
- (unsigned)objects[i].Width,objects[i].Height,HiddenPageOffs,\r
- objects[i].bg);\r
- x_put_masked_pbm(objects[i].X,objects[i].Y,HiddenPageOffs,\r
- objects[i].Image);\r
- }\r
-}\r
-\r
-void clear_objects(void){\r
- int i;\r
- for(i=object_count-1;i>=0;i--){\r
- x_put_pbm(objects[i].XOtherPage,objects[i].YOtherPage,\r
- HiddenPageOffs,objects[i].bgOtherPage);\r
- }\r
-}\r
-\r
-\r
-void textwindow(int Margin){\r
- int x0=0+Margin;\r
- int y0=0+Margin;\r
- int x1=ScrnPhysicalPixelWidth-Margin;\r
- int y1=ScrnPhysicalHeight-Margin;\r
- x_rect_fill(x0, y0, x1,y1,VisiblePageOffs,1);\r
- x_line(x0,y0,x1,y0,2,VisiblePageOffs);\r
- x_line(x0,y1,x1,y1,2,VisiblePageOffs);\r
- x_line(x0,y0,x0,y1,2,VisiblePageOffs);\r
- x_line(x1,y0,x1,y1,2,VisiblePageOffs);\r
- x_line(x0+2,y0+2,x1-2,y0+2,2,VisiblePageOffs);\r
- x_line(x0+2,y1-2,x1-2,y1-2,2,VisiblePageOffs);\r
- x_line(x0+2,y0+2,x0+2,y1-2,2,VisiblePageOffs);\r
- x_line(x1-2,y0+2,x1-2,y1-2,2,VisiblePageOffs);\r
- textwindow_x=x0;\r
- textwindow_y=y0;\r
-\r
-}\r
-\r
-\r
-void wait_for_keypress(void){\r
- x_show_mouse();\r
- while(kbhit()) getch();\r
- palscrolldir^=1;\r
-\r
- do {\r
- x_rot_pal_struc(pal,palscrolldir);\r
- MouseFrozen=1;\r
- x_put_pal_struc(pal);\r
- x_update_mouse();\r
- } while (!kbhit() && !(MouseButtonStatus==LEFT_PRESSED));\r
- while(MouseButtonStatus==LEFT_PRESSED);\r
- while(kbhit()) getch();\r
-\r
-}\r
-\r
-\r
-void exitfunc(void){\r
- x_mouse_remove();\r
- x_remove_vsync_handler();\r
- x_text_mode();\r
- printf("Thanks to everyone who assisted in the development of XLIB.\n");\r
- printf("\nSpecial thanks to Matthew Mackenzie for contributing \n");\r
- printf("lots of code, documentation and ideas.\n\n");\r
- printf("If you make any money using this code and you're the generous\n");\r
- printf("type please send us some, or at least a copy of your program!\n");\r
-}\r
-\r
-int terminate(void){\r
- exit(0);\r
-}\r
-\r
-void intro_1(void){\r
- x_set_rgb(1,40,40,40); /* BG Gray */\r
- x_set_rgb(2,63,63,0); /* Bright Yellow */\r
- x_set_rgb(3,63,0,0); /* Bright Red */\r
- x_set_rgb(4,0,63,0); /* Bright Green */\r
- x_set_rgb(5,0,0,63); /* Bright Blue */\r
- x_set_rgb(6,0,0,28); /* Dark Blue */\r
- x_set_rgb(7,0,28,0); /* Dark Green */\r
- x_set_rgb(8,28,0,0); /* Dark red */\r
- x_set_rgb(9,0,0,38); /* Med Blue */\r
-\r
- textwindow(20);\r
- x_set_font(1);\r
- x_printf(textwindow_x+54,textwindow_y+4,VisiblePageOffs,6," XLIB Version 6.0");\r
- x_printf(textwindow_x+53,textwindow_y+3,VisiblePageOffs,2," XLIB Version 6.0");\r
- x_set_font(0);\r
- x_printf(textwindow_x+24,textwindow_y+18,VisiblePageOffs,6," Not the Unix version");\r
- x_printf(textwindow_x+23,textwindow_y+17,VisiblePageOffs,2," Not the Unix version");\r
-\r
- x_printf(textwindow_x+24,168,VisiblePageOffs,6," Press any key to continue");\r
- x_printf(textwindow_x+23,167,VisiblePageOffs,2," Press any key to continue");\r
-}\r
-\r
-void subsequent_page(void){\r
- x_hide_mouse();\r
- textwindow(20);\r
- x_set_font(1);\r
- x_printf(textwindow_x+54,textwindow_y+4,VisiblePageOffs,6," XLIB Version 6.0");\r
- x_printf(textwindow_x+53,textwindow_y+3,VisiblePageOffs,2," XLIB Version 6.0");\r
- x_set_font(0);\r
- x_printf(textwindow_x+24,168,VisiblePageOffs,6," Press any key to continue");\r
- x_printf(textwindow_x+23,167,VisiblePageOffs,2," Press any key to continue");\r
-}\r
-\r
-void load_user_fonts(void){\r
- FILE *f;\r
- f=fopen("var6x8.fnt","rb");\r
- /* read char by char as fread wont read to far pointers in small model */\r
- { int i; char c;\r
- for (i=0;i<256*8+4;i++){\r
- fread(&c,1,1,f);\r
- *(userfnt1+i)=c;\r
- }\r
- }\r
-\r
- fclose(f);\r
-\r
- x_register_userfont(userfnt1);\r
-\r
-}\r
-\r
-\r
-\r
-void main(){\r
- int i, j, xinc, yinc, Margin;\r
- char ch;\r
- WORD curr_x=0, curr_y=0;\r
-\r
- pal = (char far *) farmalloc(256*3);\r
- pal2 = (char far *) farmalloc(256*3);\r
- userfnt1 = (char far *) farmalloc(256*16+4);\r
-\r
-\r
- /* INITIALIZE XLIB */\r
-\r
- /* we set up Mode X 360x200x256 with a logical width of ~ 500 */\r
- /* pixels; we actually get 496 due to the fact that the width */\r
- /* must be divisible by 8 */\r
-\r
- x_text_mode(); /* make sure VGA is in color mode, if possible */\r
- x_set_mode(X_MODE_360x200,500); /* actually is set to 496 */\r
- x_install_vsync_handler(2);\r
- x_set_splitscreen(ScrnPhysicalHeight-60); /* split screen 60 pixels high */\r
- x_set_doublebuffer(220);\r
- x_text_init();\r
- x_hide_splitscreen();\r
- x_mouse_init();\r
- MouseColor=2;\r
- atexit(exitfunc);\r
-\r
- /* DRAW BACKGROUND LINES */\r
-\r
- for(j=0;j<ScrnPhysicalHeight;j++){\r
- x_line(0,j,ScrnLogicalPixelWidth,j,16+(j%239),VisiblePageOffs);\r
- }\r
-\r
- ctrlbrk(terminate);\r
- x_get_pal_struc(pal, 240,16);\r
- load_user_fonts();\r
-\r
- intro_1();\r
- x_set_font(2);\r
- x_hide_mouse();\r
- x_printf(textwindow_x+5,50 ,VisiblePageOffs,9, " Hi, folks. This is yet another FREEWARE Mode X");\r
- x_printf(textwindow_x+5,50+8 ,VisiblePageOffs,9, " graphics library. It is by no means complete,");\r
- x_printf(textwindow_x+5,50+16,VisiblePageOffs,9, " but I believe it contains a rich enough set of");\r
- x_printf(textwindow_x+5,50+24,VisiblePageOffs,9, " functions to achieve its design goal - to be");\r
- x_printf(textwindow_x+5,50+32,VisiblePageOffs,9, " a game development oriented library for");\r
- x_printf(textwindow_x+5,50+40,VisiblePageOffs,9, " Borland TC/BC/BC++ and TASM programmers.");\r
-\r
- x_printf(textwindow_x+5,50+48,VisiblePageOffs,9, " This library comes with TASM and C sources.");\r
- x_printf(textwindow_x+5,50+56,VisiblePageOffs,9, " It was inspired by the DDJ Graphics column and");\r
- x_printf(textwindow_x+5,50+64,VisiblePageOffs,9, " many INTERNET and USENET authors who, unlike the");\r
- x_printf(textwindow_x+5,50+72,VisiblePageOffs,9, " majority of programmers (you know who you are!),");\r
- x_printf(textwindow_x+5,50+80,VisiblePageOffs,9, " willingly share their code and ideas with others.");\r
-\r
- x_printf(textwindow_x+5,50+88,VisiblePageOffs,9, " I can't afford, nor do I want, to copyright");\r
- x_printf(textwindow_x+5,50+96,VisiblePageOffs,9, " this code - but if you use it, some credit would ");\r
- x_printf(textwindow_x+5,50+104,VisiblePageOffs,9," be appreciated. ");\r
-\r
- wait_for_keypress();\r
-\r
- subsequent_page();\r
- x_set_font(0);\r
- x_printf(textwindow_x+24,textwindow_y+18,VisiblePageOffs,6,"Supported 256 colour resolutions.");\r
- x_printf(textwindow_x+23,textwindow_y+17,VisiblePageOffs,3,"Supported 256 colour resolutions.");\r
- x_set_font(2);\r
- x_printf(textwindow_x+5,50 ,VisiblePageOffs,9, " 320x200 Standard for games ~ 4 pages");\r
- x_printf(textwindow_x+5,50+8 ,VisiblePageOffs,9, " 320x240 DDJ Mode X square pixels ~ 3.5 pages");\r
- x_printf(textwindow_x+5,50+16,VisiblePageOffs,9, " 360x200 My favourite for games ~ 3 pages ");\r
- x_printf(textwindow_x+5,50+24,VisiblePageOffs,9, " 360x240 ~ 2.8 pages");\r
- x_printf(textwindow_x+5,50+32,VisiblePageOffs,9, " 320x400 ~ 2 pages ");\r
- x_printf(textwindow_x+5,50+40,VisiblePageOffs,9, " 320x480 All subsequent modes support");\r
- x_printf(textwindow_x+5,50+48,VisiblePageOffs,9, " 360x400 less than two pages.");\r
- x_printf(textwindow_x+5,50+56,VisiblePageOffs,9, " 360x480");\r
- x_printf(textwindow_x+5,50+64,VisiblePageOffs,9, " 376x282,360x360,376x308,376x564,256x200,256x240");\r
- x_printf(textwindow_x+5,50+72,VisiblePageOffs,9, " Phew! and they'll run on all VGA cards and ");\r
- x_printf(textwindow_x+5,50+80,VisiblePageOffs,9, " monitors (some of the weird ones are best suited");\r
- x_printf(textwindow_x+5,50+88,VisiblePageOffs,9, " to monitors with both vert & horiz adjustments)");\r
- x_printf(textwindow_x+5,50+98,VisiblePageOffs,2, " ");\r
- x_printf(textwindow_x+5,50+106,VisiblePageOffs,2," Overkill? Maybe!! ");\r
-\r
-\r
- wait_for_keypress();\r
-\r
- subsequent_page();\r
- x_printf(textwindow_x+24,textwindow_y+18,VisiblePageOffs,6," Text display functions.");\r
- x_printf(textwindow_x+23,textwindow_y+17,VisiblePageOffs,3," Text display functions.");\r
- x_set_font(2);\r
- x_printf(textwindow_x+5,50 ,VisiblePageOffs,9, " Several text printing functions are provided.");\r
- x_printf(textwindow_x+5,50+8 ,VisiblePageOffs,9, " They support the VGA ROM 8x14 and 8x8 fonts as");\r
- x_printf(textwindow_x+5,50+16,VisiblePageOffs,9, " well as user-defined fonts (like this 6x8 font).");\r
- x_printf(textwindow_x+5,50+24,VisiblePageOffs,9, " Furthermore, a function similar to printf is");\r
- x_printf(textwindow_x+5,50+32,VisiblePageOffs,9, " included which provides formatted text output.");\r
- x_printf(textwindow_x+5,50+40,VisiblePageOffs,9, " User defined fonts may be proportionally spaced");\r
- x_printf(textwindow_x+5,50+58,VisiblePageOffs,9, " but have a maximum width of 8 pixels.");\r
-\r
-\r
- wait_for_keypress();\r
-\r
- subsequent_page();\r
- x_printf(textwindow_x+24,textwindow_y+18,VisiblePageOffs,6," Advanced screen functions.");\r
- x_printf(textwindow_x+23,textwindow_y+17,VisiblePageOffs,3," Advanced screen functions.");\r
- x_set_font(2);\r
- x_printf(textwindow_x+5,50 ,VisiblePageOffs,9, " The library supports virtual screens larger");\r
- x_printf(textwindow_x+5,50+8 ,VisiblePageOffs,9, " than the physical screen, panning of such");\r
- x_printf(textwindow_x+5,50+16,VisiblePageOffs,9, " screens, and a split screen option.");\r
- x_printf(textwindow_x+5,50+24,VisiblePageOffs,9, " These functions can be used together or");\r
- x_printf(textwindow_x+5,50+32,VisiblePageOffs,9, " in isolation, and in the lower resolutions");\r
- x_printf(textwindow_x+5,50+40,VisiblePageOffs,9, " double buffering can also be accomplished.");\r
-\r
- x_rect_fill(0, 0, ScrnPhysicalPixelWidth,60,SplitScrnOffs,5);\r
- x_line(0,0,ScrnPhysicalPixelWidth,0,2,SplitScrnOffs);\r
- x_set_font(1);\r
- x_printf(10,10,SplitScrnOffs,2, " This is a split screen, tops for scores.");\r
- x_set_font(0);\r
- for (i=ScrnPhysicalHeight;i>ScrnPhysicalHeight-60;i--){\r
- x_adjust_splitscreen(i);\r
- }\r
- x_printf(10,25,SplitScrnOffs,2, " Even better for scrolling games etc.");\r
-\r
- x_cp_vid_rect(0,0,ScrnLogicalPixelWidth,ScrnLogicalHeight,0,0,\r
- VisiblePageOffs,HiddenPageOffs,\r
- ScrnLogicalPixelWidth,ScrnLogicalPixelWidth);\r
-\r
-\r
- x_show_mouse();\r
- wait_for_keypress();\r
-\r
- curr_x=curr_y=0;\r
-\r
-\r
- init_object(60,90,4, 12, -1, 1, MK_FP(FP_SEG(bm2),FP_OFF(bm2)));\r
- init_object(30,30,4, 12, 1, 1, MK_FP(FP_SEG(bm),FP_OFF(bm)));\r
- init_object(80,120,4, 12, 2, 1, MK_FP(FP_SEG(bm),FP_OFF(bm)));\r
- init_object(300,200,4, 12, 1, -2, MK_FP(FP_SEG(bm),FP_OFF(bm)));\r
- init_object(360,30,4, 12, -1, -1, MK_FP(FP_SEG(bm),FP_OFF(bm)));\r
- init_object(360,10,4, 12, -2, 2, MK_FP(FP_SEG(bm),FP_OFF(bm)));\r
-\r
- x_hide_mouse();\r
-\r
- while (!kbhit()&& !(MouseButtonStatus==LEFT_PRESSED)){\r
- animate();\r
- if (objects[0].X>=curr_x+ScrnPhysicalPixelWidth-32 &&\r
- curr_x < MaxScrollX) curr_x++;\r
- else if (objects[0].X < curr_x+16 && curr_x > 0) curr_x--;\r
- if (objects[0].Y>=curr_y+ScrnPhysicalHeight-92 &&\r
- curr_y < MaxScrollY) curr_y++;\r
- else if (objects[0].Y < curr_y+16 && curr_y > 0) curr_y--;\r
- x_page_flip(curr_x,curr_y);\r
- while(StartAddressFlag);\r
- }\r
- while(MouseButtonStatus==LEFT_PRESSED);\r
- while(kbhit()) getch();\r
-\r
- clear_objects();\r
- x_page_flip(curr_x,curr_y);\r
- while(StartAddressFlag);\r
-\r
-\r
- x_set_start_addr(0,0);\r
-\r
-\r
- for (j=0;j<4;j++){\r
- x_hide_splitscreen();\r
- delay(100);\r
- x_show_splitscreen();\r
- delay(100);\r
- }\r
-\r
-\r
- for (i=ScrnPhysicalHeight-60;i<=ScrnPhysicalHeight;i++){\r
- x_adjust_splitscreen(i);\r
- }\r
-\r
- x_hide_mouse();\r
- subsequent_page();\r
- x_printf(textwindow_x+24,textwindow_y+18,VisiblePageOffs,6," Palette functions.");\r
- x_printf(textwindow_x+23,textwindow_y+17,VisiblePageOffs,3," Palette functions.");\r
- x_set_font(2);\r
- x_printf(textwindow_x+5,50 ,VisiblePageOffs,9, " A number of palette manipulation functions");\r
- x_printf(textwindow_x+5,50+8 ,VisiblePageOffs,9, " are provided. You have already seen some of");\r
- x_printf(textwindow_x+5,50+16,VisiblePageOffs,9, " them in action. Another common operation is");\r
- x_printf(textwindow_x+5,50+24,VisiblePageOffs,9, " palette fading. ");\r
-\r
- i=0;\r
- ch=255;\r
- while (x_cpcontrast_pal_struc(pal, pal2,ch-=2)){\r
- x_put_pal_struc(pal2);\r
- x_rot_pal_struc(pal,palscrolldir);\r
- i++;\r
- };\r
- for (j=0;j<i;j++){\r
- x_cpcontrast_pal_struc(pal, pal2,ch+=2);\r
- x_put_pal_struc(pal2);\r
- x_rot_pal_struc(pal,palscrolldir);\r
- };\r
- wait_for_keypress();\r
-\r
- subsequent_page();\r
- x_printf(textwindow_x+24,textwindow_y+18,VisiblePageOffs,6," NEW Version 3.0 Functions!");\r
- x_printf(textwindow_x+23,textwindow_y+17,VisiblePageOffs,3," NEW Version 3.0 Functions!");\r
- x_set_font(2);\r
- x_printf(textwindow_x+5,50 ,VisiblePageOffs,9, " NEW functions not demonstrated here include:");\r
- x_printf(textwindow_x+5,50+10,VisiblePageOffs,9, " - RLE data compression");\r
- x_printf(textwindow_x+5,50+20,VisiblePageOffs,9, " - FAST compiled masked bitmaps");\r
- x_printf(textwindow_x+5,50+30,VisiblePageOffs,9, " - Hardware detection");\r
-\r
- x_show_mouse();\r
- wait_for_keypress();\r
-\r
- x_hide_mouse();\r
- for (i = 0; i < 150; i++) {\r
- x_circle(0, 0, i, 181 - i, VisiblePageOffs);\r
- x_circle(360 - i, 0, i, i + 30, VisiblePageOffs);\r
- x_circle(0, 200 - i, i, i + 30, VisiblePageOffs);\r
- x_circle(360 - i, 200 - i, i, 181 - i, VisiblePageOffs);\r
- }\r
- for (i = 0; i < 100; i++)\r
- x_filled_circle(80 + i, i, 201 - (i << 1), 30+i, VisiblePageOffs);\r
- x_show_mouse();\r
- wait_for_keypress();\r
-\r
- subsequent_page();\r
- x_printf(textwindow_x+24,textwindow_y+18,VisiblePageOffs,6," NEW Version 4.0 Functions!");\r
- x_printf(textwindow_x+23,textwindow_y+17,VisiblePageOffs,3," NEW Version 4.0 Functions!");\r
- x_set_font(2);\r
- x_printf(textwindow_x+5,50 ,VisiblePageOffs,9, " NEW functions not demonstrated here include:");\r
- x_printf(textwindow_x+5,50+10,VisiblePageOffs,9, " - FAST VRAM-based masked bitmaps, including");\r
- x_printf(textwindow_x+5,50+18,VisiblePageOffs,9, " support for clipping regions");\r
- x_printf(textwindow_x+5,50+28,VisiblePageOffs,9, " - Faster, smaller compiled bitmaps");\r
- x_printf(textwindow_x+5,50+38,VisiblePageOffs,9, " - Improved planar bitmap performance and");\r
- x_printf(textwindow_x+5,50+46,VisiblePageOffs,9, " additional support for clipping");\r
- x_printf(textwindow_x+5,50+56,VisiblePageOffs,9, " - mouse module");\r
- x_printf(textwindow_x+5,50+66,VisiblePageOffs,9, " - Detection of math co-processor and mouse");\r
- x_printf(textwindow_x+5,50+76,VisiblePageOffs,9, " - Bezier curve module");\r
- x_printf(textwindow_x+5,50+86,VisiblePageOffs,9, " - Four new resolutions, including one with");\r
- x_printf(textwindow_x+5,50+94,VisiblePageOffs,9, " square pixels (376x282)");\r
- x_printf(textwindow_x+5,50+104,VisiblePageOffs,9, " - More bug fixes");\r
-\r
- wait_for_keypress();\r
-\r
- subsequent_page();\r
- x_printf(textwindow_x+24,textwindow_y+18,VisiblePageOffs,6," NEW Version 5.0 Functions!");\r
- x_printf(textwindow_x+23,textwindow_y+17,VisiblePageOffs,3," NEW Version 5.0 Functions!");\r
- x_set_font(2);\r
- x_printf(textwindow_x+5,50 ,VisiblePageOffs,9, " - *FAST* filled and clipped triangles ideal for");\r
- x_printf(textwindow_x+5,50+10,VisiblePageOffs,9, " 3D work. Thanks to S. Dollins for the code.");\r
- x_printf(textwindow_x+5,50+20,VisiblePageOffs,9, " - Filled and clipped polygons, C++ Compatible");\r
- x_printf(textwindow_x+5,50+30,VisiblePageOffs,9, " - header files, and of course bug fixes!");\r
-\r
- x_show_mouse();\r
- wait_for_keypress();\r
-\r
- subsequent_page();\r
- x_printf(textwindow_x+24,textwindow_y+18,VisiblePageOffs,6," NEW Version 6.0 Functions!");\r
- x_printf(textwindow_x+23,textwindow_y+17,VisiblePageOffs,3," NEW Version 6.0 Functions!");\r
- x_set_font(2);\r
- x_printf(textwindow_x+5,50 ,VisiblePageOffs,9, " - Fast flood filling functions ");\r
- x_printf(textwindow_x+5,50+10,VisiblePageOffs,9, " - New pbm flipping put functions.");\r
- x_printf(textwindow_x+5,50+20,VisiblePageOffs,9, " - Timer synchronized vertical retrace");\r
- x_printf(textwindow_x+5,50+30,VisiblePageOffs,9, " - Tripple buffering extensions");\r
- x_printf(textwindow_x+5,50+40,VisiblePageOffs,9, " Checkout demo 9 and 10 for previews");\r
- \r
-\r
-\r
- x_show_mouse();\r
- wait_for_keypress();\r
-\r
-\r
- randomize();\r
- x_hide_mouse();\r
- while(kbhit()) getch();\r
- palscrolldir^=1;\r
- do {\r
- int x0,x1,x2,y0,y1,y2,i;\r
- i=random(256);\r
- x0=random(ScrnLogicalPixelWidth);\r
- x1=random(ScrnLogicalPixelWidth);\r
- x2=random(ScrnLogicalPixelWidth);\r
- y0=random(ScrnPhysicalHeight);\r
- y1=random(ScrnPhysicalHeight);\r
- y2=random(ScrnPhysicalHeight);\r
- x_triangle(x0,y0,x1,y1,x2,y2,i,VisiblePageOffs);\r
- } while (!kbhit() && !(MouseButtonStatus==LEFT_PRESSED));\r
- while(MouseButtonStatus==LEFT_PRESSED);\r
- while(kbhit()) getch();\r
- x_show_mouse();\r
-\r
- subsequent_page();\r
- x_printf(textwindow_x+24,textwindow_y+18,VisiblePageOffs,6," PLEASE...");\r
- x_printf(textwindow_x+23,textwindow_y+17,VisiblePageOffs,3," PLEASE...");\r
- x_set_font(2);\r
- x_printf(textwindow_x+5,50 ,VisiblePageOffs,9, " Please mention my name in programs that use XLIB");\r
- x_printf(textwindow_x+5,50+8 ,VisiblePageOffs,9, " just to make me feel it was worth the effort.");\r
- x_printf(textwindow_x+5,50+16,VisiblePageOffs,9, " If you have any bug to report please feel free to");\r
- x_printf(textwindow_x+5,50+24,VisiblePageOffs,9, " mail me a message. Any hints, suggestions and");\r
- x_printf(textwindow_x+5,50+32,VisiblePageOffs,9, " contributions are welcome and encouraged.");\r
- x_printf(textwindow_x+5,50+52,VisiblePageOffs,9, " I have contributed this code to the public domain.");\r
- x_printf(textwindow_x+5,50+60,VisiblePageOffs,9, " Please respect my wishes and leave it there.");\r
-\r
- x_printf(textwindow_x+5,50+80,VisiblePageOffs,9, " Finally, I hope you all find this stuff useful,");\r
- x_printf(textwindow_x+5,50+96,VisiblePageOffs,9, " Themie Gouthas - EGG@DSTOS3.DSTO.GOV.AU");\r
-\r
- wait_for_keypress();\r
-\r
- x_hide_mouse();\r
-\r
- x_shift_rect (27, 27, 360-27, 177, 27, 23, VisiblePageOffs);\r
- x_rect_fill(25, 173, 335, 176, VisiblePageOffs, 1);\r
- for (i = 0; i < 50; i++) {\r
- x_shift_rect (27, 26, 360-27, 177 - (i * 3), 27, 23, VisiblePageOffs);\r
- }\r
-}\r
-\r
-\r
+++ /dev/null
-/*************************************************************************\r
-\r
-DEMO 2\r
-\r
-Demonstrates the speed difference between compiled bitmap, conventional\r
-masked planar bitmap, and video bitmap blits.\r
-\r
-**************************************************************************/\r
-\r
-\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <conio.h>\r
-#include <ctype.h>\r
-#include <alloc.h>\r
-#include <dos.h>\r
-#include "xlib.h"\r
-#include "xcbitmap.h"\r
-#include "xpbitmap.h"\r
-#include "xvbitmap.h"\r
-#include "xbmtools.h"\r
-#include "xtext.h"\r
-#include "xrect.h"\r
-#include "xrect.h"\r
-\r
-/* Macro to make pointer parameters model independent */\r
-#define FARPTR(x) (MK_FP(FP_SEG(x),FP_OFF(x)))\r
-\r
-char turtle[] = {\r
- 20,30,\r
-/* | . | . | . | . */\r
- 8,14, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 8, 2,14, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 8, 2, 2, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 8, 0, 2,14, 0, 0,14,14,14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 8, 0, 2, 5, 0, 4, 4, 4, 4,14,14, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 8, 0, 2, 2, 4, 4, 0, 4, 4, 0, 4,14, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 2, 4, 4, 4, 0, 4, 4, 0, 4, 4,14, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 2, 4, 4, 4, 0, 0, 0, 0, 4, 4,14, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 4, 0, 4, 4, 4, 0, 0, 0, 4, 0, 0, 2, 2, 0, 0, 0,\r
- 0, 0, 0, 4, 0, 4, 4, 4, 0, 4, 4, 4, 0,14, 0, 0, 2, 2, 0, 0,\r
- 0, 0, 0, 4, 4, 0, 0, 0, 4, 4, 0, 4, 0, 4, 2, 2, 2, 2, 0, 0,\r
- 0, 0, 0, 4, 4, 4, 0, 4, 4, 0, 4, 4, 0, 4,14, 2, 2, 2, 0, 0,\r
- 0, 0, 0, 4, 4, 4, 0, 0, 0, 4, 4, 0, 4, 0, 0, 2, 2, 0, 0, 0,\r
- 0, 0, 0, 2, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4,14, 2, 0, 0, 0, 0,\r
- 0, 0, 2, 2, 0, 4, 4, 4, 4, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0,\r
- 2, 2, 2, 2, 4, 0, 0, 4, 4, 0, 4, 4, 0, 4,14, 0, 0, 0, 0, 0,\r
- 0, 2, 2, 0, 4, 4, 4, 0, 0, 4, 4, 0, 4, 0, 2, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 4, 4, 0, 4, 4, 4, 0, 4, 4, 2,14, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 0, 4, 0, 2, 2,14,14, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 4, 4, 2, 2, 2, 2, 2,14, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 5,14, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 0, 0, 2, 2, 2, 0, 2,14,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 2, 2, 2,14,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 2, 2, 2,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
- };\r
-\r
-\r
-char far *pbm, far *vbm;\r
-char far *newfnt;\r
-\r
-char far *\r
-AllocatedSprite(int width, int height, int logical_width, char far * bitmap)\r
-{\r
- char far * result;\r
- int size;\r
-\r
- pbm = farmalloc(width * height + 2);\r
- x_bm_to_pbm(bitmap,pbm);\r
-\r
- result = farmalloc((width * height * 7) / 2 + 25);\r
- if (result == 0)\r
- return(0);\r
- size = x_compile_bitmap(logical_width, bitmap, result);\r
-\r
- return farrealloc(result, size);\r
-}\r
-\r
-\r
-\r
-void load_user_fonts(){\r
- FILE *f;\r
- int i; char c;\r
-// f=fopen("c:\\font.fnt","rb");\r
- f=fopen("smalbold.fnt","rb");\r
- newfnt = farmalloc(256*16+4);\r
- for (i=0;i<256*16+4;i++){\r
- fread(&c,1,1,f);\r
- *(newfnt+i)=c;\r
- }\r
- fclose(f);\r
- x_text_init();\r
- x_register_userfont(newfnt);\r
- x_set_font(2);\r
-}\r
-\r
-void\r
-main()\r
-{\r
- int i,j,k;\r
-\r
- double ratio,ratio2;\r
- struct time pbm_t0,pbm_t1,cbm_t0,cbm_t1,vbm_t0,vbm_t1;\r
- long vbm_ticks,pbm_ticks,cbm_ticks;\r
- char far * TurtleSprite;\r
-\r
- x_set_mode(X_MODE_320x240,360);\r
-\r
- TurtleSprite = AllocatedSprite(20, 30, 90,FARPTR(turtle));\r
-\r
- vbm = x_make_vbm(MK_FP(_DS,turtle),&NonVisual_Offs);\r
- if (!vbm) {\r
- sound(1000);\r
- delay(100);\r
- nosound();\r
- }\r
-\r
- load_user_fonts();\r
- x_bgprintf(0,0,0,14,0,\r
- "This is a demo to show the speed difference between");\r
- x_bgprintf(0,8,0,14,0,\r
- "compiled, planar and video bitmaps. The bitmap:");\r
-\r
- x_put_cbitmap(140, 18, 0, TurtleSprite);\r
-\r
- x_bgprintf(0,48,0,14,0,\r
- "This demo uses the NON CLIPPED, MASKED versions of");\r
- x_bgprintf(0,56,0,14,0,\r
- " 'PBM' and VBM' put functions");\r
- x_bgprintf(0,78,0,14,0,\r
- "Press a key to start with PLANAR BITMAP demo");\r
-\r
- getch();\r
- x_rect_fill(0,0,ScrnPhysicalPixelWidth,ScrnPhysicalHeight,0,0);\r
-\r
-\r
- gettime(&pbm_t0);\r
- for (k=0;k<3;k++)\r
- for (j=0;j<(ScrnPhysicalHeight/30);j++)\r
- for (i=0;i<(ScrnPhysicalPixelWidth/20);i++)\r
- x_put_masked_pbm(i*20, j*30, 0, pbm);\r
- gettime(&pbm_t1);\r
- pbm_ticks = (((long)pbm_t1.ti_hund\r
- +((long)pbm_t1.ti_sec*100)\r
- +((long)pbm_t1.ti_min*6000)) -\r
- (((long)pbm_t0.ti_hund\r
- +((long)pbm_t0.ti_sec*100)\r
- +((long)pbm_t0.ti_min*6000))));\r
-\r
-\r
- x_bgprintf(0,0,0,14,0,\r
- "Press a key to start with the VIDEO BITMAP demo");\r
-\r
- getch();\r
- x_rect_fill(0,0,ScrnPhysicalPixelWidth,ScrnPhysicalHeight,0,0);\r
-\r
-\r
- gettime(&vbm_t0);\r
- for (k=0;k<3;k++)\r
- for (j=0;j<(ScrnPhysicalHeight/30);j++)\r
- for (i=0;i<(ScrnPhysicalPixelWidth/20);i++)\r
- x_put_masked_vbm(i*20, j*30, 0, vbm);\r
- gettime(&vbm_t1);\r
- vbm_ticks = (((long)vbm_t1.ti_hund\r
- +((long)vbm_t1.ti_sec*100)\r
- +((long)vbm_t1.ti_min*6000)) -\r
- (((long)vbm_t0.ti_hund\r
- +((long)vbm_t0.ti_sec*100)\r
- +((long)vbm_t0.ti_min*6000))));\r
-\r
-\r
-\r
-\r
- x_bgprintf(0,0,0,14,0,\r
- "Now Press a key to start with COMPILED BITMAP demo");\r
-\r
- getch();\r
- x_rect_fill(0,0,ScrnPhysicalPixelWidth,ScrnPhysicalHeight,0,0);\r
-\r
- gettime(&cbm_t0);\r
- for (k=0;k<3;k++)\r
- for (j=0;j<(ScrnPhysicalHeight/30);j++)\r
- for (i=0;i<(ScrnPhysicalPixelWidth/20);i++)\r
- x_put_cbitmap(i*20, j*30, 0, TurtleSprite);\r
- gettime(&cbm_t1);\r
- cbm_ticks = (((long)cbm_t1.ti_hund\r
- +((long)cbm_t1.ti_sec*100)\r
- +((long)cbm_t1.ti_min*6000)) -\r
- (((long)cbm_t0.ti_hund\r
- +((long)cbm_t0.ti_sec*100)\r
- +((long)cbm_t0.ti_min*6000))));\r
- if (cbm_ticks==0){\r
- cbm_ticks=1;\r
- pbm_ticks+=1;\r
- vbm_ticks+=1;\r
- }\r
- ratio = pbm_ticks*(double)1.0/cbm_ticks;\r
- ratio2 = vbm_ticks*(double)1.0/cbm_ticks;\r
-\r
- x_set_font(1);\r
- x_bgprintf(0,ScrnPhysicalHeight-30,0,14,0,\r
- "s/100 PBM=%ld VBM=%ld CBM=%ld - %4.1lf:%4.1lf:1",\r
- pbm_ticks,vbm_ticks,cbm_ticks,ratio,ratio2);\r
- x_set_font(2);\r
- x_bgprintf(0,ScrnPhysicalHeight-16,0,14,0,\r
- "Timing is rough but still, quite impressive ! ");\r
- x_bgprintf(0,ScrnPhysicalHeight-8,0,14,0,\r
- "Clipping slows things down considerably. ");\r
-\r
-\r
- getch();\r
- x_text_mode();\r
-}\r
-\r
+++ /dev/null
-#include <stdio.h>\r
-#include "xlib.h"\r
-#include "xdetect.h"\r
-int processor;\r
-void main(void){\r
- printf("Hardware detection demo...\n\n");\r
- printf("Graphics Card : ");\r
- switch (x_graphics_card()){\r
- case NoGraphics: printf("None\n"); break;\r
- case MDA: printf("MDA\n"); break;\r
- case CGA: printf("CGA\n"); break;\r
- case EGAMono: printf("EGA Mono\n"); break;\r
- case EGAColor: printf("EGA Color\n"); break;\r
- case VGAMono: printf("VGA Mono\n");\r
- case VGAColor: printf("VGA Color\n"); break;\r
- case MCGAMono: printf("MCGA mono\n"); break;\r
- case MCGAColor: printf("MCGA Color\n"); break;\r
- };\r
- printf("Processor : ");\r
- switch (processor=x_processor()){\r
- case I8086: printf("8088 or 8086\n"); break;\r
- case I80186: printf("80186\n"); break;\r
- case I80286: printf("80286\n"); break;\r
- case I80386SX: printf("80386-SX\n"); break;\r
- case I80386DX: printf("80386-DX\n"); break;\r
- };\r
-\r
- if (processor==I80486){\r
- if (x_coprocessor()) printf("80486-DX or 80486-SX+FPU\n");\r
- else printf("80486-SX\n");\r
- } else {\r
- printf("Math Co-Processor: ");\r
- switch (x_coprocessor()){\r
- case 0: printf("8088 Assumed\n"); break;\r
- case 1: switch (processor=x_processor()){\r
- case I8086: printf("80287 Assumed\n"); break;\r
- case I80186: printf("80187 Assumed\n"); break;\r
- case I80286: printf("0287 Assumed\n"); break;\r
- case I80386SX:\r
- case I80386DX: printf("80387 Assumed\n"); break;\r
- };\r
- };\r
- };\r
- printf("Mouse Driver : ");\r
- switch (x_mousedriver()){\r
- case 0: printf("not installed\n"); break;\r
- case 1: {\r
- printf("installed (Mouse Driver vers %d.%d)\n",\r
- (MouseVersion>>8),(MouseVersion&0xff));\r
- printf(" ");\r
- switch (MouseType) {\r
- case BUS_MOUSE: printf("Bus Mouse on IRQ");break;\r
- case SERIAL_MOUSE: printf("Serial Mouse on IRQ ");break;\r
- case INPORT_MOUSE: printf("Inport Mouse on IRQ ");break;\r
- case PS2_MOUSE: printf("PS/2 Mouse on IRQ ");break;\r
- case HP_MOUSE: printf("HP Mouse on IRQ ");break;\r
- default : printf("Unknown Mouse on IRQ ");break;\r
- }\r
- printf("%d with %d buttons.",MouseIRQ, MouseButtonCount);\r
- }\r
- }\r
- }
\ No newline at end of file
+++ /dev/null
-/*************************************************************************\r
-\r
-DEMO 4\r
-\r
-Demonstrates RLE encoding to file QUICK and DIRTY\r
-**************************************************************************/\r
-\r
-\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <conio.h>\r
-#include <ctype.h>\r
-#include <alloc.h>\r
-#include <dos.h>\r
-#include "xlib.h"\r
-#include "xvbitmap.h"\r
-#include "xbmtools.h"\r
-#include "xtext.h"\r
-#include "xrect.h"\r
-#include "xrletool.h"\r
-#include "xfileio.h"\r
-/* Macro to make pointer parameters model independent */\r
-#define FARPTR(x) (MK_FP(FP_SEG(x),FP_OFF(x)))\r
-\r
-char turtle[] = {\r
- 20,30,\r
-/* | . | . | . | . */\r
- 8,14, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 8, 2,14, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 8, 2, 2, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 8, 0, 2,14, 0, 0,14,14,14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 8, 0, 2, 5, 0, 4, 4, 4, 4,14,14, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 8, 0, 2, 2, 4, 4, 0, 4, 4, 0, 4,14, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 2, 4, 4, 4, 0, 4, 4, 0, 4, 4,14, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 2, 4, 4, 4, 0, 0, 0, 0, 4, 4,14, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 4, 0, 4, 4, 4, 0, 0, 0, 4, 0, 0, 2, 2, 0, 0, 0,\r
- 0, 0, 0, 4, 0, 4, 4, 4, 0, 4, 4, 4, 0,14, 0, 0, 2, 2, 0, 0,\r
- 0, 0, 0, 4, 4, 0, 0, 0, 4, 4, 0, 4, 0, 4, 2, 2, 2, 2, 0, 0,\r
- 0, 0, 0, 4, 4, 4, 0, 4, 4, 0, 4, 4, 0, 4,14, 2, 2, 2, 0, 0,\r
- 0, 0, 0, 4, 4, 4, 0, 0, 0, 4, 4, 0, 4, 0, 0, 2, 2, 0, 0, 0,\r
- 0, 0, 0, 2, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4,14, 2, 0, 0, 0, 0,\r
- 0, 0, 2, 2, 0, 4, 4, 4, 4, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0,\r
- 2, 2, 2, 2, 4, 0, 0, 4, 4, 0, 4, 4, 0, 4,14, 0, 0, 0, 0, 0,\r
- 0, 2, 2, 0, 4, 4, 4, 0, 0, 4, 4, 0, 4, 0, 2, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 4, 4, 0, 4, 4, 4, 0, 4, 4, 2,14, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 0, 4, 0, 2, 2,14,14, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 4, 4, 2, 2, 2, 2, 2,14, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 5,14, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 0, 0, 2, 2, 2, 0, 2,14,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 2, 2, 2,14,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 2, 2, 2,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
- };\r
-\r
-\r
-char far *pbm;\r
-char far *newfnt;\r
-int far *buffsize;\r
-\r
-void error(char * string){\r
- x_text_mode();\r
- printf("%s\n",string);\r
- exit(0);\r
-}\r
-\r
-void load_user_fonts(){\r
- FILE *f;\r
- int i; char c;\r
- f=fopen("var6x8.fnt","rb");\r
- newfnt = farmalloc(256*16+4);\r
- for (i=0;i<256*16+4;i++){\r
- fread(&c,1,1,f);\r
- *(newfnt+i)=c;\r
- }\r
- fclose(f);\r
- x_text_init();\r
- x_register_userfont(newfnt);\r
- x_set_font(2);\r
-}\r
-\r
-void main(){\r
- int i,j,handle,size,comp_size;\r
- char far * tempbuff,far * diskbuff;\r
-\r
- pbm = farmalloc(20 * 30 + 2);\r
- x_bm_to_pbm( MK_FP(FP_SEG(turtle),FP_OFF(turtle)), pbm);\r
-\r
- x_set_mode(X_MODE_360x240,360);\r
- load_user_fonts();\r
-\r
- x_bgprintf(0,0,0,14,0,\r
- "This is a demo of RLE compression of 360x240 video screen to ");\r
- x_bgprintf(0,8,0,14,0,\r
- "disk. Uncompressed, this screen requires a file of size ");\r
- x_bgprintf(0,16,0,14,0,"86400 (360x240) bytes.");\r
- x_bgprintf(0,48,0,14,0,\r
- "Press a key to draw the image and save it to screen:");\r
-\r
- getch();\r
- x_rect_fill(0,0,ScrnPhysicalPixelWidth,ScrnPhysicalHeight,0,0);\r
-\r
- for (j=0;j<(ScrnPhysicalHeight/30);j++)\r
- for (i=0;i<(ScrnPhysicalPixelWidth/20);i++)\r
- x_put_masked_pbm(i*20, j*30, 0, pbm);\r
-\r
- x_set_start_addr(0,240);\r
-\r
- x_bgprintf(0,0,240*90,14,0,\r
- "Now compressing and writing to file 'screen.dat'.");\r
- x_bgprintf(0,8,240*90,14,0,"Please wait... ");\r
-\r
-\r
- if((handle=f_open("screen.dat",F_WRONLY))==FILE_ERR)\r
- error("Unable to open 'screen.dat' for writing.");\r
- size=0;\r
- tempbuff=farmalloc(90*240);\r
- diskbuff=farmalloc(90*240);\r
- buffsize=(int far *)farmalloc(2);\r
-\r
- for (i=0;i<4;i++){\r
- x_select_default_plane(i);\r
- if (!(j=x_buff_RLEncode(MK_FP(0xA000,0),tempbuff,90*240)))\r
- error("Error buff compressing");\r
- *buffsize=j;\r
- f_writefar(handle,(char far *)buffsize,2);\r
- f_writefar(handle,tempbuff,j);\r
- size+=j;\r
- }\r
- comp_size=size;\r
- f_close(handle);\r
-\r
- if((handle=f_open("screen.raw",F_WRONLY))==FILE_ERR)\r
- error("Unable to open 'screen.dat' for writing.");\r
- for (i=0;i<4;i++){\r
- x_select_default_plane(i);\r
- f_writefar(handle,MK_FP(0xA000,0),90*240);\r
- }\r
- f_close(handle);\r
-\r
- x_bgprintf(0,8,240*90,14,0,"Done. Press a key to restore.");\r
- getch();\r
-\r
- x_rect_fill(0,0,ScrnPhysicalPixelWidth,ScrnPhysicalHeight,0,0);\r
- x_set_start_addr(0,0);\r
-\r
- if((handle=f_open("screen.dat",F_RDONLY))==FILE_ERR)\r
- error("Unable to open 'screen.dat' for reading.");\r
-\r
- size=0;\r
- for (i=0;i<4;i++){\r
- x_select_default_plane(i);\r
- f_readfar(handle,(char far *)buffsize,2);\r
- f_readfar(handle,diskbuff,*buffsize);\r
- j=x_buff_RLDecode(diskbuff,MK_FP(0xA000,0));\r
- size+=j;\r
- }\r
- f_close(handle);\r
-\r
- getch();\r
- x_text_mode();\r
- printf("screen size = 86400 compressed = %u",comp_size);\r
-}\r
-\r
-\1a
\ No newline at end of file
+++ /dev/null
-/*************************************************************************\r
-\r
-DEMO 5\r
-\r
-Demonstrates Planar Bitmap Clipping Functions\r
-\r
-Themie Gouthas\r
-**************************************************************************/\r
-\r
-\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <conio.h>\r
-#include <ctype.h>\r
-#include <alloc.h>\r
-#include <dos.h>\r
-#include "xlib.h"\r
-#include "xpbitmap.h"\r
-#include "xpbmclip.h"\r
-#include "xrect.h"\r
-#include "xbmtools.h"\r
-#include "xline.h"\r
-#include "xtext.h"\r
-/* Macro to make pointer parameters model independent */\r
-#define FARPTR(x) (MK_FP(FP_SEG(x),FP_OFF(x)))\r
-\r
-int i,j;\r
-\r
-char turtle[] = {\r
- 20,30,\r
-/* | . | . | . | . */\r
- 8,14, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 8, 2,14, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 8, 2, 2, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 8, 0, 2,14, 0, 0,14,14,14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 8, 0, 2, 5, 0, 4, 4, 4, 4,14,14, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 8, 0, 2, 2, 4, 4, 0, 4, 4, 0, 4,14, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 2, 4, 4, 4, 0, 4, 4, 0, 4, 4,14, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 2, 4, 4, 4, 0, 0, 0, 0, 4, 4,14, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 4, 0, 4, 4, 4, 0, 0, 0, 4, 0, 0, 2, 2, 0, 0, 0,\r
- 0, 0, 0, 4, 0, 4, 4, 4, 0, 4, 4, 4, 0,14, 0, 0, 2, 2, 0, 0,\r
- 0, 0, 0, 4, 4, 0, 0, 0, 4, 4, 0, 4, 0, 4, 2, 2, 2, 2, 0, 0,\r
- 0, 0, 0, 4, 4, 4, 0, 4, 4, 0, 4, 4, 0, 4,14, 2, 2, 2, 0, 0,\r
- 0, 0, 0, 4, 4, 4, 0, 0, 0, 4, 4, 0, 4, 0, 0, 2, 2, 0, 0, 0,\r
- 0, 0, 0, 2, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4,14, 2, 0, 0, 0, 0,\r
- 0, 0, 2, 2, 0, 4, 4, 4, 4, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0,\r
- 2, 2, 2, 2, 4, 0, 0, 4, 4, 0, 4, 4, 0, 4,14, 0, 0, 0, 0, 0,\r
- 0, 2, 2, 0, 4, 4, 4, 0, 0, 4, 4, 0, 4, 0, 2, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 4, 4, 0, 4, 4, 4, 0, 4, 4, 2,14, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 0, 4, 0, 2, 2,14,14, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 4, 4, 2, 2, 2, 2, 2,14, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 5,14, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 0, 0, 2, 2, 2, 0, 2,14,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 2, 2, 2,14,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 2, 2, 2,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
- };\r
-\r
-\r
-char far *vbm;\r
-\r
-void error(char * string){\r
- x_text_mode();\r
- printf("%s\n",string);\r
- exit(0);\r
-}\r
-\r
-typedef struct {\r
- unsigned int size; /* valid only for the first header */\r
- unsigned char ImageWidth;\r
- unsigned char ImageHeight;\r
- unsigned int ImagePtr;\r
- unsigned int MaskPtr;\r
-} alignment_header;\r
-\r
-\r
-void main(){\r
- int i,j,k,handle,size,comp_size;\r
- char far *bm;\r
-\r
- alignment_header far * tempbuff;\r
- x_set_mode(X_MODE_360x240,360);\r
- ;NonVisual_Offs=16384;\r
-\r
- x_text_init();\r
- x_set_font(FONT_8x15);\r
- x_bgprintf(0,0,0,14,0," This is a demo of PBM clipping.");\r
- getch();\r
-\r
- bm=farmalloc(20*30+2);\r
- x_bm_to_pbm(MK_FP(_DS,turtle),bm);\r
-\r
- x_set_cliprect(4,5,50,150);\r
-\r
- x_line(0,TopClip-1,320,TopClip-1,23,0);\r
- x_line(0,BottomClip+1,320,BottomClip+1,23,0);\r
- x_line((LeftClip<<2)-1,0,(LeftClip<<2)-1,200,23,0);\r
- x_line((RightClip<<2)+4,0,(RightClip<<2)+4,200,23,0);\r
-\r
- for (k=0;k<8;k++){\r
- for (j=1;j<ScrnPhysicalHeight;j+=30)\r
- for (i=0;i<ScrnPhysicalPixelWidth-20;i+=20)\r
- x_put_pbm(i+k+1,j,0,bm);\r
- }\r
-\r
- x_line(0,TopClip-1,320,TopClip-1,23,0);\r
- x_line(0,BottomClip+1,320,BottomClip+1,23,0);\r
- x_line((LeftClip<<2)-1,0,(LeftClip<<2)-1,200,23,0);\r
- x_line((RightClip<<2)+4,0,(RightClip<<2)+4,200,23,0);\r
-\r
- x_rect_fill((LeftClip<<2),TopClip,(RightClip<<2)+3,BottomClip,0,0);\r
-\r
- x_bgprintf(0,BottomClip+4,0,14,0," Now the clipping...");\r
- getch();\r
-\r
- for (k=0;k<8;k++){\r
- for (j=1;j<ScrnPhysicalHeight;j+=30)\r
- for (i=0;i<ScrnPhysicalPixelWidth-20;i+=20)\r
- x_put_pbm_clipxy(i+k+1,j,0,bm);\r
- }\r
- for (k=0;k<8;k++){\r
- for (j=1;j<ScrnPhysicalHeight;j+=30)\r
- for (i=0;i<ScrnPhysicalPixelWidth-20;i+=20)\r
- x_put_pbm_clipxy(i+7+1,j+k,0,bm);\r
- }\r
- for (k=7;k>=0;k--){\r
- for (j=1;j<ScrnPhysicalHeight;j+=30)\r
- for (i=0;i<ScrnPhysicalPixelWidth-20;i+=20)\r
- x_put_pbm_clipxy(i+k+1,j+7,0,bm);\r
- }\r
- for (k=7;k>=0;k--){\r
- for (j=1;j<ScrnPhysicalHeight;j+=30)\r
- for (i=0;i<ScrnPhysicalPixelWidth-20;i+=20)\r
- x_put_pbm_clipxy(i+1,j+k,0,bm);\r
- }\r
-\r
- getch();\r
- x_text_mode();\r
- printf("%d %d %d %d\n",LeftClip,TopClip,RightClip,BottomClip);\r
-\r
-}\r
-\r
+++ /dev/null
-#include <conio.h>\r
-\r
-#include "xlib.h"\r
-#include "xcircle.h"\r
-\r
-void main(void)\r
-{\r
- int i;\r
-\r
- x_set_mode(1, 320);\r
- for (i = 0; i < 120; i++) {\r
- x_circle(0, 0, i, 121 - i, 0);\r
- x_circle(319 - i, 0, i, i - 20, 0);\r
- x_circle(0, 239 - i, i, i - 20, 0);\r
- x_circle(319 - i, 239 - i, i, 121 - i, 0);\r
- x_filled_circle(40 + i, i, 241 - (i << 1), i+1, 0);\r
- }\r
- getch();\r
-\r
- x_text_mode();\r
-}\r
-\1a
\ No newline at end of file
+++ /dev/null
-/* Program to demonstrate Bezier curves */\r
-\r
-#include <conio.h>\r
-\r
-#include "xlib.h"\r
-#include "xbezier.h"\r
-#include "xpal.h"\r
-\r
-void main(void)\r
-{\r
- int i, r, g, b;\r
-\r
- x_set_mode(X_MODE_360x480, 360);\r
-\r
- for (b = 0; b < 6; b++)\r
- for (g = 0; g < 6; g++)\r
- for (r = 0; r < 6; r++)\r
- x_set_rgb(b + 6 * g + 36 * r,\r
- 12 * b + 3, 12 * g + 3, 12 * r + 3);\r
- for (i = 216; i < 256; i++)\r
- x_set_rgb(i, i - 193, i - 193, 279 - i);\r
-\r
- for (i = 0; i <= 1080; i++) {\r
- x_bezier(i, 240, 90, i, 270, 479-i, 359 - i, 240,\r
- 6, i ,0);\r
- }\r
- for (i = 720; i >= 0; i--) {\r
- x_bezier(360 - i, i/3, 360 - i, i, i, i, i, i/3,\r
- 4, i ,0);\r
- x_bezier(360 - i, 479-i/3, 360 - i, 479-i, i, 479-i, i, 479-i/3,\r
- 4, i ,0);\r
- }\r
-\r
- getch();\r
-\r
- x_text_mode();\r
-}\r
-\r
+++ /dev/null
-/*************************************************************************\r
-\r
-DEMO 2\r
-\r
-Demonstrates the speed difference between compiled bitmap, conventional\r
-masked planar bitmap, and video bitmap blits.\r
-\r
-**************************************************************************/\r
-\r
-\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <conio.h>\r
-#include <ctype.h>\r
-#include <alloc.h>\r
-#include <dos.h>\r
-#include <dir.h>\r
-#include <string.h>\r
-\r
-#include "xlib.h"\r
-#include "xtext.h"\r
-#include "xrect.h"\r
-\r
-/* Macro to make pointer parameters model independent */\r
-#define FARPTR(x) (MK_FP(FP_SEG(x),FP_OFF(x)))\r
-\r
-char *swidth[10]={"0","1","2","3","4","5","6","7","8","9"};\r
-char far *fonts[20];\r
-char names[20][20];\r
-int i,fcount=0;\r
- char c;\r
-\r
-typedef struct {\r
- int dummy;\r
- char height;\r
- char width;\r
-} header;\r
-\r
-void load_user_fonts(){\r
- FILE *f;\r
- long len;\r
- struct ffblk ffblock;\r
-\r
- if(findfirst("*.fnt",&ffblock,0)!=0){\r
- printf("No Fonts found in current directory!\n");\r
- exit(0);\r
- };\r
- do {\r
- printf("Loading font \"%s\"...\n",ffblock.ff_name);\r
- strncpy(names[fcount],ffblock.ff_name,14);\r
-\r
- f=fopen(ffblock.ff_name,"rb");\r
-\r
- fseek(f,0,SEEK_END);\r
- len=ftell(f);\r
- fseek(f,0,SEEK_SET);\r
-\r
- fonts[fcount] = farmalloc(len);\r
- if (!fonts[fcount]){\r
- printf("Out of memory");\r
- if (fcount!=0){\r
- printf("- No more fonts can be loaded\n");\r
- fclose(f);\r
- goto NoMoreFonts;\r
- } else printf("\n");\r
-\r
- exit(0);\r
- };\r
-\r
- for (i=0;i<len;i++){\r
- fread(&c,1,1,f);\r
- *(fonts[fcount]+i)=c;\r
- }\r
-\r
- fclose(f);\r
- fcount++;\r
-\r
- } while (!findnext(&ffblock));\r
-\r
-NoMoreFonts:\r
- printf("\n Press 'v' to view, any other key to quit\n");\r
- c=getch();\r
- if (c!='V' && c!='v'){\r
- x_text_mode();\r
- exit(0);\r
- }\r
-\r
- x_text_init();\r
- x_set_mode(X_MODE_320x240,0);\r
- x_register_userfont(fonts[0]);\r
- x_set_font(2);\r
-}\r
-\r
- //......................................//\r
-char *text[30] = {"EXTRACT: Stephen King's \"SALEM'S LOT\" ",\r
- "",\r
- "The memory rose up in almost total ",\r
- "sensory reference, and for the moment ",\r
- "of its totality he was paralyzed. He ",\r
- "could even smell the plaster and the ",\r
- "wild odour of nesting animals. It ",\r
- "seemed to him that the plain varnished",\r
- "door of Matt Burke's guest room stood ",\r
- "between him and all the secrets of ",\r
- "Hell. Then he twisted the knob and ",\r
- "pushed the door handle inwards... ",\r
- "",\r
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ ",\r
- "abcdefghijklmnopqrstuvwxyz 0123456789 ",\r
- "~!@#$%^&*()_+|`-=\\{}[]:\";'<>?,./ ",\r
- NULL};\r
-\r
-\r
-\r
-\r
-\r
-void main(){\r
- int textline;\r
- int strindex;\r
- int height;\r
- load_user_fonts();\r
-\r
-\r
-\r
- for (i=0;i<fcount;i++){\r
- x_set_font(FONT_8x8);\r
- x_rect_fill(0, 0, 319, 239, 0, 0);\r
- x_line(0,9,319,9,14,0);\r
- x_line(0,ScrnPhysicalHeight-10,319,ScrnPhysicalHeight-10,14,0);\r
-\r
- x_bgprintf(0,0,0,14,0,"Font \"%s\" H=%d,W=%s",names[i],\r
- (int)*(fonts[i]+2),\r
- (*(fonts[i]+3)==0)?"Variable":swidth[*(fonts[i]+3)]);\r
- x_bgprintf(0,ScrnPhysicalHeight-8,0,14,0,\r
- "Press a key for next font...");\r
-\r
- x_register_userfont(fonts[i]);\r
- x_set_font(FONT_USER);\r
-\r
- height=(int)*(fonts[i]+2)+1;\r
- textline=12;\r
- strindex=0;\r
- while(text[strindex]){\r
- x_printf(0,textline,0,14,text[strindex++]);\r
- textline+=height;\r
- }\r
-\r
- getch();\r
- }\r
-\r
- x_text_mode();\r
-}\r
-\r
+++ /dev/null
-IFDEF s\r
- DISPLAY "XLIB04 Small Model"\r
- .model small\r
-ELSE\r
- IFDEF c\r
- DISPLAY "XLIB04 Compact Model"\r
- .model compact\r
- ELSE\r
- IFDEF l\r
- DISPLAY "XLIB04 Large Model"\r
- .model large\r
- ELSE\r
- DISPLAY "WARNING: Model was not defined at the command line."\r
- DISPLAY " Using default small model ie /ds "\r
- DISPLAY " Include in TASM commandline either /ds, /dc or /dl"\r
- .model small\r
- ENDIF\r
- ENDIF\r
-ENDIF\r
-\r
-\1a
\ No newline at end of file
+++ /dev/null
-This is XLIB the mode X graphics library. There is no organization to the\r
-files in this archive; that is left up to each users preferences.\r
-\r
-Famous last words ;-)\r
-\r
-"This is the last version I intend to release, unless of course someone has\r
-something really nifty they'd like to contribute."\r
-\r
-MOUSE TIP:\r
-\r
-Theres a slight design flaw in the mouse driver and lots of people have had\r
-problems with mouse droppings in the lower RH corner of the screen. This \r
-happens under some circulstances because the code does not clip the saved\r
-background as is done for the cursor graphic itself so bits of the mouse \r
-graphic stored in the video ram just below the visual page get picked up into \r
-the background.\r
-\r
-To bypass this problem is simple when you know how. If you are having this \r
-problem insert NonVisual_Offs+=ScrnLogicalByteWidth*14 just before the call\r
-to x_init_mouse.\r
-\r
-Sorry about not fixing the problem more elegantly, but I didn't want to \r
-do any major work on the mouse driver.\r
-\r
-Themie\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
+++ /dev/null
-Xlib version 2 modifications\r
-\r
-Files modified:\r
- XLIB.INC\r
- XMAIN.ASM\r
- DEMO.C\r
-\r
-\r
-26-09-92 - PRIMARILY JUST ADDED SUPPORT FOR PEL PANNING\r
-\r
- Pel panning code added to allow for panning to any pixel\r
- coordinates.\r
- Functions affected:\r
- x_set_splitscreen\r
- Split screen pel panning suppression code added.\r
- Functionally unchanged.\r
- x_set_start_addr,x_page_flip\r
- Pel panning code added. The x parameter now expects\r
- a pixel coordinate where previously a byte coordinate\r
- was expected.\r
-\r
- Original files modified\r
- -----------------------\r
- XLIB.INC\r
- XMAIN.ASM\r
- DEMO.C\r
- Aknowledgements\r
- ---------------\r
- Thanks to Robert Schmidt for contributed PEL panning sample\r
- code and everyone else who responded to my rec.games.programmer\r
- post.\r
-\r
-Xlib version 3 modifications\r
-\r
-10-10-92 - BUG ERADICATION AND ADDITION OF NEW MODULES AND MINOR CODE\r
- EXTENSIONS\r
-\r
- MaxScrollX and MaxScrollY were not always set correctly, now\r
- that's fixed (I Think)\r
- Added variable "SplitScrnVisibleHeight" needed for above fix.\r
- Some miscellaneous code changes\r
- Included XCBITMAP module generously donated by Matthew MacKenzie\r
- Added support for the LARGE memory model\r
- Added a make file to simplify compilation\r
- Library modules now compiled into .LIB files\r
- Added a documentation file\r
- Added XBMTOOLS module containing bitmap type conversion\r
- Added XDETECT module containing hardware detection functions\r
- Added C header files for all modules\r
- ADDED XFILEIO module\r
- ADDED XRLETOOL module\r
-\r
- Original files modified\r
- -----------------------\r
- XLIB.INC\r
- XMAIN.ASM\r
- DEMO.C\r
- XTEXT.INC\r
- XTEXT.ASM\r
-\r
- Aknowledgements\r
- ---------------\r
- Special thanks to Matthew Mackenzie for an excellent module\r
- and Darren Lyon for putting together a C header file for XLIB.\r
- Again thanks also to everyone else who supported this software.\r
-\r
-Xlib version 4 modifications\r
-\r
-\r
-30-10-92 EXTENSIONS TO XLIB 3 AND BUG FIXES\r
-\r
- Files Modified\r
- --------------\r
- Assume all have been modified\r
-\r
- Modifications/Additions\r
- ------------------------\r
- **** Fixed ATI VGA incompatibility problem **** 4\r
- **** Fixed Large Model problems ***************\r
- Manual : The ref. manual has been split ito two files for\r
- those editors that cannot cope with file > 64k\r
- XDETECT: added numeric co-pro detection\r
- added mouse driver detection\r
- XMAIN : added new resolution tweaks\r
- added clipping rectangle setting proc and vars\r
- further bug fixes (I can't remember exactly what)\r
- XCBITMAP:Improved performance of compilation and compiled bitmaps\r
- and added a function to calculate mem required for\r
- a bitmap compilation\r
- XPBITMAP:Improved performance of planar bitmaps\r
- XRECT :Added "x_shift_rect" function\r
- XPBMTOOL:Added several utility macros\r
-\r
- New Modules\r
- -----------\r
- XPBMCLIP:Implements clipping versions of functions in XPBITMAP\r
- XVBITMAP:Video based masked bitmap functions. Contains standard\r
- and clipping versions of all functions.\r
- XMAKEVBM:Support module for XVBITMAP\r
- XMOUSE :Basic mouse support module\r
- XBEZIER :Fast Bezier curves (For scalable fonts etc..)\r
-\r
-\r
-Xlib version 4b modifications\r
-\r
-10-12-92 BUG FIX RELEASE\r
-\r
- Files Modified\r
- --------------\r
-\r
- XMAIN.*\r
- XPBMCLIP.*\r
- XVBMCLIP.*\r
- XCLIPPBM.*\r
-\r
- Modifications/Additions\r
- ------------------------\r
- Some minor fixes and modifications in xmain.asm\r
- fixed the split screen starting scan line problem\r
-\r
- This fix is a cludge - Sam Thompson has suggested a more\r
- elegant fix but I just dont have much time these days\r
-\r
- changed mode setting code to allow 320x200 mode to have same\r
- aspect ratio as mode 13h\r
-\r
- The clipped functions were modified to return 1 if the image being\r
- clipped was completely off the logical screen.\r
- Minor clipping bugs which gave inconsistent results when clipping\r
- to the left and right screen borders were fixed in the XPBMCLIP &\r
- VBMCLIP modules.\r
- A bug in demo 2 which caused crashing on 486 machines was also\r
- fixed. (The speed of the 486 resulted in 0 time delay which inturn\r
- caused a division by zero error)\r
-\r
-28-12-92 Modified PEL panning code to be smoother on snail paced PC's\r
- Added quick & dirty planar bitmap compiler\r
-\r
-\r
-15-2-93 Converted text module to allow variable width user fonts\r
-\r
- Added a function x_get_char_width in module xtext\r
- Added fonts var6x8.fnt varswisl.fnt varswisb.fnt\r
- Clened up virt screen start address setting code in xmain.asm\r
-\r
- Added demo 8 to preview user defined fonts\r
-\r
- Added x_wait_vsync in module xmain\r
-\r
- Fixed a bug with mode sets on some VGA bios'es that dont\r
- preserve CX on an int 10h\r
-\r
-18-8-93 XLIB05 Final Release\r
- -----------------------------------------------\r
-\r
- GENERAL:\r
- Added C++ compatability in header files\r
- Added new fonts \r
- XDETECT: now can differentiate between 386sx 386dx and 486\r
- (486sx can be verified by absence of FPU)\r
- XMOUSE:\r
- Fixed x_mouse_position bug and general xmouse improvements\r
- Added x_mouse_window function\r
- XFILEIO:\r
- Modified f_read and f_write functions xfileio module\r
- f_read - now reads into near buffer reguardless of model\r
- f_readfar " " " far " " " "\r
- f_write " writes " near " " " "\r
- f_writefar " " " far " " " "\r
- Added f_tell function to get file position. I beleive I\r
- improved the error handling a little but I cant remember\r
- for sure.\r
- XMAIN:\r
- Added 2 new resolutions 256x200 & 256x240.\r
- I dont know why you'd want them but theyre there if you do.\r
- These came from Draeden of VLA (Did you write them Ben ?)\r
- I think they may have originally been posted on R.G.P ???\r
- XRECT:\r
- Added x_rect_fill_clipped & x_rect_pattern_clipped, probably\r
- useless but what the heck!\r
- XPOLYGON:\r
- New function x_triangle - a fast clipped and filled trinagle\r
- function ideal for 3D work.\r
- x_polygon - a clipped and filled polygon function (convex\r
- polygons only). This one's not the fastest - it splits\r
- polygons into component triangles and uses the above\r
- triangle routine to draw them, but still it should\r
- perform fast enough for most 3D applications.\r
- MISCELLANEOUS:\r
- xdiscuss.zip: Included Robert Schmidt's excellent mode X article\r
- for those interested in the hows and why's of Mode X progamming\r
- xlibtl02.zip: Some bitmap conversion code and a TSR bitmap\r
- capture program.\r
-\r
-\r
- Aknowledgements\r
- ---------------\r
- Gerald Dalley - For getting me off my butt and doing\r
- this release.\r
-\r
- Steve Dollins - Never returned my mail asking for\r
- permission to use his code so I\r
- assumed it'd be OK ;)\r
-\r
- Christian Harms - For suggesting xdetect improvements and\r
- promising to make XLIB for T.P. freeware\r
- when its complete. good on ya mate!\r
-\r
- Jason Truong - For spotting the bug in xmouse and\r
- general suggestions for improvements\r
-\r
- Chris Kirby - For suggestion to make .h files C++\r
- compliant\r
-\r
- Robert Scmidt - For his mode X article.\r
-\r
- jeremi@ee.ualberta.ca - Thanks for the xtext suggestions\r
- (name unknown) even if they didnt make this release\r
-\r
- And others whom I may have forgotten.\r
-\r
- Also Greetings to my internet pals,\r
- Mat Mackenzie, Jari Karjala, Draeden, Victor Putz,\r
- Josh Jensen, Chicken and the rest of you dudes...\r
- Thanks for helping my productivity live up to\r
- "Public Servant" standards ;-))\r
-\r
-5-10-93\r
- -----------------------------------------------\r
- XCBITM32:\r
- 32 bit compiled bitmaps, originally developed by Matthew\r
- Mackenzie for our game. NOTE: The compiler is written in C -\r
- conversion to assembler is left as an excersise for the user :-)\r
- \r
- XMOUSE: Finished x_mouse_window this time. I had overlooked\r
- its semi-completed x_mouse_window function in the last release.\r
-\r
- XPBITMAP:\r
- Added x_flip_pbm and x_flip_masked_pbm\r
- Identical to x_put_pbm and x_put_masked_pbm but have an\r
- extra parameter which indicates whether the bitmap is flipped\r
- from left to right as drawn or not - Ideal for saving bitmap\r
- memory.\r
-\r
- XFILL:\r
- Added a new module containing 2 flood fill variants. Both return\r
- the number of pixels filled.\r
-\r
- XVSYNC:\r
- New module to synchronise timer 0 to the vertical retrace. This\r
- allows for smoother animation due to the elimination of\r
- unnecessary vsync waiting.\r
-\r
- XMAIN:\r
- Modifications to allow standard vsync polling or optional\r
- timer0/vsync synchronization and new support for tripple\r
- buffering for super-smooth animation. This stuff's way cool!\r
-\r
- BUGS:\r
- fixed the odd bug here and there - nothing too serious.\r
-\r
-\r
- Aknowledgements:\r
-\r
- Tiaan A Geldenhuys - for pointing out that I forgot to finish\r
- some code in xmouse.asm, for the new cursor shape and stuff.\r
-\r
- Thanks to Tore Jahn Bastiansen (toreba@ifi.uio.no) for the\r
- tripple buffering extensions to XMAIN and the excellent\r
- Timer vsync sunchronization which is the highlight of this\r
- release. This module is a "MUST HAVE" if youre going to do\r
- any animation.\r
-\r
- Also thanks to any others, whom I may have lost track of,\r
- for bug fixes'n stuff.\r
-\r
- Apologies to the person who sent me the pbm flipping code.\r
+++ /dev/null
-\r
-;-----------------------------------------------------------------------\r
-; MODULE XBEZIER\r
-;\r
-;\r
-; Compile with TASM.\r
-; C near-callable.\r
-;\r
-; This module was written by Matthew MacKenzie\r
-; matm@eng.umd.edu\r
-;-----------------------------------------------------------------------\r
-include xlib.inc\r
-include xbezier.inc\r
-\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-; _x_bezier\r
-;\r
-; Plot a Bezier curve, which is described by a box of two endpoints\r
-; and two control points:\r
-; C1--------C2\r
-; / \\r
-; / \\r
-; E1..............E2\r
-;\r
-; All coordinates must be in the range -1024 to 3071.\r
-; No clipping is performed.\r
-;\r
-; C near-callable as:\r
-; x_bezier (int E1x, int E1y, int C1x, int C1y, int C2x, int C2y,\r
-; int E2x, int E2y, int levels, char color,\r
-; unsigned int PageOffset);\r
-;\r
-; All four main registers are totaled.\r
-; This function may use as many as 162 bytes of stack space.\r
-\r
-; Bezier curves need 32-bit precision, so we'll define macros and\r
-; constants for operations on 32-bit virtual registers V0, V1, and V2.\r
-; V0 is made up of DI and AX, V1 of SI and BX, and V2 of CX and DX.\r
-\r
-LowWord equ 0\r
-HighWord equ 2\r
-\r
-; to load data --\r
-\r
-LoadV0 macro loc, field\r
- mov ax, word ptr [bp + loc + field + LowWord]\r
- mov di, word ptr [bp + loc + field + HighWord]\r
- endm\r
-\r
-LoadV1 macro loc, field\r
- mov bx, word ptr [bp + loc + field + LowWord]\r
- mov si, word ptr [bp + loc + field + HighWord]\r
- endm\r
-\r
-LoadV2 macro loc, field\r
- mov dx, word ptr [bp + loc + field + LowWord]\r
- mov cx, word ptr [bp + loc + field + HighWord]\r
- endm\r
-\r
-; to store data --\r
-\r
-StoreV0 macro loc, field\r
- mov word ptr [bp + loc + field + LowWord], ax\r
- mov word ptr [bp + loc + field + HighWord], di\r
- endm\r
-\r
-StoreV1 macro loc, field\r
- mov word ptr [bp + loc + field + LowWord], bx\r
- mov word ptr [bp + loc + field + HighWord], si\r
- endm\r
-\r
-\r
-; to take the average of two registers (result is in first register) --\r
-\r
-AverageV0nV1 macro\r
- add ax, bx\r
- adc di, si\r
- shr di, 1\r
- rcr ax, 1\r
- endm\r
-\r
-AverageV0nV2 macro\r
- add ax, dx\r
- adc di, cx\r
- shr di, 1\r
- rcr ax, 1\r
- endm\r
-\r
-AverageV1nV2 macro\r
- add bx, dx\r
- adc si, cx\r
- shr si, 1\r
- rcr bx, 1\r
- endm\r
-\r
-\r
-; to take the average of a register and data --\r
-\r
-AverageV1nData macro loc, field\r
- add bx, word ptr [bp + loc + field + LowWord]\r
- adc si, word ptr [bp + loc + field + HighWord]\r
- shr si, 1\r
- rcr bx, 1\r
- endm\r
-\r
-AverageV2nData macro loc, field\r
- add dx, word ptr [bp + loc + field + LowWord]\r
- adc cx, word ptr [bp + loc + field + HighWord]\r
- shr cx, 1\r
- rcr dx, 1\r
- endm\r
-\r
-\r
-; to turn a 32-bit fixed point data into a regular integer --\r
-\r
-Extract macro reg, source, field\r
- mov reg, word ptr [bp + source + field + HighWord]\r
- shr reg, 3\r
- adc reg, 0 ; round\r
- endm\r
-\r
-\r
-; to turn an integer argument into a 32-bit fixed point number\r
-; and store it as local data --\r
-\r
-Convert macro source, dest, field\r
- mov ax, source\r
- add ax, 1024\r
- shl ax, 3\r
- push ax\r
- push 0\r
- endm\r
-\r
-\r
-; useful numbers for dealing with Bezier boxes (sets of four points) --\r
-\r
-XCoord equ 4\r
-YCoord equ 0\r
-\r
-; stack offsets for splitting boxes\r
-E1Src equ 48\r
-C1Src equ 40\r
-C2Src equ 32\r
-E2Src equ 24\r
-\r
-E1Dest equ 48\r
-P1Dest equ 40\r
-P4Dest equ 32\r
-P6Dest equ 24\r
-P5Dest equ 16\r
-P2Dest equ 8\r
-E2Dest equ 0\r
-\r
-; stack offsets for drawing boxes\r
-E1Draw equ 24\r
-C1Draw equ 16\r
-C2Draw equ 8\r
-E2Draw equ 0\r
-\r
- .data\r
-\r
- align 2\r
-\r
-; depth of recursion at which to plot\r
-WhenToDraw label byte\r
- db 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4\r
- db 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5\r
-\r
-\r
-; since we'll be moving bp and sp in our recursion,\r
-; we need to put local storage in the data segment\r
-level dw (?)\r
-gencount dw (?)\r
-AdjustedOffs dw (?)\r
-p1xt dw (?)\r
-p1yt dw (?)\r
-p2xt dw (?)\r
-p2yt dw (?)\r
-p4xt dw (?)\r
-p4yt dw (?)\r
-p5xt dw (?)\r
-p5yt dw (?)\r
-c1xt dw (?)\r
-c1yt dw (?)\r
-c2xt dw (?)\r
-c2yt dw (?)\r
-xdiff dw (?)\r
-ydiff dw (?)\r
-moveline dw (?)\r
-stepper dw (?)\r
-bptemp dw (?)\r
-\r
-; by the same token we need a copy of this argument\r
-Colort dw (?)\r
-\r
-\r
-ColumnMasks label byte\r
- db 011h, 022h, 044h, 088h\r
-\r
- .code\r
-\r
- align 2\r
-_x_bezier proc\r
-ARG E1x, E1y, C1x, C1y, C2x, C2y, E2x, E2y, Levels, Color, PageOffs:word\r
-\r
- push bp\r
- mov bp, sp ; caller's stack frame\r
- push si\r
- push di\r
- push es\r
-\r
- ; set local variables\r
- mov ax, -1024 ; 1024 rows\r
- imul [_ScrnLogicalByteWidth]\r
- add ax, PageOffs\r
- sub ax, 256 ; 1024 columns\r
- mov AdjustedOffs, ax ; subtract 1024 rows and 1024 columns\r
-\r
-; copy color into data segment so we can change bp & sp\r
- mov ax, Color\r
- mov Colort, ax\r
-\r
- mov cx, Levels\r
- dec cx ; gencount (number of boxes we will actually plot) =\r
- mov ax,1 ; 2^(Levels - 1)\r
- shl ax,cl\r
- dec ax\r
- mov gencount, ax\r
-\r
- mov [level], 0 ; variable to tell us where we are in the stack\r
- mov bptemp, bp ; when the dust settles at the end\r
-\r
-; translate coordinates for adjusted offset, convert 'em to fixed-point\r
-; with 13 bits for the integer part and 19 for the fractional part,\r
-; and push them onto the stack in the right order to for a Bezier box\r
-\r
- Convert E2x\r
- Convert E2y\r
-\r
- Convert C2x\r
- Convert C2y\r
-\r
- Convert C1x\r
- Convert C1y\r
-\r
- Convert E1x\r
- Convert E1y\r
-\r
- mov bp, sp ; we are using them as basically one pointer\r
-\r
- mov ax, 0a000h ; point extra segment to VGA memory\r
- mov es, ax\r
-\r
- mov dx, SC_INDEX\r
- mov al, MAP_MASK\r
- out dx, al\r
-\r
-MainLoop:\r
- mov si, gencount\r
- mov ax, 0\r
- mov al, WhenToDraw[si]\r
- cmp ax, level ; are we at a terminal curve?\r
- jne Recurse\r
- jmp PlotCurve\r
-\r
-Recurse:\r
-; not at a terminal -- so expand this curve into two more and recurse\r
-\r
-; start with:\r
-; C1___C2\r
-; | |\r
-; E1...E2\r
-;\r
-; stack looks like: E1 C1 C2 E2\r
-\r
-; expand like this:\r
-; C1.....P3.....C2\r
-; . . . .\r
-; . _P4_P6__P5_ .\r
-; P1- .. .. P2\r
-; | .. .. |\r
-; |.. ..|\r
-; E1............E2\r
-;\r
-; stack looks like: E1 P1 P4 P6 P5 P2 E2\r
-; Since P6 is part of both new boxes, we use it twice.\r
-\r
- sub sp, 24\r
- sub bp, 24\r
-\r
-; new points for X --\r
- LoadV0 E1Src, XCoord\r
- LoadV1 E2Src, XCoord\r
- StoreV1 E2Dest, XCoord\r
- LoadV2 C1Src, XCoord\r
- AverageV0nV2\r
- StoreV0 P1Dest, XCoord\r
- AverageV1nData C2Src, XCoord\r
- StoreV1 P2Dest, XCoord\r
- AverageV2nData C2Src, XCoord\r
- AverageV0nV2\r
- StoreV0 P4Dest, XCoord\r
- AverageV1nV2\r
- StoreV1 P5Dest, XCoord\r
- AverageV0nV1\r
- StoreV0 P6Dest, XCoord\r
-\r
-; same thing for Y --\r
- LoadV0 E1Src, YCoord\r
- LoadV1 E2Src, YCoord\r
- StoreV1 E2Dest, YCoord\r
- LoadV2 C1Src, YCoord\r
- AverageV0nV2\r
- StoreV0 P1Dest, YCoord\r
- AverageV1nData C2Src, YCoord\r
- StoreV1 P2Dest, YCoord\r
- AverageV2nData C2Src, YCoord\r
- AverageV0nV2\r
- StoreV0 P4Dest, YCoord\r
- AverageV1nV2\r
- StoreV1 P5Dest, YCoord\r
- AverageV0nV1\r
- StoreV0 P6Dest, YCoord\r
-\r
- inc level ; one level further into stack\r
- jmp MainLoop\r
-\r
-PlotCurve:\r
-; pull 16-bit coordinates back out of 32-bit fixed-point coordinates;\r
-; integer part is highest 13 bits\r
-\r
- Extract cx, C1Draw, XCoord\r
- Extract di, E1Draw, XCoord\r
- mov c1xt, cx\r
- add cx, di\r
- shr cx, 1\r
- mov p1xt, cx\r
-\r
- Extract ax, C1Draw, YCoord\r
- Extract si, E1Draw, YCoord\r
- mov c1yt, ax\r
- add ax, si\r
- shr ax, 1\r
- mov p1yt, ax\r
- call ShortLine ; line from P1 to E1\r
-\r
- Extract cx, E2Draw, XCoord\r
- Extract di, C2Draw, XCoord\r
- mov c2xt, di\r
- add di, cx\r
- shr di, 1\r
- mov p2xt, di\r
-\r
- Extract ax, E2Draw, YCoord\r
- Extract si, C2Draw, YCoord\r
- mov c2yt, si\r
- add si, ax\r
- shr si, 1\r
- mov p2yt, si\r
- call ShortLine ; line from E2 to P2\r
-\r
-; P3 is not in any line we draw, so we'll use it now to find both P5\r
-; for the line after this on, and P4 for this line, then discard it --\r
- mov bx, c1xt\r
- add bx, c2xt\r
- shr bx, 1\r
- mov dx, c1yt\r
- add dx, c2yt\r
- shr dx, 1\r
-\r
-; find P5 x and save for later lines\r
- mov cx, p2xt\r
- add cx, bx\r
- shr cx, 1\r
- mov p5xt, cx\r
-; find P4 x for this line\r
- mov cx, p1xt\r
- add cx, bx\r
- shr cx, 1\r
- mov p4xt, cx\r
- mov di, p1xt\r
-\r
-; find P5 y and save for later lines\r
- mov ax, p2yt\r
- add ax, dx\r
- shr ax, 1\r
- mov p5yt, ax\r
-; find P4 y for this line\r
- mov ax, p1yt\r
- add ax, dx\r
- shr ax, 1\r
- mov p4yt, ax\r
- mov si, p1yt\r
- call ShortLine ; line from P4 to P1 -- finally!\r
-\r
-; we've already done all the work for these last two --\r
- mov cx, p2xt\r
- mov di, p5xt\r
- mov ax, p2yt\r
- mov si, p5yt\r
- call ShortLine ; line from P2 to P5\r
-\r
- mov cx, p5xt\r
- mov di, p4xt\r
- mov ax, p5yt\r
- mov si, p4yt\r
- call ShortLine ; line from P5 to P4\r
-\r
-; we've drawn our five lines; this bezier box\r
-; can be dropped off the stack\r
- add bp, 24\r
- add sp, 24\r
-\r
- dec gencount\r
- mov cx, gencount\r
- cmp cx, -1\r
-\r
- je WrapUp ; if we've generated all the terminal nodes we\r
- ; are supposed to, we pack our bags and go.\r
- dec level\r
- jmp MainLoop\r
-\r
-WrapUp:\r
-; plot the final point, which is simply the original E1\r
-\r
- mov bp, bptemp ; back where we started\r
- mov ax, E1y\r
- add ax, 1024\r
- mul [_ScrnLogicalByteWidth]\r
- mov di, E1x\r
- add di, 1024\r
- mov si, di\r
- shr di, 2\r
- add di, ax\r
- add di, AdjustedOffs\r
- and si, 3\r
- mov al, ColumnMasks[si]\r
- mov ah, byte ptr Color\r
- mov dx, SC_INDEX + 1\r
- out dx, al\r
- mov es:[di], ah\r
-\r
- pop es\r
- pop di\r
- pop si\r
- mov sp, bp\r
- pop bp\r
- ret ; git\r
-\r
-; ShortLine subfunction --\r
-;\r
-; This is designed for short line segments. For longer lines,\r
-; especially horizontal ones, the x_line routine in the XLINE module\r
-; would be faster. But calling that from here it would be a lot of\r
-; extra complication. This is part of the x_bezier routine because\r
-; it has no particular outside use, and we can call it much faster\r
-; through registers than through the stack.\r
-;\r
-; Since our line segments overlap, the second endpoint is not drawn.\r
-; These routines are all out of order for the sake of conditional jumps.\r
-\r
-LRHorz:\r
- dec di\r
-LRHorzLoop:\r
- rol al, 1\r
- adc bx, 0\r
- out dx, al\r
- mov es:[bx], ah\r
- sub di, 1\r
- jg LRHorzLoop\r
- retn\r
-\r
-; You are in a maze of little subroutines, all alike...\r
-\r
-\r
-LR45Deg:\r
- dec si\r
-LR45DegLoop:\r
- add bx, cx\r
- rol al, 1\r
- adc bx, 0\r
- out dx, al\r
- mov es:[bx], ah\r
- sub si, 1\r
- jg LR45DegLoop\r
- retn\r
-\r
-\r
-LRXMajor:\r
- mov cx, di\r
- dec cx\r
- shr di, 1\r
-LRXMajorLoop:\r
- sub di, si\r
- jge LRXMajorIterate\r
- add di, xdiff\r
- add bx, moveline\r
-LRXMajorIterate:\r
- rol al, 1\r
- adc bx, 0\r
- out dx, al\r
- mov es:[bx], ah\r
- sub cx, 1\r
- jg LRXMajorLoop\r
- retn\r
-\r
-\r
-LeftToRight:\r
- mov xdiff, di ; store distance across line\r
-\r
- mov cx, [_ScrnLogicalByteWidth]\r
- cmp si, 0 ; check if height is positive, negative, or zero\r
- je LRHorz\r
- jg LRTopToBottom\r
- neg si\r
- neg cx\r
-LRTopToBottom:\r
- mov ydiff, si\r
- mov moveline, cx\r
- cmp di, si\r
- jg LRXMajor\r
- je LR45Deg\r
-\r
-\r
-LRYMajor:\r
- mov cx, si\r
- dec cx\r
- shr si, 1\r
-LRYMajorLoop:\r
- add bx, moveline\r
- sub si, di\r
- jge LRYMajorIterate\r
- add si, ydiff\r
- rol al, 1\r
- adc bx, 0\r
-LRYMajorIterate:\r
- out dx, al\r
- mov es:[bx], ah\r
- sub cx, 1\r
- jg LRYMajorLoop\r
- retn\r
-\r
-\r
-; This is the actual starting point.\r
-; On entry, registers look like this:\r
-; X1: cx\r
-; Y1: ax\r
-; X2: di\r
-; Y2: si\r
-ShortLine:\r
- sub si, ax ; height goes out in si\r
- sub di, cx ; width goes out in di\r
-\r
- mul [_ScrnLogicalByteWidth]\r
- mov dx, cx\r
- shr dx, 2\r
- add ax, dx\r
- add ax, AdjustedOffs\r
- mov bx, ax ; starting byte of X1, Y1 goes out in bx\r
- and cx, 3\r
- mov ax, 011h\r
- shl al, cl ; column mask goes out in al\r
- mov dx, SC_INDEX + 1\r
- mov ah, byte ptr Colort; color goes out in ah\r
- out dx, al\r
- mov es:[bx], ah ; plot first point\r
-\r
- cmp di, 0\r
-\r
- jg LeftToRight\r
- je VerticalLine\r
-\r
-\r
-RightToLeft:\r
- neg di ; much more useful this way\r
- mov xdiff, di\r
-\r
- mov cx, [_ScrnLogicalByteWidth]\r
- cmp si, 0 ; check if height is positive, negative, or zero\r
- je RLHorz\r
- jg RLTopToBottom\r
- neg si\r
- neg cx\r
-RLTopToBottom:\r
- mov ydiff, si\r
- mov moveline, cx\r
- cmp di, si\r
- jg RLXMajor\r
- je RL45Deg\r
-\r
-\r
-RLYMajor:\r
- mov cx, si\r
- dec cx\r
- shr si, 1\r
-RLYMajorLoop:\r
- add bx, moveline\r
- sub si, di\r
- jge RLYMajorIterate\r
- add si, ydiff\r
- ror al, 1\r
- sbb bx, 0\r
-RLYMajorIterate:\r
- out dx, al\r
- mov es:[bx], ah\r
- sub cx, 1\r
- jg RLYMajorLoop\r
- retn\r
-\r
-\r
-VerticalLine:\r
- mov cx, [_ScrnLogicalByteWidth]\r
- cmp si, 0 ; check if height is positive\r
- jg VTopToBottom\r
- neg si\r
- neg cx\r
-VTopToBottom:\r
- dec si\r
-VLoop:\r
- add bx, cx\r
- mov es:[bx], ah\r
- sub si, 1\r
- jg VLoop\r
- retn\r
-\r
-\r
-RLHorz:\r
- dec di\r
-RLHorzLoop:\r
- ror al, 1\r
- sbb bx, 0\r
- out dx, al\r
- mov es:[bx], ah\r
- sub di, 1\r
- jg RLHorzLoop\r
- retn\r
-\r
-\r
-RL45Deg:\r
- dec si\r
-RL45DegLoop:\r
- add bx, cx\r
- ror al, 1\r
- sbb bx, 0\r
- out dx, al\r
- mov es:[bx], ah\r
- sub si, 1\r
- jg RL45DegLoop\r
- retn\r
-\r
-\r
-RLXMajor:\r
- mov cx, di\r
- dec cx\r
- shr di, 1\r
-RLXMajorLoop:\r
- sub di, si\r
- jge RLXMajorIterate\r
- add di, xdiff\r
- add bx, moveline\r
-RLXMajorIterate:\r
- ror al, 1\r
- sbb bx, 0\r
- out dx, al\r
- mov es:[bx], ah\r
- sub cx,1\r
- jg RLXMajorLoop\r
- retn\r
-\r
-\r
-_x_bezier endp\r
-\r
- end\r
-\r
+++ /dev/null
-/*********************************************************************\\r
-| XBEZIER header file\r
-|\r
-|\r
-| This module was written by Matthew MacKenzie\r
-| matm@eng.umd.edu\r
-\*********************************************************************/\r
-\r
-#ifndef _XBEZIER_H_\r
-#define _XBEZIER_H_\r
-#ifdef __cplusplus\r
-\r
-extern "C" {\r
-#endif\r
-\r
-void x_bezier (int E1x, int E1y, int C1x, int C1y, int C2x, int C2y,\r
- int E2x, int E2y, int levels, char color,\r
- unsigned PageOffset);\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; XBEZIER include file\r
-;\r
-;\r
-; This module was written by Matthew MacKenzie\r
-; matm@eng.umd.edu\r
-;-----------------------------------------------------------------------\r
-\r
-global _x_bezier : proc\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XBMTOOLS\r
-;\r
-; Bitmap conversion / manipulation tools\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-COMMENT $\r
-\r
- This module implements a set of functions to manipulate both planar\r
- bitmaps and linear bitmaps (as used by x_compile_bitmap):\r
-\r
- PLANAR BITMAPS\r
-\r
- Planar bitmaps as used by these functions have the following structure:\r
-\r
- BYTE 0 The bitmap width in bytes (4 pixel groups) range 1..255\r
- BYTE 1 The bitmap height in rows range 1..255\r
- BYTE 2..n1 The plane 0 pixels width*height bytes\r
- BYTE n1..n2 The plane 1 pixels width*height bytes\r
- BYTE n2..n3 The plane 2 pixels width*height bytes\r
- BYTE n3..n4 The plane 3 pixels width*height bytes\r
-\r
- LINEAR BITMAPS\r
-\r
- Linear bitmaps have the following structure:\r
-\r
- BYTE 0 The bitmap width in pixels range 1..255\r
- BYTE 1 The bitmap height in rows range 1..255\r
- BYTE 2..n The width*height bytes of the bitmap\r
-\r
-\r
-\r
-$\r
-\r
-LOCALS\r
-.286\r
-\r
-include model.inc\r
-include xbmtools.inc\r
-\r
- .code\r
-\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; x_pbm_to_bm\r
-;\r
-; This function converts a bitmap in the planar format to the linear format\r
-; as used by x_compile_bitmap.\r
-;\r
-; WARNING: the source and destination bitmaps must be pre - allocated\r
-;\r
-; NOTE: This function can only convert planar bitmaps that are suitable.\r
-; If the source planar bitmap's width (per plane) is >= 256/4\r
-; it cannot be converted. In this situation an error code\r
-; BM_WIDTH_ERROR. On successful conversion 0 is returned.\r
-;\r
-; C callable as:\r
-; int x_pbm_to_bm(char far * source_pbm, char far * dest_bm);\r
-;\r
-; Written By Themie Gouthas\r
-\r
-proc _x_pbm_to_bm\r
-ARG src_pbm:dword,dest_bm:dword\r
- push bp ; Preserve caller's stack frame\r
- mov bp,sp\r
- push ds\r
- push di\r
- push si\r
-\r
- les di,[dest_bm] ; es:di -> destination bitmap\r
- lds si,[src_pbm] ; ds:si -> source planar bitmap\r
- lodsb ; load AL with source pbm pixel width per plane\r
- mov bl,al ; save in CL\r
- xor ah,ah ; convert to word\r
- shl ax,2 ; mult by 4 giving source image width\r
- cmp ax,255 ; if the result > 255 then we have exceeded\r
- ja @@WidthError ; the max width of linear bm.\r
-\r
- stosb ; write do dest_bm\r
-\r
- lodsb ; tranfer source pbm height in pixels to\r
- stosb ; dest_bm\r
-\r
- xor ah,ah ; convert to word\r
- mul bl ; AX = AX * BL ie. total no. pixels per plane\r
- mov dx,di ; save DI, the pointer to the destination bm\r
- mov bl,3 ; set plane loop counter (BL)\r
-\r
-@@PlaneLoop:\r
- mov cx,ax ; set CX to total number of pixels per plane\r
-\r
-@@PixelLoop:\r
- movsb ; transfer pixel\r
- add di,3 ; increment destination to compensate for plane\r
- loop @@PixelLoop\r
-\r
- inc dx ; increment original di for next pixel plane\r
- mov di,dx ; and restore di from incremented original\r
- dec bl ; decrement plane counter\r
- jns @@PlaneLoop ; loop if more planes left\r
- xor ax,ax\r
- jmp short @@Done\r
-@@WidthError:\r
- mov ax,1\r
-\r
-@@Done:\r
- pop si\r
- pop di\r
- pop ds\r
- pop bp ;restore caller's stack frame\r
- ret\r
-_x_pbm_to_bm endp\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; x_bm_to_pbm\r
-;\r
-; This function converts a bitmap in the linear format as used by\r
-; x_compile_bitmap to the planar formap.\r
-;\r
-; WARNING: the source and destination bitmaps must be pre - allocated\r
-;\r
-; NOTE: This function can only convert linear bitmaps that are suitable.\r
-; If the source linear bitmap's width is not a multiple of 4\r
-; it cannot be converted. In this situation an error code\r
-; BM_WIDTH_ERROR. On successful conversion 0 is returned.\r
-;\r
-;\r
-; C callable as:\r
-; int x_bm_to_pbm(char far * source_pbm, char far * dest_bm);\r
-;\r
-; Written By Themie Gouthas\r
-\r
-proc _x_bm_to_pbm\r
-ARG src_bm:dword,dest_pbm:dword\r
- push bp ; Preserve caller's stack frame\r
- mov bp,sp\r
- push ds\r
- push di\r
- push si\r
-\r
- les di,[dest_pbm] ; es:di -> destination planar bitmap\r
- lds si,[src_bm] ; ds:si -> source bitmap\r
- lodsb ; load AX with source bitmap width\r
- test al,03h ; Check that width is a multiple of 4\r
- jnz @@WidthIncompatible\r
- shr al,2 ; divide by 4 giving width of plane\r
- stosb ; store destination planar bitmap width\r
- mov bl,al ; and copy to bl\r
- lodsb\r
- stosb ; Transfer source bitmap height to dest pbm\r
- xor ah,ah ; Conver height to word\r
- mul bl ; calculate the total no. of pixels / plane\r
- mov dx,si ; save source offset\r
- mov bl,3\r
-\r
-@@PlaneLoop:\r
- mov cx,ax ; set CX to total number of pixels per plane\r
-\r
-@@PixelLoop:\r
- movsb ; transfer pixel\r
- add si,3 ; increment src offset to compensate for plane\r
- loop @@PixelLoop\r
-\r
- inc dx ; increment original si for next pixel plane\r
- mov si,dx ; and restore si from incremented original\r
- dec bl ; decrement plane counter\r
- jns @@PlaneLoop ; loop if more planes left\r
- xor ax,ax\r
- jmp short @@Done\r
-@@WidthIncompatible:\r
- mov ax,1\r
-\r
-@@Done:\r
- pop si\r
- pop di\r
- pop ds\r
- pop bp ;restore caller's stack frame\r
- ret\r
-_x_bm_to_pbm endp\r
-\r
-\r
- end\r
-\r
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XPOINT - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; Macros written by Mathew Mackenzie\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;-----------------------------------------------------------------------*/\r
-\r
-#ifndef _XBMTOOLS_H_\r
-#define _XBMTOOLS_H_\r
-\r
-#define BM_WIDTH_ERROR 1\r
-\r
-#define LBMHeight(lbitmap) lbitmap[1]\r
-#define LBMWidth(lbitmap) lbitmap[0]\r
-#define PBMHeight(pbitmap) pbitmap[1]\r
-#define PBMWidth(pbitmap) (pbitmap[0]<<2)\r
-#define PBMByteWidth(pbitmap) pbitmap[0]\r
-\r
-#define LBMPutPix(x,y,lbitmap,color) \\r
- lbitmap[2 + (x) + (y) * LBMWidth(lbitmap)] = color\r
-\r
-#define LBMGetPix(x,y,lbitmap) \\r
- (lbitmap[2 + (x) + (y) * LBMWidth(lbitmap)])\r
-\r
-\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
- int x_pbm_to_bm( /* Convert from planar bitmap to linear */\r
- char far * source_pbm,\r
- char far * dest_bm);\r
-\r
- int x_bm_to_pbm( /* Convert from linear bitmap to planar */\r
- char far * source_pbm,\r
- char far * dest_bm);\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-\r
-#endif\r
-\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XBMTOOLS - Include file\r
-;\r
-; XBMTOOLS.ASM export functions\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
- global _x_pbm_to_bm :proc\r
- global _x_bm_to_pbm :proc\r
-\1a
\ No newline at end of file
+++ /dev/null
-#include "xbmtools.h"\r
-\r
-/* these are here instead of the header file because they're not part\r
- of the library interface */\r
-\r
-// rol al\r
-#define ROL_AL 0xc0d0\r
-// mov [si + disp8], imm8\r
-#define SHORT_STORE_8 0x44c6\r
-// mov [si + disp16], imm8\r
-#define STORE_8 0x84c6\r
-// mov [si + disp8], imm16\r
-#define SHORT_STORE_16 0x44c7\r
-// mov [si + disp16], imm16\r
-#define STORE_16 0x84c7\r
-// adc si, imm8\r
-#define ADC_SI_IMMED 0xd683\r
-// out dx, al\r
-#define OUT_AL 0xee\r
-// ret\r
-#define RETURN 0xcb\r
-// 32-bit prefix\r
-#define DWORD_PREFIX 0x66\r
-\r
-#define Emitb(x) *(output + output_used) = (x); output_used++\r
-\r
-#define Emitw(x) *(output + output_used) = (x) & 255; \\r
- *(output + output_used + 1) = (x) >> 8; \\r
- output_used += 2\r
-\r
-\r
-int x_compile_bitmap_32 (int logical_screen_width, char far * bitmap,\r
- char far * output)\r
-{\r
- int pix0, pix1, pix2, pix3, numpix, pos;\r
- int column = 0, set_column = 0;\r
- int scanx = 0, scany = 0;\r
- int output_used = 0;\r
-\r
- int height = LBMHeight(bitmap);\r
- int width = LBMWidth(bitmap);\r
- int margin = width - 1;\r
- int margin2 = margin - 4;\r
- int margin4 = margin - 12;\r
-\r
- while (column < 4) {\r
- numpix = 1;\r
- pix0 = LBMGetPix(scanx, scany, bitmap);\r
- if (pix0 != 0) {\r
- if (set_column != column) {\r
- do {\r
- Emitw (ROL_AL);\r
- Emitw (ADC_SI_IMMED);\r
- Emitb (0);\r
- set_column++;\r
- } while (set_column != column);\r
- Emitb (OUT_AL);\r
- }\r
- if (scanx <= margin2) {\r
- pix1 = LBMGetPix(scanx + 4, scany, bitmap);\r
- if ((pix1 != 0)\r
- &&(scanx <= margin4)) {\r
- numpix = 2;\r
- pix2 = LBMGetPix(scanx + 8, scany, bitmap);\r
- pix3 = LBMGetPix(scanx + 12, scany, bitmap);\r
- if ((pix2 != 0) && (pix3 != 0)) {\r
- numpix = 4;\r
- Emitb (DWORD_PREFIX);\r
- }\r
- }\r
- }\r
- pos = (scany * logical_screen_width) + (scanx >> 2) - 128;\r
- if ((pos >= -128) && (pos <= 127)) {\r
- if (numpix == 1) {\r
- Emitw (SHORT_STORE_8);\r
- Emitb (pos);\r
- Emitb (pix0);\r
- } else {\r
- Emitw (SHORT_STORE_16);\r
- Emitb (pos);\r
- Emitb (pix0);\r
- Emitb (pix1);\r
- if (numpix == 4) {\r
- Emitb (pix2);\r
- Emitb (pix3);\r
- }\r
- }\r
- } else {\r
- if (numpix == 1) {\r
- Emitw (STORE_8);\r
- Emitw (pos);\r
- Emitb (pix0);\r
- } else {\r
- Emitw (STORE_16);\r
- Emitw (pos);\r
- Emitb (pix0);\r
- Emitb (pix1);\r
- if (numpix == 4) {\r
- Emitb (pix2);\r
- Emitb (pix3);\r
- }\r
- }\r
- }\r
- }\r
- scanx += (numpix << 2);\r
- if (scanx > margin) {\r
- scanx = column;\r
- scany++;\r
- if (scany == height) {\r
- scany = 0;\r
- column++;\r
- }\r
- }\r
- }\r
- Emitb(RETURN);\r
- return(output_used);\r
-}\r
-\r
-\r
-int x_sizeof_cbitmap_32 (int logical_screen_width, char far * bitmap)\r
-{\r
- int pix0, pix1, pix2, pix3, numpix, pos;\r
- int column = 0, set_column = 0;\r
- int scanx = 0, scany = 0;\r
- int output_used = 1;\r
-\r
- int height = LBMHeight(bitmap);\r
- int width = LBMWidth(bitmap);\r
- int margin = width - 1;\r
- int margin2 = margin - 4;\r
- int margin4 = margin - 12;\r
-\r
- while (column < 4) {\r
- numpix = 1;\r
- pix0 = LBMGetPix(scanx, scany, bitmap);\r
- if (pix0 != 0) {\r
- if (set_column != column) {\r
- do {\r
- output_used += 5;\r
- set_column++;\r
- } while (set_column != column);\r
- output_used++;\r
- }\r
- if (scanx <= margin2) {\r
- pix1 = LBMGetPix(scanx + 4, scany, bitmap);\r
- if ((pix1 != 0)\r
- &&(scanx <= margin4)) {\r
- numpix = 2;\r
- pix2 = LBMGetPix(scanx + 8, scany, bitmap);\r
- pix3 = LBMGetPix(scanx + 12, scany, bitmap);\r
- if ((pix2 != 0) && (pix3 != 0)) {\r
- numpix = 4;\r
- output_used++;\r
- }\r
- }\r
- }\r
- pos = (scany * logical_screen_width) + (scanx >> 2) - 128;\r
- if ((pos >= -128) && (pos <= 127)) {\r
- if (numpix == 1) {\r
- output_used += 4;\r
- } else {\r
- output_used += 5;\r
- if (numpix == 4)\r
- output_used += 2;\r
- }\r
- } else {\r
- if (numpix == 1) {\r
- output_used += 5;\r
- } else {\r
- output_used += 6;\r
- if (numpix == 4)\r
- output_used += 2;\r
- }\r
- }\r
- }\r
- scanx += (numpix << 2);\r
- if (scanx > margin) {\r
- scanx = column;\r
- scany++;\r
- if (scany == height) {\r
- scany = 0;\r
- column++;\r
- }\r
- }\r
- }\r
- return(output_used);\r
-}\r
-\r
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XCBITM32 - header file\r
-;\r
-; This module was written by Matthew MacKenzie\r
-; matm@eng.umd.edu\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-;----------------------------------------------------------------------*/\r
-/* Notice that there is no function in this module to plot a\r
- compiled bitmap. Use x_put_cbitmap in module XCBITMAP. */\r
-\r
-/* This module is only for 386+ class computers. */\r
-\r
-#ifndef _XCBITM32_H_\r
-#define _XCBITM32_H_\r
-\r
-extern int x_compile_bitmap_32 ( /* Compile a linear bitmap to generate */\r
- WORD logical_screen_width, /* machine code to plot it at any */\r
- char far * bitmap, /* required screen coordinates FAST. */\r
- char far * output);\r
-\r
-extern int x_sizeof_cbitmap_32 ( /* Find the size of the code which a */\r
- WORD logical_screen_width, /* bitmap would result in, if it */\r
- char far * bitmap); /* were compiled (used for allocation). */\r
-\r
-#endif\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XCBITMAP\r
-; This module was written by Matthew MacKenzie\r
-; matm@eng.umd.edu\r
-;\r
-; Compiled bitmap functions all MODE X 256 Color resolutions\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-; ****** Aeronautical Research Laboratory ****************\r
-; ****** Defence Science and Technology Organisation ****************\r
-; ****** Australia ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-include xlib.inc\r
-include xcbitmap.inc\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-; _x_compile_bitmap\r
-;\r
-; Compile a linear bitmap to generate machine code to plot it\r
-; at any required screen coordinates FAST. Faster than blits\r
-; using planar bitmaps as in module XPBIITMAP\r
-;\r
-; C near-callable as:\r
-; int x_compile_bitmap (WORD logical_screen_width,\r
-; char far * bitmap, char far * output);\r
-;\r
-; The logical width is in bytes rather than pixels.\r
-;\r
-; All four main registers are totaled.\r
-;\r
-; The source linear bitmaps have the following structure:\r
-;\r
-; BYTE 0 The bitmap width in pixels range 1..255\r
-; BYTE 1 The bitmap height in rows range 1..255\r
-; BYTE 2..n The width*height bytes of the bitmap in\r
-; cloumn row order\r
-;\r
-; The returned value is the size of the compiled bitmap, in bytes.\r
-\r
-\r
-; accessory macros to save typing (what else?)\r
-Emitb macro arg\r
- mov byte ptr es:[di],&arg&\r
- inc di\r
- endm\r
-\r
-Emitw macro arg\r
- mov word ptr es:[di],&arg&\r
- add di,2\r
- endm\r
-\r
-; opcodes emitted by _x_compile_sprite\r
-ROL_AL equ 0c0d0h ; rol al\r
-SHORT_STORE_8 equ 044c6h ; mov [si]+disp8, imm8\r
-STORE_8 equ 084c6h ; mov [si]+disp16, imm8\r
-SHORT_STORE_16 equ 044c7h ; mov [si]+disp8, imm16\r
-STORE_16 equ 084c7h ; mov [si]+disp16, imm16\r
-ADC_SI_IMMED equ 0d683h ; adc si,imm8\r
-OUT_AL equ 0eeh ; out dx,al\r
-RETURN equ 0cbh ; ret\r
-\r
-\r
-.data\r
-\r
-align 2\r
-ColumnMask db 011h,022h,044h,088h\r
-\r
-\r
-.code\r
-\r
- align 2\r
-_x_compile_bitmap proc\r
-ARG logical_width:word,bitmap:dword,output:dword\r
-LOCAL bwidth,scanx,scany,outputx,outputy,column,set_column,input_size:word=LocalStk\r
- push bp\r
- mov bp, sp ; caller's stack frame\r
- sub sp,LocalStk ; local space\r
- push si\r
- push di\r
- push ds\r
-\r
- mov word ptr [scanx],0\r
- mov word ptr [scany],0\r
- mov word ptr [outputx],0\r
- mov word ptr [outputy],0\r
- mov word ptr [column],0\r
- mov word ptr [set_column],0\r
-\r
- lds si,[bitmap] ; 32-bit pointer to source bitmap\r
-\r
- les di,[output] ; 32-bit pointer to destination stream\r
-\r
- lodsb ; load width byte\r
- xor ah, ah ; convert to word\r
- mov [bwidth], ax ; save for future reference\r
- mov bl, al ; copy width byte to bl\r
- lodsb ; load height byte -- already a word since ah=0\r
- mul bl ; mult height word by width byte\r
- mov [input_size], ax; to get pixel total \r
-\r
-@@MainLoop:\r
- mov bx, [scanx] ; position in original bitmap\r
- add bx, [scany]\r
-\r
- mov al, [si+bx] ; get pixel\r
- or al, al ; skip empty pixels\r
- jnz @@NoAdvance\r
- jmp @@Advance\r
-@@NoAdvance:\r
-\r
- mov dx, [set_column]\r
- cmp dx, [column]\r
- je @@SameColumn\r
-@@ColumnLoop:\r
- Emitw ROL_AL ; emit code to move to new column\r
- Emitw ADC_SI_IMMED\r
- Emitb 0\r
-\r
- inc dx\r
- cmp dx, [column]\r
- jl @@ColumnLoop\r
-\r
- Emitb OUT_AL ; emit code to set VGA mask for new column\r
- mov [set_column], dx\r
-@@SameColumn:\r
- mov dx, [outputy] ; calculate output position\r
- add dx, [outputx]\r
- sub dx, 128\r
-\r
- add word ptr [scanx], 4\r
- mov cx, [scanx] ; within four pixels of right edge?\r
- cmp cx, [bwidth]\r
- jge @@OnePixel\r
-\r
- inc word ptr [outputx]\r
- mov ah, [si+bx+4] ; get second pixel\r
- or ah, ah\r
- jnz @@TwoPixels\r
-@@OnePixel:\r
- cmp dx, 127 ; can we use shorter form?\r
- jg @@OnePixLarge\r
- cmp dx, -128\r
- jl @@OnePixLarge\r
- Emitw SHORT_STORE_8\r
- Emitb dl ; 8-bit position in output\r
- jmp @@EmitOnePixel\r
-@@OnePixLarge:\r
- Emitw STORE_8\r
- Emitw dx ; position in output\r
-@@EmitOnePixel:\r
- Emitb al\r
- jmp short @@Advance\r
-@@TwoPixels:\r
- cmp dx, 127\r
- jg @@TwoPixLarge\r
- cmp dx, -128\r
- jl @@TwoPixLarge\r
- Emitw SHORT_STORE_16\r
- Emitb dl ; 8-bit position in output\r
- jmp @@EmitTwoPixels\r
-@@TwoPixLarge:\r
- Emitw STORE_16\r
- Emitw dx ; position in output\r
-@@EmitTwoPixels:\r
- Emitw ax\r
-\r
-@@Advance:\r
- inc word ptr [outputx]\r
- mov ax, [scanx]\r
- add ax, 4\r
- cmp ax, [bwidth]\r
- jl @@AdvanceDone\r
- mov dx, [outputy]\r
- add dx, [logical_width]\r
- mov cx, [scany]\r
- add cx, [bwidth]\r
- cmp cx, [input_size]\r
- jl @@NoNewColumn\r
- inc word ptr [column]\r
- mov cx, [column]\r
- cmp cx, 4\r
- je @@Exit ; Column 4: there is no column 4.\r
- xor cx, cx ; scany and outputy are 0 again for\r
- mov dx, cx ; the new column\r
-@@NoNewColumn:\r
- mov [outputy], dx\r
- mov [scany], cx\r
- mov word ptr [outputx], 0\r
- mov ax,[column]\r
-@@AdvanceDone:\r
- mov [scanx], ax\r
- jmp @@MainLoop\r
-\r
-@@Exit:\r
- Emitb RETURN\r
- mov ax,di\r
- sub ax,word ptr [output] ; size of generated code\r
-\r
- pop ds\r
- pop di\r
- pop si\r
- mov sp, bp\r
- pop bp\r
-\r
- ret\r
-_x_compile_bitmap endp\r
-\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-; _x_sizeof_cbitmap\r
-;\r
-; This function follows the same algorithm as the one above,\r
-; but does not generate a new object. Its sole purpose is to\r
-; determine how much space the compiled bitmap will require.\r
-;\r
-; C near-callable as:\r
-; int x_sizeof_cbitmap (WORD logical_screen_width,\r
-; char far * bitmap);\r
-;\r
-; The logical width is in bytes rather than pixels.\r
-;\r
-; All four main registers are totaled.\r
-;\r
-; The source linear bitmaps have the following structure:\r
-;\r
-; BYTE 0 The bitmap width in pixels range 1..255\r
-; BYTE 1 The bitmap height in rows range 1..255\r
-; BYTE 2..n The width*height bytes of the bitmap in\r
-; cloumn row order\r
-;\r
-; The returned value is the size of the compiled bitmap, in bytes.\r
-\r
-\r
- align 2\r
-_x_sizeof_cbitmap proc\r
-ARG logical_width:word,bitmap:dword\r
-LOCAL bwidth,scanx,scany,outputx,outputy,column,set_column,input_size:word=LocalStk\r
- push bp\r
- mov bp, sp ; caller's stack frame\r
- sub sp,LocalStk ; local space\r
- push si\r
- push di\r
- push ds\r
-\r
- mov word ptr [scanx], 0\r
- mov word ptr [scany], 0\r
- mov word ptr [outputx], 0\r
- mov word ptr [outputy], 0\r
- mov word ptr [column], 0\r
- mov word ptr [set_column], 0\r
-\r
- lds si,[bitmap] ; 32-bit pointer to source bitmap\r
-\r
- mov di, 1 ; initial size is just the size of the far RET\r
-\r
- lodsb ; load width byte\r
- xor ah, ah ; convert to word\r
- mov [bwidth], ax ; save for future reference\r
- mov bl, al ; copy width byte to bl\r
- lodsb ; load height byte -- already a word since ah=0\r
- mul bl ; mult height word by width byte\r
- mov [input_size], ax; to get pixel total\r
-\r
-@@MainLoop:\r
- mov bx, [scanx] ; position in original bitmap\r
- add bx, [scany]\r
-\r
- mov al, [si+bx] ; get pixel\r
- or al, al ; skip empty pixels\r
- jnz @@NoAdvance\r
- jmp @@Advance\r
-@@NoAdvance:\r
-\r
- mov dx, [set_column]\r
- cmp dx, [column]\r
- je @@SameColumn\r
-@@ColumnLoop:\r
- add di, 5 ; size of code to move to new column\r
- inc dx\r
- cmp dx,[column]\r
- jl @@ColumnLoop\r
-\r
- inc di ; size of code to set VGA mask\r
- mov [set_column], dx\r
-@@SameColumn:\r
- mov dx, [outputy] ; calculate output position\r
- add dx, [outputx]\r
- sub dx, 128\r
-\r
- add word ptr [scanx], 4\r
- mov cx, [scanx] ; within four pixels of right edge?\r
- cmp cx, [bwidth]\r
- jge @@OnePixel\r
-\r
- inc word ptr [outputx]\r
- mov ah,[si+bx+4] ; get second pixel\r
- or ah, ah\r
- jnz @@TwoPixels\r
-@@OnePixel:\r
- cmp dx, 127 ; can we use shorter form?\r
- jg @@OnePixLarge\r
- cmp dx, -128\r
- jl @@OnePixLarge\r
- add di, 4 ; size of 8-bit position in output plus one pixel\r
- jmp @@EmitOnePixel\r
-@@OnePixLarge:\r
- add di, 5 ; size of position in output plus one pixels\r
-@@EmitOnePixel:\r
- jmp short @@Advance\r
-@@TwoPixels:\r
- cmp dx, 127\r
- jg @@TwoPixLarge\r
- cmp dx, -128\r
- jl @@TwoPixLarge\r
- add di, 5 ; size of 8-bit position in output plus two pixels\r
- jmp @@EmitTwoPixels\r
-@@TwoPixLarge:\r
- add di, 6 ; size of 16-bit position in output plus two pixels\r
-@@EmitTwoPixels:\r
-\r
-@@Advance:\r
- inc word ptr [outputx]\r
- mov ax, [scanx]\r
- add ax,4\r
- cmp ax, [bwidth]\r
- jl @@AdvanceDone\r
- mov dx, [outputy]\r
- add dx, [logical_width]\r
- mov cx, [scany]\r
- add cx, [bwidth]\r
- cmp cx, [input_size]\r
- jl @@NoNewColumn\r
- inc word ptr [column]\r
- mov cx, [column]\r
- cmp cx, 4\r
- je @@Exit ; Column 4: there is no column 4.\r
- xor cx,cx ; scany and outputy are 0 again for\r
- mov dx,cx ; the new column\r
-@@NoNewColumn:\r
- mov [outputy], dx\r
- mov [scany], cx\r
- mov word ptr [outputx], 0\r
- mov ax,[column]\r
-@@AdvanceDone:\r
- mov [scanx], ax\r
- jmp @@MainLoop\r
-\r
-@@Exit:\r
- mov ax, di ; size of generated code\r
-\r
- pop ds\r
- pop di\r
- pop si\r
- mov sp,bp\r
- pop bp\r
-\r
- ret\r
-_x_sizeof_cbitmap endp\r
-\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-; _x_put_cbitmap\r
-;\r
-; Displays a compiled bitmap generated by x_compile_bitmap at given\r
-; coordinates, on a given screen page.\r
-;\r
-; C near-callable as:\r
-; void x_put_cbitmap (int XPos, int YPos,\r
-; unsigned int PageOffset, char far * Sprite);\r
-; ax, bx, cx, and dx are squashed like insignificant insects.\r
-\r
- align 2\r
-_x_put_cbitmap proc\r
-ARG XPos:word,YPos:word,PageOffset:word,Sprite:dword\r
-\r
- push bp\r
- mov bp, sp\r
- push si\r
- push ds\r
-\r
- mov ax, [_ScrnLogicalByteWidth] ; global Xlib variable\r
- mul word ptr [YPos] ; height in bytes\r
- mov si, [XPos]\r
- mov bx, si\r
- sar si, 2 ; width in bytes\r
- add si, ax\r
- add si, [PageOffset]; (YPos * screen width) +\r
- add si, 128 ; (Xpos / 4) + page base + 128 ==> starting pos\r
-\r
- and bx, 3\r
- mov ah, ColumnMask[bx]\r
-\r
- mov dx, SC_INDEX\r
- mov al, MAP_MASK\r
- out dx, ax\r
- inc dx ; ready to send out other masks as bytes\r
- mov al, ah\r
-\r
- mov bx, SCREEN_SEG\r
- mov ds, bx ; We do this so the compiled shape won't need\r
- ; segment overrides.\r
-\r
- call dword ptr [Sprite] ; the business end of the routine\r
-\r
- pop ds\r
- pop si\r
- pop bp\r
-\r
- ret\r
-_x_put_cbitmap endp\r
-\r
-end\r
-\r
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XCBITMAP - header file\r
-;\r
-; This module was written by Matthew MacKenzie\r
-; matm@eng.umd.edu\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-;----------------------------------------------------------------------*/\r
-\r
-#ifndef _XCBITMAP_H_\r
-#define _XCBITMAP_H_\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-\r
-\r
- int x_compile_bitmap ( /* Compile a linear bitmap to generate */\r
- WORD logical_screen_width, /* machine code to plot it at any */\r
- char far * bitmap, /* required screen coordinates FAST. */\r
- char far * output);\r
-\r
- int x_sizeof_cbitmap ( /* Find the size of the code which a */\r
- WORD logical_screen_width, /* bitmap would result in, if it */\r
- char far * bitmap); /* were compiled (used for allocation). */\r
-\r
- void x_put_cbitmap ( /* Displays a compiled bitmap generated */\r
- WORD XPos, /* by x_compile_bitmap. */\r
- WORD YPos,\r
- WORD PageOffset,\r
- char far * CompiledBitmap);\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-\r
-#endif\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XCBITMAP - Include file\r
-; This module was written by Matthew MacKenzie\r
-; matm@eng.umd.edu\r
-;\r
-; XCBITMAP.ASM export functions\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-global _x_compile_bitmap : proc\r
-global _x_sizeof_cbitmap : proc\r
-global _x_put_cbitmap : proc\r
-\r
-\1a
\ No newline at end of file
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; MODULE XCIRCLE\r
-;\r
-; This module was written by Matthew MacKenzie\r
-; matm@eng.umd.edu\r
-;\r
-; Circles, full and empty.\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-include xlib.inc\r
-include xcircle.inc\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-; _x_circle\r
-;\r
-; Draw a circle.\r
-;\r
-; C near-callable as:\r
-; int x_circle (WORD Left, WORD Top, WORD Diameter,\r
-; WORD Color, WORD ScreenOffs);\r
-;\r
-; No clipping is performed.\r
-;\r
-; ax, bx, cx, and dx bite the dust, as Homer would say.\r
-\r
-; we plot into eight arcs at once:\r
-; 4 0\r
-; 6 \|/ 2\r
-; --*--\r
-; 7 /|\ 3\r
-; 5 1\r
-;\r
-; 0, 1, 4, and 5 are considered x-major; the rest, y-major.\r
-;\r
-; The x-major plots grow out from the top and bottom of the circle,\r
-; while the y-major plots start at the left and right edges.\r
-\r
- .data\r
-\r
- align 2\r
-\r
-ColumnMask db 011h,022h,044h,088h\r
-\r
- .code\r
-\r
- public _x_circle\r
- align 2\r
-_x_circle proc\r
-ARG Left:word, Top:word, Diameter:word, Color:word, ScreenOffs:word\r
-LOCAL offset0,offset1,offset2,offset3,offset4,offset5,offset6,offset7,mask0n1,mask2n3,mask4n5,mask6n7,shrunk_radius,diameter_even,error:word=LocalStk\r
-; Tasm 1.0 does not allow the \ line continuation\r
-;LOCAL offset0:word, offset1:word, offset2:word, offset3:word, \\r
-; offset4:word, offset5:word, offset6:word, offset7:word, \\r
-; mask0n1:word, mask2n3:word, mask4n5:word, mask6n7:word, \\r
-; shrunk_radius:word, diameter_even:word, error:word=LocalStk\r
-\r
- push bp\r
- mov bp, sp\r
- sub sp, LocalStk\r
- push si\r
- push di\r
- push ds\r
-\r
-; find starting locations of plots 2, 3, 6, and 7\r
- mov di, _ScrnLogicalByteWidth\r
- xor dx, dx\r
-\r
- mov ax, Diameter ; find vertical midpoint\r
- dec ax\r
- shr ax, 1\r
- adc dx, 0 ; remember if it's rounded\r
- mov shrunk_radius, ax ; radius, rounded down for adding\r
- mov diameter_even, dx ; (diameter - 1) & 1, effectively\r
- add ax, Top\r
- mul di ; vertical midpoint in bytes\r
- add ax, ScreenOffs\r
-\r
- mov bx, Left\r
- mov cx, bx ; save for later\r
- mov si, bx\r
- shr si, 2\r
- add si, ax\r
- mov offset6, si\r
- and bx, 3 ; column of left side\r
- mov bl, ColumnMask[bx]\r
- mov mask6n7, bx\r
-\r
- add cx, Diameter\r
- dec cx\r
- mov bx, cx\r
- shr cx, 2\r
- add cx, ax\r
- mov offset2, cx\r
- and bx, 3 ; column of right side\r
- mov bl, ColumnMask[bx]\r
- mov mask2n3, bx\r
-\r
- cmp diameter_even, 1\r
- jne @@MiddlePlotsOverlap\r
- add si, di\r
- add cx, di\r
-@@MiddlePlotsOverlap:\r
- mov offset7, si\r
- mov offset3, cx\r
-\r
-; starting locations of 0, 1, 4, and 5\r
- mov bx, Left\r
- add bx, shrunk_radius ; find horizontal midpoint\r
-\r
- mov ax, Top ; top in bytes\r
- mul di\r
- add ax, ScreenOffs\r
- mov si, ax\r
-\r
- mov ax, Diameter ; bottom in bytes\r
- dec ax\r
- mul di\r
- add ax, si\r
-\r
- mov di, bx ; horizontal midpoint in bytes\r
- shr di, 2\r
- add si, di ; top midpoint in bytes\r
- mov offset4, si\r
- add di, ax ; bottom midpoint in bytes\r
- mov offset5, di\r
- and bx, 3 ; column of horizontal midpoint\r
- mov bl, ColumnMask[bx]\r
- mov mask4n5, bx\r
-\r
- cmp diameter_even, 1\r
- jne @@TopAndBottomPlotsOverlap\r
- rol bl, 1\r
- jnc @@TopAndBottomPlotsOverlap\r
- inc si\r
- inc di\r
-@@TopAndBottomPlotsOverlap:\r
- mov offset0, si\r
- mov offset1, di\r
- mov mask0n1, bx\r
-\r
-; we've got our eight plots in their starting positions, so\r
-; it's time to sort out the registers\r
- mov bx, _ScrnLogicalByteWidth\r
-\r
- mov dx, SCREEN_SEG\r
- mov ds, dx\r
-\r
- mov dx, SC_INDEX ; set VGA to accept column masks\r
- mov al, MAP_MASK\r
- out dx, al\r
- inc dx ; gun the engine...\r
-\r
- mov si, Diameter ; initial y is radius -- 2 #s per pixel\r
- inc si\r
-\r
- mov cx, si\r
- neg cx\r
- add cx, 2\r
- mov error, cx ; error = -y + one pixel since we're a step ahead\r
-\r
- xor cx, cx ; initial x = 0\r
- mov ah, byte ptr Color\r
- jmp @@CircleCalc ; let's actually put something on the screen!\r
-\r
-; move the x-major plots horizontally and the y-major plots vertically\r
-@@NoAdvance:\r
- mov al, byte ptr mask0n1\r
- out dx, al\r
- mov di, offset0 ; plot 0\r
- mov [di], ah\r
- rol al, 1 ; advance 0 right\r
- mov byte ptr mask0n1, al\r
- adc di, 0\r
- mov offset0, di\r
- mov di, offset1\r
- mov [di], ah ; plot 1\r
- ror al, 1 ; what was that bit again?\r
- adc di, 0 ; advance 1 right\r
- mov offset1, di\r
-\r
- mov al, byte ptr mask2n3\r
- out dx, al\r
- mov di, offset2\r
- mov [di], ah ; plot 2\r
- sub di, bx ; advance 2 up\r
- mov offset2, di\r
- mov di, offset3\r
- mov [di], ah ; plot 3\r
- add di, bx ; advance 3 down\r
- mov offset3, di\r
-\r
- mov al, byte ptr mask4n5\r
- out dx, al\r
- mov di, offset4\r
- mov [di], ah\r
- ror al, 1\r
- mov byte ptr mask4n5, al\r
- sbb di, 0\r
- mov offset4, di\r
- mov di, offset5\r
- mov [di], ah\r
- rol al, 1\r
- sbb di, 0\r
- mov offset5, di\r
-\r
- mov al, byte ptr mask6n7\r
- out dx, al\r
- mov di, offset6\r
- mov [di], ah\r
- sub di, bx\r
- mov offset6, di\r
- mov di, offset7\r
- mov [di], ah\r
- add di, bx\r
- mov offset7, di\r
-\r
- jmp @@CircleCalc\r
-\r
-; move all plots diagonally\r
-@@Advance:\r
- mov al, byte ptr mask0n1\r
- out dx, al\r
- mov di, offset0\r
- mov [di], ah ; plot 0\r
- rol al, 1 ; advance 0 right and down\r
- mov byte ptr mask0n1, al\r
- adc di, bx\r
- mov offset0, di\r
- mov di, offset1\r
- mov [di], ah ; plot 1\r
- ror al, 1 ; what was that bit again?\r
- adc di, 0 ; advance 1 right and up\r
- sub di, bx\r
- mov offset1, di\r
-\r
- mov al, byte ptr mask2n3\r
- out dx, al\r
- mov di, offset2\r
- mov [di], ah ; plot 2\r
- ror al, 1 ; advance 2 up and left\r
- mov byte ptr mask2n3, al\r
- sbb di, bx\r
- mov offset2, di\r
- mov di, offset3\r
- mov [di], ah ; plot 3\r
- rol al, 1\r
- sbb di, 0 ; advance 3 down and left\r
- add di, bx\r
- mov offset3, di\r
-\r
- mov al, byte ptr mask4n5\r
- out dx, al\r
- mov di, offset4\r
- mov [di], ah\r
- ror al, 1\r
- mov byte ptr mask4n5, al\r
- sbb di, 0\r
- add di, bx\r
- mov offset4, di\r
- mov di, offset5\r
- mov [di], ah\r
- rol al, 1\r
- sbb di, bx\r
- mov offset5, di\r
-\r
- mov al, byte ptr mask6n7\r
- out dx, al\r
- mov di, offset6\r
- mov [di], ah\r
- rol al, 1\r
- mov byte ptr mask6n7, al\r
- adc di, 0\r
- sub di, bx\r
- mov offset6, di\r
- mov di, offset7\r
- mov [di], ah\r
- ror al, 1\r
- adc di, bx\r
- mov offset7, di\r
-\r
-; do you realize the entire function has been set up for this little jot?\r
-; keep in mind that radii values are 2 per pixel\r
-@@CircleCalc:\r
- add cx, 2 ; x += 1\r
- mov di, error\r
- add di, cx ; error += (2 * x) + 1\r
- inc di\r
- jl @@CircleNoError\r
- cmp cx, si ; x > y?\r
- ja @@FleeFlyFlowFum\r
- sub si, 2 ; y -= 1\r
- sub di, si ; error -= (2 * y)\r
- mov error, di\r
- jmp @@Advance\r
-@@CircleNoError:\r
- mov error, di\r
- jmp @@NoAdvance\r
-\r
-@@FleeFlyFlowFum:\r
- pop ds\r
- pop di\r
- pop si\r
- mov sp,bp\r
- pop bp\r
-\r
- ret\r
-\r
-_x_circle endp\r
-\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-; _x_filled_circle\r
-;\r
-; Draw a disc.\r
-;\r
-; C near-callable as:\r
-; int x_filled_circle (WORD Left, WORD Top, WORD Diameter,\r
-; WORD Color, WORD ScreenOffs);\r
-;\r
-; No clipping is performed.\r
-;\r
-; ax, bx, cx, dx, and es bite the dust, as Homer would say.\r
-; DF is set to 0 (strings go forward).\r
-\r
- .data\r
-\r
- align 2\r
-\r
-; the only entries of these tables which are used are positions\r
-; 1, 2, 4, and 8\r
-LeftMaskTable db 0, 0ffh, 0eeh, 0, 0cch, 0, 0, 0, 088h\r
-RightMaskTable db 0, 011h, 033h, 0, 077h, 0, 0, 0, 0ffh\r
-\r
- .code\r
-\r
- public _x_filled_circle\r
- align 2\r
-_x_filled_circle proc\r
-ARG Left:word, Top:word, Diameter:word, Color:word, ScreenOffs:word\r
-; Tasm 1.0 does not allow the \ line continuation\r
-;LOCAL offset0:word, offset1:word, offset2:word, offset3:word, \\r
-; offset4:word, offset5:word, offset6:word, offset7:word, \\r
-; mask0n1:word, mask2n3:word, mask4n5:word, mask6n7:word, \\r
-; shrunk_radius:word, diameter_even:word, error:word, \\r
-; jump_vector:word=LocalStk\r
-LOCAL offset0,offset1,offset2,offset3,offset4,offset5,offset6,offset7,mask0n1,mask2n3,mask4n5,mask6n7,shrunk_radius,diameter_even,error,jump_vector:word=LocalStk\r
-\r
- push bp\r
- mov bp, sp\r
- sub sp, LocalStk\r
- push si\r
- push di\r
-\r
- cld ; strings march forward\r
-\r
-; this first part is identical to the other function --\r
-; the only differences, in fact, are in the drawing and moving around\r
-\r
-; find starting locations of plots 2, 3, 6, and 7\r
- mov di, _ScrnLogicalByteWidth\r
- xor dx, dx\r
-\r
- mov ax, Diameter ; find vertical midpoint\r
- dec ax\r
- shr ax, 1\r
- adc dx, 0 ; remember if it's rounded\r
- mov shrunk_radius, ax ; radius, rounded down for adding\r
- mov diameter_even, dx ; (diameter - 1) & 1, effectively\r
- add ax, Top\r
- mul di ; vertical midpoint in bytes\r
- add ax, ScreenOffs\r
-\r
- mov bx, Left\r
- mov cx, bx ; save for later\r
- mov si, bx\r
- shr si, 2\r
- add si, ax\r
- mov offset6, si\r
- and bx, 3 ; column of left side\r
- mov bl, ColumnMask[bx]\r
- mov mask6n7, bx\r
-\r
- add cx, Diameter\r
- dec cx\r
- mov bx, cx\r
- shr cx, 2\r
- add cx, ax\r
- mov offset2, cx\r
- and bx, 3 ; column of right side\r
- mov bl, ColumnMask[bx]\r
- mov mask2n3, bx\r
-\r
- cmp diameter_even, 1\r
- jne @@MiddlePlotsOverlap\r
- add si, di\r
- add cx, di\r
-@@MiddlePlotsOverlap:\r
- mov offset7, si\r
- mov offset3, cx\r
-\r
-; starting locations of 0, 1, 4, and 5\r
- mov bx, Left\r
- add bx, shrunk_radius ; find horizontal midpoint\r
-\r
- mov ax, Top ; top in bytes\r
- mul di\r
- add ax, ScreenOffs\r
- mov si, ax\r
-\r
- mov ax, Diameter ; bottom in bytes\r
- dec ax\r
- mul di\r
- add ax, si\r
-\r
- mov di, bx ; horizontal midpoint in bytes\r
- shr di, 2\r
- add si, di ; top midpoint in bytes\r
- mov offset4, si\r
- add di, ax ; bottom midpoint in bytes\r
- mov offset5, di\r
- and bx, 3 ; column of horizontal midpoint\r
- mov bl, ColumnMask[bx]\r
- mov mask4n5, bx\r
-\r
- cmp diameter_even, 1\r
- jne @@TopAndBottomPlotsOverlap\r
- rol bl, 1\r
- jnc @@TopAndBottomPlotsOverlap\r
- inc si\r
- inc di\r
-@@TopAndBottomPlotsOverlap:\r
- mov offset0, si\r
- mov offset1, di\r
- mov mask0n1, bx\r
-\r
-; we've got our eight plots in their starting positions, so\r
-; it's time to sort out the registers\r
- mov bx, _ScrnLogicalByteWidth\r
-\r
- mov dx, SCREEN_SEG\r
- mov es, dx\r
-\r
- mov dx, SC_INDEX ; set VGA to accept column masks\r
- mov al, MAP_MASK\r
- out dx, al\r
- inc dx ; gun the engine...\r
-\r
- mov si, Diameter ; initial y is radius -- 2 #s per pixel\r
- inc si\r
-\r
- mov cx, si\r
- neg cx\r
- add cx, 2\r
- mov error, cx ; error = -y + one pixel since we're a step ahead\r
-\r
- xor cx, cx ; initial x = 0\r
- mov ah, byte ptr Color\r
- jmp @@FilledCircleCalc ; let's actually put something on the screen!\r
-\r
-\r
-; plotting is completely different from in the other function (naturally)\r
-@@PlotLines:\r
- push cx ; we'll need cx for string stores\r
-\r
-; draw x-major horz. lines, from plot 4 to plot 0 and from plot 5 to plot 1\r
- mov di, mask0n1\r
- and di, 0000fh ; we only want the lower nybble for the mask table\r
- mov al, RightMaskTable[di]\r
- mov di, offset0 ; left and right offsets the same?\r
- cmp di, offset4\r
- jne @@PlotXMajorNontrivial ; try and say this one 10 times fast!\r
- mov di, mask4n5\r
- and di, 0000fh\r
- and al, LeftMaskTable[di] ; intersection of left & right masks\r
- out dx, al ; set mask\r
- mov di, offset4\r
- mov es:[di], ah\r
- mov di, offset5\r
- mov es:[di], ah\r
- jmp @@PlotYMajor\r
-@@PlotXMajorNontrivial:\r
- out dx, al ; draw right edge\r
- mov es:[di], ah\r
- mov di, offset1\r
- mov es:[di], ah\r
-\r
- mov di, mask4n5 ; draw left edge\r
- and di, 0000fh\r
- mov al, LeftMaskTable[di]\r
- out dx, al\r
- mov di, offset4\r
- mov es:[di], ah\r
- mov di, offset5\r
- mov es:[di], ah\r
-\r
- mov al, 0ffh ; set mask for middle chunks\r
- out dx, al\r
- mov al, ah ; ready to store two pixels at a time\r
- inc di ; move string start past left edge\r
- mov cx, offset1 ; store line from plot 5 to plot 1, exclusive\r
- sub cx, di ; width of section in bytes\r
- push cx\r
- shr cx, 1 ; draw midsection eight pixels at a time\r
- rep stosw\r
- adc cx, 0 ; draw last four pixels, if such there are\r
- rep stosb\r
-\r
- mov di, offset4 ; draw line from plot 4 to plot 0\r
- inc di ; move past left edge\r
- pop cx\r
- shr cx, 1\r
- rep stosw\r
- adc cx, 0\r
- rep stosb\r
-\r
-@@PlotYMajor:\r
-; draw y-major horz. lines, from plot 6 to plot 2 and from plot 7 to plot 3\r
- mov di, mask2n3\r
- and di, 0000fh ; we only want the lower nybble for the mask table\r
- mov al, RightMaskTable[di]\r
- mov di, offset2 ; left and right offsets the same?\r
- cmp di, offset6\r
- jne @@PlotYMajorNontrivial ; try and say this one 10 times fast!\r
- mov di, mask6n7\r
- and di, 0000fh\r
- and al, LeftMaskTable[di] ; intersection of left & right masks\r
- out dx, al ; set mask\r
- mov di, offset6\r
- mov es:[di], ah\r
- mov di, offset7\r
- mov es:[di], ah\r
- jmp @@ClimaxOfPlot\r
-@@PlotYMajorNontrivial:\r
- out dx, al ; draw right edge\r
- mov es:[di], ah\r
- mov di, offset3\r
- mov es:[di], ah\r
-\r
- mov di, mask6n7 ; draw left edge\r
- and di, 0000fh\r
- mov al, LeftMaskTable[di]\r
- out dx, al\r
- mov di, offset6\r
- mov es:[di], ah\r
- mov di, offset7\r
- mov es:[di], ah\r
-\r
- mov al, 0ffh ; set mask for middle chunks\r
- out dx, al\r
- mov al, ah ; ready to store two pixels at a time\r
-\r
- inc di ; move string start past left edge\r
- mov cx, offset3 ; draw line from plot 7 to plot 3, exclusive\r
- sub cx, di ; width of section in bytes\r
- push cx\r
- shr cx, 1 ; store midsection\r
- rep stosw\r
- adc cx, 0\r
- rep stosb\r
-\r
- mov di, offset6 ; draw line from plot 6 to plot 2\r
- inc di ; move past left edge\r
- pop cx\r
- shr cx, 1\r
- rep stosw\r
- adc cx, 0\r
- rep stosb\r
-\r
-@@ClimaxOfPlot:\r
- pop cx\r
- jmp [jump_vector] ; either @@Advance or @@NoAdvance\r
-\r
-\r
-; unlike their counterparts in the other function, these do not draw --\r
-; they only move the eight pointers\r
-\r
-; move the x-major plots horizontally and the y-major plots vertically\r
-@@NoAdvance:\r
- mov al, byte ptr mask0n1 ; advance left x-major plots\r
- mov di, offset0\r
- rol al, 1 ; advance 0 right\r
- mov byte ptr mask0n1, al\r
- adc di, 0\r
- mov offset0, di\r
- mov di, offset1\r
- ror al, 1 ; what was that bit again?\r
- adc di, 0 ; advance 1 right\r
- mov offset1, di\r
-\r
- mov al, byte ptr mask4n5 ; advance left x-major plots\r
- mov di, offset4\r
- ror al, 1\r
- mov byte ptr mask4n5, al\r
- sbb di, 0\r
- mov offset4, di\r
- mov di, offset5\r
- rol al, 1\r
- sbb di, 0\r
- mov offset5, di\r
-\r
- mov al, byte ptr mask2n3\r
- mov di, offset2\r
- sub di, bx ; advance 2 up\r
- mov offset2, di\r
- mov di, offset3\r
- add di, bx ; advance 3 down\r
- mov offset3, di\r
-\r
- mov al, byte ptr mask6n7\r
- mov di, offset6\r
- sub di, bx\r
- mov offset6, di\r
- mov di, offset7\r
- add di, bx\r
- mov offset7, di\r
-\r
- jmp @@FilledCircleCalc\r
-\r
-; move all plots diagonally\r
-@@Advance:\r
- mov al, byte ptr mask0n1\r
- mov di, offset0\r
- rol al, 1 ; advance 0 right and down\r
- mov byte ptr mask0n1, al\r
- adc di, bx\r
- mov offset0, di\r
- mov di, offset1\r
- ror al, 1 ; what was that bit again?\r
- adc di, 0 ; advance 1 right and up\r
- sub di, bx\r
- mov offset1, di\r
-\r
- mov al, byte ptr mask2n3\r
- mov di, offset2\r
- ror al, 1 ; advance 2 up and left\r
- mov byte ptr mask2n3, al\r
- sbb di, bx\r
- mov offset2, di\r
- mov di, offset3\r
- rol al, 1\r
- sbb di, 0 ; advance 3 down and left\r
- add di, bx\r
- mov offset3, di\r
-\r
- mov al, byte ptr mask4n5\r
- mov di, offset4\r
- ror al, 1\r
- mov byte ptr mask4n5, al\r
- sbb di, 0\r
- add di, bx\r
- mov offset4, di\r
- mov di, offset5\r
- rol al, 1\r
- sbb di, bx\r
- mov offset5, di\r
-\r
- mov al, byte ptr mask6n7\r
- mov di, offset6\r
- rol al, 1\r
- mov byte ptr mask6n7, al\r
- adc di, 0\r
- sub di, bx\r
- mov offset6, di\r
- mov di, offset7\r
- ror al, 1\r
- adc di, bx\r
- mov offset7, di\r
-\r
-; do you realize the entire function has been set up around this little jot?\r
-; keep in mind that radii values are 2 per pixel\r
-@@FilledCircleCalc:\r
- add cx, 2 ; x += 1\r
- mov di, error\r
- add di, cx ; error += (2 * x) + 1\r
- inc di\r
- jl @@FilledCircleNoError\r
- cmp cx, si ; x > y?\r
- ja @@FleeFlyFlowFum\r
- sub si, 2 ; y -= 1\r
- sub di, si ; error -= (2 * y)\r
- mov error, di\r
- mov jump_vector, offset @@Advance\r
- jmp @@PlotLines\r
-@@FilledCircleNoError:\r
- mov error, di\r
- mov jump_vector, offset @@NoAdvance\r
- jmp @@PlotLines\r
-\r
-@@FleeFlyFlowFum:\r
- pop di\r
- pop si\r
- mov sp,bp\r
- pop bp\r
-\r
- ret\r
-\r
-_x_filled_circle endp\r
-\r
- end\r
-\r
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XCIRCLE - header file\r
-;\r
-; This module was written by Matthew MacKenzie\r
-; matm@eng.umd.edu\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-;----------------------------------------------------------------------*/\r
-\r
-#ifndef _XCIRCLE_H_\r
-#define _XCIRCLE_H_\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-\r
- void x_circle (WORD Left, WORD Top, WORD Diameter,\r
- WORD Color, WORD ScreenOffs);\r
-\r
- void x_filled_circle (WORD Left, WORD Top, WORD Diameter,\r
- WORD Color, WORD ScreenOffs);\r
-\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-\r
-#endif\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XCIRCLE - Include file\r
-;\r
-; This module was written by Matthew MacKenzie\r
-; matm@eng.umd.edu\r
-;\r
-; XCIRCLE.ASM export functions\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
- global _x_circle : proc\r
- global _x_filled_circle : proc\r
-\r
-\1a
\ No newline at end of file
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XCLIPPBM\r
-;\r
-; This module was written by Matthew MacKenzie\r
-; matm@eng.umd.edu\r
-;\r
-; Clipped transfer of planar bitmaps from system memory to video memory.\r
-;\r
-; Compile with TASM.\r
-; C near-callable.\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-include xlib.inc\r
-include xclippbm.inc\r
-\r
-\r
- .data\r
-\r
- align 2\r
-\r
-; global clipping variables\r
-_TopBound dw (?)\r
-_BottomBound dw (?)\r
-_LeftBound dw (?)\r
-_RightBound dw (?)\r
-\r
-; VGA plane masks\r
-ColumnMask db 011h,022h,044h,088h\r
-\r
-; bit delay timers\r
-LeftDelay db 0, 1, 2, 4\r
-RightDelay db 0, 4, 2, 1\r
-\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-; _x_clip_pbm\r
-;\r
-; C near-callable as:\r
-;\r
-; void x_clip_pbm (int X, int Y, int ScreenOffs, char far * Bitmap);\r
-;\r
-; Bitmap is a planar bitmap, in the regular Xlib format.\r
-;\r
-; ax, bx, cx, and dx go south.\r
-\r
- .code\r
-\r
- public _x_clip_pbm\r
- align 2\r
-_x_clip_pbm proc\r
-ARG X:word, Y:word, ScreenOffs:word, Bitmap:dword\r
-LOCAL left_counter, right_counter,column,clipped_height,clipped_width,screen_pos,bitmap_pos,bitmap_size,VGA_mask,width_copy,height_temp,screen_width:word=LocalStk\r
-; Tasm 1.0 does not allow the \ line continuation\r
-;LOCAL left_counter:word, right_counter:word, \\r
-; column:word, clipped_height:word, clipped_width:word, \\r
-; screen_pos:word, bitmap_pos:word, bitmap_size:word, \\r
-; VGA_mask:word, width_copy, height_temp:word, \\r
-; screen_width:word=LocalStk\r
-\r
- push bp\r
- mov bp, sp\r
- sub sp, LocalStk\r
- push si\r
- push di\r
- push ds\r
-\r
-; sociopathic cases: are the clipping bounds out of order?\r
- mov ax, _TopBound\r
- cmp ax, _BottomBound\r
- jg @@GetOut\r
- mov ax, _LeftBound\r
- cmp ax, _RightBound\r
- jle @@ReasonableAndProper\r
-@@GetOut: ; return a 1 -- no image drawn\r
- pop ds\r
- pop di\r
- pop si\r
- mov ax, 1\r
- mov sp, bp\r
- pop bp\r
- ret\r
-\r
-@@ReasonableAndProper:\r
-\r
-; we need to use both the tables in ds and the height and width of the bitmap\r
- les si, Bitmap\r
-\r
-; vertical position\r
- xor cx, cx\r
- mov cl, byte ptr es:[si + 1] ; height of bitmap\r
- xor ax, ax\r
- mov al, byte ptr es:[si] ; width of bitmap\r
- mul cx\r
- mov bitmap_size, ax\r
- mov ax, Y\r
- cmp ax, _BottomBound ; top edge below clipping box?\r
- jg @@GetOut\r
-\r
- mov bx, cx\r
- add bx, ax\r
- dec bx ; bottom edge = Y + height - 1\r
- cmp bx, _TopBound\r
- jl @@GetOut\r
- sub bx, _BottomBound ; bottom margin = bottom edge - BottomBound\r
- jle @@NoBottomBound\r
- sub cx, bx ; clip bottom margin from height\r
-@@NoBottomBound:\r
- mov bx, _TopBound\r
- sub bx, ax ; top margin = TopBound - Y\r
- jle @@NoTopBound\r
- add ax, bx ; top edge = Y + top margin\r
- sub cx, bx ; clip top margin from height\r
- jmp @@KeepMargin\r
-@@NoTopBound:\r
- xor bx, bx\r
-@@KeepMargin:\r
- mov clipped_height, cx\r
-\r
- mul _ScrnLogicalByteWidth\r
- mov di, ax\r
- add di, ScreenOffs ; row of upper-left corner of blit\r
-\r
- mov cl, byte ptr es:[si] ; width of bitmap (ch is still 0 from height)\r
- mov ax, cx\r
- mul bx\r
- add si, ax\r
- add si, 2 ; starting position in bitmap\r
-\r
-; horizontal position\r
- mov width_copy, cx\r
- mov dx, X\r
- cmp dx, _RightBound\r
- jg @@GetOut\r
- mov dx, 0 ; unclipped value for right delay\r
-\r
- mov ax, cx\r
- shl ax, 2 ; width in pixels\r
- add ax, X\r
- dec ax ; right edge = X + width in pixels - 1\r
- cmp ax, _LeftBound\r
- jl @@GetOut\r
- sub ax, _RightBound ; right margin = right edge - RightBound\r
- jle @@NoRightBound\r
- mov bx, ax\r
- and bx, 3\r
- mov dl, RightDelay[bx]\r
- shr ax, 2\r
- sub cx, ax ; subtract clipped bytes from width\r
-@@NoRightBound:\r
- mov right_counter, dx\r
- mov dx, 0 ; unclipped value for left delay\r
- mov ax, _LeftBound\r
- sub ax, X ; left margin = LeftBound - X\r
- jle @@NoLeftBound\r
- mov bx, ax\r
- and bx, 3\r
- mov dl, LeftDelay[bx]\r
- add ax, 3\r
- shr ax, 2 ; left margin/4, rounded up\r
- sub cx, ax ; subtract clipped bytes from width\r
- add si, ax ; move starting position in bitmap past margin\r
- add di, ax ; move starting position on screen past margin\r
-@@NoLeftBound:\r
- mov left_counter, dx\r
- mov clipped_width, cx\r
-\r
- mov ax, X ; add x coordinate to screen position\r
- mov bx, ax\r
- sar ax, 2\r
- add di, ax\r
-\r
- mov dx, SC_INDEX\r
- mov al, MAP_MASK\r
- out dx, al\r
- inc dx\r
-\r
- and bx, 3 ; initial mask\r
- xor ax, ax\r
- mov al, ColumnMask[bx]\r
- mov VGA_mask, ax\r
- out dx, al ; initial mask\r
-\r
- mov column, 4\r
- mov bitmap_pos, si\r
- mov screen_pos, di\r
- mov ax, _ScrnLogicalByteWidth\r
- mov screen_width, ax ; since we move ds\r
-\r
-; we've used all our tables, so we can change ds to point to the bitmap,\r
-; and es to point to the screen\r
- mov ds, word ptr [Bitmap + 2]\r
- mov ax, SCREEN_SEG\r
- mov es, ax\r
-\r
- cld ; strings go forward\r
- mov bx, width_copy\r
- sub bx, clipped_width ; bytes to advance one line in bitmap\r
-\r
-; let's actually draw something for a change\r
-@@WritePlane:\r
- mov ax, clipped_height\r
- mov height_temp, ax\r
- mov dx, screen_width\r
- sub dx, clipped_width ; bytes to advance one line across screen\r
-\r
-@@WriteLine:\r
- mov cx, clipped_width\r
- shr cx, 1\r
- rep movsw ; in they went, two by two...\r
- adc cx, 0\r
- rep movsb ; catch stray last byte, if it's there\r
- add si, bx ; advance one bitmap line\r
- add di, dx ; advance one screen line\r
-\r
- dec height_temp\r
- jnz @@WriteLine\r
-\r
- dec column\r
- jz @@OuttaHere ; only four columns per customer, please\r
- mov dx, SC_INDEX + 1\r
- rol byte ptr VGA_mask, 1\r
- adc screen_pos, 0 ; add to location if we've wrapped to plane 0\r
- mov al, byte ptr VGA_mask\r
- out dx, al ; set VGA for next column\r
-\r
- shr right_counter, 1\r
- jnc @@NoRightCounter\r
- dec clipped_width ; cut off right edge for later planes\r
- inc bx\r
-@@NoRightCounter:\r
- shr left_counter, 1\r
- jnc @@NoLeftCounter\r
- inc clipped_width ; add to left edge for later planes\r
- dec bx\r
- dec bitmap_pos\r
- dec screen_pos\r
-@@NoLeftCounter:\r
- mov si, bitmap_pos\r
- add si, bitmap_size\r
- mov bitmap_pos, si\r
- mov di, screen_pos\r
- jmp @@WritePlane\r
-\r
-@@OuttaHere: ; return a 0 -- something was inside the boundary\r
- pop ds\r
- pop di\r
- pop si\r
- mov ax, 0\r
- mov sp, bp\r
- pop bp\r
- ret\r
-_x_clip_pbm endp\r
-\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-; _x_clip_masked_pbm\r
-;\r
-; C near-callable as:\r
-;\r
-; void x_clip_masked_pbm (int X, int Y, int ScreenOffs, char far * Bitmap);\r
-;\r
-; Bitmap is a planar bitmap, in the regular Xlib format.\r
-; The width of the bitmap cannot be greater than 90 bytes, however.\r
-; Ain't that just criminal?\r
-;\r
-; ax, bx, cx, and dx go south.\r
-\r
-\r
-; one branch per pixel is more than enough -- we'll unroll the line-writing\r
-; loop all the way to try to get a little speed (at the expense, as usual,\r
-; of a chunk of memory)\r
-\r
-MaskedPoint macro offset\r
- mov al, [si + offset]\r
- or al, al\r
- jz $+6\r
- mov es:[di + offset], al\r
- endm\r
-\r
-MaskedPointSize equ 11\r
-\r
- public _x_clip_masked_pbm\r
- align 2\r
-_x_clip_masked_pbm proc\r
-ARG X:word, Y:word, ScreenOffs:word, Bitmap:dword\r
-; Tasm 1.0 does not allow the \ line continuation\r
-LOCAL left_counter,right_counter,column:word,clipped_height,screen_pos,bitmap_pos,bitmap_size,VGA_mask,width_copy,height_temp,screen_width:word=LocalStk\r
-;LOCAL left_counter:word, right_counter:word, \\r
-; column:word, clipped_height:word, \\r
-; screen_pos:word, bitmap_pos:word, bitmap_size:word, \\r
-; VGA_mask:word, width_copy, height_temp:word, \\r
-; screen_width:word=LocalStk\r
- push bp\r
- mov bp, sp\r
- sub sp, LocalStk\r
- push si\r
- push di\r
- push ds\r
-\r
-; sociopathic cases: are the clipping bounds out of order?\r
- mov ax, _TopBound\r
- cmp ax, _BottomBound\r
- jg @@GetOut\r
- mov ax, _LeftBound\r
- cmp ax, _RightBound\r
- jle @@ReasonableAndProper\r
-@@GetOut: ; return a 1 -- no image drawn\r
- pop ds\r
- pop di\r
- pop si\r
- mov ax, 1\r
- mov sp, bp\r
- pop bp\r
- ret\r
-\r
-@@ReasonableAndProper:\r
-\r
-; we need to use both the tables in ds and the height and width of the bitmap\r
- les si, Bitmap\r
-\r
-; vertical position\r
- xor cx, cx\r
- mov cl, byte ptr es:[si + 1] ; height of bitmap\r
- xor ax, ax\r
- mov al, byte ptr es:[si] ; width of bitmap\r
- mul cx\r
- mov bitmap_size, ax\r
- mov ax, Y\r
- cmp ax, _BottomBound ; top edge below clipping box?\r
- jg @@GetOut\r
-\r
- mov bx, cx\r
- add bx, ax\r
- dec bx ; bottom edge = Y + height - 1\r
- cmp bx, _TopBound\r
- jl @@GetOut\r
- sub bx, _BottomBound ; bottom margin = bottom edge - BottomBound\r
- jle @@NoBottomBound\r
- sub cx, bx ; clip bottom margin from height\r
-@@NoBottomBound:\r
- mov bx, _TopBound\r
- sub bx, ax ; top margin = TopBound - Y\r
- jle @@NoTopBound\r
- add ax, bx ; top edge = Y + top margin\r
- sub cx, bx ; clip top margin from height\r
- jmp @@KeepMargin\r
-@@NoTopBound:\r
- xor bx, bx\r
-@@KeepMargin:\r
- mov clipped_height, cx\r
-\r
- mul _ScrnLogicalByteWidth\r
- mov di, ax\r
- add di, ScreenOffs ; row of upper-left corner of blit\r
-\r
- mov cl, byte ptr es:[si] ; width of bitmap (ch is still 0 from height)\r
- mov ax, cx\r
- mul bx\r
- add si, ax\r
- add si, 2 ; starting position in bitmap\r
-\r
-; horizontal position\r
- mov width_copy, cx\r
- mov dx, X\r
- cmp dx, _RightBound\r
- jg @@GetOut\r
- mov dx, 0 ; unclipped value for right delay\r
-\r
- mov ax, cx\r
- shl ax, 2 ; width in pixels\r
- add ax, X\r
- dec ax ; right edge = X + width in pixels - 1\r
- cmp ax, _LeftBound\r
- jl @@GetOut\r
- sub ax, _RightBound ; right margin = right edge - RightBound\r
- jle @@NoRightBound\r
- mov bx, ax\r
- and bx, 3\r
- mov dl, RightDelay[bx]\r
- shr ax, 2\r
- sub cx, ax ; subtract clipped bytes from width\r
-@@NoRightBound:\r
- mov right_counter, dx\r
- mov dx, 0 ; unclipped value for left delay\r
- mov ax, _LeftBound\r
- sub ax, X ; left margin = LeftBound - X\r
- jle @@NoLeftBound\r
- mov bx, ax\r
- and bx, 3\r
- mov dl, LeftDelay[bx]\r
- add ax, 3\r
- shr ax, 2 ; left margin/4, rounded up\r
- sub cx, ax ; subtract clipped bytes from width\r
- add si, ax ; move starting position in bitmap past margin\r
- add di, ax ; move starting position on screen past margin\r
-@@NoLeftBound:\r
- mov left_counter, dx\r
- mov ax, cx\r
- imul ax, (-1 * MaskedPointSize)\r
- add ax, offset @@LineDone + 2\r
- mov cx, ax ; jump offset for plotting\r
-\r
- mov ax, X ; add x coordinate to screen position\r
- mov bx, ax\r
- shr ax, 2\r
- add di, ax\r
-\r
- mov dx, SC_INDEX\r
- mov al, MAP_MASK\r
- out dx, al\r
- inc dx\r
-\r
- and bx, 3 ; initial mask\r
- xor ax, ax\r
- mov al, ColumnMask[bx]\r
- mov VGA_mask, ax\r
- out dx, al\r
-\r
- mov column, 4\r
- mov bitmap_pos, si\r
- mov screen_pos, di\r
- mov ax, _ScrnLogicalByteWidth\r
- mov screen_width, ax ; since we move ds\r
-\r
-; we've used all our tables, so we can change ds to point to the bitmap,\r
-; and es to point to the screen\r
- mov ds, word ptr [Bitmap + 2]\r
- mov ax, SCREEN_SEG\r
- mov es, ax\r
-\r
- mov bx, width_copy\r
-\r
-; let's actually draw something for a change\r
- mov ax, clipped_height\r
- mov height_temp, ax\r
- mov dx, screen_width\r
- jmp cx\r
-\r
-; 90 bottles of beer on the wall...\r
- PointLoop = 89\r
- rept 89\r
- MaskedPoint PointLoop\r
- PointLoop = PointLoop - 1\r
- endm\r
-; one bottle of beer...\r
-\r
-; final point needs a different branch offset, so we don't use MaskedPoint\r
- mov al, [si]\r
- or al, al\r
- jz @@LineDone\r
- mov es:[di], al\r
-\r
-@@LineDone:\r
- add si, bx ; advance one bitmap line\r
- add di, dx ; advance one screen line\r
- dec height_temp\r
- jz @@PlaneDone\r
- jmp cx\r
-\r
-@@PlaneDone:\r
- dec column\r
- jz @@OuttaHere ; only four columns per customer, please\r
- mov dx, SC_INDEX + 1\r
- rol byte ptr VGA_mask, 1\r
- adc screen_pos, 0 ; move to new column if we've wrapped to plane 0\r
- mov al, byte ptr VGA_mask\r
- out dx, al ; set VGA for next column\r
-\r
- shr right_counter, 1\r
- jnc @@NoRightCounter\r
- add cx, MaskedPointSize ; cut off right edge for later planes\r
-@@NoRightCounter:\r
- shr left_counter, 1\r
- jnc @@NoLeftCounter\r
- sub cx, MaskedPointSize ; add to left edge for later planes\r
- dec bitmap_pos\r
- dec screen_pos\r
-@@NoLeftCounter:\r
- mov si, bitmap_pos\r
- add si, bitmap_size\r
- mov bitmap_pos, si\r
- mov di, screen_pos\r
-\r
- mov ax, clipped_height\r
- mov height_temp, ax\r
- mov dx, screen_width\r
- jmp cx\r
-\r
-@@OuttaHere: ; return a 0 -- something was inside the boundary\r
- pop ds\r
- pop di\r
- pop si\r
- mov ax, 0\r
- mov sp, bp\r
- pop bp\r
- ret\r
-_x_clip_masked_pbm endp\r
-\r
- end\r
-\r
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-; MODULE XCLIPPBM\r
-;\r
-; This module was written by Matthew MacKenzie\r
-; matm@eng.umd.edu\r
-;\r
-; Clipped transfer of planar bitmaps from system memory to video memory.\r
-;\r
-; Compile with TASM.\r
-; C near-callable.\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;----------------------------------------------------------------------*/\r
-\r
-#ifndef _XCLIPPBM_H_\r
-#define _XCLIPPBM_H_\r
-\r
-/* unlike most global variables in Xlib, these are meant to be written to;\r
- in fact they start off uninitialized -- all values are in pixels */\r
-extern int TopBound;\r
-extern int BottomBound;\r
-extern int LeftBound;\r
-extern int RightBound;\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-\r
-/* for both functions, a return value of 1 indicates that the entire\r
-bitmap was outside the bounding box, while a value of 0 means that\r
-something may have ended up on the screen */\r
-\r
-/* copies a planar bitmap from SRAM to VRAM, with clipping */\r
-\r
- int x_clip_pbm (int X, int Y, int ScreenOffs, char far * Bitmap);\r
-\r
-/* copies a planar bitmap from SRAM to VRAM, with clipping -- 0 bytes\r
- in the bitmap are not copied */\r
-\r
- int x_clip_masked_pbm (int X, int Y, int ScreenOffs, char far * Bitmap);\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-\r
-#endif\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XPBITMAP - Include file\r
-;\r
-; This module was written by Matthew MacKenzie\r
-; matm@eng.umd.edu\r
-;\r
-; XPBITMAP.ASM export functions\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
- global _x_clip_masked_pbm :proc\r
- global _x_clip_pbm :proc\r
-\r
- global _LeftBound :word\r
- global _RightBound :word\r
- global _TopBound :word\r
- global _BottomBound :word\r
-\r
-\1a
\ No newline at end of file
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; module XCOMPPBM\r
-;\r
-; This module contains only the compiler and sizeof routines --\r
-; use the plotter from XCBITMAP.\r
-;\r
-;-----------------------------------------------------------------------\r
-\r
-include xlib.inc\r
-include xcomppbm.inc\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-; _x_compile_pbm\r
-;\r
-; I only changed five instructions, instead of rewriting this\r
-; for PBMs. So it is amazingly inefficient. But, what the hell,\r
-; It's only a game :).\r
-;\r
-\r
-; accessory macros to save typing (what else?)\r
-Emitb macro arg\r
- mov byte ptr es:[di],&arg&\r
- inc di\r
- endm\r
-\r
-Emitw macro arg\r
- mov word ptr es:[di],&arg&\r
- add di,2\r
- endm\r
-\r
-; opcodes emitted by _x_compile_pbm\r
-ROL_AL equ 0c0d0h ; rol al\r
-SHORT_STORE_8 equ 044c6h ; mov [si]+disp8, imm8\r
-STORE_8 equ 084c6h ; mov [si]+disp16, imm8\r
-SHORT_STORE_16 equ 044c7h ; mov [si]+disp8, imm16\r
-STORE_16 equ 084c7h ; mov [si]+disp16, imm16\r
-ADC_SI_IMMED equ 0d683h ; adc si,imm8\r
-OUT_AL equ 0eeh ; out dx,al\r
-RETURN equ 0cbh ; ret\r
-\r
-\r
-.data\r
-\r
-align 2\r
-ColumnMask db 011h,022h,044h,088h\r
-\r
-\r
-.code\r
-\r
- align 2\r
-_x_compile_pbm proc\r
-ARG logical_width:word,bitmap:dword,output:dword\r
-LOCAL bwidth,scanx,scany,outputx,outputy,column,set_column,input_size:word=LocalStk\r
- push bp\r
- mov bp, sp ; caller's stack frame\r
- sub sp,LocalStk ; local space\r
- push si\r
- push di\r
- push ds\r
-\r
- mov word ptr [scanx],0\r
- mov word ptr [scany],0\r
- mov word ptr [outputx],0\r
- mov word ptr [outputy],0\r
- mov word ptr [column],0\r
- mov word ptr [set_column],0\r
-\r
- lds si,[bitmap] ; 32-bit pointer to source bitmap\r
-\r
- les di,[output] ; 32-bit pointer to destination stream\r
-\r
- lodsb ; load width byte\r
- xor ah, ah ; convert to word\r
- mov [bwidth], ax ; save for future reference\r
- mov bl, al ; copy width byte to bl\r
- lodsb ; load height byte -- already a word since ah=0\r
- mul bl ; mult height word by width byte\r
- mov [input_size], ax; to get pixel total\r
-\r
-@@MainLoop:\r
- mov bx, [scanx] ; position in original bitmap\r
- add bx, [scany]\r
-\r
- mov al, [si+bx] ; get pixel\r
- or al, al ; skip empty pixels\r
- jnz @@NoAdvance\r
- jmp @@Advance\r
-@@NoAdvance:\r
-\r
- mov dx, [set_column]\r
- cmp dx, [column]\r
- je @@SameColumn\r
-@@ColumnLoop:\r
- Emitw ROL_AL ; emit code to move to new column\r
- Emitw ADC_SI_IMMED\r
- Emitb 0\r
-\r
- inc dx\r
- cmp dx, [column]\r
- jl @@ColumnLoop\r
-\r
- Emitb OUT_AL ; emit code to set VGA mask for new column\r
- mov [set_column], dx\r
-@@SameColumn:\r
- mov dx, [outputy] ; calculate output position\r
- add dx, [outputx]\r
- sub dx, 128\r
-\r
- inc word ptr [scanx]\r
- mov cx, [scanx] ; within four pixels of right edge?\r
- cmp cx, [bwidth]\r
- jge @@OnePixel\r
-\r
- inc word ptr [outputx]\r
- mov ah, [si+bx+1] ; get second pixel\r
- or ah, ah\r
- jnz @@TwoPixels\r
-@@OnePixel:\r
- cmp dx, 127 ; can we use shorter form?\r
- jg @@OnePixLarge\r
- cmp dx, -128\r
- jl @@OnePixLarge\r
- Emitw SHORT_STORE_8\r
- Emitb dl ; 8-bit position in output\r
- jmp @@EmitOnePixel\r
-@@OnePixLarge:\r
- Emitw STORE_8\r
- Emitw dx ; position in output\r
-@@EmitOnePixel:\r
- Emitb al\r
- jmp short @@Advance\r
-@@TwoPixels:\r
- cmp dx, 127\r
- jg @@TwoPixLarge\r
- cmp dx, -128\r
- jl @@TwoPixLarge\r
- Emitw SHORT_STORE_16\r
- Emitb dl ; 8-bit position in output\r
- jmp @@EmitTwoPixels\r
-@@TwoPixLarge:\r
- Emitw STORE_16\r
- Emitw dx ; position in output\r
-@@EmitTwoPixels:\r
- Emitw ax\r
-\r
-@@Advance:\r
- inc word ptr [outputx]\r
- mov ax, [scanx]\r
- inc ax\r
- cmp ax, [bwidth]\r
- jl @@AdvanceDone\r
- mov dx, [outputy]\r
- add dx, [logical_width]\r
- mov cx, [scany]\r
- add cx, [bwidth]\r
- cmp cx, [input_size]\r
- jl @@NoNewColumn\r
- inc word ptr [column]\r
- mov cx, [column]\r
- cmp cx, 4\r
- je @@Exit ; Column 4: there is no column 4.\r
- xor cx, cx ; scany and outputy are 0 again for\r
- mov dx, cx ; the new column\r
- add si, [input_size]\r
-@@NoNewColumn:\r
- mov [outputy], dx\r
- mov [scany], cx\r
- xor ax, ax\r
- mov word ptr [outputx], 0\r
-@@AdvanceDone:\r
- mov [scanx], ax\r
- jmp @@MainLoop\r
-\r
-@@Exit:\r
- Emitb RETURN\r
- mov ax,di\r
- sub ax,word ptr [output] ; size of generated code\r
-\r
- pop ds\r
- pop di\r
- pop si\r
- mov sp, bp\r
- pop bp\r
-\r
- ret\r
-_x_compile_pbm endp\r
-\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-; _x_sizeof_cpbm\r
-;\r
-\r
-\r
- align 2\r
-_x_sizeof_cpbm proc\r
-ARG logical_width:word,bitmap:dword\r
-LOCAL bwidth,scanx,scany,outputx,outputy,column,set_column,input_size:word=LocalStk\r
- push bp\r
- mov bp, sp ; caller's stack frame\r
- sub sp,LocalStk ; local space\r
- push si\r
- push di\r
- push ds\r
-\r
- mov word ptr [scanx], 0\r
- mov word ptr [scany], 0\r
- mov word ptr [outputx], 0\r
- mov word ptr [outputy], 0\r
- mov word ptr [column], 0\r
- mov word ptr [set_column], 0\r
-\r
- lds si,[bitmap] ; 32-bit pointer to source bitmap\r
-\r
- mov di, 1 ; initial size is just the size of the far RET\r
-\r
- lodsb ; load width byte\r
- xor ah, ah ; convert to word\r
- mov [bwidth], ax ; save for future reference\r
- mov bl, al ; copy width byte to bl\r
- lodsb ; load height byte -- already a word since ah=0\r
- mul bl ; mult height word by width byte\r
- mov [input_size], ax; to get pixel total\r
-\r
-@@MainLoop:\r
- mov bx, [scanx] ; position in original bitmap\r
- add bx, [scany]\r
-\r
- mov al, [si+bx] ; get pixel\r
- or al, al ; skip empty pixels\r
- jnz @@NoAdvance\r
- jmp @@Advance\r
-@@NoAdvance:\r
-\r
- mov dx, [set_column]\r
- cmp dx, [column]\r
- je @@SameColumn\r
-@@ColumnLoop:\r
- add di, 5 ; size of code to move to new column\r
- inc dx\r
- cmp dx,[column]\r
- jl @@ColumnLoop\r
-\r
- inc di ; size of code to set VGA mask\r
- mov [set_column], dx\r
-@@SameColumn:\r
- mov dx, [outputy] ; calculate output position\r
- add dx, [outputx]\r
- sub dx, 128\r
-\r
- inc word ptr [scanx]\r
- mov cx, [scanx] ; within four pixels of right edge?\r
- cmp cx, [bwidth]\r
- jge @@OnePixel\r
-\r
- inc word ptr [outputx]\r
- mov ah,[si+bx+1] ; get second pixel\r
- or ah, ah\r
- jnz @@TwoPixels\r
-@@OnePixel:\r
- cmp dx, 127 ; can we use shorter form?\r
- jg @@OnePixLarge\r
- cmp dx, -128\r
- jl @@OnePixLarge\r
- add di, 4 ; size of 8-bit position in output plus one pixel\r
- jmp @@EmitOnePixel\r
-@@OnePixLarge:\r
- add di, 5 ; size of position in output plus one pixels\r
-@@EmitOnePixel:\r
- jmp short @@Advance\r
-@@TwoPixels:\r
- cmp dx, 127\r
- jg @@TwoPixLarge\r
- cmp dx, -128\r
- jl @@TwoPixLarge\r
- add di, 5 ; size of 8-bit position in output plus two pixels\r
- jmp @@EmitTwoPixels\r
-@@TwoPixLarge:\r
- add di, 6 ; size of 16-bit position in output plus two pixels\r
-@@EmitTwoPixels:\r
-\r
-@@Advance:\r
- inc word ptr [outputx]\r
- mov ax, [scanx]\r
- inc ax\r
- cmp ax, [bwidth]\r
- jl @@AdvanceDone\r
- mov dx, [outputy]\r
- add dx, [logical_width]\r
- mov cx, [scany]\r
- add cx, [bwidth]\r
- cmp cx, [input_size]\r
- jl @@NoNewColumn\r
- inc word ptr [column]\r
- mov cx, [column]\r
- cmp cx, 4\r
- je @@Exit ; Column 4: there is no column 4.\r
- xor cx,cx ; scany and outputy are 0 again for\r
- mov dx,cx ; the new column\r
- add si, [input_size]\r
-@@NoNewColumn:\r
- mov [outputy], dx\r
- mov [scany], cx\r
- xor ax, ax\r
- mov word ptr [outputx], ax\r
-@@AdvanceDone:\r
- mov [scanx], ax\r
- jmp @@MainLoop\r
-\r
-@@Exit:\r
- mov ax, di ; size of generated code\r
-\r
- pop ds\r
- pop di\r
- pop si\r
- mov sp,bp\r
- pop bp\r
-\r
- ret\r
-_x_sizeof_cpbm endp\r
-\r
-end\r
-\r
+++ /dev/null
-#ifndef _XCOMPPBM_H_\r
-#define _XCOMPPBM_H_\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-\r
- int x_compile_pbm ( /* Compile a planar bitmap to generate */\r
- WORD logical_screen_width, /* machine code to plot it at any */\r
- char far * bitmap, /* required screen coordinates FAST. */\r
- char far * output);\r
-\r
- int x_sizeof_cpbm ( /* Find the size of the code which a */\r
- WORD logical_screen_width, /* pbm would result in, if it */\r
- char far * bitmap); /* were compiled (used for allocation). */\r
-\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif\r
+++ /dev/null
-global _x_compile_pbm : proc\r
-global _x_sizeof_cpbm : proc\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XDETECT\r
-;\r
-; Hardware detection module\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-LOCALS\r
-.286\r
-\r
-include model.inc\r
-include xdetect.inc\r
-\r
- .data\r
-\r
-_MouseButtonCount dw 0\r
-_MouseVersion dw 0\r
-_MouseType db 0\r
-_MouseIRQ db 0\r
-\r
- .code\r
-\r
-\r
-i86 equ 0\r
-i186 equ 1\r
-i286 equ 2\r
-i386sx equ 3\r
-i386dx equ 4\r
-i486 equ 5\r
-\r
-\r
-NONE equ 0\r
-MDA equ 1\r
-CGA equ 2\r
-EGAMono equ 3\r
-EGAColor equ 4\r
-VGAMono equ 5\r
-VGAColor equ 6\r
-MCGAMono equ 7\r
-MCGAColor equ 8\r
-\r
-PS2_CARDS db 0,1,2,2,4,3,2,5,6,2,8,7,8\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; PC Graphics detection routine. Returns graphics card type\r
-;\r
-; C callable as:\r
-; unsigned int x_graphics_card();\r
-;\r
-;\r
-\r
-proc _x_graphics_card\r
- push bp ; Preserve caller's stack frame\r
- mov bp,sp\r
- mov ax,1A00h ; Try calling VGA Identity Adapter function\r
- int 10h\r
- cmp al,1Ah ; Do we have PS/2 video bios ?\r
- jne @@not_PS2 ; No!\r
-\r
- cmp bl,0Ch ; bl > 0Ch => CGA hardware\r
- jg @@is_CGA ; Jump if we have CGA\r
- xor bh,bh\r
- xor ah,ah\r
- mov al,cs:PS2_CARDS[bx] ; Load ax from PS/2 hardware table\r
- jmp short @@done ; return ax\r
-@@is_CGA:\r
- mov ax,CGA ; Have detected CGA, return id\r
- jmp short @@done\r
-@@not_PS2: ; OK We don't have PS/2 Video bios\r
- mov ah,12h ; Set alternate function service\r
- mov bx,10h ; Set to return EGA information\r
- int 10h ; call video service\r
- cmp bx,10h ; Is EGA there ?\r
- je @@simple_adapter ; Nop!\r
- mov ah,12h ; Since we have EGA bios, get details\r
- mov bl,10h\r
- int 10h\r
- or bh,bh ; Do we have colour EGA ?\r
- jz @@ega_color ; Yes\r
- mov ax,EGAMono ; Otherwise we have Mono EGA\r
- jmp short @@done\r
-@@ega_color:\r
- mov ax,EGAColor ; Have detected EGA Color, return id\r
- jmp short @@done\r
-@@simple_adapter:\r
- int 11h ; Lets try equipment determination service\r
- and al,30h\r
- shr al,4\r
- xor ah,ah\r
- or al,al ; Do we have any graphics card at all ?\r
- jz @@done ; No ? This is a stupid machine!\r
- cmp al,3 ; Do We have a Mono adapter\r
- jne @@is_CGA ; No\r
- mov ax,MDA ; Have detected MDA, return id\r
-@@done:\r
- pop bp ;restore caller's stack frame\r
- ret\r
-_x_graphics_card endp\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; PC Processor detection routine\r
-;\r
-; C callable as:\r
-; unsigned int x_processor();\r
-;\r
-;\r
-proc _x_processor\r
- push bp\r
- mov bp,sp\r
- pushf ; Save flags\r
- xor ax,ax ; Clear AX\r
- push ax ; Push it on the stack\r
- popf ; Zero the flags\r
- pushf ; Try to zero bits 12-15\r
- pop ax ; Recover flags\r
- and ax,0F000h ; If bits 12-15 are 1 => i86 or i286\r
- cmp ax,0F000h\r
- jne @@1\r
-\r
- push cx ; save CX\r
- mov ax,0FFFFh ; Set all AX bits\r
- mov cl,33 ; Will shift once on 80186\r
- shl ax,cl ; or 33 x on 8086\r
- pop cx\r
- mov ax,i186\r
- jnz @@done\r
- mov ax,i86 ; 0 => 8086/8088\r
- jmp short @@done\r
-\r
-@@1:\r
- mov ax,07000h ; Try to set bits 12-14\r
- push ax\r
- popf\r
- pushf\r
- pop ax\r
- and ax,07000h ; If bits 12-14 are 0 => i286\r
- mov ax,i286\r
- jz @@done\r
-\r
- ;; 386/486 resolution code taken from WHATCPU.ASM by\r
- ;; Dave M. Walker\r
-\r
-\r
- P386\r
- mov eax,cr0\r
- mov ebx,eax ;Original CR0 into EBX\r
- or al,10h ;Set bit\r
- mov cr0,eax ;Store it\r
- mov eax,cr0 ;Read it back\r
- mov cr0,ebx ;Restore CR0\r
- test al,10h ;Did it set?\r
- mov ax,i386sx\r
- jz @@done ;Jump if 386SX\r
-\r
- ;*** Test AC bit in EFLAGS (386DX won't change)\r
- mov ecx,esp ;Original ESP in ECX\r
- pushfd ;Original EFLAGS in EBX\r
- pop ebx\r
- and esp,not 3 ;Align stack to prevent 486\r
- ; fault when AC is flipped\r
- mov eax,ebx ;EFLAGS => EAX\r
- xor eax,40000h ;Flip AC flag\r
- push eax ;Store it\r
- popfd\r
- pushfd ;Read it back\r
- pop eax\r
- push ebx ;Restore EFLAGS\r
- popfd\r
- mov esp,ecx ;Restore ESP\r
- cmp eax,ebx ;Compare old/new AC bits\r
- mov ax,i386dx\r
- je @@done\r
-is_486: ;Until the Pentium appears...\r
- mov ax,i486\r
-@@done:\r
- popf\r
- .286\r
- pop bp\r
- ret\r
-_x_processor endp\r
-\r
-.8086\r
-;-----------------------------------------------------------------------\r
-; PC Numeric coprocessor detection routine\r
-;\r
-; C callable as:\r
-; unsigned int x_coprocessor();\r
-;\r
-; Based on an article in PC Tech Journal, Aug 87 by Ted Forgeron\r
-;\r
-; Returns 1 if coprocessor found, zero otherwise\r
-\r
-_x_coprocessor proc\r
-ARG control:word=StkSize\r
- push bp\r
- mov bp,sp\r
- sub sp,StkSize\r
-\r
- fninit ; try to initialize the copro.\r
- mov [control],0 ; clear control word variable\r
- fnstcw control ; put control word in memory\r
- mov ax,[control] ;\r
- cmp ah,03h ; do we have a coprocessor ?\r
- je @@HaveCopro ; jump if yes!\r
- xor ax,ax ; return 0 since nothing found\r
- jmp short @@done\r
-@@HaveCopro:\r
- mov ax,1\r
-@@done:\r
- mov sp,bp\r
- pop bp\r
- ret\r
-_x_coprocessor endp\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; PC Mouse Driver detection routine\r
-;\r
-; C callable as:\r
-; unsigned int x_mousedriver();\r
-;\r
-;\r
-; Returns 1 if mouse driver found, zero otherwise\r
-_x_mousedriver proc\r
- push bp\r
- mov bp,sp\r
- mov ax,3533h ; Get int 33 interrupt vector\r
- int 21h ; Call dos\r
- xor cx,cx ; Clear "found" flag\r
- mov ax,es ; Is the vector null (ES==0 && BX==0) ?\r
- or bx,ax\r
- jz @@NoMouseDriver ; Yes! No mouse driver installed - Jump\r
-\r
- ; Just make absolutely sure the vector points to the mouse\r
- ; driver (just in case)\r
-\r
- xor ax,ax ; FUNC 0: Mouse Initialization\r
- int 33h\r
- or ax,ax ; Do we have an installed mouse driver ?\r
- jz @@NoMouseDriver; No ?\r
- mov [_MouseButtonCount],bx\r
-\r
- mov ax,24h\r
- int 33h\r
- mov [_MouseVersion],bx\r
- mov [_MouseType],ch\r
- mov [_MouseIRQ],cl\r
-\r
- mov cx,1 ; Yes! set flag\r
-\r
-@@NoMouseDriver:\r
- mov ax,cx ; Return "found" flag\r
- pop bp\r
- ret\r
-_x_mousedriver endp\r
-\r
-\r
-end
\ No newline at end of file
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XDETECT - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;-----------------------------------------------------------------------*/\r
-\r
-#ifndef _XDETECT_H_\r
-#define _XDETECT_H_\r
-\r
-#define I8086 0\r
-#define I80186 1\r
-#define I80286 2\r
-#define I80386SX 3\r
-#define I80386DX 4\r
-#define I80486 5\r
-\r
-#define NoGraphics 0\r
-#define MDA 1\r
-#define CGA 2\r
-#define EGAMono 3\r
-#define EGAColor 4\r
-#define VGAMono 5\r
-#define VGAColor 6\r
-#define MCGAMono 7\r
-#define MCGAColor 8\r
-\r
-#define BUS_MOUSE 1\r
-#define SERIAL_MOUSE 2\r
-#define INPORT_MOUSE 3\r
-#define PS2_MOUSE 4\r
-#define HP_MOUSE 5\r
-\r
-/* VARIABLES =========================================================== */\r
-\r
-extern WORD MouseButtonCount; /* number of mouse buttons */\r
-extern WORD MouseVersion; /* mouse driver version */\r
-extern WORD MouseType; /* mouse type */\r
-extern WORD MouseIRQ; /* mouse IRQ number */\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
- int x_graphics_card(void); /* Detect installed Graphics card type */\r
- int x_processor(void); /* Detect processor type */\r
- int x_coprocessor(void); /* Detect math co-processor type */\r
- int x_mousedriver(void); /* Detect math co-processor type */\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif\r
-\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XDETECT - Include file\r
-;\r
-; XDETECT.ASM export functions\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
- global _MouseButtonCount :word\r
- global _MouseVersion :word\r
- global _MouseType :byte\r
- global _MouseIRQ :byte\r
-\r
-\r
- global _x_graphics_card :proc\r
- global _x_processor :proc\r
- global _x_coprocessor :proc\r
- global _x_mousedriver :proc\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XFILEIO\r
-;\r
-; Sequential binary file I/O functions\r
-;\r
-; Some functions based on a r.g.p post by Joshua Jensen\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-COMMENT $\r
-\r
-\r
-$\r
-\r
-LOCALS\r
-.286\r
-\r
-include model.inc\r
-include xfileio.inc\r
- .data\r
-\r
- _file_err dw (?) ; error value\r
-\r
- .code\r
-\r
-PUSH_DS macro\r
- IFNDEF s\r
- push ds\r
- ENDIF\r
- endm\r
-\r
-POP_DS macro\r
- IFNDEF s\r
- pop ds\r
- ENDIF\r
- endm\r
-\r
-LDS_M macro arg1,arg2\r
- IFNDEF s\r
- lds &arg1&,&arg2&\r
- ELSE\r
- mov &arg1&,word ptr &arg2&\r
- ENDIF\r
- endm\r
-\r
-\r
-\r
-;****************************************************************\r
-;\r
-; name: f_open\r
-;\r
-; C Prototype:\r
-;\r
-; extern int f_open(char * filename, char access)\r
-;\r
-; Opens a file according to the access char:\r
-;\r
-; 0 = read only - If doesnt exist return error\r
-; 1 = write only - If doesnt exist create it otherwise clear it\r
-; 2 = read/write - If doesnt exist create it\r
-;\r
-; Returns the file handle on success, -1 on failure\r
-;\r
-;\r
-proc _f_open\r
-IFNDEF s\r
- ARG filename:dword,access:byte\r
-ELSE\r
- ARG filename:word,access:byte\r
-ENDIF\r
- push bp ; Preserve caller's stack frame\r
- mov bp,sp\r
- PUSH_DS\r
- LDS_M dx,[filename] ; point DS:DX to file name string\r
- mov [_file_err],0\r
- cmp [access],1\r
- je @@creat\r
-\r
- mov ah,3dh ; select "open file" DOS service\r
- mov al,[access] ; select access type code\r
- int 21h ; call DOS service\r
- jnb @@Done ; If carry flag set we have failed\r
-\r
-\r
- cmp [access],2\r
- jne @@error\r
-@@creat:\r
- mov ah,3ch ; select "creat file" DOS service\r
- mov cx,0\r
- int 21h ; call DOS service\r
- jnb @@Done ; If carry flag set we have failed\r
-@@error:\r
- mov [_file_err],ax\r
- mov ax,-1 ; indicate failure\r
-@@Done: ; otherwise return file handle\r
- POP_DS\r
- pop bp ;restore caller's stack frame\r
- ret\r
-_f_open endp\r
-\r
-\r
-;****************************************************************\r
-;\r
-; name: f_close\r
-;\r
-; C Prototype:\r
-;\r
-; extern int f_close(int handle)\r
-;\r
-; Closes the file associated with the specified handle\r
-;\r
-; Returns 0 on success, -1 on failure\r
-;\r
-proc _f_close\r
-ARG handle:word\r
- push bp ; Preserve caller's stack frame\r
- mov bp,sp\r
-\r
- mov [_file_err],0 ; Clear error\r
- mov ah,3eh ; select "close file handle" DOS service\r
- mov bx,[handle] ; select handle of file to close\r
- int 21h ; call DOS service\r
- jnb @@Fix ; failed if carry flag set\r
- mov [_file_err],ax;\r
- mov ax,-1 ; return error\r
- jmp short @@Done\r
-@@Fix: ; otherwise\r
- xor ax,ax ; return 0\r
-@@Done:\r
- pop bp ;restore caller's stack frame\r
- ret\r
-_f_close endp\r
-\r
-\r
-;****************************************************************\r
-;\r
-; name: f_read\r
-;\r
-; C Prototype:\r
-;\r
-; extern int f_read(int handle, char *buffer, int count)\r
-;\r
-; Reads a block of count bytes from the file specified by the handle\r
-; into the buffer\r
-;\r
-; Returns count on success, failure is detectable via _file_err\r
-;\r
-proc _f_read\r
-IFNDEF s\r
- ARG handle:word,buffer:dword,count:word\r
-ELSE\r
- ARG handle:word,buffer:word,count:word\r
-ENDIF\r
- push bp ; Preserve caller's stack frame\r
- mov bp,sp\r
- PUSH_DS\r
-\r
- mov [_file_err],0 ; Clear error\r
- mov ah,3fh ; select "read from file or device" DOS service\r
- mov bx,[handle] ; select handle of file to close\r
- mov cx,[count]\r
- LDS_M dx,[buffer]\r
- int 21h ; call DOS service\r
- jnb @@Done ; failed if carry flag set\r
- mov [_file_err],ax\r
- xor ax,ax ; return error\r
- jmp short @@Done\r
-@@Done:\r
- POP_DS\r
- pop bp ;restore caller's stack frame\r
- ret\r
-_f_read endp\r
-\r
-;****************************************************************\r
-;\r
-; name: f_write\r
-;\r
-; C Prototype:\r
-;\r
-; extern int f_write(int handle, char *buffer, int count)\r
-;\r
-; Writes a block of count bytes to the file specified by the handle\r
-; from the buffer\r
-;\r
-; Returns count on success, error is indicated by _file_err iff count = 0\r
-;\r
-proc _f_write\r
-IFNDEF s\r
- ARG handle:word,buffer:dword,count:word\r
-ELSE\r
- ARG handle:word,buffer:word,count:word\r
-ENDIF\r
- push bp ; Preserve caller's stack frame\r
- mov bp,sp\r
- PUSH_DS\r
-\r
- mov [_file_err],0 ; Clear error\r
- mov ah,40h ; select "write to file or device" DOS service\r
- mov bx,[handle] ; select handle of file to write\r
- mov cx,[count]\r
- LDS_M dx,[buffer]\r
- int 21h ; call DOS service\r
- jnb @@Done ; has the function failed ?\r
- mov [_file_err],ax\r
- xor ax,ax ; yes, return error\r
- jmp short @@Done\r
-@@Done: ; otherwise return bytes written\r
- POP_DS\r
- pop bp ; restore caller's stack frame\r
- ret\r
-_f_write endp\r
-\r
-;****************************************************************\r
-;\r
-; name: f_readfar\r
-;\r
-; C Prototype:\r
-;\r
-; extern int f_readfar(int handle, char far * buffer, int count)\r
-;\r
-; Reads a block of count bytes from the file specified by the handle\r
-; into the buffer\r
-;\r
-; Returns count on success, failure is detectable via _file_err\r
-;\r
-proc _f_readfar\r
-ARG handle:word,buffer:dword,count:word\r
- push bp ; Preserve caller's stack frame\r
- mov bp,sp\r
- push ds\r
-\r
- mov [_file_err],0 ; Clear error\r
- mov ah,3fh ; select "read from file or device" DOS service\r
- mov bx,[handle] ; select handle of file to close\r
- mov cx,[count]\r
- lds dx,[buffer]\r
- int 21h ; call DOS service\r
- jnb @@Done ; failed if carry flag set\r
- mov [_file_err],ax\r
- xor ax,ax ; return error\r
- jmp short @@Done\r
-@@Done:\r
- pop ds\r
- pop bp ;restore caller's stack frame\r
- ret\r
-_f_readfar endp\r
-\r
-;****************************************************************\r
-;\r
-; name: f_writefar\r
-;\r
-; C Prototype:\r
-;\r
-; extern int f_writefar(int handle, char far * buffer, int count)\r
-;\r
-; Writes a block of count bytes to the file specified by the handle\r
-; from the buffer\r
-;\r
-; Returns count on success, error is indicated by _file_err iff count = 0\r
-;\r
-proc _f_writefar\r
-ARG handle:word,buffer:dword,count:word\r
- push bp ; Preserve caller's stack frame\r
- mov bp,sp\r
- push ds\r
-\r
- mov [_file_err],0 ; Clear error\r
- mov ah,40h ; select "write to file or device" DOS service\r
- mov bx,[handle] ; select handle of file to write\r
- mov cx,[count]\r
- lds dx,[buffer]\r
- int 21h ; call DOS service\r
- jnb @@Done ; has the function failed ?\r
- mov [_file_err],ax\r
- xor ax,ax ; yes, return error\r
- jmp short @@Done\r
-@@Done: ; otherwise return bytes written\r
- pop ds\r
- pop bp ; restore caller's stack frame\r
- ret\r
-_f_writefar endp\r
-\r
-\r
-\r
-;****************************************************************\r
-;\r
-; name: f_seek\r
-;\r
-; C Prototype:\r
-;\r
-; extern long int f_seek(int handle, long int position, char method_code)\r
-;\r
-; Moves the file pointer according to the position and method code\r
-;\r
-; Returns file pointer position on success, -1 on failure\r
-;\r
-proc _f_seek\r
-ARG handle:word,position:dword,method_code:byte\r
- push bp ; Preserve caller's stack frame\r
- mov bp,sp\r
-\r
- mov [_file_err],0 ; Clear error\r
- mov ah,42h ; select "move file pointer" DOS service\r
- mov bx,[handle] ; select handle of file to close\r
- mov al,[method_code]\r
- mov cx,word ptr [position+2]\r
- mov dx,word ptr [position]\r
- int 21h ; call DOS service\r
- jnb @@Done ; has the function failed ?\r
- mov [_file_err],ax\r
- mov ax,-1 ; yes, return error\r
- mov dx,-1 ;\r
- jmp short @@Done\r
-@@Done: ; otherwise return bytes written\r
- pop bp ; restore caller's stack frame\r
- ret\r
-_f_seek endp\r
-\r
-;****************************************************************\r
-;\r
-; name: f_tell\r
-;\r
-; C Prototype:\r
-;\r
-; extern long int f_tell(int handle)\r
-;\r
-; Returns file pointer position on success, -1 on failure\r
-;\r
-proc _f_tell\r
-ARG handle:word,position:dword,method_code:byte\r
- push bp ; Preserve caller's stack frame\r
- mov bp,sp\r
-\r
- mov [_file_err],0 ; Clear error\r
- mov ah,42h ; select "move file pointer" DOS service\r
- mov bx,[handle] ; select handle of file to close\r
- xor dx,dx\r
- mov cx,dx\r
- int 21h\r
- jnb @@Done\r
- mov [_file_err],ax\r
- mov ax,-1 ; yes, return error\r
- mov dx,-1 ;\r
- jmp short @@Done\r
-@@Done: ; otherwise return bytes written\r
- pop bp ; restore caller's stack frame\r
- ret\r
-_f_tell endp\r
-\r
-\r
-;****************************************************************\r
-;\r
-; name: f_filelength\r
-;\r
-; C Prototype:\r
-;\r
-; extern long int f_filelength(int handle)\r
-;\r
-; Returns the length of the file associated with the specified handle\r
-;\r
-; Returns file length on success, -1 on failure\r
-;\r
-proc _f_filelength\r
-ARG handle:word\r
-LOCAL low:word,high:word=LocalStk\r
- push bp ; Preserve caller's stack frame\r
- mov bp,sp\r
- sub sp,LocalStk\r
-\r
- mov [_file_err],0 ; Clear error\r
-\r
- ; Get ptr's current location in file and save it\r
-\r
- mov ah,42h ; select "move file pointer" DOS service\r
- mov al,1 ; select "from current location" method\r
- mov bx,[handle] ; select handle of file to close\r
- xor cx,cx\r
- xor dx,dx\r
- int 21h\r
- jb @@Error\r
- mov [low],ax\r
- mov [high],dx\r
-\r
- ; Get ptr's value at end of file\r
-\r
- mov ah,42h ; select "move file pointer" DOS service\r
- mov al,2 ; select "from end of file" method\r
- mov bx,[handle] ; select handle of file to close\r
- xor cx,cx\r
- xor dx,dx\r
- int 21h\r
- jb @@Error\r
-\r
- ; Save the results while returning pointer to its previous location\r
-\r
- push ax\r
- push dx\r
-\r
- mov ah,42h ; select "move file pointer" DOS service\r
- mov al,0 ; select "from start of file" method\r
- mov bx,[handle] ; select handle of file to close\r
- mov cx,[high]\r
- mov dx,[low]\r
- int 21h\r
-\r
- ; restore resultant length\r
-\r
- pop dx\r
- pop ax\r
-\r
- jnb @@Done ; Was the operation a success ?\r
-@@Error:\r
- mov [_file_err],ax\r
- mov ax,-1 ; no, return error\r
- mov dx,-1 ;\r
-@@Done: ; otherwise return bytes written\r
- mov sp,bp\r
- pop bp ; restore caller's stack frame\r
- ret\r
-_f_filelength endp\r
-\r
-\r
- end\r
-\r
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XFILEIO - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;-----------------------------------------------------------------------*/\r
-\r
-#ifndef _XFILEIO_H_\r
-#define _XFILEIO_H_\r
-\r
-#define F_RDONLY 0\r
-#define F_WRONLY 1\r
-#define F_RDWR 2\r
-\r
-#define SEEK_START 0\r
-#define SEEK_CURR 1\r
-#define SEEK_END 2\r
-\r
-#define FILE_ERR -1\r
-\r
-#define FIO_INVALID_METHOD 1\r
-#define FIO_FILE_NOT_FOUND 2\r
-#define FIO_PATH_NOT_FOUND 3\r
-#define FIO_HANDLE_UNAVAIL 4\r
-#define FIO_ACCESS_DENIED 5\r
-#define FIO_INVALID_HANDLE 6\r
-\r
-extern int file_err;\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-\r
- int f_open( /* Open a file returning its handle */\r
- char * filename,\r
- char access);\r
-\r
- int f_close( /* Close a file */\r
- int handle);\r
-\r
- int f_read( /* Read a block of data from a file */\r
- int handle,\r
- char * buffer,\r
- int count);\r
-\r
- int f_write( /* Write a block of data to a file */\r
- int handle,\r
- char * buffer,\r
- int count);\r
-\r
- int f_readfar( /* Read a block of data from a file */\r
- int handle,\r
- char far * buffer,\r
- int count);\r
-\r
- int f_writefar( /* Write a block of data to a file */\r
- int handle,\r
- char far * buffer,\r
- int count);\r
-\r
- long int f_seek( /* Position the file pointer */\r
- int handle,\r
- long int position,\r
- char method_code);\r
-\r
- long int f_tell( /* return position the file pointer */\r
- int handle);\r
-\r
- long int f_filelength( /* Return the length of the file */\r
- int handle);\r
-\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-\r
-#endif\r
-\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XFILEIO - Include file\r
-;\r
-; XFILEIO.ASM export functions\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
- global _f_open :proc\r
- global _f_close :proc\r
- global _f_read :proc\r
- global _f_write :proc\r
- global _f_readfar :proc\r
- global _f_writefar :proc\r
- global _f_seek :proc\r
- global _f_tell :proc\r
- global _f_filelength :proc\r
-\r
- global _file_err :word
\ No newline at end of file
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XFILL\r
-;\r
-; Point functions all MODE X 256 Color resolutions\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-COMMENT $\r
-\r
- This code is my interpretation of a simple "C" flood filling algorithm\r
- titled:\r
-\r
- * A Seed Fill Algorithm\r
- * by Paul Heckbert\r
- * from "Graphics Gems", Academic Press, 1990\r
-\r
- The original C source is readily available at numerous internet archive\r
- sites.\r
-\r
- Its been modified and optimized for tweaked 13h modes (Mode X derrivatives).\r
- The most fundamental change is that it fills a column at a time rather\r
- than a row at a time to minimize the number of plane setting "out"s.\r
- And of course the border fill variant was a logical and useful further\r
- modification.\r
-\r
- Both functions return the number of pixels filled..\r
-\r
- WARNING: These fill functions make heavy use of the stack and no stack\r
- checking is performed, so caution is advised.\r
-\r
-$\r
-\r
-\r
-include xlib.inc\r
-include xfill.inc\r
-\r
- .code\r
-\r
-_x_flood_fill proc\r
- ARG X:word,Y:word,PgOfs:word,Color:word\r
- LOCAL len:word,y1:word,y2:word,deltax:word,floodval:word,\\r
- stackptr:word,FillCount:word=STK\r
- push bp\r
- mov bp,sp\r
- sub sp,STK\r
- mov [FillCount],0\r
- push di si\r
- mov si,[Y]\r
- mov ax,[_ScrnLogicalByteWidth]\r
- mul si ;offset of pixel's scan line in page\r
- mov di,[X]\r
- mov bx,di\r
- shr di,2 ;X/4 = offset of pixel in scan line\r
- add di,ax ;offset of pixel in page\r
- add di,[PgOfs] ;offset of pixel in display memory\r
- mov ax,SCREEN_SEG\r
- mov es,ax ;point ES:DI to the pixel's address\r
-\r
- ;---- Select read plane ------\r
-\r
- mov ah,bl\r
- and ah,011b ;AH = pixel's plane\r
- mov al,READ_MAP ;AL = index in GC of the Read Map reg\r
- mov dx,GC_INDEX ;set the Read Map to read the pixel's\r
- out dx,ax ; plane\r
-\r
- mov al,es:[di] ;read the pixel's color\r
- cmp al,byte ptr Color ;Is dest pixel the same color as the flood?\r
- je @@Done2 ; if it is abort.\r
-\r
- mov cx,_LeftClip ; Is the dest. pixel out of the clipping window?\r
- sal cx,2 ; if not abort.\r
- cmp bx,cx\r
- jl @@Done2\r
-\r
- mov cx,_RightClip\r
- sal cx,2\r
- cmp bx,cx\r
- jg @@Done2\r
-\r
- mov floodval,ax ; store the color to flood\r
-\r
- ;-- Push fill segment ---\r
-\r
- push bx ; X\r
- push si ; Y\r
- push si ; Y\r
- mov cx,1 ; deltaX (either 1 or -1 indicating direction)\r
- push cx\r
- mov stackptr,1\r
-\r
- mov deltax,-1 ; Initialize first column scan\r
- mov y1,si ; then bypass some of the preliminary crap in\r
- mov y2,si ; the main fill loop\r
- jmp short @@entry\r
-\r
-@@Done2:mov ax,[FillCount]\r
- pop si di\r
- mov sp,bp\r
- pop bp\r
- ret\r
-\r
-@@NextScanCol:\r
- dec stackptr\r
- js @@Done2\r
-\r
-@@WhileLoop:\r
- pop cx ; get fill segment from stack\r
- mov deltax,cx ; ie deltaX, Y1, Y2, X\r
- pop ax\r
- mov y2,ax\r
- pop si\r
- mov y1,si\r
- pop bx\r
-\r
- sub ax,si ; Acculmulate number of filled pixels\r
- jns @@PositiveY\r
- neg ax\r
-@@PositiveY:\r
- add FillCount,ax\r
-\r
-\r
- add bx,cx ; move to new column according to deltaX\r
-\r
- mov ax,bx ; Make sure the column is within the clipping\r
- sar ax,2 ; rectangle\r
- cmp ax,_LeftClip\r
- jl @@NextScanCol\r
-\r
- cmp ax,_RightClip\r
- jg @@NextScanCol\r
-\r
-\r
- ;---- Select read plane ------\r
-\r
- mov ah,bl\r
- and ah,011b ;AH = pixel's plane\r
- mov al,READ_MAP ;AL = index in GC of the Read Map reg\r
- mov dx,GC_INDEX ;set the Read Map to read the pixel's\r
- out dx,ax ; plane\r
-\r
-@@entry:\r
-\r
- ;---- Select write plane ------\r
-\r
- mov cl,bl\r
- and cl,011b ;CL = pixel's plane\r
- mov ax,0100h + MAP_MASK ;AL = index in SC of Map Mask reg\r
- shl ah,cl ;set only the bit for the pixel's\r
- ; plane to 1\r
- mov dx,SC_INDEX ;set the Map Mask to enable only the\r
- out dx,ax ; pixel's plane\r
-\r
- mov ax,_ScrnLogicalByteWidth ; store logical width in CX\r
- mov cx,ax ; get offset of scan row\r
- mul si ; set ES:DI ->\r
- mov di,bx ; address of pixel at x,y1\r
- shr di,2\r
- add di,ax\r
- add di,PgOfs ;ES:DI->first pixel of column segment to fill\r
- mov dx,di ; save y1 offset for after upward fill\r
-\r
- mov al,byte ptr Color\r
- mov ah,byte ptr floodval\r
-\r
-@@FillColUpward:\r
- cmp si,_TopClip ; Dont fill beyond clip boundaries\r
- jl @@UpwardFillDone\r
-\r
- cmp es:[di],ah ; if flood pixel color then replace\r
- jne @@UpwardFillDone ; with new color otherwise column is done\r
-\r
- mov es:[di],al\r
- sub di,cx\r
- dec si\r
- jmp short @@FillColUpward\r
-\r
-@@UpwardFillDone:\r
- cmp si,y1\r
- jge @@Skip\r
-\r
- inc si\r
- mov len,si\r
-\r
- cmp si,y1\r
- jge @@AtColumnTop\r
-\r
- push bx ; queue an upward leak check\r
- push si\r
- mov ax,y1\r
- dec ax\r
- push ax\r
- mov ax,deltax\r
- neg ax\r
- push ax\r
- inc stackptr\r
-\r
-@@AtColumnTop:\r
- mov si,y1\r
- mov di,dx\r
- add di,cx\r
- inc si\r
-\r
-\r
-@@ColumnLoop:\r
- mov ah,byte ptr floodval\r
- mov al,byte ptr Color\r
-\r
-@@DownwardFill:\r
- cmp si,_BottomClip\r
- jg @@DownwardFillDone\r
- cmp es:[di],ah\r
- jne @@DownwardFillDone\r
- mov es:[di],al\r
- add di,cx\r
- inc si\r
- jmp short @@DownwardFill\r
-\r
-@@DownwardFillDone:\r
-\r
- push bx ; queue an upward leak check\r
- mov ax,len\r
- push ax\r
- mov ax,si\r
- dec ax\r
- push ax\r
- mov ax,deltax\r
- push ax\r
- inc stackptr\r
-\r
- mov ax,y2\r
- inc ax\r
- cmp si,ax\r
- jle @@Skip\r
-\r
- push bx ; queue a downward leak check\r
- push ax\r
- mov ax,si\r
- dec ax\r
- push ax\r
- mov ax,deltax\r
- neg ax\r
- push ax\r
- inc stackptr\r
-\r
-@@Skip:\r
- mov ah,byte ptr floodval\r
- mov dx,y2\r
-\r
-@@Backtrack:\r
- add di,cx\r
- inc si\r
- cmp si,dx\r
- jg @@BacktrackDone\r
-\r
- cmp byte ptr es:[di],ah\r
- jne @@Backtrack\r
-\r
-@@BacktrackDone:\r
- mov len,si\r
- cmp si,dx\r
- jle @@ColumnLoop\r
-\r
- dec stackptr\r
- js @@Done\r
- jmp @@WhileLoop\r
-@@Done:\r
- mov ax,[FillCount]\r
- pop si di\r
- mov sp,bp\r
- pop bp\r
- ret\r
-_x_flood_fill endp\r
-\r
-\r
-_x_boundary_fill proc\r
- ARG X:word,Y:word,PgOfs:word,BoundaryColor:word,Color:word\r
- LOCAL len:word,y1:word,y2:word,deltax:word,y1_offs:word,\\r
- stackptr:word,FillCount:word=STK\r
- push bp\r
- mov bp,sp\r
- sub sp,STK\r
- mov [FillCount],0\r
- push di si\r
- mov si,[Y]\r
- mov ax,[_ScrnLogicalByteWidth]\r
- mul si ;offset of pixel's scan line in page\r
- mov di,[X]\r
- mov bx,di\r
- shr di,2 ;X/4 = offset of pixel in scan line\r
- add di,ax ;offset of pixel in page\r
- add di,[PgOfs] ;offset of pixel in display memory\r
- mov ax,SCREEN_SEG\r
- mov es,ax ;point ES:DI to the pixel's address\r
-\r
- ;---- Select read plane ------\r
-\r
- mov ah,bl\r
- and ah,011b ;AH = pixel's plane\r
- mov al,READ_MAP ;AL = index in GC of the Read Map reg\r
- mov dx,GC_INDEX ;set the Read Map to read the pixel's\r
- out dx,ax ; plane\r
-\r
- mov al,es:[di] ;read the pixel's color\r
- cmp al,byte ptr Color ;Is dest pixel the same color as the flood?\r
- je @@Done2\r
-\r
- cmp al,byte ptr BoundaryColor ;Is dest pixel the same color\r
- je @@Done2 ; as the boundary color?\r
-\r
-\r
- mov cx,_LeftClip ; Is the dest. pixel out of the clipping window?\r
- sal cx,2\r
- cmp bx,cx\r
- jl @@Done2\r
-\r
- mov cx,_RightClip\r
- sal cx,2\r
- cmp bx,cx\r
- jg @@Done2\r
-\r
- push bx ; X\r
- push si ; Y\r
- push si ; Y\r
- mov cx,1 ; DX\r
- push cx\r
- mov stackptr,1\r
- mov al,byte ptr BoundaryColor\r
- mov byte ptr [Color+1],al\r
-\r
- mov deltax,-1\r
- mov y1,si\r
- mov y2,si\r
- jmp short @@entry\r
-\r
-@@Done2:mov ax,[FillCount]\r
- pop si di\r
- mov sp,bp\r
- pop bp\r
- ret\r
-\r
-@@NextScanCol:\r
- dec stackptr\r
- js @@Done2\r
-\r
-@@WhileLoop:\r
- pop cx\r
- mov deltax,cx\r
- pop ax\r
- mov y2,ax\r
- pop si\r
- mov y1,si\r
- pop bx\r
- add bx,cx ; bx = X\r
-\r
- sub ax,si ; Acculmulate number of filled pixels\r
- jns @@PositiveY\r
- neg ax\r
-@@PositiveY:\r
- add FillCount,ax\r
-\r
-\r
-\r
- mov ax,bx ; Make sure the column is within the clipping\r
- sar ax,2 ; rectangle\r
- cmp ax,_LeftClip\r
- jl @@NextScanCol\r
- cmp ax,_RightClip\r
- jg @@NextScanCol\r
-\r
-\r
- ;---- Select read plane ------\r
-\r
- mov ah,bl\r
- and ah,011b ;AH = pixel's plane\r
- mov al,READ_MAP ;AL = index in GC of the Read Map reg\r
- mov dx,GC_INDEX ;set the Read Map to read the pixel's\r
- out dx,ax ; plane\r
-\r
-@@entry:\r
-\r
- ;---- Select write plane ------\r
-\r
- mov cl,bl\r
- and cl,011b ;CL = pixel's plane\r
- mov ax,0100h + MAP_MASK ;AL = index in SC of Map Mask reg\r
- shl ah,cl ;set only the bit for the pixel's\r
- ; plane to 1\r
- mov dx,SC_INDEX ;set the Map Mask to enable only the\r
- out dx,ax ; pixel's plane\r
-\r
- mov ax,_ScrnLogicalByteWidth ; store logical width in CX\r
- mov cx,ax ; get offset of scan row\r
- mul si ; set ES:DI ->\r
- mov di,bx ; address of pixel at x,y1\r
- shr di,2\r
- add di,ax\r
- add di,PgOfs\r
- mov y1_offs,di ; save y1 offset for after upward fill\r
-\r
- mov ax,Color ; al = Color ah = BoundaryColor\r
-\r
-@@FillColUpward:\r
- cmp si,_TopClip ; Dont fill beyond clip boundaries\r
- jl @@UpwardFillDone\r
-\r
- mov dl,es:[di]\r
- cmp dl,ah\r
- je @@UpwardFillDone\r
-\r
- cmp dl,al\r
- je @@UpwardFillDone\r
-\r
- mov es:[di],al\r
- sub di,cx\r
- dec si\r
- jmp short @@FillColUpward\r
-\r
-@@UpwardFillDone:\r
- cmp si,y1\r
- jge @@Skip\r
-\r
- inc si\r
- mov len,si\r
-\r
- cmp si,y1\r
- jge @@AtColumnTop\r
-\r
- push bx ; queue an upward leak check\r
- push si\r
- mov ax,y1\r
- dec ax\r
- push ax\r
- mov ax,deltax\r
- neg ax\r
- push ax\r
- inc stackptr\r
-\r
-@@AtColumnTop:\r
- mov si,y1\r
- mov di,y1_offs\r
- add di,cx\r
- inc si\r
-\r
-\r
-@@ColumnLoop:\r
- mov ax,Color ; al = Color ah = BoundaryColor\r
-\r
-@@DownwardFill:\r
- cmp si,_BottomClip\r
- jg @@DownwardFillDone\r
-\r
- cmp es:[di],ah\r
- je @@DownwardFillDone\r
-\r
- cmp es:[di],al\r
- je @@DownwardFillDone\r
-\r
- mov es:[di],al\r
- add di,cx\r
- inc si\r
- jmp short @@DownwardFill\r
-\r
-@@DownwardFillDone:\r
-\r
- push bx ; queue an upward leak check\r
- mov ax,len\r
- push ax\r
- mov ax,si\r
- dec ax\r
- push ax\r
- mov ax,deltax\r
- push ax\r
- inc stackptr\r
-\r
- mov ax,y2\r
- inc ax\r
- cmp si,ax\r
- jle @@Skip\r
-\r
- push bx ; queue a downward leak check\r
- push ax\r
- mov ax,si\r
- dec ax\r
- push ax\r
- mov ax,deltax\r
- neg ax\r
- push ax\r
- inc stackptr\r
-\r
-@@Skip:\r
- mov ax,Color ; al = Color ah = BoundaryColor\r
-\r
-@@Backtrack:\r
- add di,cx\r
- inc si\r
- cmp si,y2\r
- jg @@BacktrackDone\r
-\r
- mov dl,byte ptr es:[di]\r
- cmp dl,al\r
- je @@Backtrack\r
-\r
- cmp dl,ah\r
- je @@Backtrack\r
-\r
-@@BacktrackDone:\r
- mov len,si\r
- cmp si,y2\r
- jle @@ColumnLoop\r
-\r
- dec stackptr\r
- js @@Done\r
- jmp @@WhileLoop\r
-@@Done:\r
- mov ax,[FillCount]\r
- pop si di\r
- mov sp,bp\r
- pop bp\r
- ret\r
-_x_boundary_fill endp\r
-\r
-end\r
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XFILL - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;----------------------------------------------------------------------*/\r
-\r
-#ifndef _XFILL_H_\r
-#define _XFILL_H_\r
-\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-int x_flood_fill(int x,\r
- int y,\r
- unsigned ofs,\r
- int color\r
- );\r
-\r
-int x_boundary_fill(int x,\r
- int y,\r
- unsigned ofs,\r
- int boundary,\r
- int color\r
- );\r
-\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif\r
-\r
-\r
+++ /dev/null
-global _x_flood_fill:proc\r
-global _x_boundary_fill:proc
\ No newline at end of file
+++ /dev/null
-/*----------------------------------------------------------------------\r
-;\r
-; XLIB - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; Header file contributed by Darren Lyon (darren@nicky.DIALix.oz.au)\r
-;\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;----------------------------------------------------------------------*/\r
-\r
-#ifndef _XLIB_H_\r
-#define _XLIB_H_\r
-\r
-#define BYTE unsigned char\r
-#define WORD unsigned int\r
-\r
-\r
-#define X_MODE_320x200 0\r
-#define X_MODE_320x240 1\r
-#define X_MODE_360x200 2\r
-#define X_MODE_360x240 3\r
-#define X_MODE_376x282 4\r
-#define X_MODE_320x400 5\r
-#define X_MODE_320x480 6\r
-#define X_MODE_360x400 7\r
-#define X_MODE_360x480 8\r
-#define X_MODE_360x360 9\r
-#define X_MODE_376x308 10\r
-#define X_MODE_376x564 11\r
-#define X_MODE_256x400 12\r
-#define X_MODE_256x480 13\r
-\r
-\r
-#define BACKWARD 0\r
-#define FORWARD 1\r
-\r
-#define X_MODE_INVALID -1\r
-#define ERROR 1\r
-#define OK 0\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
- WORD x_set_mode(\r
- WORD mode, /* Initialize x mode */\r
- WORD WidthInPixels);\r
-\r
- void x_select_default_plane( /*Enables Read/Write access to a */\r
- BYTE plane); /* a specified plane */\r
-\r
- void x_set_splitscreen( /* set the split screen start */\r
- WORD line); /*scan line (initialize) */\r
-\r
- void x_set_start_addr(\r
- WORD X, /* Set the screen start */\r
- WORD Y); /* address in video ram */\r
-\r
- void x_hide_splitscreen(void); /* Disable the split screen (Split */\r
- /* Screen RAM remains reserved) */\r
-\r
- void x_show_splitscreen(void); /* Enable the split screen (given it */\r
- /* was previously "hidden") */\r
-\r
-\r
- void x_adjust_splitscreen( /* Adjust the start scan line of the */\r
- WORD line); /* split screen */\r
-\r
-\r
- WORD x_set_doublebuffer( /* Enable double buffering with a */\r
- WORD PageHeight); /* specified page height */\r
-\r
- WORD x_set_tripplebuffer( /* Enable tripple buffering with a */\r
- WORD PageHeight); /* specified page height */\r
-\r
-\r
- void x_page_flip( /* Swap visible page (only when double */\r
- WORD X, /* buffering is active) & sets virt start*/\r
- WORD Y);\r
-\r
- void x_set_cliprect( /* Define the clipping rectangle */\r
- WORD left, /* NOTE: left and right are in bytes */\r
- WORD top,\r
- WORD righ,\r
- WORD bottom);\r
-\r
- void x_text_mode(void); /* return to text mode */\r
- void x_wait_vsync(void); /* wait for vsync */\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-\r
-/* VARIABLES =========================================================== */\r
-\r
-extern BYTE InGraphics; /* non zero if in X graphics mode */\r
-extern WORD CurrXMode; /* contains current X graphics mode id */\r
-extern WORD ScrnPhysicalByteWidth; /* Physical screen width in bytes */\r
-extern WORD ScrnPhysicalPixelWidth; /* Physical screen width in pixels */\r
-extern WORD ScrnPhysicalHeight; /* Physical screen height in pixels */\r
-extern WORD ErrorValue; /* Error return value */\r
-extern WORD SplitScrnOffs; /* Offset in VRAM of split screen */\r
-extern WORD SplitScrnScanLine; /* Scan line split screen starts at */\r
- /* initially. Resizing the split scrn */\r
- /* using the other functions does not */\r
- /* change this value */\r
-extern WORD SplitScrnVisibleHeight; /* Height of the visible portion of the*/\r
- /* split screen. */\r
-extern WORD Page0_Offs; /* Offset in VRAM of main virt. screen */\r
-extern WORD Page1_Offs; /* Offset in VRAM of 2nd virt. screen */\r
-extern WORD Page2_Offs; /* Offset in VRAM of 3rd virt. screen */\r
-extern WORD ScrnLogicalByteWidth; /* Virtual screen width in bytes */\r
-extern WORD ScrnLogicalPixelWidth; /* Virtual screen width in pixels */\r
-extern WORD ScrnLogicalHeight; /* Virtual screen height in pixels */\r
-extern WORD MaxScrollX; /* Max X position of physical screen */\r
- /* within virtual screen */\r
-extern WORD MaxScrollY; /* Max Y position of physical screen */\r
- /* within virtual screen */\r
-extern WORD DoubleBufferActive; /* Indicates whether double buffering */\r
- /* is active */\r
-extern WORD TrippleBufferActive; /* Indicates whether tripple */\r
- /* buffering is active */\r
-extern WORD VisiblePageIdx; /* Index number of visible page 0 or 1 */\r
-extern WORD HiddenPageOffs; /* Offset of Hidden Pg | only valid */\r
-extern WORD VisiblePageOffs; /* Offset of Visible Pg| for D.B. mode */\r
-extern WORD WaitingPageOffs; /* Offset of Waiting Pg| for T.B. mode */\r
-extern WORD NonVisual_Offs; /* Offset of first non-visible VRAM */\r
-\r
-extern WORD StartAddressFlag;\r
-\r
-extern WORD TopClip; /* Clipping rectangle */\r
-extern WORD BottomClip;\r
-extern WORD LeftClip;\r
-extern WORD RightClip;\r
-\r
-extern WORD PhysicalStartPixelX; /* Coordinates of physical (visible) */\r
-extern WORD PhysicalStartByteX; /* screen relative to the virtual */\r
-extern WORD PhysicalStartY; /* screen's U.L. corner */\r
-\r
-extern char* VsyncPaletteBuffer;\r
-\r
-#endif\r
-\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XLIB - Include file\r
-;\r
-; Global equates and variables\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; MODIFICATIONS:\r
-; 26-9-92 : Pel panning code added\r
-; 23-10-92: Added clip rectangle code\r
-;-----------------------------------------------------------------------\r
-\r
-;\r
-\r
-LOCALS\r
-.286\r
-\r
-; First lets find out what memory model to use\r
-\r
-include model.inc\r
-\r
-\r
-AC_INDEX equ 03c0h ;Attribute controller index register\r
-MISC_OUTPUT equ 03c2h ;Miscellaneous Output register\r
-SC_INDEX equ 03c4h ;Sequence Controller Index\r
-GC_INDEX equ 03ceh ; Graphics controller Index\r
-CRTC_INDEX equ 03d4h ;CRT Controller Index\r
-DAC_READ_INDEX equ 03c7h ;\r
-DAC_WRITE_INDEX equ 03c8h ;\r
-DAC_DATA equ 03c9h ;\r
-INPUT_STATUS_0 equ 03dah ;Input status 0 register\r
-\r
-\r
-SCREEN_SEG equ 0a000h ;segment of display memory in mode X\r
-\r
-MAP_MASK equ 02h ;index in SC of Map Mask register\r
-READ_MAP equ 04h ;index in GC of the Read Map register\r
-BIT_MASK equ 08h ;index in GC of Bit Mask register\r
-\r
-OVERFLOW equ 07h ; CRTC overflow register index\r
-MAX_SCAN_LINE equ 09h ; CRTC maximum scan line register index\r
-ADDR_HIGH equ 0ch ;Index of Start Address High reg in CRTC\r
-ADDR_LOW equ 0dh ; Low\r
-CRTC_OFFSET equ 13h ; CRTC offset register index\r
-UNDERLINE equ 14h ; CRTC underline location register index\r
-MODE_CONTROL equ 17h ; CRTC mode control register index\r
-LINE_COMPARE equ 18h ; CRTC line compare reg. index (bits 0-7 of\r
- ; split screen scan line\r
-\r
-AC_MODE_CONTROL equ 10h ; Index of Mode COntrol register in AC\r
-PEL_PANNING equ 13h ; Pel panning register index in AC\r
-\r
-PATTERN_BUFFER equ 0fffch ;offset in screen memory of pattern buffer\r
-\r
-TRUE equ 1\r
-FALSE equ 0\r
-\r
-\r
-OK equ 0\r
-ERROR equ 1\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; Macro to wait for the vertical retrace leading edge\r
-\r
-WaitVsyncStart macro\r
- LOCAL WaitNotVsync,WaitVsync\r
- mov dx,INPUT_STATUS_0\r
-WaitNotVsync:\r
- in al,dx\r
- test al,08h\r
- jnz WaitNotVsync\r
-WaitVsync:\r
- in al,dx\r
- test al,08h\r
- jz WaitVsync\r
- endm\r
-\r
-;-----------------------------------------------------------------------\r
-; Macro to wait for the vertical retrace trailing edge\r
-\r
-WaitVsyncEnd macro\r
- LOCAL WaitNotVsync,WaitVsync\r
- mov dx,INPUT_STATUS_0\r
-WaitVsync2:\r
- in al,dx\r
- test al,08h\r
- jz WaitVsync2\r
-WaitNotVsync2:\r
- in al,dx\r
- test al,08h\r
- jnz WaitNotVsync2\r
- endm\r
-\r
-;--- Word out macro ------------------------------------------\r
-\r
- WORDOUT macro\r
- IFDEF nw\r
- out dx,al\r
- inc dx\r
- xchg al,ah\r
- out dx,al\r
- xchg al,ah\r
- dec dx\r
- ELSE\r
- out dx,al\r
- ENDIF\r
- endm\r
-\r
-;------------------------------------------------------------------------\r
-; Global variables - XMAIN exports\r
-;\r
- global _InGraphics :byte\r
- global _CurrXMode :word\r
- global _ScrnPhysicalByteWidth :word\r
- global _ScrnPhysicalPixelWidth :word\r
- global _ScrnPhysicalHeight :word\r
- global _ErrorValue :byte\r
-\r
- global _SplitScrnOffs :word\r
- global _SplitScrnScanLine :word\r
- global _SplitScrnVisibleHeight :word\r
- global _Page0_Offs :word\r
- global _Page1_Offs :word\r
- global _Page2_Offs :word\r
- global _ScrnLogicalByteWidth :word\r
- global _ScrnLogicalPixelWidth :word\r
- global _ScrnLogicalHeight :word\r
-\r
- global _MaxScrollX :word\r
- global _MaxScrollY :word\r
- global _DoubleBufferActive :word\r
- global _TrippleBufferActive :word\r
- global _VisiblePageIdx :word\r
- global _VisiblePageOffs :word\r
- global _HiddenPageOffs :word\r
- global _WaitingPageOffs :word\r
- global _NonVisual_Offs :word\r
- global _TopClip :word\r
- global _BottomClip :word\r
- global _LeftClip :word\r
- global _RightClip :word\r
-\r
- global _PhysicalStartByteX :word\r
- global _PhysicalStartPixelX :word\r
- global _PhysicalStartY :word\r
-\r
- global _VsyncHandlerActive :word\r
- global _MouseRefreshFlag :word\r
- global _MouseVsyncHandler :dword\r
- global _StartAddressFlag :word\r
- global _WaitingStartLow :word\r
- global _WaitingStartHigh :word\r
- global _WaitingPelPan :word\r
- global _VsyncPaletteStart :word\r
- global _VsyncPaletteCount :word\r
- global _VsyncPaletteBuffer :byte\r
-\r
-\r
+++ /dev/null
-PART 1 of 2\r
------------------------------------------------------------------------------\r
-\r
- ********* XLIB - Mode X graphics library ****************\r
- ********* ****************\r
- ********* Written By Themie Gouthas ****************\r
- ********* ****************\r
- ********* egg@dstos3.dsto.gov.au ****************\r
- ********* teg@bart.dsto.gov.au ****************\r
-\r
- Some of the code in this library has been contributed by :\r
-\r
- Matthew MacKenzie - matm@eng.umd.edu\r
-\r
- and others. See individual modules.\r
-\r
- I informally reserve all rights to the code in XLIB\r
- Rights to contributed code is also assumed to be reserved by\r
- the original authors.\r
------------------------------------------------------------------------------\r
-\r
-DISCLAIMER\r
-\r
- This library is distributed AS IS. The author/s specifically disclaim\r
- any responsibility for any loss of profit or any incidental, consequen-\r
- tial or other damages.\r
-\r
----------------------------------------------------------------------------\r
-INTRODUCTION\r
----------------------------------------------------------------------------\r
-\r
-XLIB is a "user supported freeware" graphics library specifically designed\r
-with game programming in mind.\r
-\r
-It has been placed in the public domain for the benefit of all, and\r
-represents *MANY* hours of work so it is requested that all users comply\r
-with the the wishes of the author/s as specified in the individual modules\r
-and:\r
-a) To leave the code in the public domain\r
-b) Not distribute any modified or incomplete versions of this library\r
-\r
-New contribution and comments are welcome and hopefully there will be\r
-more releases as the code evolves.\r
-\r
-Finally, do not trust this excuse for a manual if in doubt, as this code has\r
-undergone several revisions. The place to get the answers is in the code\r
-itself.\r
-\r
-REQUIREMENTS\r
-\r
-Minimum requirements\r
- 286 processor,\r
- Turbo C 2.0 or higher, or BORLANDC\r
- MAKE 2.0 or higher\r
- TLIB 2.0 or higher\r
- Turbo Assembler 1.01 or higher\r
-\r
-\r
-GENERAL FEATURES\r
-\r
- Support for a number of 256 colour tweaked graphics mode resolutions\r
- 320x200 320x240 360x200 360x240 376x282 320x400 320x480 360x400 360x480\r
- 360x360 376x308 376x564\r
-\r
- Please note that some of the new resolutions best suit monitors with\r
- adjustable vertical height.\r
-\r
- Virtual screens larger than the physical screen (memory\r
- permitting) that can be panned at pixel resolution in all directions\r
-\r
- A split screen capability for status displays etc.\r
-\r
- Text functions supporting 8x8 and 8x14 ROM fonts and user defined fonts\r
-\r
- Support for page flipping\r
-\r
- Graphics primitives such as line and rectangle drawing functions and\r
- of course bit block manipulation functions\r
-\r
-MODULES COMPRISING XLIB\r
- XMAIN - Main module containig mode setting code and basic functions\r
- XPOINT - Pixel functions\r
- XRECT - Filled Rectangle and VRAM to VRAM block move functions\r
- XPAL - Palette functions\r
- XLINE - Line Functions\r
- XTEXT - Text and Font Functions\r
- XPRINTF - Printf style string output\r
- XPBITMAP - Planar Bitmap functions\r
- XCBITMAP - Compiled Bitmap functions\r
- XVBITMAP - Video Bitmap functions\r
- XPBMCLIP - Clipped Planar Bitmap functions\r
- XMAKEVBM - Support module for video bitmaps\r
- XBMTOOLS - Bitmap format conversion tools\r
- XDETECT - Hardware detection module\r
- XFILEIO - File I/O functions\r
- XRLETOOL - RLE encoding/decoding functions\r
- XMOUSE - Mouse functions\r
- XBEZIER - Bezier curve drawing\r
-\r
--------------------------------------------------------------------------\r
-BUILDING THE LIBRARIES\r
--------------------------------------------------------------------------\r
-\r
-Building the library had been made simple through the use of make.\r
-\r
-To build and examples for one of the two models:\r
-\r
-a) edit the makefile for the apropriate model (see note in the makefile)\r
-b) edit the makefile for the apropriate compiler (again see note in the\r
- makefile)\r
-c) type "make" at the dos prompt.\r
-\r
-It should be as simple as that. If problems are encountered then check\r
-to see if tasm, make, tlib, link and bcc (or tcc) are withinin your path.\r
-If not either change your path or specify the full path for these programs\r
-in the makefile. It is preferrable to have your path set correctly.\r
-\r
-Individual Compilation\r
-----------------------\r
-\r
-each ASM module can be compiled with the following commandline:\r
-\r
-tasm /ml /d<model> <asm module name>\r
-\r
-where <model> is s c or l. Where s = small model, c = compact model and\r
-l = large model.\r
-\r
-The resulting libraries are:\r
-\r
- xlib<version>s.lib - small model library\r
- xlib<version>c.lib - large model library\r
- xlib<version>l.lib - large model library\r
-\r
-To link the library with your programs just include the apropriate .lib\r
-file in your project file or on the BCC or TCC command line.\r
-\r
-Using the library with your programs\r
-------------------------------------\r
-\r
-Using the XLIB library in your programs is simple. Knowing the particular\r
-modules you require, just include the associated header files in your program\r
-and link your program modules with the library. If you don't want to wory\r
-about selecting the apropriate header file then just include "XLIB_ALL.H"\r
-which automatically includes all XLIB header files in your program.\r
-\r
-For example compilations see the supplied makefile.\r
-\r
---------------------------------------------------------------------------\r
-GLOBAL DEFINES (xlib.inc)\r
---------------------------------------------------------------------------\r
-\r
-Types\r
-\r
- BYTE unsigned char\r
- WORD unsigned int\r
-\r
-Available X mode resolutions\r
-\r
- X_MODE_320x200 0\r
- X_MODE_320x240 1\r
- X_MODE_360x200 2\r
- X_MODE_360x240 3\r
- X_MODE_360x282 4\r
- X_MODE_320x400 5\r
- X_MODE_320x480 6\r
- X_MODE_360x400 7\r
- X_MODE_360x480 8\r
- X_MODE_360x360 9\r
- X_MODE_376x308 10\r
- X_MODE_376x564 11\r
-\r
-Palette rotation direction directiion\r
-\r
- BACKWARD 0\r
- FORWARD 1\r
-\r
-\r
- X_MODE_INVALID -1\r
- ERROR 1\r
- OK 0\r
-\r
-\r
---------------------------------------------------------------------------\r
-MODULE XMAIN\r
---------------------------------------------------------------------------\r
-\r
-The Xmain module is the base module of the XLIB library. It contains the\r
-essential functions that initialize and customize the graphic environment.\r
-\r
-\r
-ASM SOURCES\r
-\r
- xmain.asm xmain.inc xlib.inc model.inc\r
-\r
-C HEADER FILE\r
-\r
- xlib.h\r
-\r
-EXPORTED VARIABLES\r
-\r
- NOTE: All variables are read only unless otherwise specified. If you modify\r
- them manually, the results may be unpredictable.\r
-\r
- InGraphics - BYTE - Flag indicating that the xlib graphics system is\r
- active. Set by function "x_set_mode".\r
-\r
- CurrXMode - WORD - If the xlib graphics system is active, contains the id\r
- of the x mode. Set by function "x_set_mode".\r
- See also defines (ie X_MODE_320x200 ... )\r
-\r
- ScrnPhysicalByteWidth - WORD - Physical screen width in bytes. Set by\r
- function "x_set_mode"\r
-\r
- ScrnPhysicalPixelWidth - WORD - Physical screen width in pixels. Set by\r
- function "x_set_mode"\r
-\r
- ScrnPhysicalHeight - WORD - Physical screen height in pixels. Set by\r
- function "x_set_mode".\r
-\r
- ErrorValue - WORD - Contains error value. General use variable to\r
- communicate the error status from several functions. The value\r
- in this variable usually is only valid for the the last\r
- function called that sets it.\r
-\r
- SplitScrnOffs - WORD - Offset in video ram of split screen. Set by\r
- function "x_set_splitscrn". The value is only valid if a split\r
- screen is active. See also global variable "SplitScrnActive".\r
-\r
- SplitScrnScanLine - WORD - Screen Scan Line the Split Screen starts at\r
- initially when set by function "x_set_splitscrn". The value is only\r
- valid if a split screen is active. See also global variable\r
- "SplitScrnActive".This variable is not updated by "x_hide_splitscrn",\r
- "x_adjust_splitscrn".\r
-\r
- SplitScrnVisibleHeight - WORD - The number of rows of the initial split\r
- screen which are currently displayed. Modified by "x_hide_splitscrn",\r
- "x_adjust_splitscrn" and "x_show_splitscrn".\r
-\r
- Page0_Offs - WORD - Offset in video ram of main virtual screen. Initially\r
- set by function "x_set_mode" but is updated by functions\r
- "x_set_splitscrn" and "x_set_doublebuffer".\r
-\r
- Page1_Offs - WORD - Offset in video ram of second virtual screen. Set by\r
- and only is valid after a call to "x_set_doublebuffer".\r
-\r
- ScrnLogicalByteWidth - WORD - Virtual screen width in bytes. Set by\r
- function "x_set_mode".\r
-\r
- ScrnLogicalPixelWidth - WORD - Virtual screen width in pixels. Set\r
- by function "x_set_mode".\r
-\r
- ScrnLogicalHeight - WORD - Virtual screen height in pixels. Set\r
- initially by function "x_set_mode" but is updated by functions\r
- "x_set_splitscrn" and "x_set_doublebuffer".\r
-\r
- MaxScrollX - WORD - Max X pixel position of physical screen within\r
- virtual screen. Set by function "x_set_mode".\r
-\r
- MaxScrollY - WORD - Max Y position of physical screen within virtual\r
- screen. Set initially by function "x_set_mode" but is updated by\r
- functions "x_set_splitscrn" and "x_set_doublebuffer".\r
-\r
- DoubleBufferActive - WORD - Indicates whether double-buffering is on. Set\r
- by function "x_set_doublebuffer".\r
-\r
- VisiblePageIdx - WORD - Index number of current visible page. Initially\r
- set by function "x_set_doublebuffer" but is updated by "x_page_flip".\r
- This variable is only used while double buffering is on.\r
-\r
- HiddenPageOffs - WORD - Offset of hidden page. Initially set by function\r
- "x_set_doublebuffer" but is updated by "x_page_flip". This variable\r
- is only used while double buffering is on.\r
-\r
- VisiblePageOffs - WORD - Offset of visible page. Initially set by function\r
- "x_set_doublebuffer" but is updated by "x_page_flip". This variable\r
- is only used while double buffering is on.\r
-\r
- NonVisual_Offs - WORD - Offset of first byte of non-visual ram, the ram\r
- that is available for bitmap storage etc. Set initially by function\r
- "x_set_mode" but is updated by functions "x_set_splitscrn" and\r
- "x_set_doublebuffer".\r
-\r
- TopClip, BottomClip, LeftClip RightClip - WORD - Define the clipping\r
- rectangle for Linear and Video clipped bitmap put functions. Set\r
- either manually or by "x_set_cliprect". Note X coordinates are in\r
- bytes as all clip functions clip to byte boundaries.\r
-\r
- PhysicalStartPixelX - WORD - X pixel Offset of physical (visible) screen\r
- relative to the upper left hand corner (0,0) of the virtual screen.\r
-\r
- PhysicalStartByteX - WORD - X byte Offset of physical (visible) screen\r
- relative to the upper left hand corner (0,0) of the virtual screen.\r
-\r
- PhysicalStartY - WORD - Y pixel Offset of physical (visible) screen\r
- relative to the upper left hand corner (0,0) of the virtual screen.\r
-\r
-EXPORTED FUNCTIONS\r
-\r
- x_set_mode\r
- ----------\r
- C Prototype: extern WORD x_set_mode(WORD mode,WORD WidthInPixels);\r
-\r
- mode - The required mode as defined by the "Available X Mode\r
- resolutions" set of defines in the xlib.h header file.\r
- WidthInPixels - The required virtual screen width.\r
- Returns - The actual width in pixels of the allocated virtual\r
- screen\r
-\r
- This function initialises the graphics system, setting the apropriate\r
- screen resolution and allocating a virtual screen. The virtual screen\r
- allocated may not necessarily be of the same size as specified in the\r
- "WidthInPixels" parameter as it is rounded down to the nearest\r
- multiple of 4.\r
-\r
- The function returns the actual width of the allocated virtual screen\r
- in pixels if a valid mode was selected otherwise returns\r
- X_MODE_INVALID.\r
-\r
- Saves virtual screen pixel width in "ScrnLogicalPixelWidth".\r
- Saves virtual screen byte width in "ScrnLogicalByteWidth".\r
- Physical screen dimensions are set in "ScrnPhysicalPixelWidth".\r
- "ScrnPhysicalByteWidth" and "ScrnPhysicalHeight". Other global\r
- variables set are "CurrXMode","MaxScrollX", "MaxScrollY",\r
- "InGraphics". The variable "SplitScrnScanline" is also initialized\r
- to zero.\r
-\r
- See also:\r
- Available X Mode resolutions\r
- What is Mode X\r
-\r
- x_select_default_plane\r
- ----------------------\r
-\r
- C Prototype: void x_select_default_plane(BYTE plane);\r
-\r
- Enables default Read/Write access to a specified plane\r
-\r
-\r
- x_set_splitscreen\r
- -----------------\r
-\r
- C Prototype: extern void x_set_splitscreen(WORD line);\r
-\r
- line - The starting scan line of the required split screen.\r
-\r
- This function activates Mode X split screen and sets starting scan\r
- line. The split screen resides on the bottom half of the screen and has\r
- a starting address of A000:0000 in video RAM.\r
-\r
- It also Updates Page0_Offs to reflect the existence of the split screen\r
- region ie "MainScrnOffset" is set to the offset of the first pixel\r
- beyond the split screen region. Other variable set are "Page1_Offs" which\r
- is set to the same value as "Page0_Offs" (see graphics call sequence\r
- below), "ScrnLogicalHeight","ScrnPhysicalHeight", "SplitScrnScanLine" and\r
- "MaxScrollY".\r
-\r
- This function cannot be called after double buffering has been activated,\r
- it will return an error. To configure your graphics environment the\r
- sequence of graphics calls is as follows although either or both steps b\r
- and c may be omitted:\r
- a) x_set_mode\r
- b) x_set_splitscreen\r
- c) x_set_doublebuffer\r
- Thus when you call this function successfully, double buffering is not\r
- active so "Page1_Offs" is set to the same address as "Page0_Offs".\r
-\r
- WARNING: If you use one of the high resolution modes (376x564 as an\r
- extreme example) you may not have enough video ram for split screen\r
- and double buffering options since VGA video RAM is restricted to\r
- 64K.\r
-\r
- See Also:\r
- What is a Split Screen ?\r
- What is double buffering ?\r
-\r
- x_set_doublebuffer\r
- ------------------\r
-\r
- C Prototype: extern WORD x_set_doublebuffer(WORD PageHeight);\r
-\r
- PageHeight - The height of the two double buffering virtual screens.\r
- Returns - The closest possible height to the specified.\r
-\r
- This function sets up two double buffering virtual pages. 'ErrorValue"\r
- is set according to the success or failure of this command.\r
-\r
- Other variables set are:\r
-\r
- _Page1_Offs Offset of second virtual page\r
- _NonVisual_Offs Offset of first non visible video ram byte\r
- _DoubleBufferActive Flag\r
- _PageAddrTable Table of Double buffering pages start offsets\r
- _ScrnLogicalHeight Logical height of the double buffering pages\r
- _MaxScrollY Max vertical start address of physical screen\r
- within the virtual screen\r
-\r
- WARNING: If you use one of the high resolution modes (376x564 as an\r
- extreme example) you may not have enough video ram for split screen\r
- and double buffering options since VGA video RAM is restricted to\r
- 64K.\r
-\r
- See Also:\r
- What is double buffering ?\r
-\r
- x_hide_splitscreen\r
- ------------------\r
-\r
- C Prototype: extern void x_hide_splitscreen(void);\r
-\r
-\r
- This function hides an existing split screen by setting its starting\r
- scan line to the last physical screen scan line.\r
- "ScreenPhysicalHeight" is adjusted but the "SplitScreenScanLine" is not\r
- altered as it is required for restoring the split screen at a later stage.\r
-\r
- WARNING: Only to be used if SplitScrnLine has been previously called\r
- Disabled for mode 5-11 (320x400-376x564). The memory for\r
- the initial split screen is reserved and the size limitations\r
- of these modes means any change in the split screen scan line\r
- will encroach on the split screen ram\r
- Update: Now disabled for these modes\r
-\r
- See Also:\r
-\r
- What is a split screen ?\r
-\r
- x_show_splitscreen\r
- ------------------\r
-\r
- C Prototype: extern void x_show_splitscreen(void);\r
-\r
- Restores split screen start scan line to the initial split screen\r
- starting scan line as set by "SplitScrnScanLine".\r
- "ScreenPhysicalHeight" is adjusted.\r
-\r
- WARNING: Only to be used if SplitScrnLine has been previously called\r
- Disabled for mode 4-10 (320x400-376x564). The memory for\r
- the initial split screen is reserved and the size limitations\r
- of these modes means any change in the split screen scan line\r
- will encroach on the split screen ram\r
-\r
-\r
- x_adjust_splitscreen\r
- --------------------\r
-\r
- C Prototype: extern void x_adjust_splitscreen(WORD line);\r
-\r
- line - The scan line at which the split screen is to start.\r
-\r
- Sets the split screen start scan line to a new scan line. Valid scan lines\r
- are between the initial split screen starting scan line and the last\r
- physical screen scan line. "ScreenPhysicalHeight" is also adjusted.\r
-\r
- WARNING: Only to be used if SplitScrnLine has been previously called\r
- Disabled for mode 4-10 (320x400-376x564). The memory for\r
- the initial split screen is reserved and the size limitations\r
- of these modes means any change in the split screen scan line\r
- will encroach on the split screen ram\r
-\r
- x_set_start_addr\r
- ----------------\r
-\r
- C Prototype: extern void x_set_start_addr(WORD X,WORD Y);\r
-\r
- X,Y - coordinates of top left corner of physical screen within current\r
- virtual screen.\r
-\r
- Set Mode X non split screen physical start address within current virtual\r
- page.\r
-\r
- X must not exceed (Logical screen width - Physical screen width)\r
- ie "MaxScrollX" and Y must not exceed (Logical screen height -\r
- Physical screen height) ie "MaxScrollY"\r
-\r
- x_page_flip\r
- -----------\r
-\r
- C Prototype: extern void x_page_flip(WORD X,WORD Y);\r
-\r
- X,Y - coordinates of top left corner of physical screen within the\r
- the hidden virtual screen if double buffering is active, or\r
- the current virtual screen otherwise.\r
-\r
- Sets the physical screen start address within currently hidden virtual\r
- page and then flips pages. If double buffering is not active then this\r
- function is functionally equivalent to "x_set_start_addr".\r
-\r
- X must not exceed (Logical screen width - Physical screen width)\r
- ie "MaxScrollX" and Y must not exceed (Logical screen height -\r
- Physical screen height) ie "MaxScrollY"\r
-\r
- x_text_mode\r
- -----------\r
-\r
- C Prototype: extern void x_text_mode(void);\r
-\r
- Disables graphics mode.\r
-\r
- x_set_cliprect\r
- --------------\r
-\r
- C Prototype: extern void x_set_cliprect(WORD left,WORD top,WORD right,\r
- WORD bottom);\r
-\r
- Defines the clipping rectangle for clipping versions of planar and video\r
- bitmap puts.\r
-\r
- NOTE: Compiled bitmaps cannot be clipped.\r
-\r
-\r
---------------------------------------------------------------------------\r
-MODULE XPOINT\r
---------------------------------------------------------------------------\r
-\r
- Point functions all MODE X 256 Color resolutions\r
-\r
- ASM SOURCES\r
-\r
- xpoint.asm xpoint.inc xlib.inc model.inc\r
-\r
- C HEADER FILE\r
-\r
- xpoint.h\r
-\r
- EXPORTED FUNCTIONS\r
-\r
- x_put_pix\r
- ---------\r
-\r
- C Prototype: extern void x_put_pix(WORD X,WORD Y,WORD PageOffset,\r
- WORD Color);\r
-\r
- Draw a point of specified colour at coordinates X,Y\r
- within the virtual page starting at offset PageOffset.\r
-\r
- x_get_pix\r
- ---------\r
-\r
- C Prototype: extern WORD x_get_pix(WORD X, WORD Y, WORD PageBase);\r
-\r
- Read a point of at coordinates X,Y within the virtual page starting\r
- at offset PageOffset.\r
-\r
-\r
---------------------------------------------------------------------------\r
-MODULE XRECT\r
---------------------------------------------------------------------------\r
-\r
- Screen rectangle display and manipulation functions\r
-\r
- ASM SOURCES\r
-\r
- xrect.asm xrect.inc xlib.inc model.inc\r
-\r
- C HEADER FILE\r
-\r
- xrect.h\r
-\r
-\r
- EXPORTED FUNCTIONS\r
-\r
- x_rect_pattern\r
- --------------\r
-\r
- C Prototype: extern void x_rect_pattern(WORD StartX, WORD StartY,\r
- WORD EndX, WORD EndY,\r
- WORD PageBase,BYTE far *Pattern);\r
-\r
- StartX,StartY - Coordinates of upper left hand corner of rectangle\r
- EndX,EndY - Coordinates of lower right hand corner of rectangle\r
- PageBase - Offset of virtual screen\r
- *Pattern - Pointer to the user defined pattern (16 bytes)\r
-\r
-\r
- Mode X rectangle 4x4 pattern fill routine.\r
-\r
- Upper left corner of pattern is always aligned to a multiple-of-4\r
- row and column. Works on all VGAs. Uses approach of copying the\r
- pattern to off-screen display memory, then loading the latches with\r
- the pattern for each scan line and filling each scan line four\r
- pixels at a time. Fills up to but not including the column at EndX\r
- and the row at EndY. No clipping is performed.\r
-\r
- Based on code originally published in DDJ Mag by M. Abrash\r
-\r
- Warning the VGA memory locations PATTERN_BUFFER (A000:FFFc) to\r
- A000:FFFF are reserved for the pattern buffer\r
-\r
-\r
- See Also:\r
- Doctor Dobbs Journal references.\r
-\r
-\r
- x_rect_pattern_clipped\r
- ----------------------\r
-\r
- As above but clipped.\r
-\r
- x_rect_fill\r
- -----------\r
-\r
- C Prototype: extern void x_rect_fill(WORD StartX,WORD StartY,\r
- WORD EndX,WORD EndY,\r
- WORD PageBase,WORD color);\r
-\r
- StartX,StartY - Coordinates of upper left hand corner of rectangle\r
- EndX,EndY - Coordinates of lower right hand corner of rectangle\r
- PageBase - Offset of virtual screen\r
- Color -color to use for fill\r
-\r
- Mode X rectangle solid color fill routine.\r
- Based on code originally published in DDJ Mag by M. Abrash\r
-\r
- See Also:\r
- Doctor Dobbs Journal references.\r
-\r
- x_rect_fill_clipped\r
- -------------------\r
-\r
- as above but clipped.\r
-\r
-\r
- x_cp_vid_rect\r
- -------------\r
-\r
- C Prototype: extern void x_cp_vid_rect(WORD SourceStartX,WORD SourceStartY,\r
- WORD SourceEndX,WORD SourceEndY,\r
- WORD DestStartX,WORD DestStartY,\r
- WORD SourcePageBase,WORD DestPageBase,\r
- WORD SourceBitmapWidth,WORD DestBitmapWidth);\r
-\r
- StartX,StartY- Coordinates of upper left hand corner of source rectangle\r
- EndX,EndY - Coordinates of lower right hand corner of source rectangle\r
- DestStartX,DestStartY - Coordinates of rectangle destination\r
- SourcePageBase - source rectangle page offset\r
- DestPageBase - destination rectangles page offset\r
- SourceBitmapWidth - width of bitmap within the source virtual screen\r
- containing the source rectangle\r
- DestBitmapWidth - width of bitmap within the dest. virtual screen\r
- containing the destination rectangle\r
-\r
- Mode X display memory to display memory copy\r
- routine. Left edge of source rectangle modulo 4 must equal left edge\r
- of destination rectangle modulo 4. Works on all VGAs. Uses approach\r
- of reading 4 pixels at a time from the source into the latches, then\r
- writing the latches to the destination. Copies up to but not\r
- including the column at SrcEndX and the row at SrcEndY. No\r
- clipping is performed. Results are not guaranteed if the source and\r
- destination overlap.\r
-\r
-\r
- Based on code originally published in DDJ Mag by M. Abrash\r
-\r
- See Also:\r
- Doctor Dobbs Journal references.\r
-\r
- x_shift_rect\r
- ------------\r
-\r
- C Prototype:\r
- extern void x_shift_rect (WORD SrcLeft, WORD SrcTop,\r
- WORD SrcRight, WORD SrcBottom,\r
- WORD DestLeft, WORD DestTop, WORD ScreenOffs);\r
-\r
- SrcLeft, SrcTop - Coordinates of upper left hand corner of rectangle\r
- SrcRight, SrcBottom - Coordinates of lower right hand corner of rectangle\r
- DestLeft, DestTop - Coordinates of upper left corner of destination\r
- ScreenOffs - Offset of virtual screen\r
-\r
- This function copies a rectangle of VRAM onto another area of VRAM,\r
- even if the destination overlaps with the source. It is designed\r
- for scrolling text up and down, and for moving large areas of screens\r
- around in tiling systems. It rounds all horizontal coordinates to\r
- the nearest byte (4-column chunk) for the sake of speed. This means\r
- that it can NOT perform smooth horizontal scrolling. For that,\r
- either scroll the whole screen (minus the split screen), or copy\r
- smaller areas through system memory using the functions in the\r
- XPBITMAP module.\r
-\r
- SrcRight is rounded up, and the left edges are rounded down, to\r
- ensure that the pixels pointed to by the arguments are inside the\r
- the rectangle. That is, SrcRight is treated as (SrcRight+3) >> 2,\r
- and SrcLeft as SrcLeft >> 2.\r
-\r
- The width of the rectangle in bytes (width in pixels / 4)\r
- cannot exceed 255.\r
-\r
----------------------------------------------------------------------------\r
-MODULE XPAL\r
----------------------------------------------------------------------------\r
-\r
- Palette functions for VGA 256 color modes.\r
-\r
- All the functions in this module operate on two variations of the\r
- pallete buffer, the raw and annotated buffers.\r
-\r
- All those functions ending in "raw" operate on the following palette\r
- structure:\r
-\r
- BYTE:r0,g0,b0,r1,g1,b1,...rn,gn,bn\r
-\r
- No reference to the starting colour index or number of colours stored\r
- is contained in the structure.\r
-\r
- All those functions ending in "struc" operate on the following palette\r
- structure:\r
-\r
- BYTE:c,BYTE:n,BYTE:r0,g0,b0,r1,g1,b1,...rn,gn,bn\r
-\r
- where c is the starting colour and n is the number of colours stored\r
-\r
-\r
- WARNING: There is no validity checking in these functions. The onus is\r
- on the user to supply valid parameters to the functions.\r
-\r
-\r
- ASM SOURCES\r
-\r
- xpal.asm xpal.inc xlib.inc model.inc\r
-\r
- C HEADER FILE:\r
-\r
- xpal.h\r
-\r
- EXPORTED FUNCTIONS\r
-\r
- x_get_pal_raw\r
- -------------\r
-\r
- C Prototype: extern void x_get_pal_raw(BYTE far * pal,WORD num_colrs,\r
- WORD start_index);\r
-\r
- Read DAC palette into raw buffer with interrupts disabled\r
- ie BYTE r1,g1,b1,r1,g2,b2...rn,gn,bn\r
-\r
- WARNING: Memory for the palette buffers must all be pre-allocated.\r
-\r
- x_get_pal_struc\r
- ---------------\r
-\r
- C Prototype: extern void x_get_pal_struc(BYTE far * pal,WORD num_colrs,\r
- WORD start_index);\r
-\r
- Read DAC palette into annotated type buffer with interrupts disabled\r
- ie BYTE colours to skip, BYTE colours to set, r1,g1,b1,r1,g2,b2...rn,gn,bn\r
-\r
- WARNING: memory for the palette buffers must all be pre-allocated\r
-\r
- x_put_pal_raw\r
- -------------\r
-\r
- C Prototype: extern void x_put_pal_raw(BYTE far * pal,WORD num_colrs,\r
- WORD start_index);\r
-\r
- Write DAC palette from raw buffer with interrupts disabled\r
- ie BYTE r1,g1,b1,r1,g2,b2...rn,gn,bn\r
-\r
- x_put_pal_struc\r
- --------------\r
-\r
- C Prototype: extern void x_put_pal_struc(BYTE far * pal);\r
-\r
- Write DAC palette from annotated type buffer with interrupts disabled\r
- ie BYTE colours to skip, BYTE colours to set, r1,g1,b1,r1,g2,b2...rn,gn,bn\r
-\r
- x_set_rgb\r
- ---------\r
-\r
- C Prototype: extern x_set_rgb(BYTE color,BYTE red_c,BYTE green_c,\r
- BYTE blue_c);\r
-\r
- Set the RGB components of a vga color\r
-\r
- x_rot_pal_struc\r
- ---------------\r
-\r
- C Prototype: extern void x_rot_pal_struc(BYTE far * pal,WORD direction);\r
-\r
- Rotate annotated palette buffer entries. Direction 0 = backward,\r
- 1 = forward.\r
-\r
- x_rot_pal_raw\r
- -------------\r
-\r
- C Prototype: extern x_rot_pal_raw(BYTE far * pal,WORD direction,\r
- WORD num_colrs);\r
-\r
- Rotate a raw palette buffer. Direction 0 = backward,\r
- 1 = forward.\r
-\r
- x_put_contrast_pal_struc\r
- ------------------------\r
-\r
- C Prototype: extern void x_put_contrast_pal_struc(BYTE far * pal,\r
- BYTE intensity);\r
-\r
- Write DAC palette from annotated type buffer with specified intensity\r
- adjustment (ie palette entries are decremented where possible by\r
- "intensity" units).\r
-\r
- Designed for fading in or out a palette without using an intermediate\r
- working palette buffer ! (Slow but memory efficient ... OK for small\r
- pal strucs}\r
-\r
-\r
- x_transpose_pal_struc\r
- ---------------------\r
-\r
- C Prototype: extern void x_transpose_pal_struc(BYTE far * pal,\r
- WORD StartColor);\r
-\r
- Write DAC palette from annotated type buffer with interrupts disabled\r
- starting at a new palette index.\r
-\r
-\r
- x_cpcontrast_pal_struc\r
- ----------------------\r
-\r
- C Prototype: extern WORD x_cpcontrast_pal_struc(BYTE far *src_pal,\r
- BYTE far *dest_pal,BYTE Intensity);\r
-\r
- Copy one annotated palette buffer to another making the intensity\r
- adjustment. Used in fading in and out fast and smoothly.\r
-\r
----------------------------------------------------------------------------\r
-MODULE XLINE\r
----------------------------------------------------------------------------\r
-\r
- Line Drawing functions.\r
-\r
- ASM SOURCES\r
-\r
- xline.asm xline.inc xlib.inc model.inc\r
-\r
- C HEADER FILE\r
-\r
- xline.h\r
-\r
- EXPORTED FUNCTIONS\r
-\r
- x_line\r
- ------\r
-\r
- C Prototype: extern void x_line(WORD x0,WORD y0,WORD x1,WORD y1,\r
- WORD color,WORD PageBase);\r
-\r
- Draw a line with the specified end points in the page starting at\r
- offset "PageBase".\r
-\r
- No Clipping is performed.\r
-\r
----------------------------------------------------------------------------\r
-MODULE XTEXT\r
----------------------------------------------------------------------------\r
-\r
- ASM SOURCES\r
-\r
- xtext.asm xtext.inc xlib.inc model.inc\r
-\r
- C HEADER FILE\r
-\r
- xtext.h\r
-\r
- MACROS\r
-\r
- FONT_8x8 0\r
- FONT_8x15 1\r
- FONT_USER 2\r
-\r
- EXPORTED VARIABLES\r
-\r
- NOTE: All variables are read only. I you modify them the results may\r
- be unpredictable.\r
-\r
- CharHeight - BYTE - Height of current inbuilt character set\r
-\r
- CharWidth - BYTE - Width of current inbuilt character set\r
-\r
- FirstChar - BYTE - First character of current inbuilt character set\r
-\r
- UserCharHeight - BYTE - Height of current user character set\r
-\r
- UserCharWidth - BYTE - Width of current user character set\r
-\r
- UserFirstCh - BYTE - First character of current user character set\r
-\r
-\r
- EXPORTED FUNCTIONS\r
-\r
- x_text_init\r
- -----------\r
-\r
- C Prototype: extern WORD x_text_init(void);\r
-\r
- Initializes the Mode X text driver and sets the default font (VGA ROM 8x8)\r
-\r
- x_set_font\r
- ----------\r
-\r
- C Prototype: extern void x_set_font(WORD FontId);\r
-\r
- Select the working font where 0 = VGA ROM 8x8, 1 = VGA ROM 8x14\r
- 2 = User defined bitmapped font.\r
-\r
- WARNING: A user font must be registered before setting FontID 2\r
-\r
- See Also:\r
-\r
- Defines for this module\r
-\r
- x_register_userfont\r
- -------------------\r
-\r
- C Prototype: extern void x_register_userfont(char far *UserFontPtr);\r
-\r
-\r
- Register a user font for later selection. Only one user font can be\r
- registered at any given time. Registering a user font deregisters the\r
- previous user font. User fonts may be at most 8 pixels wide.\r
-\r
- USER FONT STRUCTURE\r
-\r
- Word: ascii code of first char in font\r
- Byte: Height of chars in font\r
- Byte: Width of chars in font\r
- n*h*Byte: the font data where n = number of chars and h = height\r
- of chars\r
-\r
- WARNING: The onus is on the program to ensure that all characters\r
- drawn whilst this font is active, are within the range of\r
- characters defined.\r
-\r
- x_put_char\r
- ----------\r
-\r
- C Prototype: extern void x_put_char(char ch,WORD X,WORD Y,WORD PgOffs,\r
- WORD Color);\r
-\r
- Draw a text character at the specified location with the specified\r
- color.\r
-\r
- ch - char to draw\r
- x,y - screen coords at which to draw ch\r
- ScrnOffs - Starting offset of page on whih to draw\r
- Color - Color of the text\r
-\r
- WARNING: InitTextDriver must be called before using this function\r
-\r
-\r
- **** NOTE ****\r
-\r
- The file "xprintf.c" implements a printf style formatted output function\r
-\r
- x_printf\r
- --------\r
-\r
- C Prototype: void x_printf(int x,int y,unsigned ScrnOffs,int color,\r
- char *ln,...);\r
-\r
- x,y - screen coords at which to draw ch\r
- ScrnOffs - Starting offset of page on whih to draw\r
- Color - Color of the text\r
-\r
- Parameters beyond Color conform to the standard printf parameters.\r
-\r
- x_bgprintf\r
- ----------\r
-\r
- C Prototype: void x_bgprintf(int x,int y,unsigned ScrnOffs,int fgcolor,\r
- int bgcolor, char *ln,...);\r
-\r
- x,y - screen coords at which to draw ch\r
- ScrnOffs - Starting offset of page on whih to draw\r
- fgcolor - Color of the text foreground\r
- bgcolor - Color of the text background\r
-\r
- Parameters beyond bgolor conform to the standard printf parameters.\r
-\r
-\r
- x_get_char_width\r
- ----------------\r
-\r
- C Prototype: unsigned int x_get_char_width(char ch)\r
-\r
- ch - character to get width of\r
-\r
---------------------------------------------------------------------------\r
-MODULE XPBITMAP\r
---------------------------------------------------------------------------\r
-\r
- This module implements a set of functions to operate on planar bitmaps.\r
- Planar bitmaps as used by these functions have the following structure:\r
-\r
- BYTE 0 The bitmap width in bytes (4 pixel groups) range 1..255\r
- BYTE 1 The bitmap height in rows range 1..255\r
- BYTE 2..n1 The plane 0 pixels width*height bytes\r
- BYTE n1..n2 The plane 1 pixels width*height bytes\r
- BYTE n2..n3 The plane 2 pixels width*height bytes\r
- BYTE n3..n4 The plane 3 pixels width*height bytes\r
-\r
- These functions provide the fastest possible bitmap blts from system ram to\r
- to video and further, the single bitmap is applicable to all pixel\r
- allignments. The masked functions do not need separate masks since all non\r
- zero pixels are considered to be masking pixels, hence if a pixel is 0 the\r
- corresponding screen destination pixel is left unchanged.\r
-\r
-\r
- ASM SOURCES\r
-\r
- xpbitmap.asm xpbitmap.inc xlib.inc model.inc\r
-\r
- C HEADER FILE\r
-\r
- xpbitmap.h\r
-\r
- EXPORT FUNCTIONS\r
-\r
- x_put_masked_pbm\r
- ----------------\r
-\r
- C Prototype: extern void x_put_masked_pbm(WORD X,WORD Y,WORD ScrnOffs,\r
- BYTE far * Bitmap);\r
-\r
- Mask write a planar bitmap from system ram to video ram. All zero source\r
- bitmap bytes indicate destination byte to be left unchanged.\r
-\r
- Source Bitmap structure:\r
-\r
- Width:byte, Height:byte, Bitmap data (plane 0)...Bitmap data (plane 1)..,\r
- Bitmap data (plane 2)..,Bitmap data (plane 3)..\r
-\r
- NOTE: width is in bytes ie lots of 4 pixels\r
-\r
- LIMITATIONS: No clipping is supported\r
- Only supports bitmaps with widths which are a multiple of\r
- 4 pixels\r
-\r
- See Also: XBMTOOLS module for linear <-> planar bitmap conversion\r
- functions.\r
-\r
- x_put_pbm\r
- ---------\r
-\r
- C Prototype: extern void x_put_pbm(WORD X, WORD Y, WORD ScrnOffs,\r
- BYTE far * Bitmap);\r
-\r
- Write a planar bitmap from system ram to video ram.\r
-\r
- Source Bitmap structure:\r
-\r
- Width:byte, Height:byte, Bitmap data (plane 0)...Bitmap data (plane 1)..,\r
- Bitmap data (plane 2)..,Bitmap data (plane 3)..\r
-\r
- NOTE: width is in bytes ie lots of 4 pixels\r
-\r
- LIMITATIONS: No clipping is supported\r
- Only supports bitmaps with widths which are a multiple of\r
- 4 pixels\r
-\r
-\r
- See Also: XBMTOOLS module for linear <-> planar bitmap conversion\r
- functions.\r
-\r
- x_get_pbm\r
- ---------\r
-\r
- C Prototype: extern void x_get_pbm(WORD X, WORD Y,BYTE Bw,BYTE Bh,\r
- WORD ScrnOffs, BYTE far * Bitmap);\r
-\r
- Read a planar bitmap to system ram from video ram.\r
-\r
- Source Bitmap structure:\r
-\r
- Width:byte, Height:byte, Bitmap data (plane 0)...Bitmap data (plane 1)..,\r
- Bitmap data (plane 2)..,Bitmap data (plane 3)..\r
-\r
- NOTE: width is in bytes ie lots of 4 pixels\r
-\r
- LIMITATIONS: No clipping is supported\r
- Only supports bitmaps with widths which are a multiple of\r
- 4 pixels\r
-\r
-\r
- See Also: XBMTOOLS module for linear <-> planar bitmap conversion\r
- functions.\r
-\r
---------------------------------------------------------------------------\r
-MODULE XPBMCLIP\r
---------------------------------------------------------------------------\r
-\r
- This module implements a similar set of functions to operate on planar\r
- bitmaps as "XPBITMAP" but incorporates clipping to a user defined\r
- clipping rectangle (which is set by "x_set_cliprect" in module xmain).\r
-\r
- The planar bitmap format is identical to the above module\r
-\r
- There are three variations of the functions in XPBITMAP in this module\r
- identified by the three function name extensions: _clipx, _clipy _clipxy.\r
- Because speed is critical in games programming you do not want to be\r
- checking for clipping if not necessary thus for sprites that move only\r
- horizontally you would use the _clipx version of the put function,\r
- for sprites that move vertically you would use the _clipy version and for\r
- sprites that move both directions you would use the clipxy version.\r
- Keep in mind also that the clipping components of these functions assume\r
- that the clipping rectangle is equal to or larger than the size of the\r
- bitmap ie. if a bitmap is top clipped, it is assumed that the bitmap's\r
- bottom is not also clipped. Similarly with horizontal clipping.\r
-\r
- Note: performance in decreasing order is as follows.\r
- _clipy,_clipx,_clipxy with masked puts being slower than unmasked\r
- puts\r
-\r
- Horizontal clipping is performed to byte boundaries (4 pixels) rather than\r
- pixels. This allows for the fastest implementation of the functions. It is\r
- not such a handicap because for one, your screen width a multiple of 4\r
- pixels wide and for most purposes it is the screen edges that form the\r
- clipping rectangle.\r
-\r
- Following is an example of setting a clipping rectangle to the logical\r
- screen edges:\r
-\r
- x_set_cliprect(0,0,ScrnLogicalByteWidth,ScrnLogicalHeight)\r
-\r
- NOTE: the functions now return a value;\r
- 1 if clipped image is fully clipped (ie no portion of it\r
- appears on the screen) otherwise it returns 0\r
-\r
-\r
- ASM SOURCES\r
-\r
- xpbmclip.asm xpbmclip.inc xlib.inc model.inc\r
-\r
- C HEADER FILE\r
-\r
- xpbmclip.h\r
-\r
- EXPORT FUNCTIONS\r
-\r
- x_put_pbm_clipx\r
- ---------------\r
- x_put_pbm_clipy\r
- ---------------\r
- x_put_pbm_clipxy\r
- ----------------\r
- x_put_masked_pbm_clipx\r
- ----------------------\r
- x_put_masked_pbm_clipy\r
- ----------------------\r
- x_put_masked_pbm_clipxy\r
- -----------------------\r
-\r
- For a detailed description of parameters etc. see equivalent functions\r
- in module "XPBITMAP".\r
-\r
-\r
---------------------------------------------------------------------------\r
-MODULE XCBITMAP\r
---------------------------------------------------------------------------\r
-\r
- XCBITMAP:\r
- The Care and Feeding of Compiled Masked Blits\r
- by Matthew MacKenzie\r
-\r
-The XCBITMAP module of the Xlib library is made up of the files\r
-XCBITMAP.ASM, XCBITMAP.INC, and XCBITMAP.H.\r
-\r
-The XCBITMAP module is small, containing only three procedures:\r
- o x_compile_bitmap compiles your bitmap into native code which writes\r
- to the VGA screen in an X mode.\r
- o x_put_cbitmap converts X and Y coordinates into a location on the\r
- screen, sets up the necessary VGA registers, and executes the compiled\r
- bitmap as a subroutine.\r
- o x_sizeof_cbitmap takes a planar bitmap and returns an integer equal to\r
- the size of the compiled bitmap which the planar bitmap would produce.\r
- It is essentially a lobotomized version of x_compile_bitmap, with all\r
- the code generation replaced with a size counter.\r
-\r
- x_compile_bitmap scans through a source bitmap and generates 8086\r
-instructions to plot every nonzero pixel. It is designed to be used\r
-before the action begins rather than on-the-fly. The compiled bitmap\r
-contains no branches, and no reference to the zero (transparent) pixels.\r
-Where two pixels are exactly four columns apart they are plotted with a\r
-single 16-bit store, and the VGA MAP_MASK register will be set at most\r
-four times. As a result your bitmap may run several times faster than a\r
-traditional memory-to-VGA masked blit routine.\r
- There is no way to perform clipping on these bitmaps, or to plot a\r
-pixel of color zero.\r
- x_compile_bitmap works with bitmaps in the standard Xlib planar bitmap\r
-format. On a time scale of 60 frames per second, it is actually relatively\r
-slow. Since a compiled bitmap is relocatable you may just want to have it\r
-saved to disk, and not include the source bitmap in your program at all.\r
- The source bitmap format is an array of bytes, a little like this:\r
-\r
-char eye[] ={4, 7, /* four byte columns across, seven rows tall */\r
- 0, 0, 0, 0, 9, 1, 1, 1, 9, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 9, 9, 1, 1, 1, 4, 4, 9, 9, 0, 0, 0, 0, 0,\r
- 0, 9, 9, 1, 2, 0, 0, 4, 4, 1, 9, 9, 0, 0, 0, 0,\r
- 9, 9, 9, 1, 0, 0, 0, 0, 1, 1, 9, 9, 9, 0, 0, 0,\r
- 0, 9, 9, 1, 2, 0, 0, 2, 1, 1, 9, 9, 0, 0, 0, 0,\r
- 0, 0, 9, 9, 1, 1, 1, 1, 1, 9, 9, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 9, 1, 1, 1, 9, 0, 0, 0, 0, 0, 0, 0};\r
-\r
- This is actually a linear bitmap, which is the wrong format for\r
-compilation, but is easier on human eyes. Use the module XBMTOOLS to\r
-convert linear bitmaps into planar bitmaps, and vice-versa.\r
- To compile this image for a mode 360 pixels (90 byte columns) across:\r
-\r
-char planar_eye[4*7 + 2];\r
-char far * EyeSize;\r
-\r
-(void) x_bm_to_pbm((char far *) eye, (char far *) planar_eye);\r
-EyeSize = x_sizeof_cbitmap((far char *) planar_eye);\r
-CompiledEye = farmalloc(EyeSize);\r
-(void) x_compile_bitmap(90, (far char *) planar_eye, CompiledEye);\r
-\r
- Notice that both buffers must exist beforehand. Since x_compile_bitmap\r
-returns the size of the compiled code, in bytes, you can reallocate the\r
-bitmap immediately to the right size if using x_sizeof_xbitmap seems\r
-inconvenient (reallocation may even be faster, though using the function is\r
-cleaner). The pointers are 32-bit because compiled bitmaps take so much\r
-space: they are at one end of the speed-versus-memory spectrum. A good\r
-rule of thumb is to allocate (3.5 x buffer-height x buffer-width) + 25\r
-bytes (rounding up ;-), then pare your bitmap down when you find out how\r
-much space you've actually used.\r
- Since the compiled bitmap has to fit within one segment of memory, it\r
-cannot contain more than about 19,000 pixels. This will not be a\r
-limitation for most sane programmers. If you are not a sane programmer try\r
-splitting your huge, unwieldy image up into smaller parts -- you can use\r
-the same gigantic bitmap if you divide it into horizontal slices for\r
-compilation. For that matter, dividing the source up that way will let\r
-you use a source bitmap large than 64K, which is an even sicker idea...\r
- Back to business. A bitmap is compiled for only one width of screen.\r
-If you are using a logical screen larger than your physical screen, call\r
-the bitmap compiler with the logical width -- the important thing is the\r
-number of bytes per line. Notice that you do not have to be in a graphics\r
-mode to use this routine. This allows you to develop and compile bitmaps\r
-separately, with whatever utility programs you might cook up.\r
-\r
- The final function is x_put_cbitmap. To plot our eye at (99,4), on\r
-the page which starts at location 0:\r
-x_put_cbitmap(99, 4, 0, CompiledEye);\r
- This function depends on the global variable ScrnLogicalByteWidth from\r
-the module XMAIN, which should be the same number as the column parameter\r
-you used to compile your bitmap.\r
- The XCBITMAP module supports memory-to-VGA blits only. Xlib also\r
-includes non-masking routines which can quickly save and restore the\r
-background screen behind your bitmap, using fast string operations.\r
-\r
- This module is part of the Xlib package, and is in the public domain.\r
-If you write something which uses it, though, please send me a copy as a\r
-courtesy -- if for no other reason so I can tilt my chair back and reflect\r
-that it may have been worth the trouble after all.\r
-\r
-The included program DEMO2.C demonstrates the performance difference\r
-between planar bitmap masked blits and compiled bitmap blits.\r
-\r
---------------------------------------------------------------------------\r
-MODULE XCOMPPBM\r
---------------------------------------------------------------------------\r
-\r
-Identical to XCBITMAP except that the source bitmaps are the PBM form\r
-rather than LBM.\r
-\r
-FUNCTIONS\r
-\r
-x_compile_pbm\r
--------------\r
-x_sizeof_cpbm\r
--------------\r
-\r
-See XCBITMAP module\r
-\r
---------------------------------------------------------------------------\r
-MODULE XVBITMAP\r
---------------------------------------------------------------------------\r
-\r
-The XVBITMAP module implements yet another type of bitmap to complement\r
-planar and compiled bitmaps, VRAM based bitmaps. If a 4 cylinder car is\r
-analagous to planar bitmaps, that is thrifty on memory consumption but low\r
-performance and and a V8 is analagous to Compiled bitmaps, memory guzzlers\r
-that really fly, then VRAM based bitmaps are the 6 cylinder modest performers\r
-with acceptable memory consumption.\r
-\r
-To summarise their selling points, VBM's are moderately fast with fair memory\r
-consumption, and unlike compiled bitmaps, can be clipped. The disadvantages\r
-are that they are limited by the amount of free video ram and have a complex\r
-structure.\r
-\r
-The VRAM bitmap format is rather complex consisting of components stored in\r
-video ram and components in system ram working together. This complexity\r
-necessitates the existence of a creation function "x_make_vbm" which takes\r
-an input linear bitmap and generates the equivalent VBM (VRAM Bit Map).\r
-\r
-VBM structure:\r
-\r
- WORD 0 Size Total size of this VBM structure in bytes\r
- WORD 1 ImageWidth Width in bytes of the image (for all alignments)\r
- WORD 2 ImageHeight Height in scan lines of the image\r
-\r
- WORD 3 Alignment 0 ImagePtr Offset in VidRAM of this aligned image\r
- +--WORD 4 MaskPtr Offset (within this structure's DS) of\r
- | . alignment masks\r
- | .\r
- | .\r
- | WORD 9 Alignment 3 ImagePtr Offset in VidRAM of this aligned image\r
- +|--WORD 10 MaskPtr Offset (within this structure's DS) of\r
- || alignment masks\r
- ||\r
- |+->BYTE 21 (WORD 11) -------+-- Image masks for alignment 0\r
- | . |\r
- | . |\r
- | BYTE 21 + ImageWidth*ImageHeight -----+\r
- |\r
- | .\r
- | . (similaly for alignments 1 - 2 )\r
- | .\r
- |\r
- +-->BYTE 21 + 3*ImageWidth*ImageHeight + 1-+-- Image masks for alignment 3\r
- . |\r
- . |\r
- BYTE 21 + 4*(ImageWidth*ImageHeight) --+\r
-\r
- .\r
- .\r
- << Similarly for alignments 2 and 3 >>\r
- .\r
- .\r
- BYTE 21 + 4*(ImageWidth*ImageHeight)\r
- -------------\r
-\r
- (And dont forget the corresponding data in video ram)\r
-\r
-You can see for yourself the complexity of this bitmap format. The image\r
-is stored in video ram in its 4 different alignments with pointers to these\r
-alignments in the VBM. Similarly there are 4 alignments of the corresponding\r
-masks within the VBM itself (towards the end). The mask bytes contain the\r
-plane settings for the corresponding video bytes so that one memory move can\r
-move up to 4 pixels at a time (depending on the mask settings) using the\r
-VGA's latches, theoretically giving you a 4x speed improvement over\r
-conventional blits like the ones implemented in "XPBITMAP". In actual fact\r
-its anywhere between 2 and 3 due to incurred overheads.\r
-\r
-These bitmaps are more difficult to store in files than PBM'S and CBM's but\r
-still posible with a bit of work, so do not dismiss these as too difficult\r
-to use. Consider all the bitmap formats carefully before deciding on which\r
-to use. There may even be situations that a careful application of all three\r
-types would be most effective ie. compiled bitmaps for Background tiles and\r
-the main game character (which never need clipping), VRAM based bitmaps for\r
-the most frequently occuring (oponent, alien etc) characters which get\r
-clipped as they come into and leave your current location and planar bitmaps\r
-for smaller or less frequently encountered characters.\r
-\r
-ASM SOURCES\r
-\r
- xvbitmap.asm xvbitmap.inc xlib.inc model.inc\r
- xmakevbm.c - Additional C module implementing creation function\r
-\r
- C HEADER FILE\r
-\r
- xvbitmap.h\r
-\r
- EXPORTED FUNCTIONS\r
-\r
- x_make_vbm\r
- ----------\r
-\r
- C Prototype: extern char far * x_make_vbm(char far *lbm, WORD *VramStart);\r
-\r
- Create the VBM from the given linear bitmap and place the image alignments\r
- in video ram starting at the offset in the variable pointed to by\r
- "VramStart". "VramStart" is then updated to point to the next free VRAM byte\r
- (just after the last byte of the image alignments). Usually you will point\r
- "VramStart" to "NonVisual_Offs".\r
-\r
- lbm Pointer to the input linear bitmap\r
- VramStart Pointer to variable containing Offset of first free VRAM byte\r
-\r
- x_put_masked_vbm\r
- ----------------\r
-\r
- C Prototype: extern int x_put_masked_vbm(int X, int Y, WORD ScrnOffs,\r
- BYTE far * VBitmap);\r
-\r
- Draw a VRAM based bitmap at (X,Y) relative to the screen with starting\r
- offset "ScrnOffs".\r
-\r
- Returns 1 if clipped image is fully clipped (ie no portion of it\r
- appears on the screen) otherwise it returns 0\r
-\r
- x_put_masked_vbm_clipx\r
- ----------------------\r
- x_put_masked_vbm_clipy\r
- ----------------------\r
- x_put_masked_vbm_clipxy\r
- -----------------------\r
-\r
- Clipping versions of "x_put_masked_vbm".\r
-\r
- See XPBMCLIP for more details on the type of clipping used as it is\r
- identical to XVBITMAP.\r
-\r
---------------------------------------------------------------------------\r
-MODULE XMOUSE\r
---------------------------------------------------------------------------\r
-The XMOUSE module implements very basic mouse handling functions. The way\r
-in which it operates is by installing an event handler function during\r
-initialization which subsequently intercepts and processes mouse events and\r
-automatically updates status variables such as mouse position and button\r
-pressed status. It does not support the full functionality of:\r
-\r
- SPLIT SCREENS\r
- SCROLLED WINDOWS\r
- VIRTUAL WINDOWS\r
-\r
-This was done to primarily prevent unecessary impedences to performance,\r
-since the mouse handler function has the potential to degrade performance.\r
-It also saves me alot of coding which I was too lazy to do.\r
-\r
-Programs communicate with the mouse driver as with other devices, through\r
-an interrupt vector namely 33h. On generating an interrupt, the mouse driver\r
-expects a function number in AX and possibly other parameters in other\r
-registers and returns information via the registers. A brief description\r
-of the mouse functions follows:\r
-\r
- --------------------------------------\r
-\r
- MS Mouse Driver Functions\r
-\r
- Mouse Initialization 0\r
- Show Cursor 1\r
- Hide Cursor 2\r
- Get Mouse Position & Button Status 3\r
- Set Mouse Cursor Position 4\r
- Get Button Press Information 5\r
- Get Button Release Information 6\r
- Set Min/Max Horizontal Position 7\r
- Set Min/Max Vertical Position 8\r
- Define Graphics Cursor Block 9\r
- Define Text Cursor 10\r
- Read Mouse Motion Counters 11\r
- Define Event Handler 12\r
- Light Pen Emulation Mode ON 13\r
- Light Pen Emulation Mode OFF 14\r
- Set Mouse Mickey/Pixel Ratio 15\r
- Conditional Hide Cursor 16\r
- Set Double-Speed Threshold 19\r
- --------------------------------------\r
-\r
-In practice only afew of these functions are used and even fewer when the\r
-mouse status is monitored by an event handler function such as is used in\r
-this module.\r
-\r
-The most important thing to note when using the mouse module is that the\r
-mouse event handler must be removed before exiting the program. It is a good\r
-idea to have an exit function (see the C "atexit" function) and include the\r
-line "x_mouse_remove();" along with any other pre-exit cleanup code.\r
-\r
-\r
- ASM SOURCES\r
-\r
- xmouse.asm xlib.inc model.inc\r
-\r
- C HEADER FILE\r
-\r
- xmouse.h\r
-\r
- EXPORTED VARIABLES\r
-\r
- MouseInstalled - WORD - Indicates whether mouse handler installed\r
- MouseHidden - WORD - Indicates whether mouse cursor is hidden\r
- MouseButtonStatus - WORD - Holds the mouse button status\r
- MouseX - WORD - Current X position of mouse cursor\r
- MouseY - WORD - Current Y position of mouse cursor\r
- MouseFrozen - WORD - Disallows position updates if TRUE\r
- MouseColor - BYTE - The mouse cursors colour\r
-\r
- EXPORTED FUNCTIONS\r
-\r
- x_mouse_init\r
- ------------\r
-\r
- C Prototype: int x_mouse_init()\r
-\r
- Initialize the mouse driver functions and install the mouse event handler\r
- function. This is the first function you must call before using any of the\r
- mouse functions. This mouse code uses the fastest possible techniques to\r
- save and restore mouse backgrounds and to draw the mouse cursor.\r
-\r
- WARNING: This function uses and updates "NonVisual_Offset" to allocate\r
- video ram for the saved mouse background.\r
-\r
- LIMITATIONS: No clipping is supported horizontally for the mouse cursor\r
- No validity checking is performed for NonVisual_Offs\r
-\r
- **WARNING** You must Hide or at least Freeze the mouse cursor while drawing\r
- using any of the other XLIB modules since the mouse handler may\r
- modify vga register settings at any time. VGA register settings\r
- are not preserved which will result in unpredictable drawing\r
- behavior. If you know the drawing will occur away from the\r
- mouse cursor set MouseFrozen to TRUE (1), do your drawing\r
- then set it to FALSE (0). Alternatively call "x_hide_mouse",\r
- perform your drawing and then call "x_show_mouse". Another\r
- alternative is to disable interrupts while drawing but usually\r
- drawing takes up alot of time and having interrupts disabled\r
- for too long is not a good idea.\r
-\r
- x_define_mouse_cursor\r
- ---------------------\r
-\r
- C Prototype:\r
- void x_define_mouse_cursor(char far *MouseDef, unsigned char MouseColor)\r
-\r
- MouseDef - a pointer to 14 characters containing a bitmask for all the\r
- cursor's rows.\r
- MouseColor - The colour to use when drawing the mouse cursor.\r
-\r
- Define a mouse cursor shape for use in subsequent cursor redraws. XMouse\r
- has a hardwired mouse cursor size of 8 pixels across by 14 pixels down.\r
-\r
- WARNING: This function assumes MouseDef points to 14 bytes.\r
-\r
- Note: Bit order is in reverse. ie bit 7 represents pixel 0 ..\r
- bit 0 represents pixel 7 in each "MouseDef" byte.\r
-\r
- x_show_mouse\r
- ------------\r
-\r
- C Prototype: void x_show_mouse()\r
-\r
- Makes the cursor visible if it was previously hidden.\r
- See Also: "x_hide_mouse".\r
-\r
- x_hide_mouse\r
- ------------\r
-\r
- C Prototype: void x_hide_mouse()\r
-\r
- Makes the cursor hidden if it was previously visible.\r
- See Also: "x_show_mouse".\r
-\r
- x_mouse_remove\r
- --------------\r
-\r
- C Prototype: void x_mouse_remove()\r
-\r
- Stop mouse event handling and remove the mouse handler.\r
-\r
- NOTE: This function MUST be called before quitting the program if\r
- a mouse handler has been installed\r
-\r
- x_position_mouse\r
- ----------------\r
-\r
- C Prototype void x_position_mouse(int x, int y)\r
-\r
- Positions the mouse cursor at the specified location\r
-\r
- x_mouse_window\r
- ------------\r
-\r
- C Prototype: void x_mouse_window(int x0, int y0, int x1, int y1)\r
-\r
- Defines a mouse window.\r
-\r
- x_update_mouse\r
- --------------\r
-\r
- C Prototype: void x_update_mouse()\r
-\r
- Forces the mouse position to be updated and cursor to be redrawn.\r
- Note: this function is useful when you have set "MouseFrozen" to true.\r
- Allows the cursor position to be updated manually rather than\r
- automatically by the installed handler.\r
-\r
-\r
---------------------------------------------------------------------------\r
-MODULE XBMTOOLS\r
---------------------------------------------------------------------------\r
-\r
- This module implements a set of functions to convert between planar\r
- bitmaps and linear bitmaps.\r
-\r
- PLANAR BITMAPS\r
-\r
- Planar bitmaps as used by these functions have the following structure:\r
-\r
- BYTE 0 The bitmap width in bytes (4 pixel groups) range 1..255\r
- BYTE 1 The bitmap height in rows range 1..255\r
- BYTE 2..n1 The plane 0 pixels width*height bytes\r
- BYTE n1..n2 The plane 1 pixels width*height bytes\r
- BYTE n2..n3 The plane 2 pixels width*height bytes\r
- BYTE n3..n4 The plane 3 pixels width*height bytes\r
-\r
- as used by x_put_pbm, x_get_pbm, x_put_masked_pbm.\r
-\r
- LINEAR BITMAPS\r
-\r
- Linear bitmaps have the following structure:\r
-\r
- BYTE 0 The bitmap width in pixels range 1..255\r
- BYTE 1 The bitmap height in rows range 1..255\r
- BYTE 2..n The width*height bytes of the bitmap\r
-\r
- ASM SOURCES\r
-\r
- xbmtools.asm xpbmtools.inc model.inc\r
-\r
- C HEADER FILE\r
-\r
- xbmtools.h\r
-\r
- MACROS\r
-\r
- BM_WIDTH_ERROR\r
-\r
- LBMHeight(lbitmap) - Height of linear bitmap "lbitmap"\r
- LBMWidth(lbitmap) - Width of linear bitmap "lbitmap"\r
- PBMHeight(pbitmap) - Height of planar bitmap "pbitmap"\r
- PBMWidth(pbitmap) - Width of planar bitmap "pbitmap"\r
-\r
- LBMPutPix(x,y,lbitmap,color) - set pixel (x,y) colour in linear bitmap\r
- LBMGetPix(x,y,lbitmap) - colour of pixel (x,y) in linear bitmap\r
-\r
- EXPORT FUNCTIONS\r
-\r
- x_pbm_to_bm\r
- ------------\r
- C Prototype: extern int x_pbm_to_bm(char far * source_pbm,\r
- char far * dest_bm);\r
-\r
- This function converts a bitmap in the planar format to the linear format\r
- as used by x_compile_bitmap.\r
-\r
- WARNING: the source and destination bitmaps must be pre - allocated\r
-\r
- NOTE: This function can only convert planar bitmaps that are suitable.\r
- If the source planar bitmap's width (per plane) is >= 256/4\r
- it cannot be converted. In this situation an error code\r
- BM_WIDTH_ERROR. On successful conversion 0 is returned.\r
-\r
- x_bm_to_pbm\r
- ------------\r
- C Prototype: extern int x_bm_to_pbm(char far * source_pbm,\r
- char far * dest_bm);\r
-\r
- This function converts a bitmap in the linear format as used by\r
- x_compile_bitmap to the planar formap.\r
-\r
- WARNING: the source and destination bitmaps must be pre - allocated\r
-\r
- NOTE: This function can only convert linear bitmaps that are suitable.\r
- If the source linear bitmap's width is not a multiple of 4\r
- it cannot be converted. In this situation an error code\r
- BM_WIDTH_ERROR. On successful conversion 0 is returned.\r
-\r
+++ /dev/null
-PART 2 of 2\r
------------------------------------------------------------------------------\r
-\r
- ********* XLIB - Mode X graphics library ****************\r
- ********* ****************\r
- ********* Written By Themie Gouthas ****************\r
- ********* ****************\r
- ********* egg@dstos3.dsto.gov.au ****************\r
- ********* teg@bart.dsto.gov.au ****************\r
-\r
- Some of the code in this library has been contributed by :\r
-\r
- Matthew MacKenzie - matm@eng.umd.edu\r
-\r
- and others. See individual modules.\r
-\r
- I informally reserve all rights to the code in XLIB\r
- Rights to contributed code is also assumed to be reserved by\r
- the original authors.\r
------------------------------------------------------------------------------\r
-MODULE XCLIPPBM note: VERY SIMILAR to XPBMCLIP\r
-This module implements blits of clipped planar bitmaps. Blits are\r
-clipped to pixels, both horizontally. This makes the unmasked blit\r
-function here slightly slower than the equivalent functions in the\r
-XPBMCLIP module.\r
---------------------------------------------------------------------------\r
- XCLIPPBM:\r
- Blits and Pieces\r
- by Matthew MacKenzie\r
-\r
-The XCLIPPBM module contains clipping versions of two of the three routines\r
-in the XPBITMAP module:\r
- o x_clip_pbm transfers a planar bitmap to the screen, clipping off any\r
- part outside a bounding box.\r
- o x_clip_masked_pbm does the same thing, but transfers only nonzero\r
- pixels.\r
-\r
- The planar bitmap format is described elsewhere. Here we will look at\r
-the clipping itself, since it is the only distinguishing feature of this\r
-module.\r
- The bounding box is made up of four integers, TopBound, BottomBound,\r
-LeftBound, and RightBound. Unlike most global variables in Xlib, these are\r
-meant to be written to. In fact, they start out uninitialized. Be sure to\r
-set them before you try plotting any clipped bitmaps.\r
- Note that these are not the same variables which are used in the other\r
-clipping modules in Xlib. This is because the two systems are incompatible:\r
-the other modules clip horizontally to columns while this one clips to\r
-pixels. As you might have guessed, those functions and these were developed\r
-in different hemispheres of the planet...\r
- If it's any consolation, this does give you two independent\r
-bounding boxes to futz with, should the mood visit you.\r
- Bitmaps cannot go outside the perimeter of the bounding box, but they\r
-can overlap it. If TopBound equals BottomBound, for example, a horizontal\r
-slice of a bitmap may still be plotted. It is safe to turn the box "inside\r
-out" to make sure nothing will be plotted -- this is the first thing each\r
-routine checks for.\r
- To plot a bitmap, minus its zero pixels, minus anything outside the\r
-bounding box:\r
-\r
-x_clip_masked_pbm (int X, int Y, int ScreenOffs, char far * Bitmap);\r
-\r
- The arguments are in the same order as those for x_put_masked_pbm in\r
-the module XPBITMAP. The bounding box is relative to the given\r
-ScreenOffs(et). This lets you perform page flipping without worrying about\r
-what screen you are clipping to -- it's always the current screen. The\r
-bitmap itself, of course, is not affected; clipping is performed on-the-\r
-fly. Both functions return an integer which indicates whether any part\r
-of the bitmap was inside the bounding box. If the entire bitmap was\r
-outside, a 1 is returned; otherwise, a 0.\r
- The third function in XPBITMAP, for which this module has no\r
-equivalent, copies from video RAM to system RAM. The absence of such a\r
-routine may seem at first like a disadvantage -- but this, like so many\r
-things in this life, is an illusion. You can use the unclipped routine,\r
-and clip the bitmap when you want to plot it back onto the screen.\r
-\r
- ASM SOURCES\r
-\r
- xclippbm.asm xclippbm.inc xlib.inc model.inc\r
-\r
- C HEADER FILE\r
-\r
- xclippbm.h\r
-\r
- EXPORTED VARIABLES\r
-\r
- TopBound - int\r
- BottomBound - int\r
- LeftBound - int\r
- RightBound - int\r
-\r
- EXPORTED FUNCTIONS\r
-\r
- x_clip_pbm\r
- ----------\r
- C Prototype: extern int x_clip_pbm (int X, int Y, int ScreenOffs, char\r
- far * Bitmap);\r
-\r
- Copies a planar bitmap from SRAM to VRAM, with clipping. If the entire\r
- bitmap turns out to be outside the bounding box, this function returns\r
- a 1; otherwise it returns a 0.\r
-\r
- x_clip_masked_pbm\r
- -----------------\r
- C Prototype: extern int x_clip_masked_pbm (int X, int Y,\r
- int ScreenOffs, char far * Bitmap);\r
-\r
- Copies a planar bitmap from SRAM to VRAM, with clipping -- 0 bytes\r
- in the bitmap are not copied. If the entire bitmap turns out to be\r
- outside the bounding box, this function returns a 1; otherwise,\r
- it returns a 0.\r
-\r
-\r
---------------------------------------------------------------------------\r
-MODULE XMOUSE\r
---------------------------------------------------------------------------\r
-The XMOUSE module implements very basic mouse handling functions. The way\r
-in which it operates is by installing an event handler function during\r
-initialization which subsequently intercepts and processes mouse events and\r
-automatically updates status variables such as mouse position and button\r
-pressed status. It does not support the full functionality of:\r
-\r
- SPLIT SCREENS\r
- SCROLLED WINDOWS\r
- VIRTUAL WINDOWS\r
-\r
-This was done to primarily prevent unecessary impedences to performance,\r
-since the mouse handler function has the potential to degrade performance.\r
-It also saves me alot of coding which I was too lazy to do.\r
-\r
-Programs communicate with the mouse driver as with other devices, through\r
-an interrupt vector namely 33h. On generating an interrupt, the mouse driver\r
-expects a function number in AX and possibly other parameters in other\r
-registers and returns information via the registers. A brief description\r
-of the mouse functions follows:\r
-\r
- --------------------------------------\r
-\r
- MS Mouse Driver Functions\r
-\r
- Mouse Initialization 0\r
- Show Cursor 1\r
- Hide Cursor 2\r
- Get Mouse Position & Button Status 3\r
- Set Mouse Cursor Position 4\r
- Get Button Press Information 5\r
- Get Button Release Information 6\r
- Set Min/Max Horizontal Position 7\r
- Set Min/Max Vertical Position 8\r
- Define Graphics Cursor Block 9\r
- Define Text Cursor 10\r
- Read Mouse Motion Counters 11\r
- Define Event Handler 12\r
- Light Pen Emulation Mode ON 13\r
- Light Pen Emulation Mode OFF 14\r
- Set Mouse Mickey/Pixel Ratio 15\r
- Conditional Hide Cursor 16\r
- Set Double-Speed Threshold 19\r
- --------------------------------------\r
-\r
-In practice only afew of these functions are used and even fewer when the\r
-mouse status is monitored by an event handler function such as is used in\r
-this module.\r
-\r
-The most important thing to note when using the mouse module is that the\r
-mouse event handler must be removed before exiting the program. It is a good\r
-idea to have an exit function (see the C "atexit" function) and include the\r
-line "x_mouse_remove();" along with any other pre-exit cleanup code.\r
-\r
-See also: XDETECT for mouse detection.\r
-\r
- ASM SOURCES\r
-\r
- xmouse.asm xlib.inc model.inc\r
-\r
- C HEADER FILE\r
-\r
- xmouse.h\r
-\r
- EXPORTED VARIABLES\r
-\r
- MouseInstalled - WORD - Indicates whether mouse handler installed\r
- MouseHidden - WORD - Indicates whether mouse cursor is hidden\r
- MouseButtonStatus - WORD - Holds the mouse button status\r
- MouseX - WORD - Current X position of mouse cursor\r
- MouseY - WORD - Current Y position of mouse cursor\r
- MouseFrozen - WORD - Disallows position updates if TRUE\r
- MouseColor - BYTE - The mouse cursors colour\r
-\r
- EXPORTED FUNCTIONS\r
-\r
- x_mouse_init\r
- ------------\r
-\r
- C Prototype: int x_mouse_init()\r
-\r
- Initialize the mouse driver functions and install the mouse event handler\r
- function. This is the first function you must call before using any of the\r
- mouse functions. This mouse code uses the fastest possible techniques to\r
- save and restore mouse backgrounds and to draw the mouse cursor.\r
-\r
- WARNING: This function uses and updates "NonVisual_Offset" to allocate\r
- video ram for the saved mouse background.\r
-\r
- LIMITATIONS: No clipping is supported horizontally for the mouse cursor\r
- No validity checking is performed for NonVisual_Offs\r
-\r
- **WARNING** You must Hide or at least Freeze the mouse cursor while drawing\r
- using any of the other XLIB modules since the mouse handler may\r
- modify vga register settings at any time. VGA register settings\r
- are not preserved which will result in unpredictable drawing\r
- behavior. If you know the drawing will occur away from the\r
- mouse cursor set MouseFrozen to TRUE (1), do your drawing\r
- then set it to FALSE (0). Alternatively call "x_hide_mouse",\r
- perform your drawing and then call "x_show_mouse". Another\r
- alternative is to disable interrupts while drawing but usually\r
- drawing takes up alot of time and having interrupts disabled\r
- for too long is not a good idea.\r
-\r
- x_define_mouse_cursor\r
- ---------------------\r
-\r
- C Prototype:\r
- void x_define_mouse_cursor(char far *MouseDef, unsigned char MouseColor)\r
-\r
- MouseDef - a pointer to 14 characters containing a bitmask for all the\r
- cursor's rows.\r
- MouseColor - The colour to use when drawing the mouse cursor.\r
-\r
- Define a mouse cursor shape for use in subsequent cursor redraws. XMouse\r
- has a hardwired mouse cursor size of 8 pixels across by 14 pixels down.\r
-\r
- WARNING: This function assumes MouseDef points to 14 bytes.\r
-\r
- Note: Bit order is in reverse. ie bit 7 represents pixel 0 ..\r
- bit 0 represents pixel 7 in each "MouseDef" byte.\r
-\r
- x_show_mouse\r
- ------------\r
-\r
- C Prototype: void x_show_mouse()\r
-\r
- Makes the cursor visible if it was previously hidden.\r
- See Also: "x_hide_mouse".\r
-\r
- x_hide_mouse\r
- ------------\r
-\r
- C Prototype: void x_hide_mouse()\r
-\r
- Makes the cursor hidden if it was previously visible.\r
- See Also: "x_show_mouse".\r
-\r
- x_remove_mouse\r
- --------------\r
-\r
- C Prototype: void x_remove_mouse()\r
-\r
- Stop mouse event handling and remove the mouse handler.\r
-\r
- NOTE: This function MUST be called before quitting the program if\r
- a mouse handler has been installed\r
-\r
- x_position_mouse\r
- ----------------\r
-\r
- C Prototype void x_position_mouse(int x, int y)\r
-\r
- Positions the mouse cursor at the specified location\r
-\r
- x_update_mouse\r
- --------------\r
-\r
- C Prototype: void x_update_mouse()\r
-\r
- Forces the mouse position to be updated and cursor to be redrawn.\r
- Note: this function is useful when you have set "MouseFrozen" to true.\r
- Allows the cursor position to be updated manually rather than\r
- automatically by the installed handler.\r
-\r
---------------------------------------------------------------------------\r
-MODULE XCIRCLE\r
---------------------------------------------------------------------------\r
- XCIRCLE:\r
- Wheel Have to See About That\r
- by Matthew MacKenzie\r
-\r
-The XCIRCLE module contains two functions, neither of which should be\r
-a big mystery:\r
- o x_circle, oddly enough, draws a circle.\r
- o x_filled_circle does too, only the circle is filled (in some\r
- libraries this is called a disc).\r
-\r
- The word `circle' here refers to a round thing which is as many\r
-pixels tall as across. It only looks like a circle in 320x240 mode --\r
-the original mode X -- and in 376x282 mode.\r
- In both functions, the circle is specified by the coordinates of the\r
-upper-left-hand corner of the smallest box which holds it, and the\r
-diameter. Some circle functions have you specify a center point;\r
-this system is kind of odd because a circle with an even diameter does\r
-not have a particular pixel for a center. Every circle, on the other\r
-hand, has a box with an upper-left corner.\r
- No bounds are checked. A diameter of zero will draw nothing, and\r
-a negative diameter will blow your VGA board into hundreds of thousands\r
-of tiny little smoldering fragments. Neither function supports clipping.\r
- The calculation of the circle is based on an algorithm described\r
-by Michael P. Lindner in a letter to the editor on page 8 of Dr. Dobb's\r
-Journal #169 (October 1990). The algorithm has been rearranged to\r
-allow drawing and moving the plots in the eight octants to be performed\r
-in one step, so that each pixel does not have to be loaded into the CPU\r
-twice. x_filled_circle does not take advantage of this optimization\r
-because it handles different parts of each plot at different times.\r
-\r
- ASM SOURCES\r
-\r
- xcircle.asm xcircle.inc xlib.inc model.inc\r
-\r
- C HEADER FILE\r
-\r
- xcircle.h\r
-\r
- EXPORTED FUNCTIONS\r
-\r
- x_circle\r
- --------\r
- C Prototype: extern void x_circle (WORD Left, WORD Top, WORD Diameter,\r
- WORD Color, WORD ScreenOffs);\r
-\r
- Draws a circle with the given upper-left-hand corner and diameter,\r
- which are given in pixels.\r
-\r
-\r
- x_filled_circle\r
- ---------------\r
- C Prototype: extern void x_filled_circle (WORD Left, WORD Top,\r
- WORD Diameter, WORD Color, WORD ScreenOffs);\r
-\r
- Draws a filled circle with the given upper-left-hand corner and\r
- diameter.\r
-\r
-\r
---------------------------------------------------------------------------\r
-MODULE XDETECT\r
---------------------------------------------------------------------------\r
-\r
- This module implements a set of functions to detect the PC's hardware\r
- configuration.\r
-\r
- ASM SOURCES\r
-\r
- xdetect.asm xdetect.inc model.inc\r
-\r
- C HEADER FILE\r
-\r
- xdetect.h\r
-\r
- EXPORTED MACROS\r
-\r
- I8086 0\r
- I80186 1\r
- I80286 2\r
- I80386 3\r
-\r
- NoGraphics 0\r
- MDA 1\r
- CGA 2\r
- EGAMono 3\r
- EGAColor 4\r
- VGAMono 5\r
- VGAColor 6\r
- MCGAMono 7\r
- MCGAColor 8\r
-\r
- BUS_MOUSE 1\r
- SERIAL_MOUSE 2\r
- INPORT_MOUSE 3\r
- PS2_MOUSE 4\r
- HP_MOUSE 5\r
-\r
-\r
- EXPORT VARIABLES\r
-\r
- MouseButtonCount - WORD - The number of buttons on the detected mouse\r
- MouseVersion - WORD - Mouse driver version (High byte = Major version\r
- Low byte = minor version)\r
- MouseType - BYTE - The mouse type\r
- MouseIRQ - BYTE - The IRQ number used by the mouse driver\r
-\r
- EXPORT FUNCTIONS\r
-\r
-\r
- x_graphics_card\r
- ---------------\r
- C Prototype: extern int x_graphics_card();\r
-\r
- This function returns the type of graphics card installed. See defines\r
- above.\r
-\r
- x_processor\r
- -----------\r
- C Prototype: extern int x_processor();\r
-\r
- This function returns the type of processor installed. A 486 registers\r
- as a 386. See defines above.\r
-\r
- x_coprocessor\r
- -------------\r
- C Prototype: extern int x_coprocessor();\r
-\r
- This function returns 1 of a numeric co-processor is present, 0 if not.\r
- The type is not detected but it's mnot really necessary as the processor\r
- type usually determines the numeric coprocessor type\r
-\r
- x_mousedriver\r
- -------------\r
- C Prototype: extern int x_mousedriver();\r
-\r
- This function returns 1 of a mouse driver is installed, 0 otherwise.\r
- If a mouse driver is detected the mouse related variable (above) are\r
- set accordingly.\r
-\r
---------------------------------------------------------------------------\r
-MODULE XFILEIO\r
---------------------------------------------------------------------------\r
-\r
- Handle based file I/O functions.\r
-\r
- See any good DOS programming reference for more information on int 21h\r
- DOS services.\r
-\r
- ASM SOURCES\r
-\r
- xfileio.asm xfileio.inc model.inc\r
-\r
- C HEADER FILE\r
-\r
- xfileio.h\r
-\r
- EXPORTED MACROS\r
-\r
- file access modes\r
-\r
- F_RDONLY\r
- F_WRONLY\r
- F_RDWR\r
-\r
- seek codes\r
-\r
- SEEK_START\r
- SEEK_CURR\r
- SEEK_END\r
-\r
- file error value\r
-\r
- FILE_ERR\r
-\r
- EXPORT FUNCTIONS\r
-\r
- f_open\r
- ------\r
- C Prototype: extern int f_open(char * filename, char access);\r
-\r
- Opens a file according to the access char:\r
-\r
- F_RDONLY = read only - If doesnt exist return error\r
- F_WRONLY = write only - If doesnt exist create it otherwise clear it\r
- F_RDWR = read/write - If doesnt exist create it\r
-\r
- Returns the file handle on success, FILE_ERR on failure\r
-\r
-\r
- f_close\r
- -------\r
-\r
- C Prototype: extern int f_close(int handle);\r
-\r
- Closes the file associated with the specified handle\r
-\r
- Returns 0 on success, FILE_ERR on failure\r
-\r
-\r
- f_read\r
- ------\r
-\r
- C Prototype:\r
-\r
- extern int f_read(int handle,char near * buffer, int count);\r
-\r
- Reads a block of count bytes from the file specified by the handle\r
- into the near buffer\r
-\r
- Returns count on success, FILE_ERR on failure\r
-\r
- f_readfar\r
- ---------\r
-\r
- C Prototype:\r
-\r
- extern int f_readfar(int handle,char far * buffer, int count);\r
-\r
- Reads a block of count bytes from the file specified by the handle\r
- into the far buffer\r
-\r
- Returns count on success, FILE_ERR on failure\r
-\r
-\r
- f_write\r
- -------\r
-\r
- C Prototype: extern int f_write(int handle, char near * buffer, int count);\r
-\r
- Writes a block of count bytes to the file specified by the handle\r
- from the near buffer\r
-\r
- Returns count on success, FILE_ERR on failure\r
-\r
- f_writefar\r
- ----------\r
-\r
- C Prototype: extern int f_write(int handle, char far * buffer, int count);\r
-\r
- Writes a block of count bytes to the file specified by the handle\r
- from the far buffer\r
-\r
- Returns count on success, FILE_ERR on failure\r
-\r
-\r
- f_seek\r
- ------\r
-\r
- C Prototype: extern long int f_seek(int handle, long int position,\r
- char method_code)\r
-\r
- Moves the file pointer according to the position and method code\r
-\r
- Returns file pointer position on success, FILE_ERR on failure\r
-\r
-\r
- f_filelength\r
- ------------\r
-\r
- C Prototype:\r
-\r
- extern long int f_filelength(int handle)\r
-\r
- Returns the length of the file associated with the specified handle\r
-\r
- Returns file length on success, FILE_ERR on failure\r
-\r
-\r
- f_tell\r
- ------\r
-\r
- C Prototype:\r
-\r
- extern long int f_tell(int handle)\r
-\r
-\r
- Returns file pointer position on success, FILE_ERR on failure\r
-\r
---------------------------------------------------------------------------\r
-MODULE XRLETOOL\r
---------------------------------------------------------------------------\r
-\r
-This module implements a number of functions comprising an RLE encoding\r
-decoding system.\r
-\r
-RLE stands for RUN LENGTH ENCODING. It is a quick simple data compression\r
-scheme which is commonly used for image data compression or compression\r
-of any data. Although not the most efficient system, it is fast, which is\r
-why it is used in image storage systems like PCX. This implementation is\r
-more efficient than the one used in PCX files because it uses 1 bit to\r
-identify a Run Length byte as opposed to two in PCX files, but more on this\r
-later.\r
-\r
-This set of functions can be used to implement your own compressed image\r
-file format or for example compress game mapse for various levels etc.\r
-The uses are limited by your imagination.\r
-\r
-I opted for trading off PCX RLE compatibility for the improved compression\r
-efficiency.\r
-\r
-Here is how the data is un-compressed to give an idea of its structure.\r
-\r
-\r
-STEP 1 read a byte from the RLE compressed source buffer.\r
-\r
-STEP 2 if has its high bit is set then the lower 7 bits represent the number\r
- of times the next byte is to be repeated in the destination buffer.\r
- if the count (lower 7 bits) is zero then\r
- we have finished decoding goto STEP 5\r
- else goto STEP 4\r
-\r
-STEP 3 Read a data from the source buffer and copy it directly to the\r
- destination buffer.\r
- goto STEP 1\r
-\r
-STEP 4 Read a data byte from the source buffer and copy it to the destination\r
- buffer the number of times specified by step 2.\r
- goto STEP 1\r
-\r
-STEP 5 Stop, decoding done.\r
-\r
-If the byte does not have the high bit set then the byte itself is transfered\r
- to the destination buffer.\r
-\r
-Data bytes that have the high bit already set and are unique in the input\r
- stream are represented as a Run Length of 1 (ie 81 which includes high bit)\r
- followed by the data byte.\r
-\r
-If your original uncompressed data contains few consecutive bytes and most\r
-have high bit set (ie have values > 127) then your so called\r
-compressed data would require up to 2x the space of the uncompressed data,\r
-so be aware that the compression ratio is extremely variable depending on the\r
-type of data being compressed.\r
-\r
-Apologies for this poor attempt at a description, but you can look up\r
-RLE in any good text. Alternatively, any text that describes the PCX file\r
-structure in any depth should have a section on RLE compression.\r
-\r
-\r
-\r
- ASM SOURCES\r
-\r
- xrletool.asm xrletool.inc model.inc\r
-\r
- C HEADER FILE\r
-\r
- xrletool.h\r
-\r
- EXPORTED MACROS\r
-\r
-\r
- EXPORT FUNCTIONS\r
-\r
- x_buff_RLDecode\r
- ---------------\r
-\r
- Expands an RLE compresses source buffer to a destination buffer.\r
- returns the size of the resultant uncompressed data.\r
-\r
- C PROTOTYPE:\r
-\r
- extern unsigned int x_buff_RLDecode(char far * source_buff,\r
- char far * dest_buff);\r
-\r
- source_buff - The buffer to compress\r
- dest_buff - The destination buffer\r
-\r
- WARNING: buffers must be pre allocated.\r
-\r
-\r
- x_buff_RLEncode\r
- ---------------\r
-\r
- RLE Compresses a source buffer to a destination buffer and returns\r
- the size of the resultant compressed data.\r
-\r
- C PROTOTYPE:\r
-\r
- extern unsigned int x_buff_RLEncode(char far * source_buff,\r
- char far * dest_buff,unsigned int count);\r
-\r
- source_buff - The buffer to compress\r
- dest_buff - The destination buffer\r
- count - The size of the source data in bytes\r
-\r
- WARNING: buffers must be pre allocated.\r
-\r
- x_buff_RLE_size\r
- ---------------\r
-\r
- Returns the size the input data would compress to.\r
-\r
- C PROTOTYPE:\r
-\r
- extern unsigned int x_buff_RLE_size(char far * source_buff,\r
- unsigned int count);\r
-\r
- source_buff - The uncompressed data buffer\r
- count - The size of the source data in bytes\r
-\r
-\r
- x_file_RLEncode\r
- ---------------\r
-\r
- RLE Compresses a source buffer to an output file returning\r
- the size of the resultant compressed data or 0 if it fails.\r
-\r
- C PROTOTYPE:\r
-\r
- extern unsigned int x_file_RLEncode(int handle,\r
- char far * source_buff,unsigned int count);\r
-\r
- source_buff - The buffer to compress\r
- handle - The file handler\r
- count - The size of the source data in bytes\r
-\r
- x_file_RLDecode\r
- ---------------\r
-\r
- Expands an RLE compresses file to a destination RAM buffer.\r
- returns the size of the resultant uncompressed data.\r
-\r
- C PROTOTYPE:\r
-\r
- extern unsigned int x_buff_RLDecode(int handle,\r
- char far * dest_buff);\r
-\r
- handle - Input file handle\r
- dest_buff - The destination buffer\r
-\r
-\r
-\r
-\r
---------------------------------------------------------------------------\r
-MODULE XPOLYGON\r
---------------------------------------------------------------------------\r
-\r
- This module implements eneral filled convex polygon and triangle\r
- functions\r
-\r
- C HEADER FILE\r
-\r
- xpolygon.h\r
-\r
- TYPE DEFS\r
-\r
- typedef struct {\r
- int X;\r
- int Y;\r
- } far VERTEX;\r
-\r
-\r
-\r
- EXPORT FUNCTIONS\r
-\r
-\r
- x_triangle\r
- ------------\r
- C Prototype:\r
-\r
- void x_triangle(int x0, int y0, int x1, int y1, int x2, int y2,\r
- WORD color, WORD PageBase);\r
-\r
- This function draws a filled triangle which is clipped to the current\r
- clipping window defined by TopClip,BottomClip,LeftClip,RightClip.\r
- Remember: the X clipping variable are in BYTES not PIXELS so you\r
- can only clip to 4 pixel byte boundaries.\r
-\r
-\r
- x_polygon\r
- ---------\r
-\r
- C Prototype:\r
-\r
- void x_polygon(VERTEX *vertices, int num_vertices,\r
- WORD color, WORD PageBase);\r
-\r
- This function is similar to the triangle function but draws\r
- convex polygons. The vertices are supplied in the form of a FAR\r
- pointer.\r
-\r
- NOTE: a convex polygon is one such that if you draw a line from\r
- any two vertices, every point on that line will be within the\r
- polygon.\r
-\r
- This function works by splitting up a polygon into its component\r
- triangles and calling the triangle routine above to draw each one.\r
- Performance is respectable but a custom polygon routine might be\r
- faster.\r
-\r
-\r
---------------------------------------------------------------------------\r
-MODULE XFILL\r
---------------------------------------------------------------------------\r
-\r
- This module implements a couple of general purpose flood fill functions\r
- functions\r
-\r
- C HEADER FILE\r
-\r
- xfill.h\r
-\r
-\r
- EXPORT FUNCTIONS\r
-\r
-\r
- x_flood_fill\r
- ------------\r
- C Prototype:\r
-\r
- int x_flood_fill(int x, int y, unsigned ofs, int color);\r
-\r
- This function performs the familiar flood filling used by many\r
- paint programs and of course the Borland BGI's flood fill function.\r
- The pixel at x,y and all adjacent pixels of the same color are filled\r
- to the new color. Filling stops when there are no more adjacent pixels\r
- of the original pixel's color. The function returns the number of\r
- pixels that have been filled.\r
-\r
- x_boundary_fill\r
- ------------\r
- C Prototype:\r
-\r
-\r
- int x_boundary_fill(int x,int y,unsigned ofs,int boundary,int color);\r
-\r
- This function is a variant of the flood fill described above. This\r
- function, unlike the above function, can fill across color boundaries.\r
- Filling stops when the area being filled is fully enclosed by pixels\r
- of the color "boundary". Again, this function returns the number of\r
- pixels filled.\r
-\r
--------------------------------------------------------------------------------\r
-MODULE VSYNC\r
--------------------------------------------------------------------------------\r
-\r
- VSYNC\r
-\r
- Simulated Vertical Retrace Interrupt Module\r
-\r
- by Tore Jahn Bastiansen <toreba@ifi.uio.no>\r
-\r
- Inspired by REND386 v3.01 by Dave Stampe and Bernie Roehl\r
-\r
-The xvsync module uses timer 0 to simulate a vertical retrace interrupt.\r
-It's designed to significantly reduce the idle waiting time in Xlib.\r
-Why simulate the VRT interrupt ? Simply because a true VRT interrupt is\r
-not implemented on many VGA cards. Using a VRT interrupt as opposed to\r
-polling, can result in huge performance improvements for your code and\r
-help make animation much smoother than it would be using polling.\r
-\r
-Normally xlib waits for vsync when x_page_flip, x_set_start_address or\r
-x_put_pal_??? is called. This waiting period could be better utilized to do\r
-housekeeping calculations or whatever. The x_put_pal_??? functions also\r
-doesn't work very smoothly in conjunction with other functions that wait for\r
-the vertical retrace since each function introduces its own VRT delay.\r
-\r
-When using the vsync handler, the VRT delay is reduced to the absolute\r
-minumum which can result in a huge performance boost for your programs.\r
-\r
-When using double buffering, you may still have to wait before drawing,\r
-but you could do as much other work as possible, like this:\r
-\r
- x_page_flip(...)\r
- ...\r
- <animate the palette>\r
- <do some collision detection and 3D calculations>\r
- <read the joystick>\r
- ...\r
- x_wait_start_address(); (Not needed with triple buffering)\r
- ...\r
- <draw next frame>\r
- ...\r
-\r
-ASM SOURCES\r
-\r
- xvsync.asm xmain.asm xvsync.inc xmain.inc\r
-\r
-C HEADER FILE\r
-\r
- xvsync.h\r
-\r
-EXPORTED VARIABLES\r
-\r
-VsyncPeriod - WORD -time in 1.193 us between two vsyncs\r
-\r
-TicksPerSecond - WORD - number of vsyncs per second\r
-\r
-VsyncTimerInt - long - number of vsyncs since x_install_vsync_handler was\r
- called. Nice for game timing.\r
-\r
-EXPORTED FUNCTIONS\r
-\r
-x_install_vsync_handler\r
------------------------\r
-\r
-C Prototype: void x_install_vsync_handler(int VrtsToSkip);\r
-\r
-This function installs the vsync handler using timer 0. It's called\r
-about 100 microseconds before every vertical retrace.\r
-\r
-The VrtsToSkip value (>=1) defines the delay in VRT's between consecutive\r
-physical screen start address changes, thus allowing you to limit the\r
-maximum frame rate for page flips in animation systems. The frame rate\r
-is calculated as Vertical refresh rate / VrtsToSkip, eg for\r
-320x240 mode which refreshes at 60Hz a VrtsToSkip value of 3 will result\r
-in a maximum page flipping rate of 20Hz (frames per second)\r
-\r
-WARNING: Be sure to remove it before exiting.\r
- When used with a debugger, the system clock may speed up.\r
-\r
-x_remove_vsync_handler\r
-----------------------\r
-\r
-C Prototype: void x_remove_vsync_handler\r
-\r
-This routine _MUST_ be called before exiting (or aborting) the program,\r
-or your system will crash.\r
-\r
-x_set_user_vsync_handler\r
-------------------------\r
-\r
-C Prototype: void x_set_user_vsync_handler(void far (*f)());\r
-\r
-Installs a user routine to be called once each vertical retrace. The user\r
-handler have its own stack of 256 bytes , so be careful with the stack\r
-checking option in BC.\r
-WARNING: This installs an interrupt driven handler, beware of the following:\r
- Only 8086 registers are preserved. If you're using 386 code, save\r
- all the 386 regs.\r
- Don't do any drawing.\r
- Don't call any DOS functions.\r
-\r
-So why use it?\r
-Well, you can update global variables if you're careful. And it's nice for\r
-palette animation. You can even do fades while loading from disk. You\r
-should use this instead of installing your own int08h routine and chain\r
-to the original.\r
-\r
-x_wait_start_addr\r
------------------\r
-\r
-C Prototype: void x_wait_start_addr(void)\r
-\r
-You must call this function before drawing after a call to x_set_start_addr\r
-or x_page_flip when you are using the vsync handler and not using\r
-triple buffering.\r
-\r
-MODULE XMAIN additions\r
-\r
-EXPORTED VARIABLES\r
-\r
-Page2_Offs - WORD - Offset in video ram of third virtual screen. Set by\r
- x_triple_buffer.\r
-\r
-WaitingPageOffs - WORD - Offset of page waiting to be invisible. Initially\r
- set by x_set_triple_buffer but is updated by x_page_flip. This\r
- variable is only used while triple buffering is on.\r
-\r
-VsyncHandlerActive - WORD - Indicates whether the vsync handler is installed.\r
-\r
-TripleBufferActive - WORD - Indicates whether triple-buffering is on.\r
- Set by x_triple_buffer.\r
-\r
-StartAddressFlag - WORD - This flag is set if there is a new start\r
- address waiting to be set by the vsync handler.\r
-\r
-WaitingStartLow - WORD - Needed by vsync handler. Keep off.\r
-WaitingStartHigh - WORD - Needed by vsync handler. Keep off.\r
-WaitingPelPan - WORD - Needed by vsync handler. Keep off.\r
-\r
-VsyncPaletteStart - WORD - Start index of video DAC register to be\r
- updated next vsync. Set by palette functions.\r
-\r
-VsyncPaletteCount - WORD - Number of palette entries to be outed next\r
- vsync. Set by palette functions.\r
-\r
-VsyncPaletteBuffer - BYTE[768] - Buffer containing values for the next\r
- update of the DAC.\r
-\r
-EXPORTED FUNCTIONS\r
-\r
-x_triple_buffer\r
-----------------\r
-\r
-C Prototype: void x_triple_buffer(WORD PageHeight);\r
-\r
-This function behaves like x_double_buffer, but when used with\r
-x_install_vsync_handler you can draw immediately after a page flip.\r
-When x_page_flip is called, VisiblePageOffs is set to the page that\r
-will be display next vsync. Until then, WaitingPageOffs will be displayed.\r
-You can draw to HiddenPageOffs .\r
-\r
-\r
-\r
-\r
---------------------------------------------------------------------\r
-REFERENCE SECTION\r
---------------------------------------------------------------------\r
-\r
-\r
-REFERENCES\r
-----------\r
-\r
-In my opinion Doctor Dobbs Journal is the best reference text for\r
-VGA Mode X graphics:\r
-\r
-Issue 178 Jul 1991 : First reference to Mode X\r
-Article Abstract : VGA's undocumented Mode X supports page flipping,\r
- makes off screen memory available, has square pixels,\r
- and increases performance by as muck as 4 times.\r
-\r
-Issue 179 Aug 1991 : Continuation\r
-Article Abstract : Michael discusses latches and VGA's undoccumented\r
- Mode X.\r
-\r
-Issue 181 Sep 1991 : Continuation\r
-Article Abstract : Michael puts the moves on animation using VGA's 256\r
- colors.\r
-\r
-Issue 184 Oct 1991 : First of a continuing series covering 3-D animation\r
- using VGA's Mode X. This series is still ongoing\r
- (October 1992)\r
-Article Abstract : Michael moves into 3-D animation, starting with basic\r
- polygon fills and page flips.\r
-\r
-\r
-WHAT IS MODE X ?\r
-----------------\r
-\r
-Mode X is a derrivative of the VGA's standard mode 13h (320x200 256 color).\r
-It is a (family) of undocumented video modes that are created by tweaking\r
-the VGA's registers. The beauty of mode X is that it offers several\r
-benefits to the programmer:\r
- - Multiple graphice pages where mode 13h doesn't allowing for page flipping\r
- (also known as double buffering) and storage of images and data in\r
- offscreen video memory\r
- - A planar video ram organization which although more difficult to program,\r
- allows the VGA's plane-oriented hardware to be used to process pixels in\r
- parallel, improving performance by up to 4 times over mode 13h\r
-\r
- See issue 178-179 of D.D.J. for a full description of VGA's Mode X.\r
-\r
-WHAT IS A SPLIT SCREEN ?\r
-------------------------\r
-\r
-A split screen is a neat hardware feature offered by the EGA and VGA video\r
-cards. A split screen is a mode of graphics operationin which the Hardware\r
-splits the visual graphics screen horizontally and treats both halves as\r
-individual screens each starting at different locations in video RAM.\r
-\r
-The bottom half (which is usually referred to as the split screen) always\r
-starts at address A000:0000 but the top half's starting address is user\r
-definable.\r
-\r
-The most common application of split screens in games is the status display\r
-in scrolling games. Split screens make this sort of game simpler to program\r
-because when the top half window is scrolled the programmer does not have to\r
-worry about redrawing the bottom half.\r
-\r
-WHAT IS DOUBLE BUFFERING ?\r
---------------------------\r
-\r
-Double buffering (also known as page flipping) is the technique most often\r
-used to do animation. it requires hardware that is capable of displaying\r
-multiple graphics pages (or at least 2). Animation is achieved by drawing\r
-an image in the non visible screen and then displaying the non visible\r
-screen. Once the page has been flipped the process starts again. The next\r
-frame of the animation is drawn on the non visible screen, the page is\r
-flipped again etc.\r
-\r
-\r
-WHAT IS TRIPPLE BUFFERING ?\r
---------------------------\r
-\r
-Triple buffering is similar to double buffering in many ways, but it\r
-relies on 3 pages being defined for animation. The main selling point\r
-of triple buffering is that it eliminates the need to wait for the\r
-vertical retrace to flip pages before drawing on the new page thus\r
-alowing the programmer to start building the next animation frame\r
-immediately after completing the current one. Heres how it works:\r
-\r
-With double buffering, once you complete drawing the hidden page and\r
-youre ready to flip pages, you have to wait for the VGA hardware to\r
-actually flip the page (during the vertical retrace) before you start\r
-drawing the next page otherwise you will be drawing on the visible page.\r
-\r
-With triple buffering you cycle between three pages, thus the page you\r
-draw on is guaranteed not to be visible. I know this is a poor\r
-description but it really is quite simple\r
-\r
-Triple buffering can acheive the fastest possible animation under the\r
-right conditions but the draw back is that more video RAM is required. If\r
-you wish to store bitmaps in video ram such as background tiles, double\r
-buffering would be the better alternative.\r
-\r
-\r
-WHAT IS MODE X ?\r
-----------------\r
-\r
-Mode X is a derrivative of the VGA's standard mode 13h (320x200 256 color).\r
-It is a (family) of undocumented video modes that are created by tweaking\r
-the VGA's registers. The beauty of mode X is that it offers several\r
-benefits to the programmer:\r
- - Multiple graphice pages where mode 13h doesn't allowing for page flipping\r
- (also known as double buffering) and storage of images and data in\r
- offscreen video memory\r
- - A planar video ram organization which although more difficult to program,\r
- allows the VGA's plane-oriented hardware to be used to process pixels in\r
- parallel, improving performance by up to 4 times over mode 13h\r
-\r
- Again see D.D.J. for an in depth discussion of animation using Mode X.\r
-\r
- -----------------------------------------------------------------------\r
-\r
-\r
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XLIB_ALL - header file\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;----------------------------------------------------------------------*/\r
-\r
-#include "XLIB.H"\r
-#include "XPOINT.H"\r
-#include "XRECT.H"\r
-#include "XLINE.H"\r
-#include "XPAL.H"\r
-#include "XTEXT.H"\r
-#include "XPBITMAP.H"\r
-#include "XCBITMAP.H"\r
-#include "XDETECT.H"\r
-#include "XBMTOOLS.H"\r
-#include "XFILEIO.H"\r
-#include "XRLETOOL.H"\r
-#include "XBEZIER.H"\r
-#include "XVBITMAP.H"\r
-#include "XMOUSE.H"\r
-#include "XPBMCLIP.H"\r
-#include "XCIRCLE.H"\r
-#include "XCLIPPBM.H"\r
-#include "XPOLYGON.H"\r
-#include "XVSYNC.H"\r
-#include "XFILL.H"\r
-#include "XCBITM32.H"\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XLINE\r
-;\r
-; Line drawing functions.\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-include xlib.inc\r
-include xline.inc\r
-\r
- .code\r
-\r
-\r
-ModeXAddr macro\r
- mov cl,bl\r
- push dx\r
- mov dx,[_ScrnLogicalByteWidth]\r
- mul dx\r
- pop dx\r
- shr bx,2\r
- add bx,ax\r
- add bx,[PgOffs]\r
- and cl,3\r
- endm\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; _x_line\r
-;\r
-; Line drawing function for all MODE X 256 Color resolutions\r
-; Based on code from "PC and PS/2 Video Systems" by Richard Wilton.\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-\r
-_x_line proc\r
-ARG x1:word,y1:word,x2:word,y2:word,Color:word,PgOffs:word\r
-LOCAL vertincr:word,incr1:word,incr2:word,routine:word=LocalStk\r
- push bp ; Set up stack frame\r
- mov bp,sp\r
- sub sp,LocalStk\r
- push si\r
- push di\r
-\r
- mov ax,0a000h\r
- mov es,ax\r
-\r
- mov dx,SC_INDEX ; setup for plane mask access\r
-\r
-; check for vertical line\r
-\r
- mov si,[_ScrnLogicalByteWidth]\r
- mov cx,[x2]\r
- sub cx,[x1]\r
- jz VertLine\r
-\r
-; force x1 < x2\r
-\r
- jns L01\r
-\r
- neg cx\r
-\r
- mov bx,[x2]\r
- xchg bx,[x1]\r
- mov [x2],bx\r
-\r
- mov bx,[y2]\r
- xchg bx,[y1]\r
- mov [y2],bx\r
-\r
-; calc dy = abs(y2 - y1)\r
-\r
-L01:\r
- mov bx,[y2]\r
- sub bx,[y1]\r
- jnz short skip\r
- jmp HorizLine\r
-skip: jns L03\r
-\r
- neg bx\r
- neg si\r
-\r
-; select appropriate routine for slope of line\r
-\r
-L03:\r
- mov [vertincr],si\r
- mov [routine],offset LoSlopeLine\r
- cmp bx,cx\r
- jle L04\r
- mov [routine],offset HiSlopeLine\r
- xchg bx,cx\r
-\r
-; calc initial decision variable and increments\r
-\r
-L04:\r
- shl bx,1\r
- mov [incr1],bx\r
- sub bx,cx\r
- mov si,bx\r
- sub bx,cx\r
- mov [incr2],bx\r
-\r
-; calc first pixel address\r
-\r
- push cx\r
- mov ax,[y1]\r
- mov bx,[x1]\r
- ModeXAddr\r
- mov di,bx\r
- mov al,1\r
- shl al,cl\r
- mov ah,al ; duplicate nybble\r
- shl al,4\r
- add ah,al\r
- mov bl,ah\r
- pop cx\r
- inc cx\r
- jmp [routine]\r
-\r
-; routine for verticle lines\r
-\r
-VertLine:\r
- mov ax,[y1]\r
- mov bx,[y2]\r
- mov cx,bx\r
- sub cx,ax\r
- jge L31\r
- neg cx\r
- mov ax,bx\r
-\r
-L31:\r
- inc cx\r
- mov bx,[x1]\r
- push cx\r
- ModeXAddr\r
-\r
- mov ah,1\r
- shl ah,cl\r
- mov al,MAP_MASK\r
- out dx,ax\r
- pop cx\r
- mov ax, word ptr [Color]\r
-\r
-; draw the line\r
-\r
-L32:\r
- mov es:[bx],al\r
- add bx,si\r
- loop L32\r
- jmp Lexit\r
-\r
-; routine for horizontal line\r
-\r
-HorizLine:\r
- push ds\r
-\r
- mov ax,[y1]\r
- mov bx,[x1]\r
- ModeXAddr\r
-\r
- mov di,bx ; set dl = first byte mask\r
- mov dl,00fh\r
- shl dl,cl\r
-\r
- mov cx,[x2] ; set dh = last byte mask\r
- and cl,3\r
- mov dh,00eh\r
- shl dh,cl\r
- not dh\r
-\r
-; determine byte offset of first and last pixel in line\r
-\r
- mov ax,[x2]\r
- mov bx,[x1]\r
-\r
- shr ax,2 ; set ax = last byte column\r
- shr bx,2 ; set bx = first byte column\r
- mov cx,ax ; cx = ax - bx\r
- sub cx,bx\r
-\r
- mov ax,dx ; mov end byte masks to ax\r
- mov dx,SC_INDEX ; setup dx for VGA outs\r
- mov bx, [Color]\r
-\r
-; set pixels in leftmost byte of line\r
-\r
- or cx,cx ; is start and end pt in same byte\r
- jnz L42 ; no !\r
- and ah,al ; combine start and end masks\r
- jmp short L44\r
-\r
-L42: push ax\r
- mov ah,al\r
- mov al,MAP_MASK\r
- out dx,ax\r
- mov al,bl\r
- stosb\r
- dec cx\r
-\r
-; draw remainder of the line\r
-\r
-L43:\r
- mov ah,0Fh\r
- mov al,MAP_MASK\r
- out dx,ax\r
- mov al,bl\r
- rep stosb\r
- pop ax\r
-\r
-; set pixels in rightmost byte of line\r
-\r
-L44:\r
- mov al,MAP_MASK\r
- out dx, ax\r
- mov byte ptr es:[di],bl\r
- pop ds\r
- jmp short Lexit\r
-\r
-\r
-; routine for dy >= dx (slope <= 1)\r
-\r
-LoSlopeLine:\r
- mov al,MAP_MASK\r
- mov bh,byte ptr [Color]\r
-L10:\r
- mov ah,bl\r
-\r
-L11:\r
- or ah,bl\r
- rol bl,1\r
- jc L14\r
-\r
-; bit mask not shifted out\r
-\r
- or si,si\r
- jns L12\r
- add si,[incr1]\r
- loop L11\r
-\r
- out dx,ax\r
- mov es:[di],bh\r
- jmp short Lexit\r
-\r
-L12:\r
- add si,[incr2]\r
- out dx,ax\r
- mov es:[di],bh\r
- add di,[vertincr]\r
- loop L10\r
- jmp short Lexit\r
-\r
-; bit mask shifted out\r
-\r
-L14: out dx,ax\r
- mov es:[di],bh\r
- inc di\r
- or si,si\r
- jns L15\r
- add si,[incr1]\r
- loop L10\r
- jmp short Lexit\r
-\r
-L15:\r
- add si,[incr2]\r
- add di,[vertincr]\r
- loop L10\r
- jmp short Lexit\r
-\r
-; routine for dy > dx (slope > 1)\r
-\r
-HiSlopeLine:\r
- mov bx,[vertincr]\r
- mov al,MAP_MASK\r
-L21: out dx,ax\r
- push ax\r
- mov ax,[Color]\r
- mov es:[di],al\r
- pop ax\r
- add di,bx\r
-\r
-L22:\r
- or si,si\r
- jns L23\r
-\r
- add si,[incr1]\r
- loop L21\r
- jmp short Lexit\r
-\r
-L23:\r
- add si,[incr2]\r
- rol ah,1\r
- adc di,0\r
-lx21: loop L21\r
-\r
-; return to caller\r
-\r
-Lexit:\r
- pop di\r
- pop si\r
- mov sp,bp\r
- pop bp\r
- ret\r
-\r
-_x_line endp\r
-\r
-end\r
-\1a
\ No newline at end of file
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XLINE - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;----------------------------------------------------------------------*/\r
-\r
-#ifndef _XLINE_H_\r
-#define _XLINE_H_\r
-\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-extern void x_line( /* Draw a line, what else */\r
- WORD x0,\r
- WORD y0,\r
- WORD x1,\r
- WORD y1,\r
- WORD color,\r
- WORD PageBase);\r
-\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif\r
-\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XLINE - Include file\r
-;\r
-; XLINE.ASM export functions\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
- global _x_line :proc\r
-\1a
\ No newline at end of file
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XMAIN\r
-;\r
-; Initialization, panning and split screen functions for all MODE X 256\r
-; Color resolutions\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; MODIFICATIONS:\r
-; 26-9-92: Pel panning code added\r
-; Dates forgotten: Numerous ;^)\r
-; 05-10-93: Timer synchronized vsync handling extensions\r
-; and tripple buffering - Tore Jahn Bastiansen\r
-; (toreba@ifi.uio.no) for the\r
-;-----------------------------------------------------------------------\r
-\r
-\r
-include xlib.inc\r
-include xmain.inc\r
-\r
-\r
- .data\r
-\r
-\r
-; Mode X CRTC register tweaks for various resolutions\r
-\r
-\r
-LABEL X256Y200 word\r
- db 0e3h ; dot clock\r
- db 8 ; Number of CRTC Registers to update\r
- dw 05f00h ; horz total\r
- dw 03f01h ; horz displayed\r
- dw 04202h ; start horz blanking\r
- dw 09f03h ; end horz blanking\r
- dw 04c04h ; start h sync\r
- dw 00005h ; end h sync\r
- dw 00014h ; turn off dword mode\r
- dw 0e317h ; turn on byte mode\r
- dw 256\r
- dw 200\r
-\r
-\r
-LABEL X256Y240 word\r
- db 0e3h ; dot clock\r
- db 16 ; Number of CRTC Registers to update\r
- dw 05f00h ; horz total\r
- dw 03f01h ; horz displayed\r
- dw 04202h ; start horz blanking\r
- dw 09f03h ; end horz blanking\r
- dw 04c04h ; start h sync\r
- dw 00005h ; end h sync\r
- dw 00d06h ; vertical total\r
- dw 03e07h ; overflow (bit 8 of vertical counts)\r
- dw 04109h ; cell height (2 to double-scan)\r
- dw 0ea10h ; v sync start\r
- dw 0ac11h ; v sync end and protect cr0-cr7\r
- dw 0df12h ; vertical displayed\r
- dw 00014h ; turn off dword mode\r
- dw 0e715h ; v blank start\r
- dw 00616h ; v blank end\r
- dw 0e317h ; turn on byte mode\r
- dw 256\r
- dw 240\r
-\r
-\r
-X320Y200 label word\r
- db 00 ; 0e3h ; dot clock\r
- db 02 ; Number of CRTC Registers to update\r
- dw 00014h ; turn off dword mode\r
- dw 0e317h ; turn on byte mode\r
- dw 320 ; width\r
- dw 200 ; height\r
-\r
-X320Y240 label word\r
- db 0e3h ; dot clock\r
- db 10 ; Number of CRTC Registers to update\r
- dw 00d06h ; vertical total\r
- dw 03e07h ; overflow (bit 8 of vertical counts)\r
- dw 04109h ; cell height (2 to double-scan)\r
- dw 0ea10h ; v sync start\r
- dw 0ac11h ; v sync end and protect cr0-cr7\r
- dw 0df12h ; vertical displayed\r
- dw 00014h ; turn off dword mode\r
- dw 0e715h ; v blank start\r
- dw 00616h ; v blank end\r
- dw 0e317h ; turn on byte mode\r
- dw 320 ; width\r
- dw 240 ; height\r
-\r
-X360Y200 label word\r
- db 0e7h ; dot clock\r
- db 08 ; Number of CRTC Registers to update\r
- dw 06b00h ; horz total\r
- dw 05901h ; horz displayed\r
- dw 05a02h ; start horz blanking\r
- dw 08e03h ; end horz blanking\r
- dw 05e04h ; start h sync\r
- dw 08a05h ; end h sync\r
- dw 00014h ; turn off dword mode\r
- dw 0e317h ; turn on byte mode\r
- dw 360 ; width\r
- dw 200 ; height\r
-\r
-X360Y240 label word\r
- db 0e7h ; dot clock\r
- db 17 ; Number of CRTC Registers to update\r
- dw 06b00h ; horz total\r
- dw 05901h ; horz displayed\r
- dw 05a02h ; start horz blanking\r
- dw 08e03h ; end horz blanking\r
- dw 05e04h ; start h sync\r
- dw 08a05h ; end h sync\r
- dw 00d06h ; vertical total\r
- dw 03e07h ; overflow (bit 8 of vertical counts)\r
- dw 04109h ; cell height (2 to double-scan)\r
- dw 0ea10h ; v sync start\r
- dw 0ac11h ; v sync end and protect cr0-cr7\r
- dw 0df12h ; vertical displayed\r
- dw 02d13h ; offset;\r
- dw 00014h ; turn off dword mode\r
- dw 0e715h ; v blank start\r
- dw 00616h ; v blank end\r
- dw 0e317h ; turn on byte mode\r
- dw 360\r
- dw 240\r
-\r
-X376Y282 label word\r
- db 0e7h\r
- db 18\r
- dw 06e00h ; horz total\r
- dw 05d01h ; horz displayed\r
- dw 05e02h ; start horz blanking\r
- dw 09103h ; end horz blanking\r
- dw 06204h ; start h sync\r
- dw 08f05h ; end h sync\r
- dw 06206h ; vertical total\r
- dw 0f007h ; overflow\r
- dw 06109h ; cell height\r
- dw 0310fh ;\r
- dw 03710h ; v sync start\r
- dw 08911h ; v sync end and protect cr0-cr7\r
- dw 03312h ; vertical displayed\r
- dw 02f13h ; offset\r
- dw 00014h ; turn off dword mode\r
- dw 03c15h ; v blank start\r
- dw 05c16h ; v blank end\r
- dw 0e317h ; turn on byte mode\r
- dw 376\r
- dw 282\r
-\r
-LABEL X256Y400 word\r
- db 0e3h ; dot clock\r
- db 8 ; Number of CRTC Registers to update\r
- dw 05f00h ; horz total\r
- dw 03f01h ; horz displayed\r
- dw 04202h ; start horz blanking\r
- dw 09f03h ; end horz blanking\r
- dw 04c04h ; start h sync\r
- dw 00005h ; end h sync\r
- dw 04009h ; cell height\r
- dw 00014h ; turn off dword mode\r
- dw 0e317h ; turn on byte mode\r
- dw 256\r
- dw 400\r
-\r
-\r
-LABEL X256Y480 word\r
- db 0e3h ; dot clock\r
- db 16 ; Number of CRTC Registers to update\r
- dw 05f00h ; horz total\r
- dw 03f01h ; horz displayed\r
- dw 04202h ; start horz blanking\r
- dw 09f03h ; end horz blanking\r
- dw 04c04h ; start h sync\r
- dw 00005h ; end h sync\r
- dw 00d06h ; vertical total\r
- dw 03e07h ; overflow (bit 8 of vertical counts)\r
- dw 04009h ; cell height (2 to double-scan)\r
- dw 0ea10h ; v sync start\r
- dw 0ac11h ; v sync end and protect cr0-cr7\r
- dw 0df12h ; vertical displayed\r
- dw 00014h ; turn off dword mode\r
- dw 0e715h ; v blank start\r
- dw 00616h ; v blank end\r
- dw 0e317h ; turn on byte mode\r
- dw 256\r
- dw 480\r
-\r
-\r
-\r
-X320Y400 label word\r
- db 0e3h ; dot clock\r
- db 03 ; Number of CRTC Registers to update\r
- dw 04009h ; cell height\r
- dw 00014h ; turn off dword mode\r
- dw 0e317h ; turn on byte mode\r
- dw 320 ; width\r
- dw 400 ; height\r
-\r
-X320Y480 label word\r
- db 0e3h ; dotclock\r
- db 10 ; Number of CRTC Registers to update\r
- dw 00d06h ; vertical total\r
- dw 03e07h ; overflow (bit 8 of vertical counts)\r
- dw 04009h ; cell height (2 to double-scan)\r
- dw 0ea10h ; v sync start\r
- dw 0ac11h ; v sync end and protect cr0-cr7\r
- dw 0df12h ; vertical displayed\r
- dw 00014h ; turn off dword mode\r
- dw 0e715h ; v blank start\r
- dw 00616h ; v blank end\r
- dw 0e317h ; turn on byte mode\r
- dw 320 ; width\r
- dw 480 ; height\r
-\r
-X360Y400 label word\r
- db 0e7h ; dot clock\r
- db 09 ; Number of CRTC Registers to update\r
- dw 06b00h ; horz total\r
- dw 05901h ; horz displayed\r
- dw 05a02h ; start horz blanking\r
- dw 08e03h ; end horz blanking\r
- dw 05e04h ; start h sync\r
- dw 08a05h ; end h sync\r
- dw 04009h ; cell height\r
- dw 00014h ; turn off dword mode\r
- dw 0e317h ; turn on byte mode\r
- dw 360 ; width\r
- dw 400 ; height\r
-\r
-\r
-\r
-X360Y480 label word\r
- db 0e7h\r
- db 17\r
- dw 06b00h ; horz total\r
- dw 05901h ; horz displayed\r
- dw 05a02h ; start horz blanking\r
- dw 08e03h ; end horz blanking\r
- dw 05e04h ; start h sync\r
- dw 08a05h ; end h sync\r
- dw 00d06h ; vertical total\r
- dw 03e07h ; overflow\r
- dw 04009h ; cell height\r
- dw 0ea10h ; v sync start\r
- dw 0ac11h ; v sync end and protect cr0-cr7\r
- dw 0df12h ; vertical displayed\r
- dw 02d13h ; offset\r
- dw 00014h ; turn off dword mode\r
- dw 0e715h ; v blank start\r
- dw 00616h ; v blank end\r
- dw 0e317h ; turn on byte mode\r
- dw 360\r
- dw 480\r
-\r
-X360Y360 label word\r
- db 0e7h\r
- db 15\r
- dw 06b00h ; horz total\r
- dw 05901h ; horz displayed\r
- dw 05a02h ; start horz blanking\r
- dw 08e03h ; end horz blanking\r
- dw 05e04h ; start h sync\r
- dw 08a05h ; end h sync\r
- dw 04009h ; cell height\r
- dw 08810h ; v sync start\r
- dw 08511h ; v sync end and protect cr0-cr7\r
- dw 06712h ; vertical displayed\r
- dw 02d13h ; offset\r
- dw 00014h ; turn off dword mode\r
- dw 06d15h ; v blank start\r
- dw 0ba16h ; v blank end\r
- dw 0e317h ; turn on byte mode\r
- dw 360\r
- dw 360\r
-\r
-\r
-X376Y308 label word\r
- db 0e7h\r
- db 18\r
- dw 06e00h ; horz total\r
- dw 05d01h ; horz displayed\r
- dw 05e02h ; start horz blanking\r
- dw 09103h ; end horz blanking\r
- dw 06204h ; start h sync\r
- dw 08f05h ; end h sync\r
- dw 06206h ; vertical total\r
- dw 00f07h ; overflow\r
- dw 04009h ;\r
- dw 0310fh ;\r
- dw 03710h ; v sync start\r
- dw 08911h ; v sync end and protect cr0-cr7\r
- dw 03312h ; vertical displayed\r
- dw 02f13h ; offset\r
- dw 00014h ; turn off dword mode\r
- dw 03c15h ; v blank start\r
- dw 05c16h ; v blank end\r
- dw 0e317h ; turn on byte mode\r
- dw 376\r
- dw 308\r
-\r
-X376Y564 label word\r
- db 0e7h\r
- db 18\r
- dw 06e00h ; horz total\r
- dw 05d01h ; horz displayed\r
- dw 05e02h ; start horz blanking\r
- dw 09103h ; end horz blanking\r
- dw 06204h ; start h sync\r
- dw 08f05h ; end h sync\r
- dw 06206h ; vertical total\r
- dw 0f007h ; overflow\r
- dw 06009h ;\r
- dw 0310fh ;\r
- dw 03710h ; v sync start\r
- dw 08911h ; v sync end and protect cr0-cr7\r
- dw 03312h ; vertical displayed\r
- dw 02f13h ; offset\r
- dw 00014h ; turn off dword mode\r
- dw 03c15h ; v blank start\r
- dw 05c16h ; v blank end\r
- dw 0e317h ; turn on byte mode\r
- dw 376\r
- dw 564\r
-\r
-LAST_X_MODE equ 13\r
-ModeTable label word ; Mode X tweak table\r
- dw offset X320Y200\r
- dw offset X320Y240\r
- dw offset X360Y200\r
- dw offset X360Y240\r
- dw offset X376Y282\r
- dw offset X320Y400\r
- dw offset X320Y480\r
- dw offset X360Y400\r
- dw offset X360Y480\r
- dw offset X360Y360\r
- dw offset X376Y308\r
- dw offset X376Y564\r
- dw offset X256Y200\r
- dw offset X256Y240\r
-\r
-\r
-PARAMS label byte\r
-\r
- _CurrXMode dw 0 ; Current graphics mode index\r
- _InGraphics db 0 ; Flag indicating graphics activity\r
- _ScrnPhysicalByteWidth dw 0 ; Physical width in bytes of screen\r
- _ScrnPhysicalPixelWidth dw 0 ; Physical width in pixels of screen\r
- _ScrnPhysicalHeight dw 0 ; Physical Height of screen\r
- _ErrorValue db 0 ; Set after function calls\r
-\r
-\r
- _SplitScrnActive db 0 ; Flag indicating Split scrn activity\r
- _DoubleBufferActive dw 0 ; Flag indicating double buffering\r
- _TrippleBufferActive dw 0 ; Flag indicating tripple buffering\r
-\r
- _SplitScrnScanLine dw 0 ; Split Screen's starting scan line\r
- _SplitScrnVisibleHeight dw 0 ; Split Screen's height on screen\r
-\r
- _SplitScrnOffs dw 0 ; Offset in video ram of Split Screen\r
- ; always = 0\r
- _Page0_Offs dw 0 ; Ofset in video ram of Main virtual\r
- ; screen ( = 0 if no split screen\r
- ; otherwise = offset of first byte\r
- ; after split screen\r
- _Page1_Offs dw 0 ; Ofset in video ram of Second virtual\r
- ; screen ( = 0 if no split screen\r
- ; otherwise = offset of first byte\r
- ; after split screen\r
- ; = Page0_Offs if Doubble buffering\r
- ; not enabled\r
- _Page2_Offs dw 0\r
-\r
- _NonVisual_Offs dw 0 ; Ofset in video ram of first byte\r
- ; of non visible ram\r
- _ScrnLogicalByteWidth dw 0 ; Logical width in bytes of screen\r
- _ScrnLogicalPixelWidth dw 0 ; Logical width in pixels of screen\r
- _ScrnLogicalHeight dw 0 ; Logical Height of screen\r
-\r
- _MaxScrollX dw 0 ; Max X start position of Physical\r
- ; screen within virtual screen (in\r
- ; bytes)\r
- _MaxScrollY dw 0 ; Max Y start position of Physical\r
- ; screen within virtual screen\r
-\r
- _VisiblePageIdx dw 0 ; Index of currently visible D.B.\r
- ; page\r
-\r
- PageAddrTable label word\r
- _VisiblePageOffs dw 0 ; Table containing starting offsets\r
- _HiddenPageOffs dw 0 ; of the double buffer pages\r
- _WaitingPageOffs dw 0\r
-\r
- _TopClip dw 0 ; Clipping Rectangle\r
- _BottomClip dw 0 ;\r
- _LeftClip dw 0 ; Left/Right coordinates in bytes\r
- _RightClip dw 0 ;\r
- _PhysicalStartByteX dw 0 ; X byte coord of physical screen\r
- ; relative to virtual virtual screen\r
- _PhysicalStartPixelX dw 0 ; X pixel coord of physical screen\r
- ; relative to virtual screen\r
- _PhysicalStartY dw 0 ; Y pixel coord of physical screen\r
- ; relative to virtual screen\r
-\r
-; NEW\r
- _VsyncHandlerActive dw 0\r
- _MouseRefreshFlag dw 0\r
- _MouseVsyncHandler dd 0\r
- _StartAddressFlag dw 0\r
- _WaitingStartLow dw 0\r
- _WaitingStartHigh dw 0\r
- _WaitingPelPan dw 0\r
- _VsyncPaletteStart dw 0\r
- _VsyncPaletteCount dw 0\r
- _VsyncPaletteBuffer label byte\r
- db 768 dup(?)\r
-\r
-\r
-PARAMS_END label byte\r
-\r
-PARAM_COUNT equ ($-PARAMS)\r
-\r
-\r
-; Index/data pairs for CRT Controller registers that differ between\r
-; mode 13h and mode X.\r
-\r
- ;Pelpan values for 0,1,2,3 pixel panning to the left, respectively\r
- PelPanMask db 000h,002h,004h,006h\r
-\r
-DoubleScanFlag db ? ; Flag to indicate double scanned mode\r
-\r
- .code\r
-\r
-;-------------------------------------------------------------------------\r
-; Local Logical Screen Width setting function\r
-; cx = Requitrd Logical Width\r
-;\r
-; WARNING: no registers are preserved\r
-\r
-SetLogicalScrWidth proc\r
- mov dx,CRTC_INDEX\r
- mov al,CRTC_OFFSET\r
- out dx,al\r
- inc dx\r
-\r
- mov ax,cx\r
- cmp ax,[_ScrnPhysicalPixelWidth]; Is logical width >= physical width\r
- jge @@ValidLogicalWidth ; yes - continue\r
- mov ax,bx ; no - set logical width = physical\r
-\r
-@@ValidLogicalWidth:\r
- shr ax,3\r
- out dx,al\r
-\r
- ; The EXACT logical pixel width may not have been possible since\r
- ; it should be divisible by 8. Round down to the closest possible\r
- ; width and update the status variables\r
-\r
- shl ax,1\r
- mov bx,ax\r
- mov [_ScrnLogicalByteWidth],ax ; Store the byte width of virtual\r
- mov [_RightClip],ax ; Set default Right clip column\r
- ; screen\r
- sub ax,[_ScrnPhysicalByteWidth] ; Calculate and store Max X position\r
- shl ax,2 ; of physical screen in virtual\r
- mov [_MaxScrollX],ax ; screen in pixels\r
- mov ax,bx ; set ax to byte width of virt scrn\r
- shl ax,2 ; convert to pixels\r
- mov [_ScrnLogicalPixelWidth],ax ; store virt scrn pixel width\r
- mov cx,ax ; save ax (return value)\r
-\r
- ; calculate no. non split screen rows in video ram\r
-\r
- mov ax,0ffffh ; cx = Maximum video ram offset\r
- sub dx,dx ; DX:AX is divide operand, set DX = 0\r
- div bx ; divide ax by ScrnLogicalByteWidth\r
- mov [_ScrnLogicalHeight],ax ; Save Screen Logical Height\r
- mov [_BottomClip],ax ; Set default bottom clip row\r
- sub ax,[_ScrnPhysicalHeight] ; Update the maximum Y position of\r
- mov [_MaxScrollY],ax ; Physical screen in logical screen\r
- mov ax,cx ; restore ax (return value)\r
-\r
- ; calculate initial NonVisual\r
- mov ax,[_ScrnLogicalByteWidth]\r
- mul [_ScrnPhysicalHeight]\r
- mov [_NonVisual_Offs],ax\r
-\r
-@@Done: ret\r
-SetLogicalScrWidth endp\r
-\r
-clear_vram proc\r
- push di\r
- mov dx,SC_INDEX\r
- mov ax,0f02h\r
- out dx,ax ; enable writes to all four planes\r
- mov ax,SCREEN_SEG ; now clear all display memory, 8 pixels\r
- mov es,ax ; at a time\r
- sub di,di ; point ES:DI to display memory\r
-\r
- WaitVsyncEnd\r
-\r
- sub ax,ax ; clear to zero-value pixels\r
- mov cx,0FFFFh ; # of words in display memory\r
- rep stosw ; clear all of display memory\r
- pop di\r
- ret\r
-clear_vram endp\r
-\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; Mode X graphics mode set with a virtual screen\r
-; logical screen width.\r
-; C near-callable as:\r
-;\r
-; int x_set_mode(unsigned int mode,unsigned int WidthInPixels);\r
-;\r
-; returns the actual width of the allocated virtual screen in pixels\r
-; if a valid mode was selected otherwise returns -1\r
-;\r
-; Saves virtual screen pixel width in _ScrnLogicalPixelWidth.\r
-; Saves virtual screen byte width in _ScrnLogicalByteWidth.\r
-; Physical screen dimensions are set in _ScrnPhysicalPixelWidth,\r
-; _ScrnPhysicalByteWidth and _ScrnPhysicalHeight\r
-;\r
-;\r
-; Modes: 0 = 320 x 200 (256 color) NOTE: Some of these modes require\r
-; 1 = 320 x 240 (256 color) vertical size adjustment.\r
-; 2 = 360 x 200 (256 color)\r
-; 3 = 360 x 240 (256 color)\r
-; 4 = 320 x 400 (256 color)\r
-; 5 = 320 x 480 (256 color)\r
-; 6 = 360 x 200 (256 color)\r
-; 7 = 360 x 480 (256 color)\r
-; 8 = 360 x 360 (256 color)\r
-; 9 = 376 x 308 (256 color)\r
-; 10 = 376 x 564 (256 color)\r
-;\r
-; Written by Themie Gouthas,\r
-; parts adapted from M. Abrash code.\r
-;------------------------------------------------------------------------\r
-_x_set_mode proc\r
- ARG mode:word,logicalscrwidth:word\r
- push bp ;preserve caller's stack frame\r
- mov bp,sp\r
-\r
- push si ;preserve C register vars\r
- push di ; (don't count on BIOS preserving anything)\r
-\r
- cld\r
- mov ax,ds\r
- mov es,ax\r
- mov di,offset PARAMS\r
- xor ax,ax\r
- mov cx,PARAM_COUNT\r
- rep stosb\r
-\r
- mov cx,[mode]\r
- cmp cx,LAST_X_MODE ; have we selected a valid mode\r
- jle @@ValidMode ; Yes !\r
-\r
- mov [_InGraphics],FALSE ; No return -1\r
- mov ax,-1\r
- pop di\r
- pop si\r
- pop bp\r
- ret\r
-\r
-@@ValidMode:\r
-\r
- mov [_CurrXMode],cx\r
- mov [_InGraphics],TRUE\r
-\r
- xor al,al\r
- cmp cx,3\r
- jg @@SetDoubleScanFlag\r
- mov al,TRUE\r
-@@SetDoubleScanFlag:\r
- mov [DoubleScanFlag],al\r
- push cx ; some bios's dont preserve cx\r
-\r
- call clear_vram\r
-\r
- mov ax,13h ; let the BIOS set standard 256-color\r
- int 10h ; mode (320x200 linear)\r
-\r
-\r
- pop cx\r
-\r
- mov dx,SC_INDEX\r
- mov ax,0604h\r
- out dx,ax ; disable chain4 mode\r
- mov ax,0100h\r
- out dx,ax ; synchronous reset while setting Misc\r
- ; Output for safety, even though clock\r
- ; unchanged\r
-\r
- mov bx,offset ModeTable\r
- shl cx,1\r
- add bx,cx\r
- mov si, word ptr [bx]\r
- lodsb\r
-\r
- or al,al\r
- jz @@DontSetDot\r
- mov dx,MISC_OUTPUT\r
- out dx,al ; select the dot clock and Horiz\r
- ; scanning rate\r
-@@DontSetDot:\r
- mov dx,SC_INDEX\r
- mov ax,0300h\r
- out dx,ax ; undo reset (restart sequencer)\r
-\r
-\r
- mov dx,CRTC_INDEX ; reprogram the CRT Controller\r
- mov al,11h ; VSync End reg contains register write\r
- out dx,al ; protect bit\r
- inc dx ; CRT Controller Data register\r
- in al,dx ; get current VSync End register setting\r
- and al,07fh ; remove write protect on various\r
- out dx,al ; CRTC registers\r
- dec dx ; CRT Controller Index\r
- cld\r
- xor cx,cx\r
- lodsb\r
- mov cl,al\r
-\r
-@@SetCRTParmsLoop:\r
- lodsw ; get the next CRT Index/Data pair\r
- out dx,ax ; set the next CRT Index/Data pair\r
- loop @@SetCRTParmsLoop\r
-\r
- mov dx,SC_INDEX\r
- mov ax,0f02h\r
- out dx,ax ; enable writes to all four planes\r
- mov ax,SCREEN_SEG ; now clear all display memory, 8 pixels\r
- mov es,ax ; at a time\r
- sub di,di ; point ES:DI to display memory\r
- sub ax,ax ; clear to zero-value pixels\r
- mov cx,8000h ; # of words in display memory\r
- rep stosw ; clear all of display memory\r
-\r
- ; Set pysical screen dimensions\r
-\r
- lodsw ; Load scrn pixel width\r
- mov [_ScrnPhysicalPixelWidth],ax ; from tweak table and store\r
- mov [_SplitScrnScanLine],ax ; No splitscrn ==\r
- ; splitscrn=PhysicalscrnHeight\r
- mov bx,ax ; Copy width for later use\r
- shr ax,2 ; Convert to byte width\r
- mov [_ScrnPhysicalByteWidth],ax ; Store for later use\r
- lodsw ; Load Screen Phys. Height\r
- mov [_ScrnPhysicalHeight],ax ; Store for later use\r
-\r
-\r
- ; Mode X is set, now set the required logical page width.\r
-\r
- mov cx,[logicalscrwidth]\r
-\r
- call SetLogicalScrWidth\r
-\r
- pop di ;restore C register vars\r
- pop si\r
- pop bp ;restore caller's stack frame\r
- ret\r
-_x_set_mode endp\r
-\r
-;----------------------------------------------------------------------\r
-; Mode X (256 color mode) set default access video plane\r
-;\r
-; C near-callable as:\r
-; void x_select_default_plane(unsigned char plane);\r
-;\r
-; Enables Read/Write access to a plane using general memory access\r
-; methods\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_select_default_plane proc\r
-ARG Plane:byte\r
- push bp\r
- mov bp,sp ; set up stack frame\r
- mov cl,byte ptr [Plane]\r
-\r
- ; SELECT WRITE PLANE\r
- and cl,011b ;CL = plane\r
- mov ax,0100h + MAP_MASK ;AL = index in SC of Map Mask reg\r
- shl ah,cl ;set only the bit for the required\r
- ; plane to 1\r
- mov dx,SC_INDEX ;set the Map Mask to enable only the\r
- out dx,ax ; pixel's plane\r
-\r
- ; SELECT READ PLANE\r
- mov ah,cl ;AH = plane\r
- mov al,READ_MAP ;AL = index in GC of the Read Map reg\r
- mov dx,GC_INDEX ;set the Read Map to read the pixel's\r
- out dx,ax ; plane\r
-\r
- pop bp\r
- ret\r
-_x_select_default_plane endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; Mode X (256 color mode) Set Mode X split screen starting row\r
-; The split screen resides on the bottom half of the screen and has a\r
-; starting address of A000:0000\r
-;\r
-; C near-callable as:\r
-; void x_set_splitscreen(unsigned int line);\r
-;\r
-; Updates _Page0_Offs to reflect the existence of the split screen region\r
-; ie _MainScrnOffset is set to the offset of the first pixel beyond the split\r
-; screen region\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-\r
-_x_set_splitscreen proc\r
- ARG Line:word\r
- push bp\r
- mov bp,sp ; set up stack frame\r
- push si\r
-\r
- xor si,si ; si=0 -> x virtual page start coord\r
-\r
- cmp [_DoubleBufferActive],0\r
- jne @@error\r
-\r
- cmp [_SplitScrnActive],0\r
- je @@NotPreviouslyCalled\r
-\r
-@@error:\r
- mov [_ErrorValue],ERROR\r
- pop si\r
- pop bp ; Return if previously called\r
- ret\r
-\r
-@@NotPreviouslyCalled:\r
-\r
- ; Turn on split screen pal pen suppression, so the split screen\r
- ; wo'nt be subject to pel panning as is the non split screen portion.\r
-\r
- mov dx,INPUT_STATUS_0\r
- in al,dx ; Reset the AC Index/Data toggle to\r
- ; index state\r
- mov al,AC_MODE_CONTROL+20h ; Bit 5 set to prevent screen blanking\r
- mov dx,AC_INDEX ; Point AC to Index/Data register\r
- out dx,al\r
- inc dx ; Point to AC Data reg (for reads only)\r
- in al,dx ; Get the current AC Mode Control reg\r
- or al,20h ; Enable split scrn Pel panning suppress.\r
- dec dx ; Point to AC Index/Data reg (for writes only)\r
- out dx,al ; Write the new AC Mode Control setting\r
- ; with split screen pel panning\r
- ; suppression turned on\r
-\r
- mov [_PhysicalStartByteX],ax ; Set the Phisical screen start\r
- mov [_PhysicalStartPixelX],ax ; offset within virtual screen\r
- mov [_PhysicalStartY],ax\r
- mov [_SplitScrnActive],TRUE\r
- mov ax,[Line]\r
- jns @@NotNeg ; Check that Split Scrn start scan line is +ve\r
-\r
- mov ax,0 ; Since -ve set to 0\r
-\r
-@@NotNeg:\r
- mov [_SplitScrnScanLine],ax ; save the scanline\r
-\r
-\r
-\r
- or [DoubleScanFlag],0\r
- jz @@NotDoubleScanned\r
- shl ax,1\r
- dec ax\r
-@@NotDoubleScanned:\r
- ;mov cl,[DoubleScanFlag]\r
- ;shl ax,cl ; Mode X 200 and 240 line modes are actually\r
- ; 400 and 480 lines that are double scanned\r
- ; so for start scanline multiply required ModeX\r
- ; scan line by 2 if its a double scanned mode\r
-\r
-\r
- mov bx,ax ; save the scanline\r
-\r
-\r
- WaitVsyncStart ; wait for vertical retrace\r
-\r
- cli ; Dont allow register setting to be interrupted\r
- mov dx,CRTC_INDEX\r
- mov ah,bl\r
- mov al,LINE_COMPARE\r
- out dx,ax ; Bits 7-0 of the split screen scan line\r
-\r
- mov ah,bh\r
- and ah,1\r
- shl ah,4\r
- mov al,OVERFLOW ; Bit 4 of overflow register = Bit 8 of split\r
- out dx,al ; screen scan line,\r
- inc dx ; So using readability of VGA registers\r
- in al,dx ; Read the OVERFLOW register, and set the\r
- and al, not 10h ; bit corresponding to Bit 8 (above)\r
- or al,ah\r
- out dx,al\r
-\r
- dec dx\r
- mov ah,bh\r
- and ah,2\r
- ror ah,3\r
- mov al,MAX_SCAN_LINE ; Bit 6 of max scan line register =\r
- out dx,al ; Bit 9 of split screen scan line\r
- inc dx ; As we did before, update the apropriate\r
- in al,dx ; bit without disturbing the rest\r
- and al, not 40h\r
- or al,ah\r
- out dx,al\r
- sti ; Registers are set, so interrupts are safe\r
-\r
- mov ax,[_ScrnPhysicalHeight] ; Determine where the first byte\r
- sub ax,[_SplitScrnScanLine] ; of the non split screen video ram\r
- mov [_SplitScrnVisibleHeight],ax ; starts and store it for reference\r
-\r
- mov bx,[_ScrnLogicalByteWidth]\r
- mul bx\r
- mov [_Page0_Offs],ax\r
- mov [_Page1_Offs],ax\r
- mov [_Page2_Offs],ax\r
-\r
- ; calculate no. non split screen rows in video ram\r
- mov cx,0ffffh ; cx = Maximum video ram offset\r
- sub cx,ax ; cx = cx - _Page0_Offs\r
- xchg cx,ax ; swap cx and ax\r
- sub dx,dx ; DX:AX is divide operand, set DX = 0\r
- div bx ; divide ax (prev cx) by\r
- ; ScrnLogicalByteWidth\r
-\r
- mov [_ScrnLogicalHeight],ax ; Save Screen Logical Height\r
- cmp ax,[_BottomClip]\r
- jle @@BottomClipOK ; Adjust Clip Rectangle if necessary\r
- mov [_BottomClip],ax\r
-@@BottomClipOK:\r
- sub ax,[_SplitScrnScanLine] ; Update the maximum Y position of\r
- mov [_MaxScrollY],ax ; Physical screen in logical screen\r
-\r
- xchg cx,ax ; restore original ax (MainScrnOfs)\r
- mov bh,al ; Set the visible screen start address\r
- mov ch,ah ; to the top left corner of the virtual\r
- jmp StartAddrEntry ; screen\r
-_x_set_splitscreen endp\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; Mode X (256 color mode) Page flip primer\r
-; No clipping is performed.\r
-; C near-callable as:\r
-;\r
-; void x_page_flip(unsigned int x, unsigned int y);\r
-;\r
-; Swaps visible and hidden page offsets and then executes the SetStartAddr\r
-; to achieve a page flip.\r
-;\r
-; SEE x_set_start_addr below\r
-;\r
-; Written by Themie Gouthas\r
-;------------------------------------------------------------------------\r
-\r
-_x_page_flip proc\r
- ARG x:word,y:word\r
- push bp ;preserve caller's stack frame\r
- mov bp,sp ;point to local stack frame\r
- push si\r
-\r
- mov si,[x]\r
- mov ax,[_ScrnLogicalByteWidth] ; Calculate Offset increment\r
- mov cx,[y]\r
- mul cx ; for Y\r
- cmp [_DoubleBufferActive],TRUE ; Do we have double buffering ?\r
- je @@DoubleBuffer\r
- cmp [_TrippleBufferActive],TRUE\r
- jne PageFlipEntry1\r
-\r
-; TrippleBuffer\r
- mov bx,[_HiddenPageOffs]\r
- xchg bx,[_VisiblePageOffs]\r
- xchg bx,[_WaitingPageOffs]\r
- mov [_HiddenPageOffs],bx\r
- mov bx,[_VisiblePageIdx]\r
- inc bx\r
- cmp bx,3\r
- jne @@IdxOk\r
- xor bx,bx\r
-@@IdxOk:\r
- mov [_VisiblePageIdx],bx\r
- jmp short PageFlipEntry2\r
-@@DoubleBuffer:\r
- mov bx,[_HiddenPageOffs]\r
- xchg bx,[_VisiblePageOffs] ; Swap the Page Offsete\r
- xchg [_HiddenPageOffs],bx\r
- xor [_VisiblePageIdx],01h ; Set the Visible page index\r
- jmp short PageFlipEntry2\r
-_x_page_flip endp\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; Mode X (256 color mode) Set Mode X non split screen start address\r
-; of logical screen.\r
-; C near-callable as:\r
-;\r
-; void x_set_start_addr(unsigned int x, unsigned int y);\r
-;\r
-; Params: StartOffset is offset of first byte of logical screen ram\r
-; (Useful if you want to double buffer by splitting your non\r
-; split screen video ram into 2 pages)\r
-; X,Y coordinates of the top left hand corner of the physical screen\r
-; within the logical screen\r
-; X must not exceed (Logical screen width - Physical screen width)\r
-; Y must not exceed (Logical screen height - Physical screen height)\r
-;\r
-;\r
-; Written by Themie Gouthas,\r
-; Parts addapted from M. Abrash code published in DDJ Mag.\r
-;------------------------------------------------------------------------\r
-_x_set_start_addr proc\r
- ARG x:word,y:word\r
- push bp\r
- mov bp,sp\r
- push si\r
-\r
- mov si,[x]\r
- mov ax,[_ScrnLogicalByteWidth] ; Calculate Offset increment\r
- mov cx,[y] ; for Y\r
- mul cx\r
- cmp [_DoubleBufferActive],TRUE ; Do we have double buffering ?\r
- je @@PageResolution\r
- cmp [_TrippleBufferActive],TRUE\r
- je @@PageResolution\r
-PageFlipEntry1:\r
- add ax,[_Page0_Offs] ; no - add page 0 offset\r
- jmp short @@AddColumn\r
-\r
-PageFlipEntry2:\r
-\r
- mov [_PhysicalStartPixelX],si\r
- mov [_PhysicalStartY],cx\r
-\r
-@@PageResolution:\r
- add ax,[_VisiblePageOffs] ; Add visible page offset\r
-\r
-@@AddColumn:\r
- mov cx,si\r
- shr cx,2\r
- mov [_PhysicalStartByteX],cx\r
- add ax,cx ; add the column offset for X\r
- mov bh,al ; setup CRTC start addr regs and\r
- ; values in word registers for\r
- mov ch,ah ; fast word outs\r
-\r
-StartAddrEntry:\r
- mov bl,ADDR_LOW\r
- mov cl,ADDR_HIGH\r
- and si,0003h ; select pel pan register value for the\r
- mov ah,PelPanMask[si] ; required x coordinate\r
- mov al,PEL_PANNING+20h\r
- mov si,ax\r
-\r
- cmp [_VsyncHandlerActive],TRUE\r
- jne @@NoVsyncHandler\r
-; NEW STUFF\r
-@@WaitLast:\r
- cmp [_StartAddressFlag],0\r
- jne @@WaitLast\r
- cli\r
- mov [_WaitingStartLow],bx\r
- mov [_WaitingStartHigh],cx\r
- mov [_WaitingPelPan],si\r
- mov [_StartAddressFlag],1\r
- sti\r
- jmp short @@Return\r
-\r
-@@NoVsyncHandler:\r
- mov dx,INPUT_STATUS_0 ;Wait for trailing edge of Vsync pulse\r
-@@WaitDE:\r
- in al,dx\r
- test al,01h\r
- jnz @@WaitDE ;display enable is active low (0 = active)\r
-\r
- mov dx,CRTC_INDEX\r
- mov ax,bx\r
- cli\r
- out dx,ax ;start address low\r
- mov ax,cx\r
- out dx,ax ;start address high\r
- sti\r
-\r
-; Now wait for vertical sync, so the other page will be invisible when\r
-; we start drawing to it.\r
- mov dx,INPUT_STATUS_0 ;Wait for trailing edge of Vsync pulse\r
-@@WaitVS:\r
- in al,dx\r
- test al,08h\r
- jz @@WaitVS ;display enable is active low (0 = active)\r
-\r
-\r
- mov dx,AC_INDEX\r
- mov ax,si ; Point the attribute controller to pel pan\r
- cli\r
- out dx,al ; reg. Bit 5 also set to prevent blanking\r
- mov al,ah\r
- out dx,al ; load new Pel Pan setting.\r
- sti\r
-\r
-@@Return:\r
- mov [_ErrorValue],OK\r
- pop si\r
- pop bp\r
- ret\r
-_x_set_start_addr endp\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; Mode X (256 color mode) Mode X split screen hide\r
-; C near-callable as:\r
-;\r
-; void x_hide_splitscreen()\r
-;\r
-; Hides an existing split screen by setting its starting scan line to\r
-; the last physical screen scan line\r
-;\r
-; WARNING: Only to be used if SplitScrnLine has been previously called\r
-; WARNING: DO NOT USE with mode 5-11 (320x400-376x564). The memory for\r
-; the initial split screen is reserved and the size limitations\r
-; of these modes means any change in the split screen scan line\r
-; will encroach on the split screen ram\r
-;\r
-; Written by Themie Gouthas\r
-;------------------------------------------------------------------------\r
-\r
-_x_hide_splitscreen proc\r
- push bp\r
- mov bp,sp\r
-\r
- cmp [_SplitScrnActive],TRUE\r
- je @@SplitScreenEnabled\r
-\r
-@@error:\r
- mov [_ErrorValue],ERROR\r
- pop bp\r
- ret\r
-\r
-@@SplitScreenEnabled:\r
- cmp [_CurrXMode],4 ; Do nothing for Modes > 2\r
- jg @@error\r
- mov bx,[_ScrnPhysicalHeight]\r
-\r
- mov ax,[_ScrnLogicalHeight]\r
- sub ax,bx\r
- mov [_MaxScrollY],ax\r
- xor ax,ax\r
- mov [_SplitScrnVisibleHeight],ax\r
-\r
- or [DoubleScanFlag],0\r
- jz @@NotDoubleScanned\r
- shl bx,1\r
- dec bx\r
-@@NotDoubleScanned:\r
- ;mov cl,[DoubleScanFlag] ; Compensate for double scanned modes\r
- ;shl bx,cl\r
-\r
- WaitVsyncStart ; wait for vertical retrace\r
-\r
- cli ; Dont allow register setting to be interrupted\r
- mov dx,CRTC_INDEX\r
- mov ah,bl\r
- mov al,LINE_COMPARE\r
- out dx,ax ; Bits 7-0 of the split screen scan line\r
-\r
- mov ah,bh\r
- and ah,1\r
- shl ah,4\r
- mov al,OVERFLOW ; Bit 4 of overflow register = Bit 8 of split\r
- out dx,al ; screen scan line,\r
- inc dx ; So using readability of VGA registers\r
- in al,dx ; Read the OVERFLOW register, and set the\r
- and al, not 10h ; bit corresponding to Bit 8 (above)\r
- or al,ah\r
- out dx,al\r
-\r
- dec dx\r
- mov ah,bh\r
- and ah,2\r
- ror ah,3\r
- mov al,MAX_SCAN_LINE ; Bit 6 of max scan line register =\r
- out dx,al ; Bit 9 of split screen scan line\r
- inc dx ; As we did before, update the apropriate\r
- in al,dx ; bit without disturbing the rest\r
- and al, not 40h\r
- or al,ah\r
- out dx,al\r
- sti ; Registers are set, so interrupts are safe\r
-\r
-@@done:\r
-\r
- mov [_ErrorValue],OK\r
- pop bp\r
- ret\r
-_x_hide_splitscreen endp\r
-\r
-;-----------------------------------------------------------------------\r
-; Mode X (256 color mode) Mode X split screen show\r
-; C near-callable as:\r
-;\r
-; void x_show_splitscreen()\r
-;\r
-; Restores split screen start scan line to the initial split screen\r
-; starting scan line as set by SplitScrnLine.\r
-;\r
-; WARNING: Only to be used if SplitScrnLine has been previously called\r
-; WARNING: DO NOT USE with mode 5-11 (320x400-376x564). The memory for\r
-; the initial split screen is reserved and the size limitations\r
-; of these modes means any change in the split screen scan line\r
-; will encroach on the split screen ram\r
-; Update: Now disabled for these modes\r
-;\r
-; Written by Themie Gouthas\r
-;------------------------------------------------------------------------\r
-\r
-\r
-_x_show_splitscreen proc\r
- push bp\r
- mov bp,sp\r
-\r
- cmp [_SplitScrnActive],TRUE\r
- je @@SplitScreenEnabled\r
-\r
-@@error:\r
- mov [_ErrorValue],ERROR\r
- pop bp\r
- ret\r
-\r
-@@SplitScreenEnabled:\r
- cmp [_CurrXMode],4 ; Do nothing for Modes > 2\r
- jg @@error\r
-\r
- mov bx,[_SplitScrnScanLine]\r
- mov ax,[_ScrnLogicalHeight] ; Update Max Scroll Y\r
- sub ax,bx\r
- mov [_MaxScrollY],ax\r
-\r
- mov ax,[_ScrnPhysicalHeight]\r
- sub ax,bx\r
- mov [_SplitScrnVisibleHeight],ax\r
-\r
- or [DoubleScanFlag],0\r
- jz @@NotDoubleScanned\r
- shl bx,1\r
- dec bx\r
-@@NotDoubleScanned:\r
- ;mov cl,[DoubleScanFlag] ; Compensate for double scanned modes\r
- ;shl bx,cl\r
- WaitVsyncStart ; wait for vertical retrace\r
-\r
- cli ; Dont allow register setting to be interrupted\r
- mov dx,CRTC_INDEX\r
- mov ah,bl\r
- mov al,LINE_COMPARE\r
- out dx,ax ; Bits 7-0 of the split screen scan line\r
-\r
- mov ah,bh\r
- and ah,1\r
- shl ah,4\r
- mov al,OVERFLOW ; Bit 4 of overflow register = Bit 8 of split\r
- out dx,al ; screen scan line,\r
- inc dx ; So using readability of VGA registers\r
- in al,dx ; Read the OVERFLOW register, and set the\r
- and al, not 10h ; bit corresponding to Bit 8 (above)\r
- or al,ah\r
- out dx,al\r
-\r
- dec dx\r
- mov ah,bh\r
- and ah,2\r
- ror ah,3\r
- mov al,MAX_SCAN_LINE ; Bit 6 of max scan line register =\r
- out dx,al ; Bit 9 of split screen scan line\r
- inc dx ; As we did before, update the apropriate\r
- in al,dx ; bit without disturbing the rest\r
- and al, not 40h\r
- or al,ah\r
- out dx,al\r
- sti ; Registers are set, so interrupts are safe\r
-\r
-@@Done:\r
- mov [_ErrorValue],0\r
- pop bp\r
- ret\r
-_x_show_splitscreen endp\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; Mode X (256 color mode) Modify Mode X split screen starting scan line\r
-; C near-callable as:\r
-;\r
-; void x_adjust_splitscreen(unsigned int ScanLine)\r
-;\r
-; Sets the split screen start scan line to a new scan line. Valid scan lines\r
-; are between the initial split screen starting scan line and the last\r
-; physical screen scan line.\r
-;\r
-; WARNING: Only to be used if SplitScrnLine has been previously called\r
-; WARNING: DO NOT USE with mode 5-11 (320x400-376x564). The memory for\r
-; the initial split screen is reserved and the size limitations\r
-; of these modes means any change in the split screen scan line\r
-; will encroach on the split screen ram\r
-; Update: Now disabled for these modes\r
-;\r
-;\r
-; Written by Themie Gouthas\r
-;------------------------------------------------------------------------\r
-\r
-\r
-_x_adjust_splitscreen proc\r
- ARG ScanLine\r
- push bp\r
- mov bp,sp\r
-\r
- cmp [_SplitScrnActive],TRUE\r
- je @@SplitScreenEnabled\r
-\r
-@@error:\r
- mov [_ErrorValue],ERROR\r
- pop bp\r
- ret\r
-\r
-@@SplitScreenEnabled:\r
- cmp [_CurrXMode],4 ; Do nothing for Modes > 2\r
- jg @@error\r
- mov bx,[ScanLine] ; Is the required starting scan line\r
- cmp bx,[_SplitScrnScanLine] ; valid ?\r
- js @@Done ; No - Then do nothing\r
-\r
-@@ValidScanLine:\r
-\r
- mov ax,[_ScrnLogicalHeight] ; Update Max Scroll Y\r
- sub ax,bx\r
- mov [_MaxScrollY],ax\r
-\r
- mov ax,[_ScrnPhysicalHeight]\r
- sub ax,bx\r
- mov [_SplitScrnVisibleHeight],ax\r
-\r
- or [DoubleScanFlag],0\r
- jz @@NotDoubleScanned\r
- shl bx,1\r
- dec bx\r
-@@NotDoubleScanned:\r
- ;mov cl,[DoubleScanFlag] ; Compensate for double scanned modes\r
- ;shl bx,cl\r
-\r
- WaitVsyncStart ; wait for vertical retrace\r
-\r
- cli ; Dont allow register setting to be interrupted\r
-\r
- mov dx,CRTC_INDEX\r
- mov ah,bl\r
- mov al,LINE_COMPARE\r
- out dx,ax ; Bits 7-0 of the split screen scan line\r
-\r
- mov ah,bh\r
- and ah,1\r
- shl ah,4\r
- mov al,OVERFLOW ; Bit 4 of overflow register = Bit 8 of split\r
- out dx,al ; screen scan line,\r
- inc dx ; So using readability of VGA registers\r
- in al,dx ; Read the OVERFLOW register, and set the\r
- and al, not 10h ; bit corresponding to Bit 8 (above)\r
- or al,ah\r
- out dx,al\r
-\r
- dec dx\r
- mov ah,bh\r
- and ah,2\r
- ror ah,3\r
- mov al,MAX_SCAN_LINE ; Bit 6 of max scan line register =\r
- out dx,al ; Bit 9 of split screen scan line\r
- inc dx ; As we did before, update the apropriate\r
- in al,dx ; bit without disturbing the rest\r
- and al, not 40h\r
- or al,ah\r
- out dx,al\r
- sti ; Registers are set, so interrupts are safe\r
-@@Done:\r
- mov [_ErrorValue],OK\r
- pop bp\r
- ret\r
-_x_adjust_splitscreen endp\r
-\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; Mode X (256 color mode) Enable DoubleBuffering on non split screen area\r
-; C near-callable as:\r
-;\r
-; int x_set_doublebuffer(unsigned int PageHeight);\r
-;\r
-; Params: PageHeight is the height of the virtual screen to double buffer\r
-; Returns the closest possible height to the specified.\r
-;\r
-; Sets up two double buffering virtual pages\r
-; GLOBAL variables set:\r
-;\r
-; _Page1_Offs Offset of second virtual page\r
-; _NonVisual_Offs Offset of first non visible video ram byte\r
-; _DoubleBufferActive Flag\r
-; _PageAddrTable Table of Double buffering pages start offsets\r
-; _ScrnLogicalHeight Logical height of the double buffering pages\r
-;\r
-;\r
-; Written by Themie Gouthas\r
-;------------------------------------------------------------------------\r
-\r
-\r
-_x_set_doublebuffer proc\r
- ARG PageHeight:word\r
- push bp\r
- mov bp,sp\r
-\r
- cmp [_DoubleBufferActive],0\r
- je @@OkToContinue\r
-@error:\r
- mov [_ErrorValue],ERROR\r
- pop bp\r
- ret\r
-\r
-@@OkToContinue:\r
- mov [_VisiblePageIdx],0 ; Set visible Page to 0\r
- mov ax,[_ScrnLogicalHeight] ; Set Maximum D.B. Page height to\r
- shr ax,1 ; _ScrnLogicalHeight / 2\r
-\r
- mov bx,[PageHeight] ; Is the require D.B. Page Height\r
- cmp ax,bx ; > the Maximum D.B. Page Height ?\r
-\r
- js @@InvalidHeight ; no - jump\r
- mov ax,bx ; yes - Set the D.B. Page height to\r
- ; to the maximum allowed.\r
-\r
-@@InvalidHeight:\r
- mov [_ScrnLogicalHeight],ax ; Update logical screen height to\r
- ; reflect the height of a D.B. page\r
- cmp ax,[_BottomClip]\r
- jle @@BottomClipOK ; Adjust Clip Rectangle if necessary\r
- mov [_BottomClip],ax\r
-@@BottomClipOK:\r
- push ax\r
- mul [_ScrnLogicalByteWidth] ; Calculate the offset of the second\r
- mov cx,ax ; D.B. Page in video ram\r
- mov bx,[_Page0_Offs]\r
- mov [_VisiblePageOffs],bx\r
-\r
- add ax,bx\r
- mov [_Page1_Offs],ax ; Save it\r
- mov [_HiddenPageOffs],ax\r
-\r
- add ax,cx ; Calculate the offset of first byte\r
- mov [_NonVisual_Offs],ax ; beyond the D.B. pages and save it\r
- mov [_DoubleBufferActive],TRUE ; Set flag indicating D.B'ing mode on\r
-\r
- pop ax\r
- sub ax,[_ScrnPhysicalHeight]\r
- add ax,[_SplitScrnVisibleHeight]\r
- mov [_MaxScrollY],ax\r
-\r
- mov ax,dx ; return the D.B. pages' height\r
- mov [_ErrorValue],OK\r
- pop bp\r
- ret\r
-_x_set_doublebuffer endp\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; Mode X (256 color mode) Enable TrippleBuffering on non split screen area\r
-; C near-callable as:\r
-;\r
-; int x_set_tripplebuffer(unsigned int PageHeight);\r
-;\r
-; Params: PageHeight is the height of the virtual screen to tripple buffer\r
-; Returns the closest possible height to the specified.\r
-;\r
-; Sets up two tripple buffering virtual pages\r
-; GLOBAL variables set:\r
-;\r
-; _Page1_Offs Offset of second virtual page\r
-; _Page2_Offs Offset of third virtual page\r
-; _NonVisual_Offs Offset of first non visible video ram byte\r
-; _DoubleBufferActive Flag\r
-; _PageAddrTable Table of Double buffering pages start offsets\r
-; _ScrnLogicalHeight Logical height of the double buffering pages\r
-;\r
-;\r
-; Almost written by Tore Bastiansen (cut & paste from _x_set_doublebuffer)\r
-;------------------------------------------------------------------------\r
-\r
-_x_set_tripplebuffer proc\r
- ARG PageHeight:word\r
- push bp\r
- mov bp,sp\r
-\r
- cmp [_DoubleBufferActive],0\r
- jne @@Error\r
- cmp [_TrippleBufferActive],0\r
- je @@OkToContinue\r
-@@Error:\r
- mov [_ErrorValue],ERROR\r
- pop bp\r
- ret\r
-\r
-@@OkToContinue:\r
- mov [_VisiblePageIdx],0 ; Set visible Page to 0\r
- mov ax,[_ScrnLogicalHeight] ; Set Maximum T.B. Page height to\r
- mov bx,3\r
- xor dx,dx\r
- idiv bx ; _ScrnLogicalHeight / 3\r
-\r
- mov bx,[PageHeight] ; Is the require T.B. Page Height\r
- cmp ax,bx ; > the Maximum T.B. Page Height ?\r
-\r
- js @@InvalidHeight ; no - jump\r
- mov ax,bx ; yes - Set the T.B. Page height to\r
- ; to the maximum allowed.\r
-\r
-@@InvalidHeight:\r
- mov [_ScrnLogicalHeight],ax ; Update logical screen height to\r
- ; reflect the height of a T.B. page\r
- cmp ax,[_BottomClip]\r
- jle @@BottomClipOK ; Adjust Clip Rectangle if necessary\r
- mov [_BottomClip],ax\r
-@@BottomClipOK:\r
- push ax\r
- mul [_ScrnLogicalByteWidth] ; Calculate the offset of the second\r
- mov cx,ax ; D.B. Page in video ram\r
- mov bx,[_Page0_Offs]\r
- mov [_VisiblePageOffs],bx\r
-\r
- add ax,bx\r
- mov [_Page1_Offs],ax ; Save it\r
- mov [_HiddenPageOffs],ax\r
-\r
- add ax,cx\r
- mov [_Page2_Offs],ax ; Save the other it ?\r
- mov [_WaitingPageOffs],ax\r
-\r
- add ax,cx ; Calculate the offset of first byte\r
- mov [_NonVisual_Offs],ax ; beyond the D.B. pages and save it\r
- mov [_TrippleBufferActive],TRUE ; Set flag indicating T.B'ing mode on\r
-\r
- pop ax\r
- sub ax,[_ScrnPhysicalHeight]\r
- add ax,[_SplitScrnVisibleHeight]\r
- mov [_MaxScrollY],ax\r
-\r
- mov ax,dx ; return the D.B. pages' height\r
- mov [_ErrorValue],OK\r
- pop bp\r
- ret\r
-_x_set_tripplebuffer endp\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; Set Clipping rectangle\r
-; C callable as:\r
-;\r
-;\r
-; int x_set_cliprect(WORD left,WORD top, WORD right, WORD bottom);\r
-;\r
-;\r
-; NOTE clipping is byte oriented. "left" and "right" are in bytes not pixels.\r
-; Only selected functions perform any clipping at all.\r
-;\r
-; Written by Themie Gouthas\r
-;------------------------------------------------------------------------\r
-\r
-_x_set_cliprect proc\r
-ARG left:word,top:word,right:word,bottom:word\r
- push bp\r
- mov bp,sp\r
- mov ax,[left]\r
- mov bx,[right]\r
- cmp bx,ax\r
- jns @@CorrectXOrder\r
- xchg bx,ax\r
-@@CorrectXOrder:\r
- mov [_LeftClip],ax\r
- mov [_RightClip],bx\r
- mov ax,[top]\r
- mov bx,[bottom]\r
- cmp bx,ax\r
- jns @@CorrectYOrder\r
- xchg bx,ax\r
-@@CorrectYOrder:\r
- mov [_TopClip],ax\r
- mov [_BottomClip],bx\r
- pop bp\r
- ret\r
-_x_set_cliprect endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; Return to text mode\r
-;\r
-_x_text_mode proc\r
- push bp\r
- call clear_vram\r
- mov ax,03h ; Restore Text Mode\r
- int 10h\r
-\r
- pop bp\r
- ret\r
-_x_text_mode endp\r
-\r
-;-----------------------------------------------------------------------\r
-; Wait for Vertical sync\r
-_x_wait_vsync proc\r
- push bp\r
- WaitVsyncStart\r
- pop bp\r
- ret\r
-_x_wait_vsync endp\r
-\r
-\r
- end\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XMAIN - Include file\r
-;\r
-; XMAIN.ASM export functions\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
- global _x_set_mode :proc\r
- global _x_page_flip :proc\r
- global _x_set_start_addr :proc\r
- global _x_set_splitscreen :proc\r
- global _x_text_mode :proc\r
- global _x_set_mode :proc\r
- global _x_select_default_plane :proc\r
- global _x_hide_splitscreen :proc\r
- global _x_show_splitscreen :proc\r
- global _x_adjust_splitscreen :proc\r
- global _x_set_doublebuffer :proc\r
- global _x_set_tripplebuffer :proc\r
- global _x_set_cliprect :proc\r
- global _x_wait_vsync :proc
\ No newline at end of file
+++ /dev/null
-/*----------------------------------------------------------------------\r
-; MODULE XMAKEVBM\r
-;\r
-; Implements function to generate a Video bitmap (VBM) from a linear bitmap\r
-; (LBM)\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; Based on "CreateMaskedAlignedImage" published in Dr Dobbs Journal\r
-; by Michael Abrash (Jul - Aug 1991)\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-; ****** Aeronautical Research Laboratory ****************\r
-; ****** Defence Science and Technology Organisation ****************\r
-; ****** Australia ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------*/\r
-/*\r
- Here is an outline of the XLIB image formats\r
-\r
-\r
- PLANAR BITMAPS\r
- --------------\r
-\r
- Planar bitmaps as used by these functions have the following structure:\r
-\r
- BYTE 0 The bitmap width in bytes (4 pixel groups) range 1..255\r
- BYTE 1 The bitmap height in rows range 1..255\r
- BYTE 2..n1 The plane 0 pixels width*height bytes\r
- BYTE n1..n2 The plane 1 pixels width*height bytes\r
- BYTE n2..n3 The plane 2 pixels width*height bytes\r
- BYTE n3..n4 The plane 3 pixels width*height bytes\r
-\r
- LINEAR BITMAPS\r
- --------------\r
-\r
- Linear bitmaps have the following structure:\r
-\r
- BYTE 0 The bitmap width in pixels range 1..255\r
- BYTE 1 The bitmap height in rows range 1..255\r
- BYTE 2..n The width*height bytes of the bitmap\r
-\r
-\r
- VIDEO BITMAPS\r
- -------------\r
-\r
- WORD 0 Size Total size of this VBM structure in bytes\r
- WORD 1 ImageWidth Width in bytes of the image (for all alignments)\r
- WORD 2 ImageHeight Height in scan lines of the image\r
-\r
- WORD 3 Alignment 0 ImagePtr Offset in VidRAM of this aligned image\r
- +--WORD 4 MaskPtr Offset (within this structure's DS) of\r
- | . alignment masks\r
- | .\r
- | .\r
- | WORD 9 Alignment 3 ImagePtr Offset in VidRAM of this aligned image\r
- +|--WORD 10 MaskPtr Offset (within this structure's DS) of\r
- || alignment masks\r
- ||\r
- |+->BYTE 21 (WORD 11) -------+-- Image masks for alignment 0\r
- | . |\r
- | . |\r
- | BYTE 21 + ImageWidth*ImageHeight -----+\r
- |\r
- | .\r
- | . (similaly for alignments 1 - 2 )\r
- | .\r
- |\r
- +-->BYTE 21 + 3*ImageWidth*ImageHeight + 1-+-- Image masks for alignment 3\r
- . |\r
- . |\r
- BYTE 21 + 4*(ImageWidth*ImageHeight) --+\r
-\r
- .\r
- .\r
- << Similarly for alignments 2 and 3 >>\r
- .\r
- .\r
- BYTE 21 + 4*(ImageWidth*ImageHeight)\r
- -------------\r
-\r
- (And dont forget the corresponding data in video ram)\r
-\r
-\r
-*/\r
-\r
-\r
-\r
-#include <alloc.h>\r
-#include <dos.h>\r
-\r
-/* function to store the linear bitmap in the required video RAM offset */\r
-/* and in the required alignment */\r
-\r
-extern unsigned int x_store_vbm_image(unsigned int, int, char far *);\r
-\r
-\r
-/* Alignment structures, 4 of which make up the header section of the */\r
-/* video bitmap */\r
-\r
-typedef struct {\r
- unsigned int size;\r
- unsigned int ImageWidth;\r
- unsigned int ImageHeight;\r
- struct {\r
- unsigned int ImagePtr;\r
- unsigned int MaskPtr;\r
- } alignments[4];\r
-} alignment_header;\r
-\r
-/* Structure to extract width/height frol LBM (linear bit map) */\r
-\r
-typedef struct {\r
- unsigned char width;\r
- unsigned char height;\r
-} lbm_header;\r
-\r
-\r
-/*************************************************************************/\r
-/* */\r
-/* Generates all four possible mode X image/mask alignments, stores */\r
-/* image alignments in display memory, allocates memory for and generates*/\r
-/* mask alignments, and fills out a VBM aligned masked image structure. */\r
-/* Each non-zero byte in source bitmap corresponds to image pixel to be */\r
-/* drawn. */\r
-/* On success returns a far pointer to the new VBM structure otherwise */\r
-/* it returns NULL */\r
-/* */\r
-/* Source Language: C */\r
-/* */\r
-/* Parameters: */\r
-/* lbm pointer to linear bitmap */\r
-/* vramStart contains the next available video offset which is */\r
-/* also updated after calling this function */\r
-/* */\r
-/*************************************************************************/\r
-\r
-char far *x_make_vbm(char far *lbm, unsigned int *VramStart)\r
-{\r
-\r
- lbm_header far *lbm_headr;\r
- alignment_header far *vbm_headr;\r
- char far *vbm_mask_ptr,*p;\r
- char far *lbm_pixel_ptr;\r
- int align,BitNum,TempImageWidth;\r
- unsigned int TempWidth,TempHeight,TempSize,MaskSize,VramOffs,MaskSpace=0;\r
- int scanline;\r
- unsigned char MaskTemp;\r
-\r
- VramOffs = *VramStart;\r
- lbm_headr = (lbm_header far *) lbm;\r
-\r
- TempWidth = (lbm_headr->width+3)/4+1;\r
- TempHeight = lbm_headr->height;\r
- TempSize = TempWidth*TempHeight;\r
-\r
- vbm_headr = (alignment_header far *) farmalloc(22+TempSize*4);\r
- if (!vbm_headr) return NULL;\r
-\r
- MaskSpace=22;\r
-\r
- vbm_headr->ImageWidth = TempWidth;\r
- vbm_headr->ImageHeight = TempHeight;\r
- vbm_headr->size = 22+TempSize*4;\r
- for (align=0;align<4;align++){\r
- vbm_headr->alignments[align].ImagePtr = VramOffs;\r
- x_store_vbm_image(VramOffs,align,lbm);\r
- MaskSpace+=TempSize;\r
- VramOffs+=TempSize;\r
- }\r
-\r
-\r
- vbm_mask_ptr = (char far *)vbm_headr+22;\r
-\r
- for (align=0;align<4;align++){\r
- lbm_pixel_ptr = lbm + 2;\r
- vbm_headr->alignments[align].MaskPtr = FP_OFF(vbm_mask_ptr);\r
- for (scanline=0;scanline<TempHeight;scanline++){\r
- BitNum=align;\r
- MaskTemp=0;\r
- TempImageWidth=lbm_headr->width;\r
- do {\r
- MaskTemp |= (*lbm_pixel_ptr++ !=0) << BitNum;\r
- if (++BitNum > 3) {\r
- *vbm_mask_ptr++=MaskTemp;\r
- MaskTemp=BitNum=0;\r
- }\r
- } while (--TempImageWidth);\r
- *vbm_mask_ptr++=(BitNum != 0)?MaskTemp:0;\r
- }\r
-\r
- }\r
-\r
- *VramStart=VramOffs;\r
- return (char far *) vbm_headr;\r
-}\r
-\r
-\r
-\1a
\ No newline at end of file
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XMOUSE\r
-;\r
-; Mouse functions functions for all MODE X 256 Color resolutions\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; This module is based on Shane Hyde's module of the same name,\r
-; posted to Rec.Games.Programmer, October 92.\r
-;\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; mouse cursor shape by Tiaan A Geldenhuys\r
-;\r
-;-----------------------------------------------------------------------\r
-\r
-COMMENT $\r
-\r
-\r
-This is a module implementing very basic mouse functions.\r
-\r
-It does not support the full functionality of:\r
-\r
- SPLIT SCREENS\r
- SCROLLED WINDOWS\r
- VIRTUAL WINDOWS\r
-\r
- --------------------------------------\r
-\r
- MS Mouse Driver Functions\r
-\r
- Mouse Initialization 0\r
- Show Cursor 1\r
- Hide Cursor 2\r
- Get Mouse Position & Button Status 3\r
- Set Mouse Cursor Position 4\r
- Get Button Press Information 5\r
- Get Button Release Information 6\r
- Set Min/Max Horizontal Position 7\r
- Set Min/Max Vertical Position 8\r
- Define Graphics Cursor Block 9\r
- Define Text Cursor 10\r
- Read Mouse Motion Counters 11\r
- Define Event Handler 12\r
- Light Pen Emulation Mode ON 13\r
- Light Pen Emulation Mode OFF 14\r
- Set Mouse Mickey/Pixel Ratio 15\r
- Conditional Hide Cursor 16\r
- Set Double-Speed Threshold 19\r
- --------------------------------------\r
-$\r
-\r
-include xlib.inc\r
-include xdetect.inc\r
-\r
-.data\r
-\r
-global _MouseInstalled :word\r
-global _MouseHidden :word\r
-global _MouseButtonStatus :word\r
-global _MouseX :word\r
-global _MouseY :word\r
-global _MouseFrozen :byte\r
-global _MouseColor :byte\r
-\r
-global _x_define_mouse_cursor :proc\r
-global _x_show_mouse :proc\r
-global _x_hide_mouse :proc\r
-global _x_mouse_remove :proc\r
-global _x_position_mouse :proc\r
-global _x_put_cursor :proc\r
-global _x_update_mouse :proc\r
-global _x_mouse_init :proc\r
-global _x_mouse_window :proc\r
-\r
-\r
-ALIGN 2\r
-\r
-\r
-\r
- InitMouseDef db 00000001b ; Default mouse mask, note the reverse order\r
- db 00000011b\r
- db 00000111b\r
- db 00001111b\r
- db 00011111b\r
- db 00111111b\r
- db 01111111b\r
- db 11111111b\r
- db 00011111b\r
- db 00011011b\r
- db 00110001b\r
- db 00110000b\r
- db 01100000b\r
- db 01100000b\r
-\r
-\r
-\r
-COMMENT $\r
-\r
- Old mouse definition\r
-\r
- InitMouseDef db 00000001b ; Default mouse mask, note the reverse order\r
- db 00000011b\r
- db 00000111b\r
- db 00001111b\r
- db 00011111b\r
- db 00111111b\r
- db 01111111b\r
- db 11111111b\r
- db 00011100b\r
- db 00111100b\r
- db 01111100b\r
- db 00000000b\r
- db 00000000b\r
- db 00000000b\r
-\r
-$\r
-\r
- MouseMask db 168 dup(?)\r
- OldHandlerSeg dw ?\r
- OldHandlerOffs dw ?\r
- OldHandlerMask dw ?\r
- OldX dw ?\r
- OldY dw ?\r
- OldScrnOffs dw ?\r
-\r
- BGSaveOffs dw 0\r
-\r
- _MouseInstalled dw 0 ; Flag indicating whether mouse is installed\r
- _MouseHidden dw 0 ; Flag indicating whether mouse is hidden\r
- _MouseButtonStatus dw 0 ; Holds current button press information\r
- _MouseX dw 0 ; Coords of cursor hot spot\r
- _MouseY dw 0\r
- _MouseFrozen db 0 ; Mouse motion enable/disable control\r
- _MouseColor db 0 ; Mouse cursor colour\r
-\r
- inhandler db 0\r
-.code\r
-\r
-;----------------------------------------------------------------------\r
-; Local function that updates the cursor position\r
-;\r
-; Destroys SI,DI,AX,BX\r
-;\r
-;----------------------------------------------------------------------\r
-proc update_cursor near\r
- WaitVsyncStart\r
-\r
- mov di,[OldScrnOffs] ; Delete cursor (restore old background)\r
- mov ax,[OldY]\r
- mov bx,[OldX]\r
-\r
- call restorebg\r
-\r
- mov si,[_VisiblePageOffs] ; Save cursor background\r
- mov ax,[_MouseY]\r
- mov bx,[_MouseX]\r
- mov [OldScrnOffs],si\r
- mov [OldY],ax\r
- mov [OldX],bx\r
- call getbg\r
-\r
- push [_VisiblePageOffs] ; Draw the cursor\r
- mov ax,[_ScrnPhysicalHeight]\r
- push ax\r
- mov ax,0\r
- push ax\r
- push [OldY]\r
- push [OldX]\r
- call _x_put_cursor\r
- add sp,10\r
- ret\r
-update_cursor endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_mouse_init - Initialise Mode X mouse handler\r
-;\r
-; C Prototype\r
-;\r
-; int x_mouse_init()\r
-;\r
-; This is the first function you must call before using any of the mouse\r
-; functions\r
-;\r
-; WARNING: This function uses and updates "NonVisual_Offset" to allocate\r
-; video ram for the saved mouse background.\r
-;\r
-; This mouse code uses the fastest possible techniques to save and restore\r
-; mouse backgrounds and to draw the mouse cursor.\r
-;\r
-; LIMITATIONS: No clipping is supported horizontally for the mouse cursor\r
-; No validity checking is performed for NonVisual_Offs\r
-;\r
-;\r
-; **WARNING** Hide or freeze mouse while drawing using any of the other\r
-; Modules. VGA register settings are not preserved which will\r
-; result in unpredictable drawing behavior.\r
-; If you know the drawing will occur away from the mouse cursor\r
-; set MouseFrozen to TRUE (1), do your drawing then set it to\r
-; FALSE (0). Alternatively call "x_hide_mouse", perform your\r
-; drawing and then call "x_show_mouse"\r
-;\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_mouse_init proc\r
- push bp\r
- mov bp,sp\r
-\r
- cmp [_MouseButtonCount],0 ; Dont initialize if mouse detection\r
- jne @@DontInitialize ; or initialization function previously\r
- ; called\r
- xor ax,ax ; FUNC 0: Mouse Initialization\r
- int 33h ;\r
- or ax,ax ; Is there a mouse installed ?\r
- jz @@Done\r
- mov [_MouseButtonCount],bx ; Set the button count\r
-\r
-@@DontInitialize:\r
-\r
- mov [_MouseInstalled],ax\r
- or ax,ax ; Do we have an installed mouse driver ?\r
- jz @@Done ; Nop!\r
-\r
- mov ax,[_NonVisual_Offs]; ; Allocate VRAM for saved background\r
- mov BGSaveOffs,ax\r
-\r
- add ax,14*3\r
- mov [_NonVisual_Offs],ax ; Update NonVisualOffset\r
-\r
- mov ax,02 ; FUNC 2: Hide Cursor\r
- int 33h ; (hide the mouse driver's default cursor)\r
- mov _MouseInstalled,TRUE ; Indicate user mouse driver present\r
-\r
- mov ax,07h ; FUNC 7:Set min/max horizontal position\r
- mov cx,0\r
- mov dx,[_ScrnPhysicalPixelWidth]\r
- shl dx,1 ; Mult X by 2 as cursor steps by 2 pixels\r
- int 33h ; 0 < X < _ScrnPhysicalPixelWidth\r
-\r
- mov ax,08h ; FUNC 8:Set min/max vertical position\r
- mov cx,0\r
- mov dx,_ScrnPhysicalHeight\r
- int 33h ; 0 < Y < _ScrnPhysicalHeight\r
-\r
- mov ax,0fh ; FUNC 15: Mouse Hor/Vert resolution\r
- mov cx,4 ; Horiz speed >> Value => << Speed\r
- mov dx,8 ; Vert Speed\r
- int 33h\r
-\r
- mov ax,3 ; FUNC 3: Get mouse pos & button status\r
- int 33h\r
- mov [_MouseY],dx\r
- shr cx,1\r
- mov [_MouseX],cx\r
-\r
- mov ax,12 ; FUNC 12: Define Event Handler\r
- mov bx,seg mouse_handler ; ES:DX -> Event handler\r
- mov es,bx\r
- mov dx,offset mouse_handler\r
- mov cx,1fh ; Set handler for all events\r
- int 33h\r
-\r
-\r
-\r
- mov [_MouseHidden],TRUE ; Mouse initially hidden\r
-\r
- push ds ; Set the default cursor shape\r
- mov ax,offset InitMouseDef\r
- push ax\r
- call _x_define_mouse_cursor\r
- add sp,04h\r
-\r
- mov ax,[_MouseInstalled] ; Return MouseInstalled flag\r
-@@Done:\r
- pop bp\r
- ret\r
-_x_mouse_init endp\r
-\r
-;----------------------------------------------------------------------\r
-; x_mouse_window - Define a mouse window\r
-;\r
-; C Prototype\r
-;\r
-; void x_mouse_window(int x0, int y0, int x1, int y1);\r
-;\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_mouse_window proc\r
-ARG x0:word,y0:word,x1:word,y1:word\r
- push bp\r
- mov bp,sp\r
-\r
- mov ax,7 ; FUNC 7: Set X range\r
- mov cx,x0\r
- shl cx,1\r
- mov dx,x1\r
- shl dx,1\r
- int 33h\r
-\r
- mov ax,8 ; FUNC 8: Set Y range\r
- mov cx,y0\r
- mov dx,y1\r
- int 33h\r
- pop bp\r
- ret\r
-_x_mouse_window endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_define_mouse_cursor - Define a mouse cursor from an input bitmask\r
-;\r
-; C Prototype\r
-;\r
-; void x_define_mouse_cursor(char far *MouseDef, unsigned char MouseColor)\r
-;\r
-; WARNING: This function assumes MouseDef points to 14 bytes.\r
-;\r
-; Note: Bit order is in reverse. ie bit 7 represents pixel 0 ..\r
-; bit 0 represents pixel 7 in each "MouseDef" byte.\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_define_mouse_cursor proc\r
-ARG MouseDef:dword,MouseColor:byte\r
- push bp\r
- mov bp,sp\r
-\r
- cmp [_MouseInstalled],FALSE ; Check whether we have installed\r
- je @@Done ; our mouse handler and leave if not\r
-\r
- mov al,[MouseColor] ; Set the mouse pointers color\r
- mov [_MouseColor],al\r
-\r
- push si\r
- push di\r
- push ds\r
- mov ax,ds ; ES:DI -> Stored plane mask for all\r
- mov es,ax ; pixel alignments of mouse cursor\r
- mov di,offset MouseMask\r
- lds si,MouseDef\r
- xor cl,cl ; CL = current alignment (initially zero)\r
-@@AlignmentLoop:\r
- push si ; save MouseDef ptr for next alignment\r
- mov dh,14 ; Init Row counter to Cursor Height\r
-@@RowLoop:\r
- lodsb ; Load first cursor def byte each bit\r
- ; representing pixel in the row\r
- xor ah,ah ; AH is the shift overflow byte\r
- shl ax,cl ; Shift mask for current alignment\r
-\r
- mov bl,al ; store first three nibbles of ax into\r
- and bl,0fh ; consecutive bytes in the destination\r
- mov es:[di],bl ; buffer\r
- inc di\r
- shr al,4\r
- stosw\r
-\r
- dec dh ; Next row for this alignment if there\r
- jnz @@RowLoop ; are more to do\r
-\r
- pop si ; point to the start of the cursor def.\r
- inc cl ; Select next pixel alignment\r
- cmp cl,4 ; If there are more alignments to do\r
- jne @@AlignmentLoop ; then jump\r
-\r
- pop ds\r
- pop di\r
- pop si\r
-@@Done:\r
- pop bp\r
- ret\r
-_x_define_mouse_cursor endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_show_mouse - Shows a previously hidden mouse cursor\r
-;\r
-; C Prototype\r
-;\r
-; void x_show_mouse()\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_show_mouse proc\r
- push bp\r
- mov bp,sp\r
- cmp [_MouseInstalled],FALSE ; Make sure our handler is installed\r
- je @@Done\r
- cmp [_MouseHidden],FALSE ; If not hidden then exit\r
- je @@Done\r
- push si\r
- push di\r
-\r
-\r
-@@WaitEndOfHandler: ; Make sure handler not currently active\r
- mov cl,[inhandler]\r
- or cl,cl\r
- jnz @@WaitEndOfHandler\r
-\r
-\r
- mov si,[_VisiblePageOffs] ; Save mouse background and pos details\r
- mov ax,[_MouseY]\r
- mov bx,[_MouseX]\r
- mov [OldScrnOffs],si\r
- mov [OldY],ax\r
- mov [OldX],bx\r
- call getbg\r
-\r
- push [_VisiblePageOffs] ; Draw cursor\r
- push [_ScrnLogicalHeight]\r
- xor ax,ax\r
- push ax\r
- push [OldY]\r
- push [OldX]\r
- call _x_put_cursor\r
- add sp,10\r
-\r
- mov [_MouseHidden],FALSE ; Indicate mouse cursor no longer hidden\r
-\r
- pop di\r
- pop si\r
-@@Done:\r
- pop bp\r
- ret\r
-_x_show_mouse endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_hide_mouse - Hides a previously visible mouse cursor\r
-;\r
-; C Prototype\r
-;\r
-; void x_hide_mouse()\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_hide_mouse proc\r
- push bp\r
- mov bp,sp\r
-\r
- cmp [_MouseInstalled],FALSE ; Make sure our handler is installed\r
- je @@Done\r
- cmp [_MouseHidden],FALSE ; If cursor is already hidden exit\r
- jne @@Done\r
- push si\r
- push di\r
-\r
-@@WaitEndOfHandler: ; Make sure handler not currently active\r
- mov cl,[inhandler]\r
- or cl,cl\r
- jnz @@WaitEndOfHandler\r
-\r
- mov [_MouseHidden],TRUE ; Delete mouse cursor\r
- mov di,[OldScrnOffs]\r
- mov ax,[OldY]\r
- mov bx,[OldX]\r
- call restorebg\r
- pop di\r
- pop si\r
-@@Done:\r
- pop bp\r
- ret\r
-_x_hide_mouse endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_remove_mouse - removes mouse handler\r
-;\r
-; C Prototype\r
-;\r
-; void x_remove_mouse()\r
-;\r
-; NOTE: This function MUST be called before quitting the program if\r
-; a mouse handler has been installed\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_mouse_remove proc\r
- push bp\r
- mov bp,sp\r
- cmp [_MouseInstalled],FALSE ; Check whether we have installed\r
- je @@Done ; our mouse handler\r
- call _x_hide_mouse\r
- mov ax,12 ; FUNC 12: Install event handler\r
- xor cx,cx ; Disable all events\r
- int 33h\r
- mov [_MouseInstalled],FALSE\r
-@@Done:\r
- pop bp\r
- ret\r
-_x_mouse_remove endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_position_mouse - Positions the mouse cursor at the specified location\r
-;\r
-; C Prototype\r
-;\r
-; void x_position_mouse(int x, int y)\r
-;\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_position_mouse proc\r
-ARG X:word,Y:word\r
- push bp\r
- mov bp,sp\r
-\r
-@@WaitEndOfHandler: ; Make sure handler not currently active\r
- mov bl,[inhandler]\r
-\r
- or bl,bl\r
- jnz @@WaitEndOfHandler\r
-\r
- mov ax,4\r
- mov cx,X\r
- mov dx,Y\r
- mov [_MouseX],cx\r
- mov [_MouseY],dx\r
- shl cx,1\r
-\r
- mov [inhandler],1\r
- int 33h\r
-\r
- ; The handler doesnt get called so need\r
- ; to update manually;\r
-\r
- cmp [_MouseHidden],FALSE\r
- jne @@NotVisible\r
- push di si\r
- call update_cursor\r
- pop si di\r
-\r
-@@NotVisible:\r
- mov [inhandler],0\r
- pop bp\r
- ret\r
-_x_position_mouse endp\r
-\r
-;----------------------------------------------------------------------\r
-; x_update_mouse - Forces the mouse position to be updated and cursor\r
-; to be redrawn.\r
-;\r
-; C Prototype\r
-;\r
-; void x_update_mouse()\r
-;\r
-; Note this function is useful when you have set "MouseFrozen" to true.\r
-; Allows the cursor position to be updated manually rather than\r
-; automatically by the installed handler.\r
-;\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_update_mouse proc\r
- push bp\r
- mov bp,sp\r
- cmp [_MouseInstalled],FALSE ; Make sure our handler is installed\r
- je @@Done\r
- cmp [_MouseHidden],FALSE ; If cursor is already hidden exit\r
- jne @@Done\r
- push si\r
- push di\r
- mov ax,03h ; FUNC 3: get cursor pos / button status\r
- int 33h ; Update position variables first\r
- shr cx,1\r
- mov [_MouseX],cx\r
- mov [_MouseY],dx\r
- mov [_MouseButtonStatus],bx ; Update button status\r
- call update_cursor\r
- pop di\r
- pop si\r
-@@Done:\r
- pop bp\r
- ret\r
-_x_update_mouse endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_put_cursor - Draws the mouse cursor\r
-;\r
-; C Prototype\r
-;\r
-; void x_put_cursor(int X, int Y, int TopClip, int BottomClip, WORD ScrnOffs)\r
-;\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-ALIGN 2\r
-_x_put_cursor proc\r
-ARG X:word,Y:word,TopClip,BottomClip,ScrnOffs\r
-LOCAL Height,TopRow,NextLineIncr:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- mov ax,@data\r
- mov ds,ax\r
- cld\r
-\r
- mov ax,14 ; Get image height and save in AX\r
- mov bx,Y\r
- ; cx = top Row\r
-\r
- ;;;;; CLIP PROCESSING FOR TOP CLIP BORDER ;;;;;;;;;;;;;;;;;;;;;\r
-\r
- mov dx,[TopClip] ; Compare u.l. Y coord with Top\r
- sub dx,bx ; clipping border\r
- jle @@NotTopClip ; jump if not clipped from above\r
- cmp dx,ax\r
- jnl @@NotVisible ; jump if is completely obscured\r
- mov cx,dx\r
- sub ax,dx\r
- add bx,dx\r
- jmp short @@VertClipDone\r
-\r
- ;;;; EXIT FOR COMPLETELY OBSCURED ;;;;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotVisible:\r
- pop ds\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-\r
- ;;;;; CLIP PROCESSING FOR BOTTOM CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotTopClip:\r
- mov dx,[BottomClip]\r
- sub dx,bx\r
- js @@NotVisible\r
- mov cx,0\r
- cmp dx,ax\r
- jg @@VertClipDone\r
- inc dx\r
- mov ax,dx\r
-\r
-@@VertClipDone:\r
-\r
- mov [Height],ax\r
- mov [TopRow],cx\r
-\r
- mov ax,SCREEN_SEG ; Point es to VGA segment\r
- mov es,ax\r
-\r
- mov ax,bx\r
- mov cx,[_ScrnLogicalByteWidth] ; Find required screen address\r
- mul cx\r
- mov di,ax\r
-\r
- sub cx,3 ; Distance to next screen row\r
- mov [NextLineIncr],cx\r
-\r
-\r
- mov cx,[X]\r
- mov bx,cx\r
- shr cx,2\r
- add di,cx\r
- and bx,3\r
- add di,[ScrnOffs]\r
-\r
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-\r
-\r
- mov ax,42\r
- mul bx\r
- mov si,offset MouseMask\r
- add si,ax\r
-\r
- mov ax,3 ; Increment DS:BX and DS:SI to\r
- mul [TopRow] ; been clipped by the top border\r
- add si,ax ; by the L.H.S border\r
-\r
- mov dx,SC_INDEX ; Point SC register to map mask\r
- mov al,MAP_MASK ; in preperation for masking data\r
- out dx,al\r
- inc dx ; Point dx to SC data register\r
- mov ah,byte ptr [Height] ; AH = Scanline loop counter\r
- mov bl,[_MouseColor]\r
-@@RowLoop:\r
- mov cx,3 ; Width in bytes across\r
-@@ColLoop:\r
- lodsb ; load plane mask and set MAP MASK\r
- out dx,al\r
- mov es:[di],bl ; store color to specified planes\r
- inc di\r
- loop @@ColLoop\r
-\r
- add di,[NextLineIncr]\r
- dec ah\r
- jnz @@RowLoop\r
-\r
- pop ds\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_put_cursor endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; getbg - saves cursor background\r
-;\r
-; C Prototype\r
-;\r
-; local function using register parameters\r
-;\r
-; si = screen offset\r
-; ax = y\r
-; bx = x\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-ALIGN 2\r
-getbg proc near\r
-\r
- push bp\r
- mov bp,sp\r
- push ds\r
- cld\r
-\r
- mov cx,[_ScrnLogicalByteWidth] ; by mult. dest Y coord by Screen\r
- mul cx ; width then adding screen offset\r
- add si,ax ; Add Dest Screen Row to di\r
- sub cx,3\r
- shr bx,2\r
- add si,bx\r
- mov bx,cx\r
-\r
- mov di,BGSaveOffs\r
- mov ax,SCREEN_SEG ; Point es to VGA segment\r
- mov es,ax\r
- mov ds,ax\r
-\r
- mov dx,GC_INDEX ; Set bit mask for all bits from\r
- mov ax,BIT_MASK ; VGA latches and none from CPU\r
- out dx,ax\r
-\r
- mov dx,SC_INDEX ; Point SC register to map mask\r
- mov al,MAP_MASK ; in preperation for masking data\r
- out dx,al\r
- inc dx\r
- mov al,0fh\r
- out dx,al\r
-\r
- mov cx,14\r
-@@Loop:\r
- movsb\r
- movsb\r
- movsb\r
- add si,bx\r
- loop @@Loop\r
-\r
-mov dx,GC_INDEX+1 ;restore the bit mask to its default,\r
- mov al,0ffh ; which selects all bits from the CPU\r
- out dx,al ; and none from the latches (the GC\r
- ; Index still points to Bit Mask)\r
-\r
- pop ds\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-getbg endp\r
-\r
-;----------------------------------------------------------------------\r
-; restorebg - restores cursor background\r
-;\r
-; C Prototype\r
-;\r
-; local function using register parameters\r
-;\r
-; di = screen offset\r
-; ax = y\r
-; bx = x\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-ALIGN 2\r
-restorebg proc near\r
-;di = scrn offs\r
-;ax = y\r
-;bx = x\r
- push bp\r
- mov bp,sp\r
- push ds\r
- cld\r
-\r
- mov cx,[_ScrnLogicalByteWidth] ; by mult. dest Y coord by Screen\r
- mul cx ; width then adding screen offset\r
- add di,ax ; Add Dest Screen Row to di\r
- sub cx,3\r
- shr bx,2\r
- add di,bx\r
- mov si,BGSaveOffs\r
- mov ax,SCREEN_SEG ; Point es to VGA segment\r
- mov es,ax\r
- mov ds,ax\r
-\r
- mov dx,GC_INDEX ; Set bit mask for all bits from\r
- mov ax,BIT_MASK ; VGA latches and none from CPU\r
- out dx,ax\r
-\r
- mov dx,SC_INDEX ; Point SC register to map mask\r
- mov al,MAP_MASK ; in preperation for masking data\r
- out dx,al\r
- inc dx\r
- mov al,0fh\r
- out dx,al\r
-\r
- mov bx,cx\r
- mov cx,14\r
-@@Loop:\r
- movsb\r
- movsb\r
- movsb\r
- add di,bx\r
- loop @@Loop\r
- mov dx,GC_INDEX+1 ;restore the bit mask to its default,\r
- mov al,0ffh ; which selects all bits from the CPU\r
- out dx,al ; and none from the latches (the GC\r
- ; Index still points to Bit Mask)\r
- pop ds\r
- pop bp\r
- ret\r
-restorebg endp\r
-\r
-\r
-\r
-;********************** The Mouse event handler *************************\r
-\r
-ALIGN 2\r
-mouse_handler proc far\r
- push bp\r
- mov bp,sp\r
- push ds\r
-\r
- mov di,@data ; Make sure DS points to data segment\r
- mov ds,di\r
- cmp [inhandler],1\r
- jne @@NotActive\r
- pop ds\r
- pop bp\r
- ret\r
-\r
-@@NotActive:\r
- mov [inhandler],1\r
- mov [_MouseButtonStatus],bx ; Update button status\r
- test ax,1 ; Is this a motion event ?\r
- jz @@Done ; No Jump\r
-\r
- shr cx,1 ; convert X coord to pixel coords\r
- mov [_MouseX],cx ; save mouse position\r
- mov [_MouseY],dx\r
-\r
- cmp [_MouseHidden],TRUE ; If mouse hidden dont bother drawing\r
- je @@Done\r
-\r
- cmp [_MouseFrozen],TRUE ; If mouse hidden dont bother drawing\r
- je @@Done\r
-\r
- call update_cursor\r
-@@Done:\r
- mov [inhandler],0\r
- pop ds\r
- pop bp\r
- ret\r
-mouse_handler endp\r
-\r
-\r
-end\r
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XMOUSE - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;-----------------------------------------------------------------------*/\r
-\r
-#ifndef _XMOUSE_H_\r
-#define _XMOUSE_H_\r
-\r
-#define LEFT_PRESSED 1\r
-#define RIGHT_PRESSED 2\r
-\r
-/* GLOBAL VARS ========================================================= */\r
-\r
-extern WORD MouseInstalled; /* Indicates whether mouse handler installed */\r
-extern WORD MouseHidden; /* Indicates whether mouse cursor is hidden */\r
-extern WORD MouseButtonStatus;/* Holds the mouse button status */\r
-extern WORD MouseX; /* Current X position of mouse cursor */\r
-extern WORD MouseY; /* Current Y position of mouse cursor */\r
-extern BYTE MouseFrozen; /* Disallows position updates if TRUE */\r
-extern BYTE MouseColor; /* The mouse cursors colour */\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-\r
-\r
-void x_mouse_init(void); /* Initialize mouse cursor */\r
-\r
-void x_define_mouse_cursor( /* Define and set a cursor shape */\r
- char far MouseDef,\r
- int color);\r
-\r
-void x_update_mouse(void); /* Force mouse cursor position update */\r
-\r
-void x_show_mouse(void); /* Show mouse cursor if hidden */\r
-\r
-void x_hide_mouse(void); /* Hide mouse cursor if visible */\r
-\r
-void x_mouse_remove(void); /* Remove installed mouse handler */\r
-\r
-void x_position_mouse( /* Set the mouse position */\r
- int x,\r
- int y);\r
-\r
-void x_put_cursor( /* Draw the mouse cursor (NOT FOR */\r
- int x, /* general use) */\r
- int y,\r
- int topclip,\r
- int botclip,\r
- WORD ScrnOff);\r
-\r
-\r
-void x_mouse_window(int x0, /* Define a mouse window */\r
- int y0,\r
- int x1,\r
- int y1);\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif\1a\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XPAL\r
-;\r
-; Palette functions all MODE X 256 Color resolutions\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
-COMMENT $\r
-\r
-\r
-\r
- All the functions in this module operate on two variations of the\r
- pallete buffer, the raw and annotated buffers.\r
-\r
- All those functions ending in buff operate on the following palette\r
- structure:\r
-\r
- BYTE:r0,g0,b0,r1,g1,b1,...rn,gn,bn\r
-\r
- No reference to the starting colour index or number of colours stored\r
- is contained in the structure.\r
-\r
- All those functions ending in struc operate on the following palette\r
- structure:\r
-\r
- BYTE:c,BYTE:n,BYTE:r0,g0,b0,r1,g1,b1,...rn,gn,bn\r
-\r
- where c is the starting colour and n is the number of colours stored\r
-\r
-\r
- NOTE: previously interrupts were disabled for DAC reads/writes but\r
- they have been left enabled in this version to allow the mouse\r
- interrupt to be invoked.\r
-\r
-$\r
-\r
-\r
-\r
-\r
-include xlib.inc\r
-include xpal.inc\r
-\r
-.code\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; Read DAC palette into annotated type buffer with interrupts disabled\r
-; ie BYTE colours to skip, BYTE colours to set, r1,g1,b1,r1,g2,b2...rn,gn,bn\r
-;\r
-; x_get_pal_struc(char far * pal, int num_colrs, int start_color)\r
-;\r
-; WARNING: memory for the palette buffers must all be pre-allocated\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_get_pal_struc proc\r
-ARG PalBuff:dword,NumColors:word,StartColor:word\r
- push bp ; Set up stack frame\r
- mov bp,sp\r
- push di\r
- push si\r
- cld\r
-\r
- les di,dword ptr [PalBuff] ; Point es:di to palette buffer\r
- mov si,[StartColor] ; Store the Start Colour\r
- mov ax,si\r
- stosb\r
- mov dx,[NumColors] ; Store the Number of Colours\r
- mov al,dl\r
- stosb\r
-\r
- mov cx,dx ; setup regs and jump\r
- jmp short ReadPalEntry\r
-\r
-_x_get_pal_struc endp\r
-\r
-\r
-\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; Read DAC palette into raw buffer with interrupts disabled\r
-; ie BYTE r1,g1,b1,r1,g2,b2...rn,gn,bn\r
-;\r
-; x_get_pal_raw(char far * pal, int num_colrs, int start_index)\r
-;\r
-; WARNING: memory for the palette buffers must all be pre-allocated\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_get_pal_raw proc\r
-ARG PalBuff:dword,NumColors:word,StartColor:word\r
- push bp ; Set up stack frame\r
- mov bp,sp\r
- push di\r
- push si\r
-\r
- les di,dword ptr [PalBuff] ; Point es:di to palette buffer\r
-\r
- mov si,[StartColor]\r
- mov cx,[NumColors]\r
-\r
-ReadPalEntry:\r
- cld\r
- WaitVsyncStart\r
- mov ax,si\r
- mov dx,DAC_READ_INDEX\r
- ;cli\r
- out dx,al ; Tell DAC what colour to start reading\r
- mov dx,DAC_DATA\r
-\r
- mov bx,cx ; set cx to Num Colors * 3 ( size of\r
- shl bx,1 ; palette buffer)\r
- add cx,bx\r
-\r
- rep insb ; read the palette enntries\r
-\r
- ;sti\r
- pop si\r
- pop di\r
- pop bp\r
- ret\r
-_x_get_pal_raw endp\r
-\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; Write DAC palette from annotated type buffer with interrupts disabled\r
-; ie BYTE colours to skip, BYTE colours to set, r1,g1,b1,r1,g2,b2...rn,gn,bn\r
-;\r
-; x_put_pal_struc(char far * pal)\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-\r
-_x_put_pal_struc proc\r
-ARG CompPalBuff:dword\r
- push bp ;preserve caller's stack frame\r
- mov bp,sp ;point to local stack frame\r
- push ds\r
- push si\r
- cld\r
- lds si,[CompPalBuff] ; load the source compressed colour data\r
- lodsb ; get the colours to skip\r
- mov ah,0\r
- mov bx,ax ; skip colours\r
-\r
- lodsb ; get the count of colours to set\r
- mov ah,0\r
- mov cx,ax ; use it as a loop counter\r
- jmp short WritePalEntry\r
-\r
-_x_put_pal_struc endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; Write DAC palette from annotated type buffer with interrupts disabled\r
-; starting at a new palette index\r
-;\r
-; ie BYTE colours to skip, BYTE colours to set, r1,g1,b1,r1,g2,b2...rn,gn,bn\r
-;\r
-; x_transpose_pal_struc(char far * pal, int StartColor)\r
-;\r
-; WARNING: memory for the palette buffers must all be pre-allocated\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-\r
-_x_transpose_pal_struc proc\r
-ARG CompPalBuff:dword,StartColor:word\r
- push bp ;preserve caller's stack frame\r
- mov bp,sp ;point to local stack frame\r
- push ds\r
- push si\r
- cld\r
- lds si,[CompPalBuff] ; load the source compressed colour data\r
- mov bx,[StartColor]\r
- mov [si],bl\r
- inc si\r
- lodsb ; get the count of colours to set\r
- mov ah,0\r
- mov cx,ax ; use it as a loop counter\r
- jmp short WritePalEntry\r
-_x_transpose_pal_struc endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; Write DAC palette from raw buffer with interrupts disabled\r
-; ie BYTE r1,g1,b1,r1,g2,b2...rn,gn,bn\r
-;\r
-; _x_put_pal_raw(char far * pal, int num_colrs, int start_index)\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_put_pal_raw proc\r
-ARG PalBuff:dword,NumColors:word,StartColor:word\r
- push bp ; Set up stack frame\r
- mov bp,sp\r
- push ds\r
- push si\r
-\r
- mov cx,[NumColors] ; Number of colours to set\r
- mov bx,[StartColor]\r
- lds si,[PalBuff] ; ds:si -> palette buffer\r
-\r
-\r
-WritePalEntry:\r
- mov ax,@data\r
- mov es,ax\r
- cmp es:[_VsyncHandlerActive],TRUE\r
- jne @@NoVsyncHandler\r
-@@WaitForLast:\r
- cmp es:[_VsyncPaletteCount],0\r
- jne @@WaitForLast\r
- push cx\r
- push es\r
- mov di, offset _VsyncPaletteBuffer\r
- mov ax,3\r
- mul cx\r
- mov cx,ax\r
- rep movsb\r
- pop ds\r
- pop cx\r
- mov [_VsyncPaletteStart],bx\r
- mov [_VsyncPaletteCount],cx\r
- jmp short @@Done\r
-@@NoVsyncHandler:\r
-\r
-\r
- or cx,cx\r
- jz @@Done\r
- ;cli\r
- cld ; Make sure we're going the right way\r
- WaitVsyncStart ; Wait for vert sync to start\r
- mov ax,bx\r
- mov bx,60 ; set the vsync check timer (Vsync\r
- ; is tested for at each bx'th entry to\r
- ; prevent snow 60 is otimum for 10\r
- ; MHz 286 or greater\r
-\r
-@@SetLoop:\r
- mov dx,DAC_WRITE_INDEX ; Tell DAC what colour index to start\r
- out dx,al ; writing from\r
- mov dx,DAC_DATA\r
-\r
- outsb ; Set the red component\r
- outsb ; Set the green component\r
- outsb ; Set the blue component\r
- inc al ; increment the colour index\r
- dec bx ; decrement vsync test counter\r
- js @@test_vsync ; ready to test for vsync again ?\r
- loop @@SetLoop ; No! - continue loop\r
- jmp short @@Done ; All colours done\r
-\r
-@@test_vsync:\r
- mov dx,INPUT_STATUS_0\r
- push ax ; save current colour index\r
-@@Wait:\r
- in al,dx ; wait for vsync leading edge pulse\r
- test al,08h\r
- jz @@Wait\r
-\r
- pop ax ; restore current colour index\r
- mov bx,60 ; reset vsync test counter\r
- loop @@SetLoop ; loop for next colour index\r
-\r
-@@Done:\r
- ;sti\r
- pop si\r
- pop ds\r
- pop bp\r
- ret\r
-_x_put_pal_raw endp\r
-\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; Set the RGB setting of a vga color\r
-;\r
-; _x_set_rgb(unsigned char color, unsigned char R,unsigned char G,\r
-; unsigned char B)\r
-;\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_set_rgb proc\r
-ARG ColorIndex:byte,R:byte,G:byte,B:byte\r
- push bp ; Set up stack frame\r
- mov bp,sp\r
-\r
- mov al,[ColorIndex]\r
- mov dx,DAC_WRITE_INDEX ; Tell DAC what colour index to\r
- out dx,al ; write to\r
- mov dx,DAC_DATA\r
-\r
- mov al,[R] ; Set the red component\r
- out dx,al\r
- mov al,[G] ; Set the green component\r
- out dx,al\r
- mov al,[B] ; Set the blue component\r
- out dx,al\r
- pop bp\r
- ret\r
-_x_set_rgb endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; Rotate annotated palette buffer entries\r
-;\r
-; x_rot_pal_struc(char far * pal, int direction)\r
-;\r
-; Direction : 0 = backward 1 = forward\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_rot_pal_struc proc\r
-ARG PalBuff:dword,Direction:word\r
- push bp ; Set up stack frame\r
- mov bp,sp\r
- push ds\r
- push si\r
- push di\r
-\r
- cld\r
- lds si,dword ptr [PalBuff] ; point ds:si to Palette buffer\r
- lodsw ; al = colorst ot skip, ah = num colors\r
-\r
- xor ch,ch ; Set the number of palette entries to cycle in cx\r
- mov cl,ah ;\r
-\r
- jmp short RotatePalEntry\r
-\r
-_x_rot_pal_struc endp\r
-\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; Rotate raw palette buffer\r
-;\r
-; x_rot_pal_raw(char far * pal, int direction, int num_colrs)\r
-;\r
-; Direcction : 0 = backward 1 = forward\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_rot_pal_raw proc\r
-ARG PalBuff:dword,Direction:word,NumColors:word\r
- push bp ; Set up stack frame\r
- mov bp,sp\r
- push ds\r
- push si\r
- push di\r
-\r
- cld\r
- mov cx,[NumColors] ; Set the number of palette entries to cycle\r
- lds si,dword ptr [PalBuff] ; point ds:si to Palette buffer\r
-\r
-RotatePalEntry:\r
-\r
-\r
- mov ax,ds ; copy ds to es\r
- mov es,ax\r
-\r
- dec cx\r
- mov bx,cx ; Multiply cx by 3\r
- shl bx,1\r
- add cx,bx\r
-\r
- cmp [Direction],0 ; are we going forward ?\r
- jne @@forward ; yes - jump (colors move one position back)\r
-\r
- std ; no - set reverse direction\r
- add si,cx ; set si to last byte in palette\r
- add si,2\r
-\r
-@@forward:\r
- mov ax,si ; copy si to di\r
- mov di,ax\r
-\r
- lodsb ; load first color triplet into regs\r
- mov dl,al\r
- lodsb\r
- mov dh,al\r
- lodsb\r
- mov bl,al\r
-\r
- rep movsb ; move remaining triplets direction indicated\r
- ; by direction flag\r
-\r
- mov al,dl ; write color triplet from regs to last position\r
- stosb\r
- mov al,dh\r
- stosb\r
- mov al,bl\r
- stosb\r
-\r
- pop di\r
- pop si\r
- pop ds\r
- pop bp\r
- ret\r
-_x_rot_pal_raw endp\r
-\r
-;----------------------------------------------------------------------\r
-; Copy palette making intensity adjustment\r
-; x_cpcontrast_pal_struc(char far *src_pal, char far *dest_pal, unsigned char Intensity)\r
-;\r
-; WARNING: memory for the palette buffers must all be pre-allocated\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_cpcontrast_pal_struc proc\r
-ARG PalSrcBuff:dword,PalDestBuff:dword,Intensity:byte\r
- push bp ; Set up stack frame\r
- mov bp,sp\r
- push ds\r
- push si\r
- push di\r
-\r
- cld\r
- mov bh,0ffh\r
- sub bh,[Intensity]\r
- and bh,07fh ; Palettes are 7 bit\r
- lds si,dword ptr [PalSrcBuff] ; point ds:si to Source Palette buffer\r
- les di,dword ptr [PalDestBuff] ; point ds:si to Source Palette buffer\r
- lodsw ; al = colorst ot skip, ah = num color\r
- stosw\r
-\r
- xor ch,ch ; Set the number of palette entries to adjust\r
- mov cl,ah ;\r
-\r
- mov dx,0 ; flag set to 0 if all output palette entries zero\r
-@@MainLoop:\r
- lodsw\r
- sub al,bh ; adjust intensity and copy RED\r
- jns @@DecrementOK_R\r
- xor al,al\r
-@@DecrementOK_R:\r
- sub ah,bh ; adjust intensity and copy GREEN\r
- jns @@DecrementOK_G\r
- xor ah,ah\r
-@@DecrementOK_G:\r
- or dx,ax\r
- or dl,ah\r
- stosw\r
- lodsb\r
- sub al,bh ; adjust intensity and copy BLUE\r
- jns @@DecrementOK_B\r
- xor al,al\r
-@@DecrementOK_B:\r
- or dl,al\r
- stosb\r
- loop @@MainLoop\r
-\r
- mov ax,dx\r
- pop di\r
- pop si\r
- pop ds\r
- pop bp\r
- ret\r
-_x_cpcontrast_pal_struc endp\r
-\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; Write DAC palette from annotated type buffer with specified intensity\r
-; ie BYTE colours to skip, BYTE colours to set, r1,g1,b1,r1,g2,b2...rn,gn,bn\r
-;\r
-; x_put_contrast_pal_struc(char far * pal, unsigned char intensity)\r
-;\r
-; Designed for fading in or out a palette without using an intermediate\r
-; working palette buffer ! (Slow but memory efficient ... OK for small\r
-; pal strucs}\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-\r
-_x_put_contrast_pal_struc proc\r
-ARG CompPalBuff:dword,Intensity:byte\r
- push bp ;preserve caller's stack frame\r
- mov bp,sp ;point to local stack frame\r
- push ds\r
- push si\r
- push di\r
- cld\r
-\r
- mov bh,0ffh\r
- sub bh,[Intensity]\r
- and bh,07fh ; Palettes are 7 bit\r
- mov di,40 ; set the vsync check timer (Vsync\r
- ; is tested for at each di'th entry to\r
- ; prevent snow 40 is otimum for 10\r
- ; MHz 286 or greater)\r
- lds si,[CompPalBuff] ; load the source compressed colour data\r
- lodsb ; get the colours to skip\r
- mov bl,al\r
-\r
- lodsb ; get the count of colours to set\r
- mov ah,0\r
- mov cx,ax ; use it as a loop counter\r
- or cx,cx\r
- jz @@Done\r
-\r
- WaitVsyncStart ; Wait for vert sync to start\r
-\r
-@@MainLoop:\r
- mov al,bl\r
- mov dx,DAC_WRITE_INDEX ; Tell DAC what colour index to start\r
- out dx,al ; writing from\r
- inc dx ; == mov dx,DAC_DATA\r
-\r
- lodsb ; Load each colour component, modify for\r
- sub al,bh ; intensity and write to DAC H/Ware\r
- jns @@DecrementOK_R\r
- xor al,al\r
-@@DecrementOK_R:\r
- out dx,al\r
-\r
- lodsb\r
- sub al,bh\r
- jns @@DecrementOK_G\r
- xor al,al\r
-@@DecrementOK_G:\r
- out dx,al\r
-\r
- lodsb\r
- sub al,bh\r
- jns @@DecrementOK_B\r
- xor al,al\r
-@@DecrementOK_B:\r
- out dx,al\r
-\r
- inc bl ; increment color index\r
- dec di ; decrement vsync test flag\r
- js @@test_vsync\r
- loop @@MainLoop\r
- jmp short @@Done\r
-\r
-\r
-@@test_vsync:\r
- mov dx,INPUT_STATUS_0\r
- push ax ; save current colour index\r
-@@Wait:\r
- in al,dx ; wait for vsync leading edge pulse\r
- test al,08h\r
- jz @@Wait\r
-\r
- pop ax ; restore current colour index\r
- mov di,40 ; reset vsync test counter\r
- loop @@MainLoop ; loop for next colour index\r
-\r
-@@Done:\r
- ;sti\r
- pop di\r
- pop si\r
- pop ds\r
- pop bp\r
- ret\r
-\r
-_x_put_contrast_pal_struc endp\r
-\r
-\r
- end\r
-\r
-\r
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XPAL - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;----------------------------------------------------------------------*/\r
-\r
-#ifndef _XPAL_H_\r
-#define _XPAL_H_\r
-\r
-#define PAL_ROTATE_DOWN 0\r
-#define PAL_ROTATE_UP 1\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-\r
- void x_get_pal_raw( /* Read DAC palette into raw buffer */\r
- BYTE far * pal,\r
- WORD num_colrs,\r
- WORD start_index);\r
-\r
- void x_get_pal_struc( /* Read DAC palette into annotated buffer */\r
- BYTE far * pal,\r
- WORD num_colrs,\r
- WORD start_index);\r
-\r
- void x_put_pal_raw( /* Write DAC palette from raw buffer */\r
- BYTE far * pal,\r
- WORD num_colrs,\r
- WORD start_index);\r
-\r
- void x_put_pal_struc( /* Write DAC palette from annotated buffer*/\r
- BYTE far * pal);\r
-\r
- x_set_rgb( /* Set the RGB components of a color index*/\r
- BYTE color,\r
- BYTE red_c,\r
- BYTE green_c,\r
- BYTE blue_c);\r
-\r
- x_rot_pal_raw( /* Rotate a raw palette buffer */\r
- BYTE far * pal,\r
- WORD direction,\r
- WORD num_colrs);\r
-\r
- void x_rot_pal_struc( /* Rotate an anottated palette buffer */\r
- BYTE far * pal,\r
- WORD direction);\r
-\r
- WORD x_cpcontrast_pal_struc( /* Copy and contrast adjust annotated */\r
- BYTE far *src_pal, /* palette buffer */\r
- BYTE far *dest_pal,\r
- BYTE Intensity);\r
-\r
- void x_transpose_pal_struc( /* Write DAC palette from annotated type*/\r
- BYTE far * pal, /* buffer with a new offset */\r
- WORD StartColor);\r
-\r
- void x_put_contrast_pal_struc( /* Write DAC palette from annotated */\r
- BYTE far * pal, /* type buffer with specified intensity */\r
- BYTE intensity);\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-\r
-#endif\r
-\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XPAL - Include file\r
-;\r
-; XPAL.ASM export functions\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
- global _x_get_pal_struc :proc\r
- global _x_get_pal_raw :proc\r
-\r
- global _x_put_pal_struc :proc\r
- global _x_put_pal_raw :proc\r
- global _x_set_rgb :proc\r
-\r
- global _x_rot_pal_struc :proc\r
- global _x_rot_pal_raw :proc\r
-\r
-\r
- global _x_put_contrast_pal_struc:proc\r
-\r
- global _x_transpose_pal_struc :proc\r
-\r
- global _x_cpcontrast_pal_struc :proc\1a
\ No newline at end of file
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XPBITMAP\r
-;\r
-; Planar Bitmap functions - System Ram <-> Video Ram\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
-COMMENT $\r
-\r
- This module implements a set of functions to operate on planar bitmaps.\r
- Planar bitmaps as used by these functions have the following structure:\r
-\r
- BYTE 0 The bitmap width in bytes (4 pixel groups) range 1..255\r
- BYTE 1 The bitmap height in rows range 1..255\r
- BYTE 2..n1 The plane 0 pixels width*height bytes\r
- BYTE n1..n2 The plane 1 pixels width*height bytes\r
- BYTE n2..n3 The plane 2 pixels width*height bytes\r
- BYTE n3..n4 The plane 3 pixels width*height bytes\r
-\r
- These functions provide the fastest possible bitmap blts from system ram to\r
- to video and further, the single bitmap is applicable to all pixel\r
- allignments. The masked functions do not need separate masks since all non\r
- zero pixels are considered to be masking pixels, hence if a pixel is 0 the\r
- corresponding screen destination pixel is left unchanged.\r
-\r
-\r
-$\r
-\r
-include xlib.inc\r
-include xpbitmap.inc\r
-LOCALS\r
- .code\r
-\r
-;----------------------------------------------------------------------\r
-; x_flip_masked_pbm - mask write a planar bitmap from system ram to video ram\r
-; all zero source bitmap bytes indicate destination byte to be left unchanged\r
-; If "Orientation" is set then the bitmap is flipped from left to right as\r
-; it is drawn\r
-;\r
-; Source Bitmap structure:\r
-;\r
-; Width:byte, Height:byte, Bitmap data (plane 0)...Bitmap data (plane 1)..,\r
-; Bitmap data (plane 2)..,Bitmap data (plane 3)..\r
-;\r
-; note width is in bytes ie lots of 4 pixels\r
-;\r
-; x_flip_masked_pbm(X,Y,ScrnOffs,char far * Bitmap, Orientation)\r
-;\r
-;\r
-; LIMITATIONS: No clipping is supported\r
-; Only supports bitmaps with widths which are a multiple of\r
-; 4 pixels\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_flip_masked_pbm proc\r
- ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword,Orientation:word\r
- LOCAL Plane:byte,BMHeight:byte,LineInc:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
- mov ax,SCREEN_SEG\r
- mov es,ax\r
- mov ax,[Y] ; Calculate dest screen row\r
- mov bx,[_ScrnLogicalByteWidth] ; by mult. dest Y coord by Screen\r
- mul bx ; width then adding screen offset\r
- mov di,[ScrnOffs] ; store result in DI\r
- add di,ax\r
- mov cx,[X] ; Load X coord into CX and make a\r
- mov dx,cx ; copy in DX\r
- shr dx,2 ; Find starting byte in dest row\r
- add di,dx ; add to DI giving screen offset of\r
- ; first pixel's byte\r
- lds si,[Bitmap] ; DS:SI -> Bitmap data\r
- lodsw ; Al = B.M. width (bytes) AH = B.M.\r
- ; height\r
- cmp Orientation,0\r
- jz UnFlippedMasked\r
-\r
- mov [BMHeight],ah ; Save source bitmap dimensions\r
- xor ah,ah ; LineInc = bytes to the begin.\r
- add bx,ax ; of bitmaps next row on screen\r
- mov [LineInc],bx\r
- mov bh,al ; Use bh as column loop count\r
- and cx,0003h ; mask X coord giving plane of 1st\r
- ; bitmap pixel(zero CH coincidentally)\r
- mov ah,11h ; Init. mask for VGA plane selection\r
- shl ah,cl ; Shift for starting pixel plane\r
- mov dx,SC_INDEX ; Prepare VGA for cpu to video writes\r
- mov al,MAP_MASK\r
- out dx,al\r
- inc dx\r
- mov [Plane],4 ; Set plane counter to 4\r
-@@PlaneLoop:\r
- push di ; Save bitmap's start dest. offset\r
- mov bl,[BMHeight] ; Reset row counter (BL)\r
- mov al,ah\r
- out dx,al ; set vga write plane\r
-@@RowLoop:\r
- mov cl,bh ; Reset Column counter cl\r
-@@ColLoop:\r
- lodsb ; Get next source bitmap byte\r
- or al,al ; If not zero then write to dest.\r
- jz @@NoPixel ; otherwise skip to next byte\r
- mov es:[di],al\r
-@@NoPixel:\r
- dec di\r
- loop @@ColLoop ; loop if more columns left\r
- add di,[LineInc] ; Move to next row\r
- dec bl ; decrement row counter\r
- jnz @@RowLoop ; Jump if more rows left\r
- pop di ; Restore bitmaps start dest byte\r
- ror ah,1 ; Shift mask for next plane\r
- sbb di,0 ; If wrapped increment dest address\r
- dec [Plane] ; Decrement plane counter\r
- jnz @@PlaneLoop ; Jump if more planes left\r
-\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_flip_masked_pbm endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_put_masked_pbm - mask write a planar bitmap from system ram to video ram\r
-; all zero source bitmap bytes indicate destination byte to be left unchanged\r
-;\r
-; Source Bitmap structure:\r
-;\r
-; Width:byte, Height:byte, Bitmap data (plane 0)...Bitmap data (plane 1)..,\r
-; Bitmap data (plane 2)..,Bitmap data (plane 3)..\r
-;\r
-; note width is in bytes ie lots of 4 pixels\r
-;\r
-; x_put_masked_pbm(X,Y,ScrnOffs,char far * Bitmap)\r
-;\r
-;\r
-; LIMITATIONS: No clipping is supported\r
-; Only supports bitmaps with widths which are a multiple of\r
-; 4 pixels\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_put_masked_pbm proc\r
- ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword\r
- LOCAL Plane:byte,BMHeight:byte,LineInc:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
- mov ax,SCREEN_SEG\r
- mov es,ax\r
- mov ax,[Y] ; Calculate dest screen row\r
- mov bx,[_ScrnLogicalByteWidth] ; by mult. dest Y coord by Screen\r
- mul bx ; width then adding screen offset\r
- mov di,[ScrnOffs] ; store result in DI\r
- add di,ax\r
- mov cx,[X] ; Load X coord into CX and make a\r
- mov dx,cx ; copy in DX\r
- shr dx,2 ; Find starting byte in dest row\r
- add di,dx ; add to DI giving screen offset of\r
- ; first pixel's byte\r
- lds si,[Bitmap] ; DS:SI -> Bitmap data\r
- lodsw ; Al = B.M. width (bytes) AH = B.M.\r
- ; height\r
-UnFlippedMasked:\r
- mov [BMHeight],ah ; Save source bitmap dimensions\r
- xor ah,ah ; LineInc = bytes to the begin.\r
- sub bx,ax ; of bitmaps next row on screen\r
- mov [LineInc],bx\r
- mov bh,al ; Use bh as column loop count\r
- and cx,0003h ; mask X coord giving plane of 1st\r
- ; bitmap pixel(zero CH coincidentally)\r
- mov ah,11h ; Init. mask for VGA plane selection\r
- shl ah,cl ; Shift for starting pixel plane\r
- mov dx,SC_INDEX ; Prepare VGA for cpu to video writes\r
- mov al,MAP_MASK\r
- out dx,al\r
- inc dx\r
- mov [Plane],4 ; Set plane counter to 4\r
-@@PlaneLoop:\r
- push di ; Save bitmap's start dest. offset\r
- mov bl,[BMHeight] ; Reset row counter (BL)\r
- mov al,ah\r
- out dx,al ; set vga write plane\r
-@@RowLoop:\r
- mov cl,bh ; Reset Column counter cl\r
-@@ColLoop:\r
- lodsb ; Get next source bitmap byte\r
- or al,al ; If not zero then write to dest.\r
- jz @@NoPixel ; otherwise skip to next byte\r
- mov es:[di],al\r
-@@NoPixel:\r
- inc di\r
- loop @@ColLoop ; loop if more columns left\r
- add di,[LineInc] ; Move to next row\r
- dec bl ; decrement row counter\r
- jnz @@RowLoop ; Jump if more rows left\r
- pop di ; Restore bitmaps start dest byte\r
- rol ah,1 ; Shift mask for next plane\r
- adc di,0 ; If wrapped increment dest address\r
- dec [Plane] ; Decrement plane counter\r
- jnz @@PlaneLoop ; Jump if more planes left\r
-\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_put_masked_pbm endp\r
-\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_put_pbm - Write a planar bitmap from system ram to video ram\r
-;\r
-; Source Bitmap structure:\r
-;\r
-; Width:byte, Height:byte, Bitmap data (plane 0)...Bitmap data (plane 1)..,\r
-; Bitmap data (plane 2)..,Bitmap data (plane 3)..\r
-;\r
-; note width is in bytes ie lots of 4 pixels\r
-;\r
-; x_put_pbm(X,Y,ScrnOffs,char far * Bitmap)\r
-;\r
-;\r
-; LIMITATIONS: No clipping is supported\r
-; Only supports bitmaps with widths which are a multiple of\r
-; 4 pixels\r
-; FEATURES : Automatically selects REP MOVSB or REP MOVSW depending on\r
-; source bitmap width, by modifying opcode ;-).\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-\r
-\r
-_x_put_pbm proc\r
- ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword\r
- LOCAL Plane:byte,BMHeight:byte,LineInc:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
- mov ax,SCREEN_SEG\r
- mov es,ax\r
- mov ax,[Y] ; Calculate dest screen row\r
- mov bx,[_ScrnLogicalByteWidth] ; by mult. dest Y coord by Screen\r
- mul bx ; width then adding screen offset\r
- mov di,[ScrnOffs] ; store result in DI\r
- add di,ax\r
- mov cx,[X] ; Load X coord into CX and make a\r
- mov dx,cx ; copy in DX\r
- shr dx,2 ; Find starting byte in dest row\r
- add di,dx ; add to DI giving screen offset of\r
- ; first pixel's byte\r
- lds si,[Bitmap] ; DS:SI -> Bitmap data\r
- lodsw ; Al = B.M. width (bytes) AH = B.M.\r
- ; height\r
-UnFlipped:\r
- mov [BMHeight],ah ; Save source bitmap dimensions\r
- xor ah,ah ; LineInc = bytes to the begin.\r
- sub bx,ax ; of bitmaps next row on screen\r
- mov [LineInc],bx\r
- mov bh,al\r
- ; Self Modifying, Shame, shame shame..\r
- and cx,0003h ; mask X coord giving plane of 1st\r
- ; bitmap pixel(zero CH coincidentally)\r
- mov ah,11h ; Init. mask for VGA plane selection\r
- shl ah,cl ; Shift for starting pixel plane\r
- mov dx,SC_INDEX ; Prepare VGA for cpu to video writes\r
- mov al,MAP_MASK\r
- out dx,al\r
- inc dx\r
- mov [Plane],4 ; Set plane counter to 4\r
-@@PlaneLoop:\r
- push di\r
- mov bl,[BMHeight]\r
- mov al,ah\r
- out dx,al\r
-@@RowLoop:\r
- mov cl,bh\r
- shr cl,1\r
- rep movsw ; Copy a complete row for curr plane\r
- adc cl,0\r
- rep movsb\r
- add di,[LineInc] ; Move to next row\r
- dec bl ; decrement row counter\r
- jnz @@RowLoop ; Jump if more rows left\r
- pop di ; Restore bitmaps start dest byte\r
- rol ah,1 ; Shift mask for next plane\r
- adc di,0 ; If wrapped increment dest address\r
- dec [Plane] ; Decrement plane counter\r
- jnz @@PlaneLoop ; Jump if more planes left\r
-\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_put_pbm endp\r
-\r
-;----------------------------------------------------------------------\r
-; x_flip_pbm - Write a planar bitmap from system ram to video ram\r
-; If "Orientation" is set then the bitmap is flipped from left to right as\r
-; it is drawn\r
-\r
-;\r
-; Source Bitmap structure:\r
-;\r
-; Width:byte, Height:byte, Bitmap data (plane 0)...Bitmap data (plane 1)..,\r
-; Bitmap data (plane 2)..,Bitmap data (plane 3)..\r
-;\r
-; note width is in bytes ie lots of 4 pixels\r
-;\r
-; x_flip_pbm(X,Y,ScrnOffs,char far * Bitmap, WORD orientation)\r
-;\r
-;\r
-; LIMITATIONS: No clipping is supported\r
-; Only supports bitmaps with widths which are a multiple of\r
-; 4 pixels\r
-;\r
-; NOTES: The flipped put function is slower than the standard put function\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_flip_pbm proc\r
- ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword,Orientation:word\r
- LOCAL Plane:byte,BMHeight:byte,LineInc:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
- mov ax,SCREEN_SEG\r
- mov es,ax\r
- mov ax,[Y] ; Calculate dest screen row\r
- mov bx,[_ScrnLogicalByteWidth] ; by mult. dest Y coord by Screen\r
- mul bx ; width then adding screen offset\r
- mov di,[ScrnOffs] ; store result in DI\r
- add di,ax\r
- mov cx,[X] ; Load X coord into CX and make a\r
- mov dx,cx ; copy in DX\r
- shr dx,2 ; Find starting byte in dest row\r
- add di,dx ; add to DI giving screen offset of\r
- ; first pixel's byte\r
- lds si,[Bitmap] ; DS:SI -> Bitmap data\r
- lodsw ; Al = B.M. width (bytes) AH = B.M.\r
- ; height\r
- cmp Orientation,0\r
- jz UnFlipped\r
-\r
- mov [BMHeight],ah ; Save source bitmap dimensions\r
- xor ah,ah ; LineInc = bytes to the begin.\r
- add bx,ax ; of bitmaps next row on screen\r
- mov [LineInc],bx\r
- mov bh,al ; Use bh as column loop count\r
- and cx,0003h ; mask X coord giving plane of 1st\r
- ; bitmap pixel(zero CH coincidentally)\r
- mov ah,11h ; Init. mask for VGA plane selection\r
- shl ah,cl ; Shift for starting pixel plane\r
- mov dx,SC_INDEX ; Prepare VGA for cpu to video writes\r
- mov al,MAP_MASK\r
- out dx,al\r
- inc dx\r
- mov [Plane],4 ; Set plane counter to 4\r
-@@PlaneLoop:\r
- push di ; Save bitmap's start dest. offset\r
- mov bl,[BMHeight] ; Reset row counter (BL)\r
- mov al,ah\r
- out dx,al ; set vga write plane\r
-@@RowLoop:\r
- mov cl,bh ; Reset Column counter cl\r
-@@ColLoop:\r
- lodsb\r
- mov es:[di],al\r
- dec di\r
- sub di,2\r
- loop @@ColLoop ; loop if more columns left\r
-@@DoneCol:\r
- add di,[LineInc] ; Move to next row\r
- dec bl ; decrement row counter\r
- jnz @@RowLoop ; Jump if more rows left\r
- pop di ; Restore bitmaps start dest byte\r
- ror ah,1 ; Shift mask for next plane\r
- sbb di,0 ; If wrapped increment dest address\r
- dec [Plane] ; Decrement plane counter\r
- jnz @@PlaneLoop ; Jump if more planes left\r
-\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_flip_pbm endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_get_pbm - Read a planar bitmap to system ram from video ram\r
-;\r
-; Source Bitmap structure:\r
-;\r
-; Width:byte, Height:byte, Bitmap data (plane 0)...Bitmap data (plane 1)..,\r
-; Bitmap data (plane 2)..,Bitmap data (plane 3)..\r
-;\r
-; note width is in bytes ie lots of 4 pixels\r
-;\r
-; x_get_pbm(X,Y,BMwidth,BMheight,ScrnOffs,char far * Bitmap)\r
-;\r
-;\r
-; LIMITATIONS: No clipping is supported\r
-; Only supports bitmaps with widths which are a multiple of\r
-; 4 pixels\r
-; FEATURES : Automatically selects REP MOVSB or REP MOVSW depending on\r
-; source bitmap width, by modifying opcode ;-).\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_get_pbm proc\r
- ARG X:word,Y:word,SrcWidth:byte,SrcHeight:byte,ScrnOffs:word,Bitmap:dword\r
- LOCAL Plane:byte,LineInc:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
-\r
- mov ax,[Y] ; Calculate screen row\r
- mov bx,[_ScrnLogicalByteWidth] ; by mult. Y coord by Screen\r
- mul bx ; width then adding screen offset\r
- mov si,[ScrnOffs] ; store result in SI\r
- add si,ax\r
- mov cx,[X] ; Load X coord into CX and make a\r
- mov dx,cx ; copy in DX\r
- shr dx,2 ; Find starting byte in screen row\r
- add si,dx ; add to SI giving screen offset of\r
- ; first pixel's byte\r
- mov ax,SCREEN_SEG\r
- mov ds,ax\r
- les di,[Bitmap] ; ES:DI -> Bitmap data\r
- mov al,[SrcWidth]\r
- mov ah,[SrcHeight]\r
- stosw ; Al = B.M. width (bytes) AH = B.M.\r
- ; height\r
- xor ah,ah ; LineInc = bytes to the begin.\r
- sub bx,ax ; of bitmaps next row on screen\r
- mov [LineInc],bx\r
- mov bh,al\r
- ; Self Modifying, Shame, shame shame..\r
- and cx,0003h ; mask X coord giving plane of 1st\r
- ; bitmap pixel(zero CH coincidentally)\r
- mov ah,11h ; Init. mask for VGA plane selection\r
- shl ah,cl ; Shift for starting pixel plane\r
- mov dx,GC_INDEX ; Prepare VGA for cpu to video reads\r
- mov al,READ_MAP\r
- out dx,al\r
- inc dx\r
- mov [Plane],4 ; Set plane counter (BH) to 4\r
- mov al,cl\r
-@@PlaneLoop:\r
- push si\r
- mov bl,[SrcHeight]\r
- out dx,al\r
-@@RowLoop:\r
- mov cl,bh\r
- shr cl,1\r
- rep movsw ; Copy a complete row for curr plane\r
- adc cl,0\r
- rep movsb\r
- add si,[LineInc] ; Move to next row\r
- dec bl ; decrement row counter\r
- jnz @@RowLoop ; Jump if more rows left\r
- pop si ; Restore bitmaps start dest byte\r
-\r
- inc al ; Select next plane to read from\r
- and al,3 ;\r
-\r
- rol ah,1 ; Shift mask for next plane\r
- adc si,0 ; If wrapped increment dest address\r
- dec [Plane] ; Decrement plane counter\r
- jnz @@PlaneLoop ; Jump if more planes left\r
-\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_get_pbm endp\r
-\r
-\r
-\r
-\r
- end\r
-\r
-\r
-\r
- ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword,Orientation:word\r
- LOCAL Plane:byte,BMHeight:byte,LineInc:word,Columns:byte=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
- mov ax,SCREEN_SEG\r
- mov es,ax\r
- mov ax,[Y] ; Calculate dest screen row\r
- mov bx,[_ScrnLogicalByteWidth] ; by mult. dest Y coord by Screen\r
- mul bx ; width then adding screen offset\r
- mov di,[ScrnOffs] ; store result in DI\r
- add di,ax\r
- mov cx,[X] ; Load X coord into CX and make a\r
- mov dx,cx ; copy in DX\r
- shr dx,2 ; Find starting byte in dest row\r
- add di,dx ; add to DI giving screen offset of\r
- ; first pixel's byte\r
- lds si,[Bitmap] ; DS:SI -> Bitmap data\r
- lodsw ; Al = B.M. width (bytes) AH = B.M.\r
- ; height\r
- cmp Orientation,0\r
- jz UnFlipped\r
-\r
- mov [BMHeight],ah ; Save source bitmap dimensions\r
- xor ah,ah ; LineInc = bytes to the begin.\r
- add bx,ax ; of bitmaps next row on screen\r
- mov [LineInc],bx\r
- mov [Columns],al ; Use bh as column loop count\r
- and cx,0003h ; mask X coord giving plane of 1st\r
- ; bitmap pixel(zero CH coincidentally)\r
- mov ah,11h ; Init. mask for VGA plane selection\r
- shl ah,cl ; Shift for starting pixel plane\r
- mov bh,ah\r
- mov dx,SC_INDEX ; Prepare VGA for cpu to video writes\r
- mov al,MAP_MASK\r
- out dx,al\r
- inc dx\r
- mov [Plane],4 ; Set plane counter to 4\r
-@@PlaneLoop:\r
- push di ; Save bitmap's start dest. offset\r
- mov bl,[BMHeight] ; Reset row counter (BL)\r
- mov al,bh\r
- out dx,al ; set vga write plane\r
-@@RowLoop:\r
- mov cl,[Columns] ; Reset Column counter cl\r
- shr cx,1\r
- jnc @@ColLoop\r
- lodsb\r
- mov es:[di],al\r
- dec di\r
-@@ColLoop:\r
- lodsw ; Get next source bitmap byte\r
- xchg al,ah\r
- mov es:[di],ax\r
- sub di,2\r
- loop @@ColLoop ; loop if more columns left\r
-\r
- add di,[LineInc] ; Move to next row\r
- dec bl ; decrement row counter\r
- jnz @@RowLoop ; Jump if more rows left\r
- pop di ; Restore bitmaps start dest byte\r
- ror bh,1 ; Shift mask for next plane\r
- sbb di,0 ; If wrapped increment dest address\r
- dec [Plane] ; Decrement plane counter\r
- jnz @@PlaneLoop ; Jump if more planes left\r
-\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret
\ No newline at end of file
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XPBITMAP - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-; ****** Aeronautical Research Laboratory ****************\r
-; ****** Defence Science and Technology Organisation ****************\r
-; ****** Australia ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;-----------------------------------------------------------------------*/\r
-\r
-#ifndef _XPBITMAP_H_\r
-#define _XPBITMAP_H_\r
-\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-\r
- void x_put_masked_pbm( /* Copy a planar bitmap from SRAM masking */\r
- WORD X, /* only non zero pixels to VRAM */\r
- WORD Y,\r
- WORD ScrnOffs,\r
- BYTE far * Bitmap);\r
-\r
- void x_flip_masked_pbm( /* Copy a planar bitmap from SRAM masking */\r
- WORD X, /* only non zero pixels to VRAM. Bitmap */\r
- WORD Y, /* is mirrored. */\r
- WORD ScrnOffs,\r
- BYTE far * Bitmap,\r
- WORD orientation);\r
-\r
- void x_put_pbm( /* Copy a planar bitmap from SRAM to VRAM */\r
- WORD X,\r
- WORD Y,\r
- WORD ScrnOffs,\r
- BYTE far * Bitmap);\r
-\r
- void x_flip_pbm( /* Copy a planar bitmap from SRAM to VRAM */\r
- WORD X,\r
- WORD Y,\r
- WORD ScrnOffs,\r
- BYTE far * Bitmap,\r
- WORD orientation);\r
-\r
- void x_get_pbm( /* Copy a planar bitmap from VRAM to SRAM */\r
- WORD X,\r
- WORD Y,\r
- BYTE Bw,\r
- BYTE Bh,\r
- WORD ScrnOffs,\r
- BYTE far * Bitmap);\r
-\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-\r
-#endif\r
-\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XPBITMAP - Include file\r
-;\r
-; XPBITMAP.ASM export functions\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
- global _x_put_masked_pbm :proc\r
- global _x_flip_masked_pbm :proc\r
- global _x_put_pbm :proc\r
- global _x_flip_pbm :proc\r
- global _x_get_pbm :proc\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XPBMCLIP\r
-;\r
-; Clipped Planar Bitmap functions - System Ram <-> Video Ram\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
-COMMENT $\r
-\r
- This module implements a set of functions to operate on planar bitmaps.\r
- Planar bitmaps as used by these functions have the following structure:\r
-\r
- BYTE 0 The bitmap width in bytes (4 pixel groups) range 1..255\r
- BYTE 1 The bitmap height in rows range 1..255\r
- BYTE 2..n1 The plane 0 pixels width*height bytes\r
- BYTE n1..n2 The plane 1 pixels width*height bytes\r
- BYTE n2..n3 The plane 2 pixels width*height bytes\r
- BYTE n3..n4 The plane 3 pixels width*height bytes\r
-\r
- These functions provide the fastest possible bitmap blts from system ram to\r
- to video and further, the single bitmap is applicable to all pixel\r
- allignments. The masked functions do not need separate masks since all non\r
- zero pixels are considered to be masking pixels, hence if a pixel is 0 the\r
- corresponding screen destination pixel is left unchanged.\r
-\r
-\r
-$\r
-LOCALS\r
-include xlib.inc\r
-include xpbmclip.inc\r
-\r
- .code\r
-\r
-;----------------------------------------------------------------------\r
-; x_put_masked_pbm_clipx - mask write a planar bitmap from system ram to video\r
-; ram all zero source bitmap bytes indicate destination\r
-; byte to be left unchanged.\r
-; Performs clipping in x directions. similar to\r
-; "x_put_masked_pbm".\r
-;\r
-; See Also: x_put_masked_pbm, x_put_masked_pbm_clipxy\r
-;\r
-; Clipping region variables: LeftClip,RightClip\r
-;\r
-; Written by Themie Gouthas\r
-;\r
-; This code is a SLOW hack, any better ideas are welcome\r
-;----------------------------------------------------------------------\r
-_x_put_masked_pbm_clipx proc\r
-ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword\r
-LOCAL Plane:byte,CType,LeftSkip,DataInc,Width,Height,TopRow,LineInc:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
-\r
- les si,[Bitmap] ; Point ES:SI to start of bitmap\r
-\r
- xor ax,ax ; Clear AX\r
- mov [CType],ax ; Clear Clip type descision var\r
- mov al,byte ptr es:[si] ; AX=width (byte coverted to word)\r
-\r
-\r
- mov di,[X] ; DI = X coordinate of dest\r
- mov cx,di ; copy to CX\r
- sar di,2 ; convert to offset in row\r
-\r
-\r
- ;;;;; CLIP PROCESSING FOR LEFT CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
- mov dx,[_LeftClip] ; Is X Coord to the right of\r
- sub dx,di ; LeftClip ?\r
- jle @@NotLeftClip ; Yes! => no left clipping\r
- cmp dx,ax ; Is dist of X Coord from\r
- jnl @@NotVisible ; ClipLeft > Width ? yes => the\r
- ; bitmap is not visible\r
- add di,dx\r
- mov [LeftSkip],dx\r
- mov [DataInc],dx\r
- sub ax,dx\r
- mov [CType],1\r
- jmp short @@HorizClipDone\r
-\r
- ;;;; EXIT FOR COMPLETELY OBSCURED P.B.M's ;;;;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotVisible:\r
- mov ax,1\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-\r
- ;;;;; CLIP PROCESSING FOR RIGHT CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotLeftClip:\r
- mov dx,[_RightClip]\r
- sub dx,di\r
- js @@NotVisible\r
- mov [LeftSkip],0\r
- mov [DataInc],0\r
- cmp dx,ax\r
- jge @@HorizClipDone ; was jg\r
- inc dx\r
- sub ax,dx\r
- mov [DataInc],ax\r
- mov ax,dx\r
- mov [CType],-1\r
-\r
-@@HorizClipDone:\r
-\r
- xor bh,bh\r
- mov bl,byte ptr es:[si+1] ; BX = height\r
-\r
- mov [Width],ax ; Save width and height of clipped\r
- mov [Height],bx ; image\r
-\r
-\r
- add si,2 ; Skip dimension bytes in source\r
- add si,[LeftSkip] ; Skip pixels in front of row that\r
- ; are clipped\r
-\r
-\r
- mov bx,[_ScrnLogicalByteWidth] ; Set BX to Logical Screen Width\r
- mov dx,bx ; BX - Width of image = No. bytes\r
- sub dx,ax ; to first byte of next screen\r
- mov [LineInc],dx ; row.\r
-\r
- mov ax,[Y] ; Calculate screen start row\r
- mul bx ; then adding screen offset\r
- add di,ax\r
- add di,[ScrnOffs]\r
- mov ax,es ; copy ES to DS\r
- mov ds,ax\r
- mov ax,SCREEN_SEG ; Point ES to VGA segment\r
- mov es,ax\r
-\r
- and cx,3\r
- mov ah,11h ; Set up initial plane mask\r
- shl ah,cl\r
-\r
- mov dx,SC_INDEX ; Prepare VGA for cpu to video writes\r
- mov al,MAP_MASK\r
- out dx,al\r
- inc dx\r
- mov [Plane],4 ; Set plane counter to 4\r
- mov bh,byte ptr [Width] ; set bh to width for fast looping\r
-@@PlaneLoop:\r
- push di ; Save bitmap's start dest. offset\r
- mov bl,byte ptr [Height] ; Reset row counter (BL)\r
- mov al,ah\r
- out dx,al ; set vga write plane\r
-@@RowLoop:\r
- mov cl,bh ; Reset Column counter cl\r
- jcxz @@NoWidth\r
-@@ColLoop:\r
- lodsb ; Get next source bitmap byte\r
- or al,al ; If not zero then write to dest.\r
- jz @@NoPixel ; otherwise skip to next byte\r
- mov es:[di],al\r
-@@NoPixel:\r
- inc di\r
- loop @@ColLoop\r
-@@NoWidth:\r
- add si,[DataInc] ; Move to next source row\r
- add di,[LineInc] ; Move to next screen row\r
- dec bl ; decrement row counter\r
- jnz @@RowLoop ; Jump if more rows left\r
- pop di ; Restore bitmaps start dest byte\r
- rol ah,1 ; Shift mask for next plane\r
-\r
- ; Plane Transition (A HACK but it works!)\r
-\r
- jnb @@Nocarry ; Jump if not plane transition\r
- mov bl,ah ; Save Plane Mask\r
- mov ax,[CType] ; set AX to clip type inc variable\r
- add bh,al ; Update advancing variables\r
- sub [DataInc],ax ;\r
- sub [LineInc],ax ;\r
- cmp al,0 ; What type of clip do we have\r
- mov ah,bl ; restore Plane mask\r
- jg @@RightAdvance ; jump on a right clip!\r
- inc di ; otherwise increment DI\r
- jmp @@Nocarry\r
-@@RightAdvance:\r
- dec si\r
-@@Nocarry:\r
- dec [Plane] ; Decrement plane counter\r
- jnz @@PlaneLoop ; Jump if more planes left\r
-\r
- xor ax,ax\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_put_masked_pbm_clipx endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_put_masked_pbm_clipy - mask write a planar bitmap from system ram to video\r
-; ram all zero source bitmap bytes indicate destination\r
-; byte to be left unchanged.\r
-; Performs clipping in y direction. similar to\r
-; "x_put_masked_pbm".\r
-;\r
-; See Also: x_put_masked_pbm, x_put_masked_pbm_clipx, x_put_masked_pbm_clipy\r
-;\r
-; Clipping region variables: TopClip,BottomClip\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_put_masked_pbm_clipy proc\r
-ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword\r
-LOCAL Width,Height,TopRow,LineInc,PlaneInc:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
-\r
- les si,[Bitmap]\r
-\r
- xor bh,bh\r
- mov bl,byte ptr es:[si+1] ; BX = height\r
-\r
- xor ah,ah\r
- mov al,byte ptr es:[si] ; AX = width\r
-\r
- mov cx,ax ; Save AX\r
- mul bx ; AX = AX*BX = bytes/plane\r
- mov [PlaneInc],ax ; save as PlaneInc\r
- mov ax,cx ; Restore AX\r
-\r
- mov di,[X]\r
- mov cx,di\r
- shr di,2\r
-\r
- ;;;;; CLIP PROCESSING FOR TOP CLIP BORDER ;;;;;;;;;;;;;;;;;;;;;\r
-\r
- mov dx,[_TopClip] ; Compare u.l. Y coord with Top\r
- sub dx,[Y] ; clipping border\r
- jle @@NotTopClip ; jump if VBM not clipped from above\r
- cmp dx,bx\r
- jnl @@NotVisible ; jump if VBM is completely obscured\r
- mov [TopRow],dx\r
- sub bx,dx\r
- add [Y],dx\r
- jmp short @@VertClipDone\r
-\r
- ;;;; EXIT FOR COMPLETELY OBSCURED P.B.M's ;;;;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotVisible:\r
- mov ax,1\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-\r
- ;;;;; CLIP PROCESSING FOR BOTTOM CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotTopClip:\r
- mov dx,[_BottomClip]\r
- sub dx,[Y]\r
- js @@NotVisible\r
- mov [TopRow],0\r
- cmp dx,bx\r
- jg @@VertClipDone\r
- inc dx\r
- mov bx,dx\r
-\r
-@@VertClipDone:\r
-\r
- mov [Width],ax\r
- mov [Height],bx ; Calculate relative offset in data\r
- mul [TopRow] ; of first visible scanline\r
- add ax,2 ; Skip dimension bytes in source\r
- add si,ax ; Skip top rows that arent visible\r
-\r
-\r
- mov ax,[Y] ; Calculate screen row\r
- mov bx,[_ScrnLogicalByteWidth] ; by mult. Y coord by Screen\r
- mul bx ; width then adding screen offset\r
- add di,ax\r
- add di,[ScrnOffs]\r
- sub bx,[Width] ; calculate difference from end of\r
- mov [LineInc],bx ; b.m. in curr line to beginning of\r
- ; b.m. on next scan line\r
- mov ax,es ; copy ES to DS\r
- mov ds,ax\r
- mov ax,SCREEN_SEG ; Point ES to VGA segment\r
- mov es,ax\r
-\r
- mov ah,11h ; Set up initial plane mask\r
- and cx,3\r
- shl ah,cl\r
-\r
- mov dx,SC_INDEX ; Prepare VGA for cpu to video writes\r
- mov al,MAP_MASK\r
- out dx,al\r
- inc dx\r
- mov bh,4 ; Set plane counter to 4\r
-@@PlaneLoop:\r
- push di ; Save bitmap's start dest. offset\r
- push si ; Save Bitmaps data offset\r
- mov bl,byte ptr [Height] ; Reset row counter (BL)\r
- mov al,ah\r
- out dx,al ; set vga write plane\r
-@@RowLoop:\r
- mov cl,byte ptr [Width] ; Reset Column counter cl\r
-@@ColLoop:\r
- lodsb ; Get next source bitmap byte\r
- or al,al ; If not zero then write to dest.\r
- jz @@NoPixel ; otherwise skip to next byte\r
- mov es:[di],al\r
-@@NoPixel:\r
- inc di\r
- loop @@ColLoop ; loop if more columns left\r
- add di,[LineInc] ; Move to next row\r
- dec bl ; decrement row counter\r
- jnz @@RowLoop ; Jump if more rows left\r
- pop si ; Restore SI and set to offset of\r
- add si,[PlaneInc] ; first vis pixel in next plane data\r
- pop di ; Restore bitmaps start dest byte\r
- rol ah,1 ; Shift mask for next plane\r
- adc di,0 ; if carry increment screen offset\r
- dec bh ; Decrement plane counter\r
- jnz @@PlaneLoop ; Jump if more planes left\r
-\r
- xor ax,ax\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_put_masked_pbm_clipy endp\r
-\r
-;----------------------------------------------------------------------\r
-; x_put_masked_pbm_clipxy - Write a planar bitmap from system ram to video\r
-; RAM with clipping in x and y directions. similar to\r
-; "x_put_masked_pbm".\r
-;\r
-; See Also: x_put_masked_pbm, x_put_masked_pbm_clipx, x_put_masked_pbm_clipxy\r
-;\r
-; Clipping region variables: LeftClip,RightClip,TopClip,BottomClip\r
-;\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_put_masked_pbm_clipxy proc\r
-ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword\r
-LOCAL Plane:byte,CType,LeftSkip,DataInc,Width,Height,TopRow,LineInc,PlaneInc:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
-\r
- les si,[Bitmap]\r
-\r
- xor ax,ax\r
- mov [CType],ax\r
- mov al,byte ptr es:[si] ; AX = width\r
- xor bh,bh\r
- mov bl,byte ptr es:[si+1] ; BX = height\r
-\r
- mov cx,ax ; Save AX\r
- mul bx ; AX = AX*BX = bytes/plane\r
- mov [PlaneInc],ax ; save as PlaneInc\r
- mov ax,cx ; Restore AX\r
-\r
-\r
- mov di,[X] ; DI = X coordinate of dest.\r
- mov cx,di ; save in CX\r
- sar di,2 ; convert to address byte\r
-\r
-\r
- ;;;;; CLIP PROCESSING FOR TOP CLIP BORDER ;;;;;;;;;;;;;;;;;;;;;\r
-\r
- mov dx,[_TopClip] ; Compare u.l. Y coord with Top\r
- sub dx,[Y] ; clipping border\r
- jle @@NotTopClip ; jump if VBM not clipped from above\r
- cmp dx,bx\r
- jnl @@NotVisible ; jump if VBM is completely obscured\r
- mov [TopRow],dx\r
- sub bx,dx\r
- add [Y],dx\r
- jmp short @@VertClipDone\r
-\r
- ;;;; EXIT FOR COMPLETELY OBSCURED P.B.M's ;;;;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotVisible:\r
- mov ax,1\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-\r
- ;;;;; CLIP PROCESSING FOR BOTTOM CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotTopClip:\r
- mov dx,[_BottomClip]\r
- sub dx,[Y]\r
- js @@NotVisible\r
- mov [TopRow],0\r
- cmp dx,bx\r
- jg @@VertClipDone\r
- inc dx\r
- mov bx,dx\r
-\r
-@@VertClipDone:\r
-\r
- ;;;;; CLIP PROCESSING FOR LEFT CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
- mov dx,[_LeftClip]\r
- sub dx,di\r
- jle @@NotLeftClip\r
- cmp dx,ax\r
- jnl @@NotVisible\r
-\r
- add di,dx\r
- mov [LeftSkip],dx\r
- mov [DataInc],dx\r
- sub ax,dx\r
- mov [CType],1\r
- jmp short @@HorizClipDone\r
-\r
- ;;;;; CLIP PROCESSING FOR RIGHT CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotLeftClip:\r
- mov dx,[_RightClip]\r
- sub dx,di\r
- js @@NotVisible\r
- mov [LeftSkip],0\r
- mov [DataInc],0\r
- cmp dx,ax\r
- jge @@HorizClipDone ; was jg\r
- inc dx\r
- sub ax,dx\r
- mov [DataInc],ax\r
- mov ax,dx\r
-\r
-\r
- mov [CType],-1\r
-\r
-@@HorizClipDone:\r
-\r
-\r
-\r
- mov [Width],ax ; Save width and height of clipped\r
- mov [Height],bx ; image\r
-\r
- add ax,[DataInc] ; AX = original width of image\r
- mul [TopRow] ; Calculate bytes in clipped top\r
- add si,ax ; rows\r
- add si,2 ; Skip dimension bytes in source\r
- add si,[LeftSkip] ; Skip pixels in front of row that\r
- ; are clipped\r
-\r
- mov bx,[_ScrnLogicalByteWidth] ; Set BX to Logical Screen Width\r
- mov dx,bx ; BX - Width of image = No. bytes\r
- sub dx,[Width] ; to first byte of next screen\r
- mov [LineInc],dx ; row.\r
-\r
- mov ax,[Y] ; Calculate screen start row\r
- mul bx ; then adding screen offset\r
- add di,ax\r
- add di,[ScrnOffs]\r
- mov ax,es ; copy ES to DS\r
- mov ds,ax\r
- mov ax,SCREEN_SEG ; Point ES to VGA segment\r
- mov es,ax\r
-\r
-\r
-\r
- and cx,3\r
- mov ah,11h ; Set up initial plane mask\r
- shl ah,cl\r
-\r
- mov dx,SC_INDEX ; Prepare VGA for cpu to video writes\r
- mov al,MAP_MASK\r
- out dx,al\r
- inc dx\r
- mov [Plane],4 ; Set plane counter to 4\r
- mov bh,byte ptr [Width] ; set bh to width for fast looping\r
-@@PlaneLoop:\r
- push di ; Save bitmap's start dest. offset\r
- push si\r
- mov bl,byte ptr [Height] ; Reset row counter (BL)\r
- mov al,ah\r
- out dx,al ; set vga write plane\r
-@@RowLoop:\r
- mov cl,bh ; Reset Column counter cl\r
- jcxz @@NoWidth\r
-@@ColLoop:\r
- lodsb ; Get next source bitmap byte\r
- or al,al ; If not zero then write to dest.\r
- jz @@NoPixel ; otherwise skip to next byte\r
- mov es:[di],al\r
-@@NoPixel:\r
- inc di\r
- loop @@ColLoop\r
-@@NoWidth:\r
- add si,[DataInc] ; Move to next source row\r
- add di,[LineInc] ; Move to next screen row\r
- dec bl ; decrement row counter\r
- jnz @@RowLoop ; Jump if more rows left\r
- pop si ; Restore SI and set to offset of\r
- add si,[PlaneInc] ; first vis pixel in next plane data\r
- pop di ; Restore bitmaps start dest byte\r
- rol ah,1 ; Shift mask for next plane\r
-\r
- ; Plane Transition (A HACK but it works!)\r
-\r
- jnb @@Nocarry ; Jump if not plane transition\r
- mov bl,ah ; Save Plane Mask\r
- mov ax,[CType] ; set AX to clip type inc variable\r
- add bh,al ; Update advancing variables\r
- sub [DataInc],ax ;\r
- sub [LineInc],ax ;\r
- cmp al,0 ; What type of clip do we have\r
- mov ah,bl ; restore Plane mask\r
- jg @@RightAdvance ; jump on a right clip!\r
- inc di ; otherwise increment DI\r
- jmp @@Nocarry\r
-@@RightAdvance:\r
- dec si\r
-@@Nocarry:\r
- dec [Plane] ; Decrement plane counter\r
- jnz @@PlaneLoop ; Jump if more planes left\r
-\r
- xor ax,ax\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_put_masked_pbm_clipxy endp\r
-\r
-\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_put_pbm_clipx - Write a planar bitmap from system ram to video ram\r
-; with clipping in x and y directions. similar to\r
-; "x_put_pbm".\r
-;\r
-; See Also: x_put_pbm_clip\r
-;\r
-;\r
-; See Also: x_put_pbm,x_put_pbm_clipy,x_put_pbm_clipxy\r
-;\r
-; Clipping region variables: LeftClip,RightClip\r
-;\r
-; Written by Themie Gouthas\r
-;\r
-; This code is a SLOW hack, any better ideas are welcome\r
-;----------------------------------------------------------------------\r
-_x_put_pbm_clipx proc\r
-ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword\r
-LOCAL Plane:byte,CType,LeftSkip,DataInc,Width,Height,TopRow,LineInc:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
-\r
- les si,[Bitmap]\r
-\r
- xor ax,ax\r
- mov [CType],ax\r
- mov al,byte ptr es:[si] ; AX = width\r
-\r
-\r
- mov di,[X] ; DI = X coordinate of dest.\r
- mov cx,di ; save in CX\r
- sar di,2 ; convert to address byte\r
-\r
-\r
-\r
- ;;;;; CLIP PROCESSING FOR LEFT CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
- mov dx,[_LeftClip]\r
- sub dx,di\r
- jle @@NotLeftClip\r
- cmp dx,ax\r
- jnl @@NotVisible\r
-\r
- add di,dx\r
- mov [LeftSkip],dx\r
- mov [DataInc],dx\r
- sub ax,dx\r
- mov [CType],1\r
- jmp short @@HorizClipDone\r
-\r
- ;;;; EXIT FOR COMPLETELY OBSCURED P.B.M's ;;;;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotVisible:\r
- mov ax,1\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-\r
- ;;;;; CLIP PROCESSING FOR RIGHT CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotLeftClip:\r
- mov dx,[_RightClip]\r
- sub dx,di\r
- js @@NotVisible\r
- mov [LeftSkip],0\r
- mov [DataInc],0\r
- cmp dx,ax\r
- jge @@HorizClipDone ; was jg\r
- inc dx\r
- sub ax,dx\r
- mov [DataInc],ax\r
- mov ax,dx\r
- mov [CType],-1\r
-\r
-@@HorizClipDone:\r
-\r
- xor bh,bh\r
- mov bl,byte ptr es:[si+1] ; BX = height\r
-\r
- mov [Width],ax ; Save width and height of clipped\r
- mov [Height],bx ; image\r
-\r
-\r
- add si,2 ; Skip dimension bytes in source\r
- add si,[LeftSkip] ; Skip pixels in front of row that\r
- ; are clipped\r
-\r
-\r
- mov bx,[_ScrnLogicalByteWidth] ; Set BX to Logical Screen Width\r
- mov dx,bx ; BX - Width of image = No. bytes\r
- sub dx,ax ; to first byte of next screen\r
- mov [LineInc],dx ; row.\r
-\r
- mov ax,[Y] ; Calculate screen start row\r
- mul bx ; then adding screen offset\r
- add di,ax\r
- add di,[ScrnOffs]\r
- mov ax,es ; copy ES to DS\r
- mov ds,ax\r
- mov ax,SCREEN_SEG ; Point ES to VGA segment\r
- mov es,ax\r
-\r
- and cx,3\r
- mov ah,11h ; Set up initial plane mask\r
- shl ah,cl\r
-\r
- mov dx,SC_INDEX ; Prepare VGA for cpu to video writes\r
- mov al,MAP_MASK\r
- out dx,al\r
- inc dx\r
- mov [Plane],4 ; Set plane counter to 4\r
- mov bh,byte ptr [Width] ; set bh to width for fast looping\r
-@@PlaneLoop:\r
- push di ; Save bitmap's start dest. offset\r
- mov bl,byte ptr [Height] ; Reset row counter (BL)\r
- mov al,ah\r
- out dx,al ; set vga write plane\r
-@@RowLoop:\r
- mov cl,bh ; Reset Column counter cl\r
- shr cl,1\r
- rep movsw ; Copy a complete row\r
- adc cl,0\r
- rep movsb\r
- add si,[DataInc] ; Move to next source row\r
- add di,[LineInc] ; Move to next screen row\r
- dec bl ; decrement row counter\r
- jnz @@RowLoop ; Jump if more rows left\r
- pop di ; Restore bitmaps start dest byte\r
- rol ah,1 ; Shift mask for next plane\r
-\r
- ; Plane Transition (A HACK but it works!)\r
-\r
- jnb @@Nocarry ; Jump if not plane transition\r
- mov bl,ah ; Save Plane Mask\r
- mov ax,[CType] ; set AX to clip type inc variable\r
- add bh,al ; Update advancing variables\r
- sub [DataInc],ax ;\r
- sub [LineInc],ax ;\r
- cmp al,0 ; What type of clip do we have\r
- mov ah,bl ; restore Plane mask\r
- jg @@RightAdvance ; jump on a right clip!\r
- inc di ; otherwise increment DI\r
- jmp @@Nocarry\r
-@@RightAdvance:\r
- dec si\r
-@@Nocarry:\r
- dec [Plane] ; Decrement plane counter\r
- jnz @@PlaneLoop ; Jump if more planes left\r
-\r
- xor ax,ax\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_put_pbm_clipx endp\r
-\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_put_pbm_clipy - Write a planar bitmap from system ram to video ram\r
-; with clipping in y direction only. similar to\r
-; "x_put_pbm".\r
-;\r
-; See Also: x_put_pbm,x_put_pbm_clipx,x_put_pbm_clipxy\r
-;\r
-; Clipping region variables: TopClip,BottomClip\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_put_pbm_clipy proc\r
-ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword\r
-LOCAL Width,Height,TopRow,LineInc,PlaneInc:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
-\r
- les si,[Bitmap]\r
-\r
- xor bh,bh\r
- mov bl,byte ptr es:[si+1] ; BX = height\r
- ;mov [Height],bx\r
-\r
- xor ah,ah\r
- mov al,byte ptr es:[si] ; AX = width\r
- mov [Width],ax\r
-\r
- mov cx,ax ; Save AX\r
- mul bx ; AX = AX*BX = bytes/plane\r
- mov [PlaneInc],ax ; save as PlaneInc\r
- mov ax,cx ; Restore AX\r
-\r
- mov di,[X]\r
- mov cx,di\r
- and cx,3\r
- shr di,2\r
-\r
- ;;;;; CLIP PROCESSING FOR TOP CLIP BORDER ;;;;;;;;;;;;;;;;;;;;;\r
-\r
- mov dx,[_TopClip] ; Compare u.l. Y coord with Top\r
- sub dx,[Y] ; clipping border\r
- jle @@NotTopClip ; jump if VBM not clipped from above\r
- cmp dx,bx\r
- jnl @@NotVisible ; jump if VBM is completely obscured\r
- mov [TopRow],dx\r
- sub bx,dx\r
- add [Y],dx\r
- jmp short @@VertClipDone\r
-\r
- ;;;; EXIT FOR COMPLETELY OBSCURED P.B.M's ;;;;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotVisible:\r
- mov ax,1\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-\r
- ;;;;; CLIP PROCESSING FOR BOTTOM CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotTopClip:\r
- mov dx,[_BottomClip]\r
- sub dx,[Y]\r
- js @@NotVisible\r
- mov [TopRow],0\r
- cmp dx,bx\r
- jg @@VertClipDone\r
- inc dx\r
- mov bx,dx\r
-\r
-@@VertClipDone:\r
-\r
- mov [Height],bx ; Calculate relative offset in data\r
- mul [TopRow] ; of first visible scanline\r
- add ax,2 ; Skip dimension bytes in source\r
- add si,ax ; Skip top rows that arent visible\r
-\r
-\r
- mov ax,[Y] ; Calculate screen row\r
- mov bx,[_ScrnLogicalByteWidth] ; by mult. Y coord by Screen\r
- mul bx ; width then adding screen offset\r
- add di,ax\r
- add di,[ScrnOffs]\r
- sub bx,[Width] ; calculate difference from end of\r
- mov [LineInc],bx ; b.m. in curr line to beginning of\r
- ; b.m. on next scan line\r
- mov ax,es ; copy ES to DS\r
- mov ds,ax\r
- mov ax,SCREEN_SEG ; Point ES to VGA segment\r
- mov es,ax\r
-\r
- mov ah,11h ; Set up initial plane mask\r
- shl ah,cl\r
-\r
- mov dx,SC_INDEX ; Prepare VGA for cpu to video writes\r
- mov al,MAP_MASK\r
- out dx,al\r
- inc dx\r
- mov bh,4 ; Set plane counter to 4\r
-@@PlaneLoop:\r
- push di ; Save bitmap's start dest. offset\r
- push si ; Save Bitmaps data offset\r
- mov bl,byte ptr [Height] ; Reset row counter (BL)\r
- mov al,ah\r
- out dx,al ; set vga write plane\r
-@@RowLoop:\r
- mov cl,byte ptr [Width] ; Reset Column counter cl\r
- shr cl,1\r
- rep movsw ; Copy a complete row\r
- adc cl,0\r
- rep movsb\r
-\r
- add di,[LineInc] ; Move to next row\r
- dec bl ; decrement row counter\r
- jnz @@RowLoop ; Jump if more rows left\r
- pop si ; Restore SI and set to offset of\r
- add si,[PlaneInc] ; first vis pixel in next plane data\r
- pop di ; Restore bitmaps start dest byte\r
- rol ah,1 ; Shift mask for next plane\r
- adc di,0 ; if carry increment screen offset\r
- dec bh ; Decrement plane counter\r
- jnz @@PlaneLoop ; Jump if more planes left\r
-\r
- xor ax,ax\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_put_pbm_clipy endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_put_pbm_clipxy - Write a planar bitmap from system ram to video ram\r
-; with clipping in x and y directions. similar to\r
-; "x_put_pbm".\r
-;\r
-; See Also: x_put_pbm,x_put_pbm_clipy,x_put_pbm_clipx\r
-;\r
-; Clipping region variables: LeftClip,RightClip,TopClip,BottomClip\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_put_pbm_clipxy proc\r
-ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword\r
-LOCAL Plane:byte,CType,LeftSkip,DataInc,Width,Height,TopRow,LineInc,PlaneInc:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
-\r
- les si,[Bitmap]\r
-\r
- xor ax,ax\r
- mov [CType],ax\r
- mov al,byte ptr es:[si] ; AX = width\r
- xor bh,bh\r
- mov bl,byte ptr es:[si+1] ; BX = height\r
-\r
- mov cx,ax ; Save AX\r
- mul bx ; AX = AX*BX = bytes/plane\r
- mov [PlaneInc],ax ; save as PlaneInc\r
- mov ax,cx ; Restore AX\r
-\r
-\r
- mov di,[X] ; DI = X coordinate of dest.\r
- mov cx,di ; save in CX\r
- sar di,2 ; convert to address byte\r
-\r
-\r
- ;;;;; CLIP PROCESSING FOR TOP CLIP BORDER ;;;;;;;;;;;;;;;;;;;;;\r
-\r
- mov dx,[_TopClip] ; Compare u.l. Y coord with Top\r
- sub dx,[Y] ; clipping border\r
- jle @@NotTopClip ; jump if VBM not clipped from above\r
- cmp dx,bx\r
- jnl @@NotVisible ; jump if VBM is completely obscured\r
- mov [TopRow],dx\r
- sub bx,dx\r
- add [Y],dx\r
- jmp short @@VertClipDone\r
-\r
- ;;;; EXIT FOR COMPLETELY OBSCURED P.B.M's ;;;;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotVisible:\r
- mov ax,1\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-\r
- ;;;;; CLIP PROCESSING FOR BOTTOM CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotTopClip:\r
- mov dx,[_BottomClip]\r
- sub dx,[Y]\r
- js @@NotVisible\r
- mov [TopRow],0\r
- cmp dx,bx\r
- jg @@VertClipDone\r
- inc dx\r
- mov bx,dx\r
-\r
-@@VertClipDone:\r
-\r
- ;;;;; CLIP PROCESSING FOR LEFT CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
- mov dx,[_LeftClip]\r
- sub dx,di\r
- jle @@NotLeftClip\r
- cmp dx,ax\r
- jnl @@NotVisible\r
-\r
- add di,dx\r
- mov [LeftSkip],dx\r
- mov [DataInc],dx\r
- sub ax,dx\r
- mov [CType],1\r
- jmp short @@HorizClipDone\r
-\r
- ;;;;; CLIP PROCESSING FOR RIGHT CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotLeftClip:\r
- mov dx,[_RightClip]\r
- sub dx,di\r
- js @@NotVisible\r
- mov [LeftSkip],0\r
- mov [DataInc],0\r
- cmp dx,ax\r
- jge @@HorizClipDone ; was jg\r
- inc dx\r
- sub ax,dx\r
- mov [DataInc],ax\r
- mov ax,dx\r
- mov [CType],-1\r
-\r
-@@HorizClipDone:\r
-\r
-\r
-\r
- mov [Width],ax ; Save width and height of clipped\r
- mov [Height],bx ; image\r
-\r
- add ax,[DataInc] ; AX = original width of image\r
- mul [TopRow] ; Calculate bytes in clipped top\r
- add si,ax ; rows\r
- add si,2 ; Skip dimension bytes in source\r
- add si,[LeftSkip] ; Skip pixels in front of row that\r
- ; are clipped\r
-\r
- mov bx,[_ScrnLogicalByteWidth] ; Set BX to Logical Screen Width\r
- mov dx,bx ; BX - Width of image = No. bytes\r
- sub dx,[Width] ; to first byte of next screen\r
- mov [LineInc],dx ; row.\r
-\r
- mov ax,[Y] ; Calculate screen start row\r
- mul bx ; then adding screen offset\r
- add di,ax\r
- add di,[ScrnOffs]\r
- mov ax,es ; copy ES to DS\r
- mov ds,ax\r
- mov ax,SCREEN_SEG ; Point ES to VGA segment\r
- mov es,ax\r
-\r
-\r
-\r
- and cx,3\r
- mov ah,11h ; Set up initial plane mask\r
- shl ah,cl\r
-\r
- mov dx,SC_INDEX ; Prepare VGA for cpu to video writes\r
- mov al,MAP_MASK\r
- out dx,al\r
- inc dx\r
- mov [Plane],4 ; Set plane counter to 4\r
- mov bh,byte ptr [Width] ; set bh to width for fast looping\r
-@@PlaneLoop:\r
- push di ; Save bitmap's start dest. offset\r
- push si\r
- mov bl,byte ptr [Height] ; Reset row counter (BL)\r
- mov al,ah\r
- out dx,al ; set vga write plane\r
-@@RowLoop:\r
- mov cl,bh ; Reset Column counter cl\r
- shr cl,1\r
- rep movsw ; Copy a complete row\r
- adc cl,0\r
- rep movsb\r
- add si,[DataInc] ; Move to next source row\r
- add di,[LineInc] ; Move to next screen row\r
- dec bl ; decrement row counter\r
- jnz @@RowLoop ; Jump if more rows left\r
- pop si ; Restore SI and set to offset of\r
- add si,[PlaneInc] ; first vis pixel in next plane data\r
- pop di ; Restore bitmaps start dest byte\r
- rol ah,1 ; Shift mask for next plane\r
-\r
- ; Plane Transition (A HACK but it works!)\r
-\r
- jnb @@Nocarry ; Jump if not plane transition\r
- mov bl,ah ; Save Plane Mask\r
- mov ax,[CType] ; set AX to clip type inc variable\r
- add bh,al ; Update advancing variables\r
- sub [DataInc],ax ;\r
- sub [LineInc],ax ;\r
- cmp al,0 ; What type of clip do we have\r
- mov ah,bl ; restore Plane mask\r
- jg @@RightAdvance ; jump on a right clip!\r
- inc di ; otherwise increment DI\r
- jmp @@Nocarry\r
-@@RightAdvance:\r
- dec si\r
-@@Nocarry:\r
- dec [Plane] ; Decrement plane counter\r
- jnz @@PlaneLoop ; Jump if more planes left\r
-\r
- xor ax,ax\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_put_pbm_clipxy endp\r
-\r
- end\r
-\r
-\r
-\r
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XPBMCLIP - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;-----------------------------------------------------------------------*/\r
-\r
-#ifndef _XPBMCLIP_H_\r
-#define _XPBMCLIP_H_\r
-\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-\r
- int x_put_masked_pbm_clipx( /* Copy a planar bitmap from SRAM masking */\r
- int X, /* only non zero pixels to VRAM */\r
- int Y, /* Supports clipping in the X direction */\r
- WORD ScrnOffs,\r
- BYTE far * Bitmap);\r
-\r
-\r
- int x_put_masked_pbm_clipy( /* Copy a planar bitmap from SRAM masking */\r
- int X, /* only non zero pixels to VRAM */\r
- int Y, /* Supports clipping in the Y direction */\r
- WORD ScrnOffs,\r
- BYTE far * Bitmap);\r
-\r
- int x_put_masked_pbm_clipxy( /* Copy a planar bitmap from SRAM masking */\r
- int X, /* only non zero pixels to VRAM */\r
- int Y, /* Supports clipping in the Y direction */\r
- WORD ScrnOffs,\r
- BYTE far * Bitmap);\r
-\r
- int x_put_pbm_clipx( /* Copy a planar bitmap from SRAM masking */\r
- int X, /* Supports clipping in the x direction */\r
- int Y,\r
- WORD ScrnOffs,\r
- BYTE far * Bitmap);\r
-\r
- int x_put_pbm_clipy( /* Copy a planar bitmap from SRAM masking */\r
- int X, /* Supports clipping in the Y direction */\r
- int Y,\r
- WORD ScrnOffs,\r
- BYTE far * Bitmap);\r
-\r
- int x_put_pbm_clipx( /* Copy a planar bitmap from SRAM masking */\r
- int X, /* Supports clipping in the X direction */\r
- int Y,\r
- WORD ScrnOffs,\r
- BYTE far * Bitmap);\r
-\r
- int x_put_pbm_clipxy( /* Copy a planar bitmap from SRAM masking */\r
- int X, /* Supports clipping in the X&Y directions */\r
- int Y,\r
- WORD ScrnOffs,\r
- BYTE far * Bitmap);\r
-\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-\r
-#endif\r
-\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XPBMCLIP - Include file\r
-;\r
-; XPBMCLIP.ASM export functions\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
- global _x_put_masked_pbm_clipx :proc\r
- global _x_put_masked_pbm_clipy :proc\r
- global _x_put_masked_pbm_clipxy :proc\r
-\r
- global _x_put_pbm_clipx :proc\r
- global _x_put_pbm_clipy :proc\r
- global _x_put_pbm_clipxy :proc\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XPOINT\r
-;\r
-; Point functions all MODE X 256 Color resolutions\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
-include xlib.inc\r
-include xpoint.inc\r
-\r
- .code\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; Mode X (256 color mode) write pixel routine.\r
-; No clipping is performed.\r
-;\r
-; Based on code originally published in DDJ Mag by M. Abrash\r
-;\r
-; C near-callable as:\r
-; void x_put_pix(int X, int Y, int PageOffset, int Color);\r
-;\r
-;\r
-\r
-_x_put_pix proc \r
- ARG X:word,Y:word,PgOfs:word,Color:word\r
- push bp ;preserve caller's stack frame\r
- mov bp,sp ;point to local stack frame\r
-\r
- mov ax,[_ScrnLogicalByteWidth]\r
- mul [Y] ;offset of pixel's scan line in page\r
- mov bx,[X]\r
- shr bx,2 ;X/4 = offset of pixel in scan line\r
- add bx,ax ;offset of pixel in page\r
- add bx,[PgOfs] ;offset of pixel in display memory\r
- mov ax,SCREEN_SEG\r
- mov es,ax ;point ES:BX to the pixel's address\r
-\r
- mov cl,byte ptr [X]\r
- and cl,011b ;CL = pixel's plane\r
- mov ax,0100h + MAP_MASK ;AL = index in SC of Map Mask reg\r
- shl ah,cl ;set only the bit for the pixel's\r
- ; plane to 1\r
- mov dx,SC_INDEX ;set the Map Mask to enable only the\r
- out dx,ax ; pixel's plane\r
-\r
- mov al,byte ptr [Color]\r
- mov es:[bx],al ;draw the pixel in the desired color\r
-\r
- pop bp ;restore caller's stack frame\r
- ret\r
-_x_put_pix endp\r
-\r
-;-------------------------------------------------------------------------\r
-; Mode X (320x240, 256 colors) read pixel routine. Works on all VGAs.\r
-; No clipping is performed.\r
-;\r
-; Based on code originally published in DDJ Mag by M. Abrash\r
-;\r
-; C near-callable as:\r
-; unsigned int x_get_pix(int X, int Y, unsigned int PageBase);\r
-\r
-\r
-_x_get_pix proc\r
- ARG x:word,y:word,PageBase:word\r
- push bp ;preserve caller's stack frame\r
- mov bp,sp ;point to local stack frame\r
-\r
- mov ax,[_ScrnLogicalByteWidth]\r
- mul [Y] ;offset of pixel's scan line in page\r
- mov bx,[X]\r
- shr bx,1\r
- shr bx,1 ;X/4 = offset of pixel in scan line\r
- add bx,ax ;offset of pixel in page\r
- add bx,[PageBase] ;offset of pixel in display memory\r
- mov ax,SCREEN_SEG\r
- mov es,ax ;point ES:BX to the pixel's address\r
-\r
- mov ah,byte ptr [X]\r
- and ah,011b ;AH = pixel's plane\r
- mov al,READ_MAP ;AL = index in GC of the Read Map reg\r
- mov dx,GC_INDEX ;set the Read Map to read the pixel's\r
- out dx,ax ; plane\r
-\r
- mov al,es:[bx] ;read the pixel's color\r
- sub ah,ah ;convert it to an unsigned int\r
-\r
- pop bp ;restore caller's stack frame\r
- ret\r
-_x_get_pix endp\r
- end\r
-\r
-\r
- end\r
-\r
-\1a
\ No newline at end of file
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XPOINT - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;-----------------------------------------------------------------------*/\r
-\r
-#ifndef _XPOINT_H_\r
-#define _XPOINT_H_\r
-\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-\r
- void x_put_pix( /* Draw a pixel on the screen */\r
- WORD X,\r
- WORD Y,\r
- WORD PageOffset,\r
- WORD Color);\r
-\r
- WORD x_get_pix( /* Read a pixel from the screen */\r
- WORD X,\r
- WORD Y,\r
- WORD PageBase);\r
-\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-\r
-#endif\r
-\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XPOINT - Include file\r
-;\r
-; XPOINT.ASM export functions\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
- global _x_put_pix :proc\r
- global _x_get_pix :proc\r
-\1a
\ No newline at end of file
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XPOLYGON\r
-;\r
-; Filled Triangle function for all MODE X 256 Color resolutions\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; This module is based on code developed by Steve Dollind for his\r
-; XSPACE game.\r
-; Copyright (C) 1992 Steven Dollins -- sdollins@uiuc.edu\r
-;\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-include xlib.inc\r
-include xpolygon.inc\r
-\r
-.data\r
-; Plane masks for clipping left and right edges of rectangle.\r
- LeftClipPlaneMask db 00fh,00eh,00ch,008h\r
- RightClipPlaneMask db 00fh,001h,003h,007h\r
-\r
-.code\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; void HLineClipR\r
-;\r
-; Draws a horizontal line from (X1, Y) to (X2, Y).\r
-; Uses Watcom Parameter passing convention in registers\r
-;\r
-; X1 in AX\r
-; X2 in DX\r
-; Y in CX\r
-; Color in BX\r
-; PageOffset in DI\r
-;\r
-; By Themie Gouthas - Adapted from x_fill_rect.\r
-;-----------------------------------------------------------------------\r
-proc _HLineClipR near\r
- push di\r
- cmp dx,ax ; if (X2 < X1) then assume no line\r
- jl @@Invisible ; is visible\r
-\r
- cmp cx,[_TopClip] ; if (Y < TopClip) then no line\r
- jl @@Invisible\r
-\r
- cmp cx,[_BottomClip] ;if (Y > BottomClip) then no line\r
- jg @@Invisible\r
-\r
- mov di,[_RightClip] ;convert RightClip to pixel coords\r
- sal di,2\r
- cmp ax,di ; if (X1 > RightClip) then no line\r
- jg @@Invisible\r
-\r
- cmp dx,di ; if (X2 > RightClip) then\r
- jle @@ClipLeft ; X2:=RightClip\r
- mov dx,di\r
-\r
-@@ClipLeft:\r
- mov di,[_LeftClip] ;convert LeftClip to pixel coords\r
- sal di,2\r
- cmp dx,di ; if (X2 < LeftClip) then no line\r
- jl @@Invisible\r
-\r
- cmp ax,di ;if (X1 > LeftClip) then were ready to plot\r
- jge @@DoLine\r
-\r
- mov ax,di ; X1:=LeftClip\r
- jmp short @@DoLine\r
-\r
-@@Invisible:\r
- pop di\r
- ret\r
-\r
-@@DoLine:\r
- pop di ; di = PageOffset\r
- xchg cx,ax ; AX = Y, CX = X1\r
- mov si,dx ; SI = DX = X2\r
- mul [_ScrnLogicalByteWidth]\r
- mov dx,si ; Reset DX to X1 since mul erases DX\r
- add ax,di\r
- mov di,cx\r
- sar di,2 ; Convert to bytes\r
- add di,ax ; DI->First byte\r
-\r
- and si,03h ; look up right edge plane mask\r
- mov ah,RightClipPlaneMask[si]\r
- mov si,cx ; look up left edge plane mask\r
- and si,03h\r
- mov al,LeftClipPlaneMask[si]\r
-\r
- cmp dx,cx ; No harm in being paranoid..\r
- jle @@Invisible2\r
-\r
- xchg cx,dx ;CX=X2, DX=X1\r
- dec cx\r
- and dx,not 03h\r
- sub cx,dx\r
- js @@Invisible2\r
- shr cx,2\r
- jnz @@MasksSet\r
- and al,ah\r
-@@MasksSet:\r
- mov dl,bl ; set BX=Plane Masks, AH=Color\r
- mov bx,ax\r
- mov ah,dl\r
- mov dx,SC_INDEX+1 ;set the Sequence Controller Index to\r
- mov al,bl\r
- out dx,al\r
- mov al,ah\r
- stosb ; Plot left byte\r
- dec cx\r
- js @@Invisible2\r
- jz @@RightEnd\r
-\r
-\r
- mov al,0fh ; plot middle bytes\r
- out dx,al\r
- mov al,ah\r
- shr cx,1\r
- rep stosw\r
- adc cx,cx\r
- rep stosb\r
-\r
-\r
-\r
-@@RightEnd:\r
- mov al,bh ; Plot right byte\r
- out dx,al\r
- mov al,ah\r
- stosb\r
-@@Invisible2:\r
- ret\r
-_HLineClipR endp\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; void x_triangle( int X0, int Y0, int X1, int Y1,\r
-; int X2, int Y2, unsigned Color, unsigned PageOffset );\r
-;\r
-;\r
-; Written by S. Dollins\r
-\r
-_x_triangle proc\r
-ARG X0:word,Y0:word,X1:word,Y1:word,X2:word,Y2:word,Color:word,PageOffset:word\r
-LOCAL DX01:word, DY01:word, DX02:word, DY02:word, DX12:word, DY12:word, \\r
- DP01:word, DP02:word, DP12:word, XA01:word, XA02:word, XA12:word=STK\r
-\r
- push bp\r
- mov bp,sp\r
- sub sp,STK\r
- push ds es si di ; Save es for polygon routine\r
-\r
- mov ax,X0\r
- mov bx,Y0\r
- mov cx,X1\r
- mov dx,Y1\r
-\r
- cmp bx,dx ; Y0,Y1\r
- jl tri_Y0lY1\r
- je tri_Y0eY1\r
- xchg ax,cx ; X0,X1\r
- xchg bx,dx ; Y0,Y1\r
-tri_Y0lY1:\r
- cmp dx,Y2 ; Y1,Y2\r
- jg tri_a\r
- jmp tri_sorted\r
-tri_a: xchg cx,X2 ; X1,X2\r
- xchg dx,Y2 ; Y1,Y2\r
- cmp bx,dx ; Y0,Y1\r
- jge tri_b\r
- jmp tri_sorted\r
-tri_b: je tri_bot\r
- xchg ax,cx ; X0,X1\r
- xchg bx,dx ; Y0,Y1\r
- jmp tri_sorted\r
-tri_Y0eY1:\r
- cmp bx,Y2 ; Y0,Y2\r
- jl tri_bot\r
- jg tri_c\r
- jmp tri_done\r
-tri_c: xchg ax,X2 ; X0,X2\r
- xchg bx,Y2 ; Y0,Y2\r
- jmp tri_sorted\r
-\r
-tri_bot:\r
- cmp ax,cx ; X0,X1\r
- jl tri_bot_sorted\r
- jg tri_bot_a\r
- jmp tri_done\r
-tri_bot_a:\r
- xchg ax,cx ; X0,X1\r
-tri_bot_sorted:\r
- cmp bx,[_BottomClip]\r
- jle tri_bot_y0ok\r
- jmp tri_done\r
-tri_bot_y0ok:\r
- mov si,Y2\r
- cmp si,[_TopClip]\r
- jge tri_bot_y2ok\r
- jmp tri_done\r
-tri_bot_y2ok:\r
- mov X0,ax\r
- mov Y0,bx\r
- mov X1,cx\r
- mov Y1,dx\r
-\r
- mov bx,Y2 ; bx <- Y2\r
- sub bx,Y0 ; bx <- Y2 - Y0\r
- mov DY02,bx ; DY02 <- Y2 - Y0\r
- mov ax,X2 ; ax <- X2\r
- sub ax,X0 ; ax <- X2 - X0\r
- mov DX02,ax ; DX02 <- X2 - X0\r
- mov cx,ax ; cx <- DX02\r
- cwd ; dx:ax <- DX02\r
- idiv bx ; ax <- DX02 / DY02\r
- cmp cx,0\r
- jge short tri_bot02\r
- dec ax ; ax <- DX02 / DY02 - 1\r
-tri_bot02:\r
- mov XA02,ax ; XA02 <- DX02 / DY02\r
- imul bx ; ax <- XA02 * DY02\r
- sub cx,ax ; cx <- DX02 - XA02 * DY02\r
- mov DP02,cx ; DP02 <- DX02 - XA02 * DY02\r
-\r
- mov bx,Y2 ; bx <- Y2\r
- sub bx,Y1 ; bx <- Y2 - Y1\r
- mov DY12,bx ; DY02 <- Y2 - Y1\r
- mov ax,X2 ; ax <- X2\r
- sub ax,X1 ; ax <- X2 - X1\r
- mov DX12,ax ; DX12 <- X2 - X1\r
- mov cx,ax ; cx <- DX12\r
- cwd ; dx:ax <- DX12\r
- idiv bx ; ax <- DX12 / DY12\r
- cmp cx,0\r
- jge short tri_bot12\r
- dec ax ; ax <- DX12 / DY12 - 1\r
-tri_bot12:\r
- mov XA12,ax ; XA12 <- DX12 / DY12\r
- imul bx ; ax <- XA12 * DY12\r
- sub cx,ax ; cx <- DX12 - XA12 * DY12\r
- mov DP12,cx ; DP12 <- DX12 - XA12 * DY12\r
-\r
- mov ax,0 ; PL <- 0\r
- mov bx,0 ; PS <- 0\r
- mov cx,Y0 ; Y <- Y0\r
- mov si,X0\r
- mov di,X1\r
- dec di\r
-tri_bot_loop:\r
- inc cx ; Y\r
-\r
- add ax,DP02 ; PL,DP02\r
- jle short tri_bot_shortl\r
- sub ax,DY02 ; PL,DY02\r
- inc si ; XL\r
-tri_bot_shortl:\r
- add si,XA02 ; XL,XA02\r
-\r
- add bx,DP12 ; PS,DP12\r
- jle short tri_bot_shortr\r
- sub bx,DY12 ; PS,DY12\r
- inc di ; XS\r
-tri_bot_shortr:\r
- add di,XA12 ; XS,XA12\r
-\r
- push di ; XS\r
- push si ; XL\r
- cmp cx,Y2 ; Y,Y2\r
- jl short tri_bot_loop\r
-\r
- jmp tri_draw_lines\r
-\r
-\r
-tri_sorted:\r
- cmp bx,[_BottomClip]\r
- jle tri_y0ok\r
- jmp tri_done\r
-tri_y0ok:\r
- mov si,Y2\r
- cmp si,[_TopClip]\r
- jge tri_y2ok\r
- jmp tri_done\r
-tri_y2ok:\r
- mov X0,ax\r
- mov Y0,bx\r
- mov X1,cx\r
- mov Y1,dx\r
-\r
- mov bx,dx ; bx <- Y1\r
- sub bx,Y0 ; bx <- Y1 - Y0\r
- mov DY01,bx ; DY01 <- Y1 - Y0\r
- mov ax,X1 ; ax <- X1\r
- sub ax,X0 ; ax <- X1 - X0\r
- mov DX01,ax ; DX01 <- X1 - X0\r
- mov cx,ax ; cx <- DX01\r
- cwd ; dx:ax <- DX01\r
- idiv bx ; ax <- DX01 / DY01\r
- cmp cx,0 ; DX01 ? 0\r
- jge short tri_psl01\r
- dec ax ; ax <- DX01 / DY01 - 1\r
-tri_psl01:\r
- mov XA01,ax ; XA01 <- DX01 / DY01\r
- imul bx ; ax <- XA01 * DY01\r
- sub cx,ax ; cx <- DX01 - XA01 * DY01\r
- mov DP01,cx ; DP01 <- DX01 - XA01 * DY01\r
-\r
- mov bx,Y2 ; bx <- Y2\r
- sub bx,Y0 ; bx <- Y2 - Y0\r
- mov DY02,bx ; DY02 <- Y2 - Y0\r
- mov ax,X2 ; ax <- X2\r
- sub ax,X0 ; ax <- X2 - X0\r
- mov DX02,ax ; DX02 <- X2 - X0\r
- mov cx,ax ; cx <- DX02\r
- cwd ; dx:ax <- DX02\r
- idiv bx ; ax <- DX02 / DY02\r
- cmp cx,0\r
- jge short tri_psl02\r
- dec ax ; ax <- DX02 / DY02 - 1\r
-tri_psl02:\r
- mov XA02,ax ; XA02 <- DX02 / DY02\r
- imul bx ; ax <- XA02 * DY02\r
- sub cx,ax ; cx <- DX02 - XA02 * DY02\r
- mov DP02,cx ; DP02 <- DX02 - XA02 * DY02\r
-\r
- mov bx,Y2 ; bx <- Y2\r
- sub bx,Y1 ; bx <- Y2 - Y1\r
- jle short tri_const_computed\r
- mov DY12,bx ; DY12 <- Y2 - Y1\r
- mov ax,X2 ; ax <- X2\r
- sub ax,X1 ; ax <- X2 - X1\r
- mov DX12,ax ; DX12 <- X2 - X1\r
- mov cx,ax ; cx <- DX12\r
- cwd ; dx:ax <- DX12\r
- idiv bx ; ax <- DX12 / DY12\r
- cmp cx,0\r
- jge short tri_psl12\r
- dec ax ; ax <- DX12 / DY12 - 1\r
-tri_psl12:\r
- mov XA12,ax ; XA12 <- DX12 / DY12\r
- imul bx ; ax <- XA12 * DY12\r
- sub cx,ax ; cx <- DX12 - XA12 * DY12\r
- mov DP12,cx ; DP12 <- DX12 - XA12 * DY12\r
-\r
-tri_const_computed:\r
- mov ax,DX01\r
- imul word ptr DY02\r
- mov bx,ax\r
- mov cx,dx ; DX01 * DY02 in cx:bx\r
-\r
- mov ax,DX02\r
- imul word ptr DY01 ; DX02 * DY01 in dx:ax\r
- cmp cx,dx\r
- jg tri_pt1rt\r
- jl tri_pt1lt\r
- cmp bx,ax\r
- ja tri_pt1rt\r
- jb tri_pt1lt\r
- jmp tri_done\r
-\r
-;------------------------------------\r
-; Short sides are on the left\r
-;\r
-tri_pt1lt:\r
- mov ax,0 ; PL <- 0\r
- mov bx,0 ; PS <- 0\r
- mov cx,Y0 ; Y <- Y0\r
- mov si,X0\r
- mov di,si\r
- dec si\r
-tri_lt_loop:\r
- inc cx ; Y\r
-\r
- add ax,DP02 ; PL,DP02\r
- jle short tri_lt_shortl\r
- sub ax,DY02 ; PL,DY02\r
- inc si ; XL\r
-tri_lt_shortl:\r
- add si,XA02 ; XL,XA02\r
-\r
- add bx,DP01 ; PS,DP01\r
- jle short tri_lt_shortr\r
- sub bx,DY01 ; PS,DY01\r
- inc di ; XS\r
-tri_lt_shortr:\r
- add di,XA01 ; XS,XA01\r
-\r
- push si ; XL\r
- push di ; XS\r
- cmp cx,Y1 ; Y,Y1\r
- jl short tri_lt_loop\r
-\r
- jmp short tri_lb_start\r
-tri_lb_loop:\r
- inc cx ; Y\r
-\r
- add ax,DP02 ; PL,DP02\r
- jle short tri_lb_shortl\r
- sub ax,DY02 ; PL,DY02\r
- inc si ; XL\r
-tri_lb_shortl:\r
- add si,XA02 ; XL,XA02\r
-\r
- add bx,DP12 ; PS,DP12\r
- jle short tri_lb_shortr\r
- sub bx,DY12 ; PS,DY12\r
- inc di ; XS\r
-tri_lb_shortr:\r
- add di,XA12 ; XS,XA12\r
-\r
- push si ; XL\r
- push di ; XS\r
-tri_lb_start:\r
- cmp cx,Y2 ; Y,Y2\r
- jl tri_lb_loop\r
- jmp short tri_draw_lines\r
-\r
-;------------------------------------\r
-; short sides are on the right\r
-;\r
-tri_pt1rt:\r
- mov ax,0 ; PL <- 0\r
- mov bx,0 ; PS <- 0\r
- mov cx,Y0 ; Y <- Y0\r
- mov si,X0\r
- mov di,si\r
- dec di\r
-tri_rt_loop:\r
- inc cx ; Y\r
-\r
- add ax,DP02 ; PL,DP02\r
- jle short tri_rt_shortl\r
- sub ax,DY02 ; PL,DY02\r
- inc si ; XL\r
-tri_rt_shortl:\r
- add si,XA02 ; XL,XA02\r
-\r
- add bx,DP01 ; PS,DP01\r
- jle short tri_rt_shortr\r
- sub bx,DY01 ; PS,DY01\r
- inc di ; XS\r
-tri_rt_shortr:\r
- add di,XA01 ; XS,XA01\r
-\r
- push di ; XS\r
- push si ; XL\r
- cmp cx,Y1 ; Y,Y1\r
- jl short tri_rt_loop\r
-\r
- jmp short tri_rb_start\r
-tri_rb_loop:\r
- inc cx ; Y\r
-\r
- add ax,DP02 ; PL,DP02\r
- jle short tri_rb_shortl\r
- sub ax,DY02 ; PL,DY02\r
- inc si ; XL\r
-tri_rb_shortl:\r
- add si,XA02 ; XL,XA02\r
-\r
- add bx,DP12 ; PS,DP12\r
- jle short tri_rb_shorts\r
- sub bx,DY12 ; PS,DY12\r
- inc di ; XS\r
-tri_rb_shorts:\r
- add di,XA12 ; XS,XA12\r
-\r
- push di ; XS\r
- push si ; XL\r
-tri_rb_start:\r
- cmp cx,Y2 ; Y,Y2\r
- jl short tri_rb_loop\r
-\r
-;------------------------------------\r
-; Draw the horizontal lines\r
-;\r
-\r
-\r
-tri_draw_lines:\r
-\r
- mov cx,SCREEN_SEG ;point ES to video segment\r
- mov es,cx\r
- mov dx,SC_INDEX ;set the Sequence Controller Index to\r
- mov al,MAP_MASK ; point to the Map Mask register\r
- out dx,al\r
-\r
-\r
-line_loop:\r
- pop ax\r
- pop dx\r
- cmp ax,dx\r
- jg tri_draw_next\r
- mov bx,Color\r
- mov cx,Y2\r
- add dx,2\r
- mov di,PageOffset\r
- call _HLineClipR\r
-tri_draw_next:\r
- dec word ptr Y2\r
- dec word ptr DY02\r
- jnz line_loop\r
-\r
-tri_done:\r
- pop di si es ds\r
- mov sp,bp\r
- pop bp\r
- ret\r
-_x_triangle endp\r
-\r
-;-----------------------------------------------------------------------\r
-; void x_polygon( VERTEX vertices[], int num_vertices,unsigned Color,\r
-; unsigned PageOffset );\r
-;\r
-; Where VERTEX is defined as:\r
-;\r
-; typedef struct {\r
-; int X;\r
-; int Y;\r
-; } far VERTEX;\r
-;\r
-;\r
-; Written by T. Gouthas\r
-;\r
-;\r
-;\r
-; Note: This is just a quick hack of a generalized polygon routine.\r
-; The way it works is by splitting up polygons into triangles and\r
-; drawing each individual triangle.\r
-;\r
-; Obviously this is not as fast as it could be, but for polygons of\r
-; 4 vertices it should perform quite respectably.\r
-;\r
-; Warning: Only works for convex polygons (convex polygons are such\r
-; that if you draw a line from any two vertices, every point on that\r
-; line will be within the polygon)\r
-;\r
-;\r
-\r
-_x_polygon proc\r
- ARG vertices:dword,numvertices:word,Color:word,PageOffset:word\r
- LOCAL x0:word,y0:word,tri_count:word=STK\r
- push bp\r
- mov bp,sp\r
- sub sp,STK\r
- push di si\r
-\r
- mov cx,numvertices\r
- cmp cx,3\r
- jl @@Done\r
-\r
- sub cx,3\r
- mov tri_count,cx ; Number of triangles to draw\r
- les di,vertices ; ES:DI -> Vertices\r
-\r
- mov ax,es:[di] ; Save first vertex\r
- mov x0,ax\r
- mov ax,es:[di+2]\r
- mov y0,ax\r
-\r
- ; Set up permanent parameter stack frame for\r
- ; triangle parameters\r
-\r
- mov ax,PageOffset\r
- push ax\r
- mov ax,Color\r
- push ax\r
-\r
- sub sp,12\r
- mov si,sp\r
-\r
-@@NextTriangle:\r
-\r
- add di,4\r
- mov ax,es:[di] ; Vertex 2\r
- mov ss:[si],ax\r
- mov ax,es:[di+2]\r
- mov ss:[si+2],ax\r
-\r
- mov ax,es:[di+4] ; Vertex 1\r
- mov ss:[si+4],ax\r
- mov ax,es:[di+6]\r
- mov ss:[si+6],ax\r
-\r
- mov ax,x0 ; Vertex 0: The first vertex is\r
- mov ss:[si+8],ax ; part of every triangle\r
- mov ax,y0\r
- mov ss:[si+10],ax\r
-\r
- call _x_triangle\r
- dec tri_count\r
- jns @@NextTriangle\r
-\r
- add sp,16 ; Remove triangle stack frame\r
-\r
-@@Done:\r
- pop si di\r
- mov sp,bp\r
- pop bp\r
- ret\r
-_x_polygon endp\r
- end
\ No newline at end of file
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XPOLYGON - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;----------------------------------------------------------------------*/\r
-\r
-#ifndef _XPOLYGON_H_\r
-#define _XPOLYGON_H_\r
-\r
-\r
-typedef struct {\r
- int X;\r
- int Y;\r
-} far VERTEX;\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-void x_triangle( /* Draw a triangle */\r
- int x0,\r
- int y0,\r
- int x1,\r
- int y1,\r
- int x2,\r
- int y2,\r
- WORD color,\r
- WORD PageBase);\r
-\r
-void x_polygon( /* Draw a convex polygon */\r
- VERTEX *vertices,\r
- int num_vertices,\r
- WORD color,\r
- WORD PageBase);\r
-\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif\r
-\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XPOLYGON - Include file\r
-;\r
-; XPOLYGON.ASM export functions\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
- global _x_triangle :proc\r
- global _x_polygon :proc\r
+++ /dev/null
-#include <stdarg.h>\r
-#include <string.h>\r
-#include "xlib.h"\r
-#include "xrect.h"\r
-#include "xtext.h"\r
-\r
-\r
-extern unsigned char CharWidth;\r
-extern unsigned char CharHeight;\r
-\r
-void x_printf(WORD x, WORD y,WORD ScrnOffs,WORD color,char *ln,...){\r
- char dlin[100],*dl=dlin;\r
- char ch;\r
- va_list ap;\r
-\r
- va_start(ap,ln);\r
- vsprintf(dlin,ln,ap);\r
- va_end(ap);\r
-\r
- while(*dl){\r
- x+=x_char_put(*dl++,x,y,ScrnOffs,color);\r
- }\r
-\r
-}\r
-\r
-void x_bgprintf(WORD x, WORD y,WORD ScrnOffs,WORD fgcolor,\r
- WORD bgcolor, char *ln,...){\r
- char dlin[100],*dl=dlin;\r
- char ch;\r
- va_list ap;\r
-\r
- va_start(ap,ln);\r
- vsprintf(dlin,ln,ap);\r
- va_end(ap);\r
-\r
- while(*dl){\r
- x_rect_fill(x,y,x+x_get_char_width(*dl),y+CharHeight,ScrnOffs,bgcolor);\r
- x+=x_char_put(*dl++,x,y,ScrnOffs,fgcolor);\r
- }\r
-\r
-}\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XRECT\r
-;\r
-; Rectangle functions all MODE X 256 Color resolutions\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
-include xlib.inc\r
-include xrect.inc\r
-\r
-\r
- .data\r
-; Plane masks for clipping left and right edges of rectangle.\r
- LeftClipPlaneMask db 00fh,00eh,00ch,008h\r
- RightClipPlaneMask db 00fh,001h,003h,007h\r
- .code\r
-\r
-;---------------------------------------------------------------------------\r
-; Mode X (320x240, 256 colors) rectangle solid colour fill routine.\r
-;\r
-; Based on code originally published in DDJ Mag by M. Abrash\r
-;\r
-; with TASM 2. C near-callable as:\r
-;\r
-; void x_rect_fill_clipped(int StartX, int StartY, int EndX, int EndY,\r
-; unsigned int PageBase, unsigne int color);\r
-;\r
-;\r
-\r
-\r
-_x_rect_fill_clipped proc\r
-ARG StartX:word,StartY:word,EndX:word,EndY:word,PageBase:word,Color:word\r
- push bp ;preserve caller's stack frame\r
- mov bp,sp ;point to local stack frame\r
- push si ;preserve caller's register variables\r
- push di\r
-\r
- mov dx,[_TopClip] ; Compare u.l. Y coord with Top\r
- mov cx,[_BottomClip]\r
- mov ax,[StartY]\r
- mov bx,[EndY]\r
- cmp dx,ax\r
- jle @@CheckBottomClip\r
- cmp dx,bx\r
- jg @@NotVisible\r
- mov [StartY],dx\r
-\r
-@@CheckBottomClip:\r
- cmp cx,bx\r
- jg @@CheckLeftClip\r
- cmp cx,ax\r
- jl @@NotVisible\r
- mov [EndY],cx\r
-\r
-@@CheckLeftClip:\r
- mov dx,[_LeftClip] ; Compare u.l. Y coord with Top\r
- mov cx,[_RightClip]\r
- mov ax,[StartX]\r
- mov bx,[EndX]\r
- sal dx,2\r
- sal cx,2\r
- cmp dx,ax\r
- jle @@CheckRightClip\r
- cmp dx,bx\r
- jg @@NotVisible\r
- mov [StartX],dx\r
-\r
-@@CheckRightClip:\r
- cmp cx,bx\r
- jg RFClipDone\r
- cmp cx,ax\r
- jl @@NotVisible\r
- mov [EndX],cx\r
- jmp RFClipDone\r
-\r
-@@NotVisible:\r
- mov ax,1\r
- pop di ; restore registers\r
- pop si\r
- pop bp\r
- ret\r
-_x_rect_fill_clipped endp\r
-\r
-\r
-\r
-;---------------------------------------------------------------------------\r
-; Mode X (320x240, 256 colors) rectangle solid colour fill routine.\r
-;\r
-; Based on code originally published in DDJ Mag by M. Abrash\r
-;\r
-; with TASM 2. C near-callable as:\r
-;\r
-; void x_rect_fill(int StartX, int StartY, int EndX, int EndY,\r
-; unsigned int PageBase, unsigne int color);\r
-;\r
-;\r
-\r
-\r
-_x_rect_fill proc\r
-ARG StartX:word,StartY:word,EndX:word,EndY:word,PageBase:word,Color:word\r
- push bp ;preserve caller's stack frame\r
- mov bp,sp ;point to local stack frame\r
- push si ;preserve caller's register variables\r
- push di\r
-\r
-RFClipDone:\r
- cld\r
- mov ax,[_ScrnLogicalByteWidth]\r
- mul [StartY] ;offset in page of top rectangle scan line\r
- mov di,[StartX]\r
- sar di,2 ;X/4 = offset of first rectangle pixel in scan\r
- add di,ax ;offset of first rectangle pixel in page\r
- add di,[PageBase] ;offset of first rectangle pixel in\r
- ; display memory\r
- mov ax,SCREEN_SEG ;point ES:DI to the first rectangle\r
- mov es,ax ; pixel's address\r
- mov dx,SC_INDEX ;set the Sequence Controller Index to\r
- mov al,MAP_MASK ; point to the Map Mask register\r
- out dx,al\r
- inc dx ;point DX to the SC Data register\r
- mov si,[StartX]\r
- and si,0003h ;look up left edge plane mask\r
- mov bh,LeftClipPlaneMask[si] ; to clip & put in BH\r
- mov si,[EndX]\r
- and si,0003h ;look up right edge plane\r
- mov bl,RightClipPlaneMask[si] ; mask to clip & put in BL\r
-\r
- mov cx,[EndX] ;calculate # of addresses across rect\r
- mov si,[StartX]\r
- cmp cx,si\r
- jle @@FillDone ;skip if 0 or negative width\r
- dec cx\r
- and si,not 011b\r
- sub cx,si\r
- sar cx,2 ;# of addresses across rectangle to fill - 1\r
- jnz @@MasksSet ;there's more than one byte to draw\r
- and bh,bl ;there's only one byte, so combine the left\r
- ; and right edge clip masks\r
-@@MasksSet:\r
- mov si,[EndY]\r
- sub si,[StartY] ;BX = height of rectangle\r
- jle @@FillDone ;skip if 0 or negative height\r
- mov ah,byte ptr [Color] ;color with which to fill\r
- mov bp,[_ScrnLogicalByteWidth] ;stack frame isn't needed any more\r
- sub bp,cx ;distance from end of one scan line to start\r
- dec bp ; of next\r
-@@FillRowsLoop:\r
- push cx ;remember width in addresses - 1\r
- mov al,bh ;put left-edge clip mask in AL\r
- out dx,al ;set the left-edge plane (clip) mask\r
- mov al,ah ;put color in AL\r
- stosb ;draw the left edge\r
- dec cx ;count off left edge byte\r
- js @@FillLoopBottom ;that's the only byte\r
- jz @@DoRightEdge ;there are only two bytes\r
- mov al,00fh ;middle addresses drawn 4 pixels at a pop\r
- out dx,al ;set the middle pixel mask to no clip\r
- mov al,ah ;put color in AL\r
- rep stosb ;draw middle addresses four pixels apiece\r
-@@DoRightEdge:\r
- mov al,bl ;put right-edge clip mask in AL\r
- out dx,al ;set the right-edge plane (clip) mask\r
- mov al,ah ;put color in AL\r
- stosb ;draw the right edge\r
-@@FillLoopBottom:\r
- add di,bp ;point to start of the next scan line of\r
- ; the rectangle\r
- pop cx ;retrieve width in addresses - 1\r
- dec si ;count down scan lines\r
- jnz @@FillRowsLoop\r
-@@FillDone:\r
- pop di ;restore caller's register variables\r
- pop si\r
- pop bp ;restore caller's stack frame\r
- ret\r
-_x_rect_fill endp\r
-\r
-\r
-\r
-;---------------------------------------------------------------------------\r
-; Mode X (320x240, 256 colors) rectangle 4x4 pattern fill routine.\r
-; Upper left corner of pattern is always aligned to a multiple-of-4\r
-; row and column. Works on all VGAs. Uses approach of copying the\r
-; pattern to off-screen display memory, then loading the latches with\r
-; the pattern for each scan line and filling each scan line four\r
-; pixels at a time. Fills up to but not including the column at EndX\r
-; and the row at EndY. No clipping is performed. All ASM code tested\r
-;\r
-;\r
-; Based on code originally published in DDJ Mag by M. Abrash\r
-;\r
-;\r
-; C near-callable as:\r
-;\r
-; void x_rect_pattern_clipped(int StartX, int StartY, int EndX, int EndY,\r
-; unsigned int PageBase, char far * Pattern);\r
-;\r
-;\r
-\r
-_x_rect_pattern_clipped proc\r
-ARG StartX:word,StartY:word,EndX:word,EndY:word,PageBase:word,Pattern:dword\r
-LOCAL NextScanOffset:word,RectAddrWidth:word,Height:word=LocalStk\r
- push bp ;preserve caller's stack frame\r
- mov bp,sp ;point to local stack frame\r
- sub sp,LocalStk ;allocate space for local vars\r
- push si ;preserve caller's register variables\r
- push di\r
- push ds\r
-\r
- mov dx,[_TopClip] ; Compare u.l. Y coord with Top\r
- mov cx,[_BottomClip]\r
- mov ax,[StartY]\r
- mov bx,[EndY]\r
- cmp dx,ax\r
- jle @@CheckBottomClip\r
- cmp dx,bx\r
- jg @@NotVisible\r
- mov [StartY],dx\r
-\r
-@@CheckBottomClip:\r
- cmp cx,bx\r
- jg @@CheckLeftClip\r
- cmp cx,ax\r
- jl @@NotVisible\r
- mov [EndY],cx\r
-\r
-@@CheckLeftClip:\r
- mov dx,[_LeftClip] ; Compare u.l. Y coord with Top\r
- mov cx,[_RightClip]\r
- mov ax,[StartX]\r
- mov bx,[EndX]\r
- sal dx,2\r
- sal cx,2\r
- cmp dx,ax\r
- jle @@CheckRightClip\r
- cmp dx,bx\r
- jg @@NotVisible\r
- mov [StartX],dx\r
-\r
-@@CheckRightClip:\r
- cmp cx,bx\r
- jg RPClipDone\r
- cmp cx,ax\r
- jl @@NotVisible\r
- mov [EndX],cx\r
- jmp RPClipDone\r
-\r
-@@NotVisible:\r
- mov ax,1\r
- pop ds\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp\r
- pop bp\r
- ret\r
-\r
-_x_rect_pattern_clipped endp\r
-\r
-;---------------------------------------------------------------------------\r
-; Mode X (320x240, 256 colors) rectangle 4x4 pattern fill routine.\r
-; Upper left corner of pattern is always aligned to a multiple-of-4\r
-; row and column. Works on all VGAs. Uses approach of copying the\r
-; pattern to off-screen display memory, then loading the latches with\r
-; the pattern for each scan line and filling each scan line four\r
-; pixels at a time. Fills up to but not including the column at EndX\r
-; and the row at EndY. No clipping is performed. All ASM code tested\r
-;\r
-;\r
-; Based on code originally published in DDJ Mag by M. Abrash\r
-;\r
-;\r
-; C near-callable as:\r
-;\r
-; void x_rect_pattern(int StartX, int StartY, int EndX, int EndY,\r
-; unsigned int PageBase, char far * Pattern);\r
-\r
-\r
-\r
-_x_rect_pattern proc\r
-ARG StartX:word,StartY:word,EndX:word,EndY:word,PageBase:word,Pattern:dword\r
-LOCAL NextScanOffset:word,RectAddrWidth:word,Height:word=LocalStk\r
- push bp ;preserve caller's stack frame\r
- mov bp,sp ;point to local stack frame\r
- sub sp,LocalStk ;allocate space for local vars\r
- push si ;preserve caller's register variables\r
- push di\r
- push ds\r
-\r
-RPClipDone:\r
- cld\r
- mov ax,SCREEN_SEG ;point ES to display memory\r
- mov es,ax\r
- ;copy pattern to display memory buffer\r
- lds si,dword ptr [Pattern] ;point to pattern to fill with\r
- mov di,PATTERN_BUFFER ;point ES:DI to pattern buffer\r
- mov dx,SC_INDEX ;point Sequence Controller Index to\r
- mov al,MAP_MASK ; Map Mask\r
- out dx,al\r
- inc dx ;point to SC Data register\r
- mov cx,4 ;4 pixel quadruplets in pattern\r
-@@DownloadPatternLoop:\r
- mov al,1 ;\r
- out dx,al ;select plane 0 for writes\r
- movsb ;copy over next plane 0 pattern pixel\r
- dec di ;stay at same address for next plane\r
- mov al,2 ;\r
- out dx,al ;select plane 1 for writes\r
- movsb ;copy over next plane 1 pattern pixel\r
- dec di ;stay at same address for next plane\r
- mov al,4 ;\r
- out dx,al ;select plane 2 for writes\r
- movsb ;copy over next plane 2 pattern pixel\r
- dec di ;stay at same address for next plane\r
- mov al,8 ;\r
- out dx,al ;select plane 3 for writes\r
- movsb ;copy over next plane 3 pattern pixel\r
- ; and advance address\r
- loop @@DownloadPatternLoop\r
- pop ds\r
-\r
- mov dx,GC_INDEX ;set the bit mask to select all bits\r
- mov ax,00000h+BIT_MASK ; from the latches and none from\r
- out dx,ax ; the CPU, so that we can write the\r
- ; latch contents directly to memory\r
- mov ax,[StartY] ;top rectangle scan line\r
- mov si,ax\r
- and si,011b ;top rect scan line modulo 4\r
- add si,PATTERN_BUFFER ;point to pattern scan line that\r
- ; maps to top line of rect to draw\r
- mov dx,[_ScrnLogicalByteWidth]\r
- mul dx ;offset in page of top rect scan line\r
- mov di,[StartX]\r
- mov bx,di\r
- sar di,2 ;X/4 = offset of first rectangle pixel in scan\r
- add di,ax ;offset of first rectangle pixel in page\r
- add di,[PageBase] ;offset of first rectangle pixel in\r
- ; display memory\r
- and bx,0003h ;look up left edge plane mask\r
- mov ah,LeftClipPlaneMask[bx] ; to clip\r
- mov bx,[EndX]\r
- and bx,0003h ;look up right edge plane\r
- mov al,RightClipPlaneMask[bx] ; mask to clip\r
- mov bx,ax ;put the masks in BX\r
-\r
- mov cx,[EndX] ;calculate # of addresses across rect\r
- mov ax,[StartX]\r
- cmp cx,ax\r
- jle @@FillDone ;skip if 0 or negative width\r
- dec cx\r
- and ax,not 011b\r
- sub cx,ax\r
- sar cx,2 ;# of addresses across rectangle to fill - 1\r
- jnz @@MasksSet ;there's more than one pixel to draw\r
- and bh,bl ;there's only one pixel, so combine the left\r
- ; and right edge clip masks\r
-@@MasksSet:\r
- mov ax,[EndY]\r
- sub ax,[StartY] ;AX = height of rectangle\r
- jle @@FillDone ;skip if 0 or negative height\r
- mov [Height],ax\r
- mov ax,[_ScrnLogicalByteWidth]\r
- sub ax,cx ;distance from end of one scan line to start\r
- dec ax ; of next\r
- mov [NextScanOffset],ax\r
- mov [RectAddrWidth],cx ;remember width in addresses - 1\r
- mov dx,SC_INDEX+1 ;point to Sequence Controller Data reg\r
- ; (SC Index still points to Map Mask)\r
-@@FillRowsLoop:\r
- mov cx,[RectAddrWidth] ;width across - 1\r
- mov al,es:[si] ;read display memory to latch this scan\r
- ; line's pattern\r
- inc si ;point to the next pattern scan line, wrapping\r
- jnz short @@NoWrap ; back to the start of the pattern if\r
- sub si,4 ; we've run off the end\r
-@@NoWrap:\r
- mov al,bh ;put left-edge clip mask in AL\r
- out dx,al ;set the left-edge plane (clip) mask\r
- stosb ;draw the left edge (pixels come from latches;\r
- ; value written by CPU doesn't matter)\r
- dec cx ;count off left edge address\r
- js @@FillLoopBottom ;that's the only address\r
- jz @@DoRightEdge ;there are only two addresses\r
- mov al,00fh ;middle addresses drawn 4 pixels at a pop\r
- out dx,al ;set middle pixel mask to no clip\r
- rep stosb ;draw middle addresses four pixels apiece\r
- ; (from latches; value written doesn't matter)\r
-@@DoRightEdge:\r
- mov al,bl ;put right-edge clip mask in AL\r
- out dx,al ;set the right-edge plane (clip) mask\r
- stosb ;draw the right edge (from latches; value\r
- ; written doesn't matter)\r
-@@FillLoopBottom:\r
- add di,[NextScanOffset] ;point to the start of the next scan\r
- ; line of the rectangle\r
- dec word ptr [Height] ;count down scan lines\r
- jnz @@FillRowsLoop\r
-@@FillDone:\r
- mov dx,GC_INDEX+1 ;restore the bit mask to its default,\r
- mov al,0ffh ; which selects all bits from the CPU\r
- out dx,al ; and none from the latches (the GC\r
- ; Index still points to Bit Mask)\r
-\r
- pop di ;restore caller's register variables\r
- pop si\r
- mov sp,bp ;discard storage for local variables\r
- pop bp ;restore caller's stack frame\r
- ret\r
-_x_rect_pattern endp\r
-\r
-;-----------------------------------------------------------------------\r
-; Mode X (320x240, 256 colors) display memory to display memory copy\r
-; routine. Left edge of source rectangle modulo 4 must equal left edge\r
-; of destination rectangle modulo 4. Works on all VGAs. Uses approach\r
-; of reading 4 pixels at a time from the source into the latches, then\r
-; writing the latches to the destination. Copies up to but not\r
-; including the column at SrcEndX and the row at SrcEndY. No\r
-; clipping is performed. Results are not guaranteed if the source and\r
-; destination overlap.\r
-;\r
-;\r
-; Based on code originally published in DDJ Mag by M. Abrash\r
-;\r
-;C near-callable as:\r
-; void x_cp_vid_rect(int SrcStartX, int SrcStartY,\r
-; int SrcEndX, int SrcEndY, int DestStartX,\r
-; int DestStartY, unsigned int SrcPageBase,\r
-; unsigned int DestPageBase, int SrcBitmapWidth,\r
-; int DestBitmapWidth);\r
-\r
-_x_cp_vid_rect proc\r
- ARG SrcStartX:word,SrcStartY:word,SrcEndX:word,SrcEndY:word,DestStartX:word,DestStartY:word,SrcPageBase:word,DestPageBase:word,SrcBitmapW:word,DestBitmapW:word\r
- LOCAL SrcNextOffs:word,DestNextOffs:word,RectAddrW:word,Height:word=LocalStk\r
- push bp ;preserve caller's stack frame\r
- mov bp,sp ;point to local stack frame\r
- sub sp,LocalStk ;allocate space for local vars\r
- push si ;preserve caller's register variables\r
- push di\r
- push ds\r
-\r
- cld\r
- mov dx,GC_INDEX ;set the bit mask to select all bits\r
- mov ax,00000h+BIT_MASK ; from the latches and none from\r
- out dx,ax ; the CPU, so that we can write the\r
- ; latch contents directly to memory\r
- mov ax,SCREEN_SEG ;point ES to display memory\r
- mov es,ax\r
- mov ax,[DestBitmapW]\r
- shr ax,2 ;convert to width in addresses\r
- mul [DestStartY] ;top dest rect scan line\r
- mov di,[DestStartX]\r
- sar di,2 ;X/4 = offset of first dest rect pixel in\r
- ; scan line\r
- add di,ax ;offset of first dest rect pixel in page\r
- add di,[DestPageBase] ;offset of first dest rect pixel\r
- ; in display memory\r
- mov ax,[SrcBitmapW]\r
- sar ax,2 ;convert to width in addresses\r
- mul [SrcStartY] ;top source rect scan line\r
- mov si,[SrcStartX]\r
- mov bx,si\r
- sar si,2 ;X/4 = offset of first source rect pixel in\r
- ; scan line\r
- add si,ax ;offset of first source rect pixel in page\r
- add si,[SrcPageBase] ;offset of first source rect\r
- ; pixel in display memory\r
- and bx,0003h ;look up left edge plane mask\r
- mov ah,LeftClipPlaneMask[bx] ; to clip\r
- mov bx,[SrcEndX]\r
- and bx,0003h ;look up right edge plane\r
- mov al,RightClipPlaneMask[bx] ; mask to clip\r
- mov bx,ax ;put the masks in BX\r
-\r
- mov cx,[SrcEndX] ;calculate # of addresses across\r
- mov ax,[SrcStartX] ; rect\r
- cmp cx,ax\r
- jle @@CopyDone ;skip if 0 or negative width\r
- dec cx\r
- and ax,not 011b\r
- sub cx,ax\r
- sar cx,2 ;# of addresses across rectangle to copy - 1\r
- jnz @@MasksSet ;there's more than one address to draw\r
- and bh,bl ;there's only one address, so combine the left\r
- ; and right edge clip masks\r
-@@MasksSet:\r
- mov ax,[SrcEndY]\r
- sub ax,[SrcStartY] ;AX = height of rectangle\r
- jle @@CopyDone ;skip if 0 or negative height\r
- mov [Height],ax\r
- mov ax,[DestBitmapW]\r
- sar ax,2 ;convert to width in addresses\r
- sub ax,cx ;distance from end of one dest scan line\r
- dec ax ; to start of next\r
- mov [DestNextOffs],ax\r
- mov ax,[SrcBitmapW]\r
- sar ax,2 ;convert to width in addresses\r
- sub ax,cx ;distance from end of one source scan line\r
- dec ax ; to start of next\r
- mov [SrcNextOffs],ax\r
- mov [RectAddrW],cx ;remember width in addresses - 1\r
- mov dx,SC_INDEX+1 ;point to Sequence Controller Data reg\r
- ; (SC Index still points to Map Mask)\r
- mov ax,es ;DS=ES=screen segment for MOVS\r
- mov ds,ax\r
-@@CopyRowsLoop:\r
- mov cx,[RectAddrW] ;width across - 1\r
- mov al,bh ;put left-edge clip mask in AL\r
- out dx,al ;set the left-edge plane (clip) mask\r
- movsb ;copy the left edge (pixels go through\r
- ; latches)\r
- dec cx ;count off left edge address\r
- js @@CopyLoopBottom ;that's the only address\r
- jz @@DoRightEdge ;there are only two addresses\r
- mov al,00fh ;middle addresses are drawn 4 pix per go\r
- out dx,al ;set the middle pixel mask to no clip\r
- rep movsb ;draw the middle addresses four pix per go\r
- ; (pixels copied through latches)\r
-@@DoRightEdge:\r
- mov al,bl ;put right-edge clip mask in AL\r
- out dx,al ;set the right-edge plane (clip) mask\r
- movsb ;draw the right edge (pixels copied through\r
- ; latches)\r
-@@CopyLoopBottom:\r
- add si,[SrcNextOffs] ;point to the start of\r
- add di,[DestNextOffs] ; next source & dest lines\r
- dec word ptr [Height] ;count down scan lines\r
- jnz @@CopyRowsLoop\r
-@@CopyDone:\r
- mov dx,GC_INDEX+1 ;restore the bit mask to its default,\r
- mov al,0ffh ; which selects all bits from the CPU\r
- out dx,al ; and none from the latches (the GC\r
- ; Index still points to Bit Mask)\r
- pop ds\r
- pop di ;restore caller's register variables\r
- pop si\r
- mov sp,bp ;discard storage for local variables\r
- pop bp ;restore caller's stack frame\r
- ret\r
-_x_cp_vid_rect endp\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-; Copy a rectangular region of a VGA screen, with x coordinates\r
-; rounded to the nearest byte -- source and destination may overlap.\r
-;\r
-; C near-callable as:\r
-;\r
-; void x_shift_rect (WORD SrcLeft, WORD SrcTop,\r
-; WORD SrcRight, WORD SrcBottom,\r
-; WORD DestLeft, WORD DestTop, WORD ScreenOffs);\r
-;\r
-; SrcRight is rounded up, and the left edges are rounded down, to ensure\r
-; that the pixels pointed to by the arguments are inside the rectangle.\r
-;\r
-; The width of the rectangle in bytes (width in pixels / 4)\r
-; cannot exceed 255.\r
-;\r
-; ax, bx, cx, dx, and es eat hot lead.\r
-;\r
-; This function was written by Matthew MacKenzie\r
-; matm@eng.umd.edu\r
-\r
- align 2\r
-_x_shift_rect proc\r
-ARG SrcLeft,SrcTop,SrcRight,SrcBottom,DestLeft,DestTop,ScreenOffs:word\r
-LOCAL width_temp:word=LocalStk\r
-\r
- push bp\r
- mov bp, sp\r
- sub sp, LocalStk\r
- push si\r
- push di\r
- push ds\r
-\r
- ; find values for width & x motion\r
- mov si, SrcLeft ; source x in bytes\r
- sar si, 2\r
-\r
- mov di, DestLeft ; destination x in bytes\r
- sar di, 2\r
-\r
- mov bx, SrcRight ; right edge of source in bytes, rounded up\r
- add bx, 3\r
- sar bx, 2\r
- sub bx, si\r
- mov ax, bx ; width - 1\r
- inc bx ; we'll use this as an offset for moving up or down\r
- mov width_temp, bx\r
-\r
- cld ; by default, strings increment\r
-\r
- cmp si, di\r
- jge @@MovingLeft\r
-\r
-; we're moving our rectangle right, so we copy it from right to left\r
- add si, ax ; source & destination will start on the right edge\r
- add di, ax\r
- neg bx\r
- std ; strings decrement\r
-\r
-@@MovingLeft:\r
-\r
-; find values for height & y motion\r
- mov cx, _ScrnLogicalByteWidth ; bytes to move to advance one line\r
- mov ax, SrcTop\r
- mov dx, DestTop ; default destination y\r
- cmp ax, dx\r
- jge @@MovingUp\r
-\r
-; we're moving our rectangle down, so we copy it from bottom to top\r
- mov ax, SrcBottom ; source starts at bottom\r
- add dx, ax ; add (height - 1) to destination y\r
- sub dx, SrcTop\r
- neg cx ; advance up screen rather than down\r
-\r
-@@MovingUp:\r
- push dx ; save destination y during multiply\r
- mul _ScrnLogicalByteWidth\r
- add si, ax ; add y in bytes to source\r
- pop ax ; restore destination y\r
- mul _ScrnLogicalByteWidth\r
- add di, ax ; add y in bytes to destination\r
-\r
- sub cx, bx ; final value for moving up or down\r
-\r
- add si, ScreenOffs ; source & destination are on the same screen\r
- add di, ScreenOffs\r
-\r
- mov dx, SC_INDEX ; set map mask to all four planes\r
- mov ax, 00f02h\r
- out dx, ax\r
-\r
- mov dx, GC_INDEX ; set bit mask to take data from latches\r
- mov ax, BIT_MASK ; rather than CPU\r
- out dx, ax\r
-\r
- mov ax, SCREEN_SEG ; source and destination are VGA memory\r
- mov es, ax\r
- mov ds, ax\r
-\r
- mov ah, byte ptr width_temp ; width in bytes should fit in 8 bits\r
-\r
- mov bx, SrcBottom ; height - 1\r
- sub bx, SrcTop\r
-\r
- mov dx, cx ; bytes to add to advance one line\r
-\r
- xor ch, ch ; ready to rock\r
-\r
-@@LineLoop:\r
- mov cl, ah ; load width in bytes\r
- rep movsb ; move 4 pixels at a time using latches (YOW!)\r
-\r
- add si, dx ; advance source by one line\r
- add di, dx ; advance destination by one line\r
-\r
- dec bx ; line counter\r
- jge @@LineLoop ; 0 still means one more to go\r
-\r
- mov dx, GC_INDEX + 1; set bit mask to take data from CPU (normal setting)\r
- mov al, 0ffh\r
- out dx, al\r
-\r
-; kick\r
- pop ds\r
- pop di\r
- pop si\r
- mov sp, bp\r
- pop bp\r
-\r
- ret\r
-_x_shift_rect endp\r
-\r
- end\r
-\r
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XRECT - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;-----------------------------------------------------------------------*/\r
-\r
-#ifndef _XRECT_H_\r
-#define _XRECT_H_\r
-\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
- void x_rect_pattern( /* draw a pattern filled rectangle */\r
- WORD StartX,\r
- WORD StartY,\r
- WORD EndX,\r
- WORD EndY,\r
- WORD PageBase,\r
- BYTE far * Pattern);\r
-\r
- void x_rect_pattern_clipped( /* draw a pattern filled clipped */\r
- WORD StartX, /* rectangle */\r
- WORD StartY,\r
- WORD EndX,\r
- WORD EndY,\r
- WORD PageBase,\r
- BYTE far * Pattern);\r
-\r
- void x_rect_fill( /* draw a single colour filled rectangle */\r
- WORD StartX,\r
- WORD StartY,\r
- WORD EndX,\r
- WORD EndY,\r
- WORD PageBase,\r
- WORD color);\r
-\r
- void x_rect_fill_clipped( /* draw a single colour filled */\r
- WORD StartX, /* and clipped rectangle */\r
- WORD StartY,\r
- WORD EndX,\r
- WORD EndY,\r
- WORD PageBase,\r
- WORD color);\r
-\r
- void x_cp_vid_rect( /* Copy rect region within VRAM */\r
- WORD SourceStartX,\r
- WORD SourceStartY,\r
- WORD SourceEndX,\r
- WORD SourceEndY,\r
- WORD DestStartX,\r
- WORD DestStartY,\r
- WORD SourcePageBase,\r
- WORD DestPageBase,\r
- WORD SourceBitmapWidth,\r
- WORD DestBitmapWidth);\r
-\r
-/* Copy a rectangular region of a VGA screen, with x coordinates\r
- rounded to the nearest byte -- source and destination may overlap. */\r
-\r
- void x_shift_rect (WORD SrcLeft, WORD SrcTop,\r
- WORD SrcRight, WORD SrcBottom,\r
- WORD DestLeft, WORD DestTop, WORD ScreenOffs);\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-\r
-#endif\r
-\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XRECT - Include file\r
-;\r
-; XRECT.ASM export functions\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
- global _x_rect_fill :proc\r
- global _x_rect_fill_clipped :proc\r
- global _x_rect_pattern :proc\r
- global _x_rect_pattern_clipped :proc\r
- global _x_cp_vid_rect :proc\r
- global _x_shift_rect :proc\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XRLETOOL\r
-;\r
-; Hardware detection module\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-COMMENT $\r
-\r
-Firstly, please note that this module has been built from the ground up\r
-in a rush so although I'm confident all the functions work, I have'nt\r
-extensively checked them. If any should surface please let me know.\r
-\r
-\r
-This module implements a number of functions comprising an RLE encoding\r
-decoding system.\r
-\r
-RLE stands for RUN LENGTH ENCODING. It is a quick simple data compression\r
-scheme which is commonly used for image data compression or compression\r
-of any data. Although not the most efficient system, it is fast, which is\r
-why it is used in image storage systems like PCX. This implementation is\r
-more efficient than the one used in PCX files because it uses 1 bit to\r
-identify a Run Length byte as opposed to two in PCX files, but more on this\r
-later.\r
-\r
-This set of functions can be used to implement your own compressed image\r
-file format or for example compress game mapse for various levels etc.\r
-The uses are limited by your imagination.\r
-\r
-I opted for trading off PCX RLE compatibility for the improved compression\r
-efficiency.\r
-\r
-Here is how the data is un-compressed to give an idea of its structure.\r
-\r
-\r
-STEP 1 read a byte from the RLE compressed source buffer.\r
-\r
-STEP 2 if has its high bit then the lower 7 bits represent the number of\r
- times the next byte is to be repeated in the destination buffer.\r
- if the count (lower 7 bits) is zero then\r
- we have finished decoding goto STEP 5\r
- else goto STEP 4\r
-\r
-STEP 3 Read a data from the source buffer and copy it directly to the\r
- destination buffer.\r
- goto STEP 1\r
-\r
-STEP 4 Read a data from the source buffer and copy it to the destination\r
- buffer the number of times specified by step 2.\r
- goto STEP 1\r
-\r
-STEP 5 Stop, decoding done.\r
-\r
-If the byte does not have the high bit set then the byte itself is transfered\r
- to the destination buffer.\r
-\r
-Data bytes that have the high bit already set and are unique in the input\r
- stream are represented as a Run Length of 1 (ie 81 which includes high bit)\r
- followed by the data byte.\r
-\r
-If your original uncompressed data contains few consecutive bytes and most\r
-have high bit set (ie have values > 127) then your so called\r
-compressed data would require up to 2x the space of the uncompressed data,\r
-so be aware that the compression ratio is extremely variable depending on the\r
-type of data being compressed.\r
-\r
-Apologies for this poor attempt at a description, but you can look up\r
-RLE in any good text. Alternatively, any text that describes the PCX file\r
-structure in any depth should have a section on RLE compression.\r
-\r
-\r
-\r
-$\r
-\r
-LOCALS\r
-.286\r
-\r
-include model.inc\r
-include xrletool.inc\r
-\r
- .data\r
-\r
-_RLE_last_buff_offs dw (0)\r
-RLEbuff db 2 dup (?)\r
-\r
- .code\r
-\r
-;****************************************************************\r
-;*\r
-;* NAME: x_buff_RLEncode\r
-;*\r
-;*\r
-;* RLE Compresses a source buffer to a destination buffer and returns\r
-;* the size of the resultant compressed data.\r
-;*\r
-;* C PROTOTYPE:\r
-;*\r
-;* extern unsigned int x_buff_RLEncode(char far * source_buff,\r
-;* char far * dest_buff,unsigned int count);\r
-;*\r
-;* source_buff - The buffer to compress\r
-;* dest_buff - The destination buffer\r
-;* count - The size of the source data in bytes\r
-;*\r
-;* WARNING: buffers must be pre allocated.\r
-;*\r
-proc _x_buff_RLEncode\r
-ARG src:dword,dest:dword,count:word\r
- push bp\r
- mov bp,sp\r
- push ds\r
- push si\r
- push di\r
-\r
- lds si,[src]\r
- les di,[dest]\r
- mov dx,[count]\r
-\r
- push di\r
-\r
- lodsb ; Load first byte into BL\r
- mov bl,al\r
- xor cx,cx ; Set number characters packed to zero\r
- cld ; All moves are forward\r
-\r
-@@RepeatByte:\r
- lodsb ; Get byte into AL\r
- inc cx ; Increment compressed byte count\r
- sub dx,1 ; Decrement bytes left\r
- je @@LastByte ; Finished when dx = 1\r
- cmp cx,7fh ; Filled block yet\r
- jne @@NotFilled ; Nope!\r
-\r
- or cl,80h ; Set bit to indicate value is repeat count\r
- mov es:[di],cl ; store it\r
- inc di\r
- xor cx,cx ; clear compressed byte count\r
- mov es:[di],bl ; store byte to be repeated\r
- inc di\r
-\r
-@@NotFilled:\r
- cmp al,bl ; hase there been a byte transition ?\r
- je @@RepeatByte ; No!\r
-\r
- cmp cl,1 ; do we have a unique byte ?\r
- jne @@NotUnique ; No\r
-\r
- test bl,80h ; Can this byte be mistaken for repeat count\r
- jz @@Unambiguous ; No ! Dont bother with repeat count\r
-\r
-@@NotUnique:\r
- or cl,80h ; Set bit to indicate value is repeat count\r
- mov es:[di],cl ; store it\r
- inc di\r
-@@Unambiguous:\r
- xor cx,cx ; clear compressed byte count\r
- mov es:[di],bl ; store byte to be repeated\r
- inc di\r
- mov bl,al ; move latest byte into bl\r
- jmp short @@RepeatByte\r
-\r
-@@LastByte:\r
- cmp cl,1 ; Is this a unique byte\r
- jne @@FinalCount ; No\r
-\r
- test bl,80h ; Can this byte be mistaken for repeat count\r
- jz @@FinalByte ; No, so dont bother with the repeat count\r
-\r
-@@FinalCount: ; Output the repeat count\r
- or cl,80h\r
- mov al,cl\r
- stosb\r
-\r
-@@FinalByte:\r
- mov al,bl\r
- stosb\r
-\r
- mov al,80h ; store terminating null length\r
- stosb\r
-\r
- ; Calculate encoded length of buffer\r
-\r
- mov ax,di\r
- pop di\r
- sub ax,di\r
-\r
- pop di\r
- pop si\r
- pop ds\r
- pop bp\r
- ret\r
-_x_buff_RLEncode endp\r
-\r
-\r
-\r
-;****************************************************************\r
-;*\r
-;* NAME: x_buff_RLE_size\r
-;*\r
-;*\r
-;* Returns the size the input data would compress to.\r
-;*\r
-;* C PROTOTYPE:\r
-;*\r
-;* extern unsigned int x_buff_RLE_size(char far * source_buff,\r
-;* unsigned int count);\r
-;*\r
-;* source_buff - The uncompressed data buffer\r
-;* count - The size of the source data in bytes\r
-;*\r
-;*\r
-proc _x_buff_RLE_size\r
-ARG src:dword,count:word\r
- push bp\r
- mov bp,sp\r
- push ds\r
- push si\r
- push di\r
-\r
- lds si,[src]\r
- mov dx,[count]\r
-\r
- xor di,di\r
-\r
- lodsb ; Load first byte into BL\r
- mov bl,al\r
- xor cx,cx ; Set number characters packed to zero\r
- cld ; All moves are forward\r
-\r
-@@RepeatByte:\r
- lodsb ; Get byte into AL\r
- inc cx ; Increment compressed byte count\r
- sub dx,1 ; Decrement bytes left\r
- je @@LastByte ; Finished when dx = 1\r
- cmp cx,7fh ; Filled block yet\r
- jne @@NotFilled ; Nope!\r
-\r
- add di,2 ; RL/BYTE pair stub\r
-\r
-@@NotFilled:\r
- cmp al,bl ; hase there been a byte transition ?\r
- je @@RepeatByte ; No!\r
-\r
- cmp cl,1 ; do we have a unique byte ?\r
- jne @@NotUnique ; No\r
-\r
- test bl,80h ; Can this byte be mistaken for repeat count\r
- jz @@Unambiguous ; No ! Dont bother with repeat count\r
-\r
-@@NotUnique:\r
- inc di ; RL stub\r
-\r
-@@Unambiguous:\r
- xor cx,cx ; clear compressed byte count\r
- inc di ; BYTE stub\r
- mov bl,al ; move latest byte into bl\r
- jmp short @@RepeatByte\r
-\r
-@@LastByte:\r
- cmp cl,1 ; Is this a unique byte\r
- jne @@FinalCount ; No\r
-\r
- test bl,80h ; Can this byte be mistaken for repeat count\r
- jz @@FinalByte ; No, so dont bother with the repeat count\r
-\r
-@@FinalCount: ; Output the repeat count\r
- inc di ; RL stub\r
-\r
-@@FinalByte:\r
- inc di ; BYTE stub\r
- inc di ; RL stub - Account for termiating null\r
- mov ax,di\r
-\r
- pop di\r
- pop si\r
- pop ds\r
- pop bp\r
- ret\r
-_x_buff_RLE_size endp\r
-\r
-;****************************************************************\r
-;*\r
-;* NAME: x_buff_RLDecode\r
-;*\r
-;*\r
-;* Expands an RLE compresses source buffer to a destination buffer.\r
-;* returns the size of the resultant uncompressed data.\r
-;*\r
-;* C PROTOTYPE:\r
-;*\r
-;* extern unsigned int x_buff_RLDecode(char far * source_buff,\r
-;* char far * dest_buff);\r
-;*\r
-;* source_buff - The buffer to compress\r
-;* dest_buff - The destination buffer\r
-;*\r
-;* WARNING: buffers must be pre allocated.\r
-;*\r
-proc _x_buff_RLDecode\r
-ARG src:dword,dest:dword\r
-LOCAL si_ini:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk\r
- push ds\r
- push si\r
- push di\r
-\r
- mov dx,-1 ; zero output data buffer size - 1 (compensate for\r
- ; terminating null RL)\r
- xor cx,cx ; clear CX\r
- cld ; Move forward\r
-\r
- lds si,[src] ; point ds:si -> RLE source\r
- les di,[dest] ; point es:di -> uncompressed buffer\r
- mov [si_ini],si\r
-\r
-@@UnpackLoop:\r
- lodsb ; load a byte into AL\r
- cmp al,80h ; is it terminating null RL code\r
- je @@done ; if so jump\r
-\r
- test al,80h ; is AL a RL code (is high bit set ?)\r
- jz @@NoRepeats ; if not the no RL encoding for this byte, jump\r
-\r
- mov cl,al ; set CL to RL (run length) taking care\r
- xor cl,80h ; to remove the bit identifying it as a RL\r
- add dx,cx ; increment buffer size\r
-\r
- lodsb ; get the next byte which should be a data byte\r
-\r
- shr cx,1 ; divide RL by 2 to use word stos\r
- jcxz @@NoRepeats ; result is zero, jump\r
-\r
- mov ah,al ; copy data byte to AH since going to use stosw\r
- rep stosw ; copy AX to outbut buffer RL times\r
- jnb @@UnpackLoop ; when we shifted the RL if we had a carry =>\r
- ; we had an odd number of repeats so store the\r
- ; last BYTE if carry was set otherwise jump\r
- stosb ; store AL in destination buffer\r
- jmp short @@UnpackLoop\r
-\r
-@@NoRepeats:\r
- inc dx ; increment buffer size\r
- stosb ; store AL in destination buffer\r
- jmp short @@UnpackLoop\r
-\r
-@@done:\r
-\r
- mov bx,si\r
- sub bx,[si_ini]\r
- mov ax,dx\r
- pop di\r
- pop si\r
- pop ds\r
- mov [_RLE_last_buff_offs],bx\r
- mov sp,bp\r
- pop bp\r
- ret\r
-_x_buff_RLDecode endp\r
-\r
-;==========================================================================\r
-;==========================================================================\r
-; RLEncode to file / RLDecode from file\r
-; WARNING the following functions are *MUCH* slower than the above\r
-; Its best to use the above functions with intermediate buffers where\r
-; disk i/o is concearned... See demo 4\r
-;==========================================================================\r
-;==========================================================================\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-;\r
-; put_cx\r
-;\r
-; Local utility proc for x_file_RLEncode - write cx to file\r
-;\r
-; Entry:\r
-; es:dx -> output buffer\r
-; cx = word to write\r
-;\r
-;\r
-put_cx proc near\r
- push ds ; preserve critical registers\r
- push ax\r
- push bx\r
- mov ax,ds ; set up DS to output buffers segment\r
- mov ds,ax\r
- mov word ptr [RLEbuff],cx ; copy CX to output buffer\r
- mov ah,40h ; select "write to file or device" DOS service\r
- mov bx,[handle] ; select handle of file to write\r
- mov cx,2 ; sending 2 bytes\r
- int 21h ; call DOS service\r
- pop bx ; recover registers\r
- pop ax\r
- pop ds\r
- ret\r
-put_cx endp\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-;\r
-; put_cx\r
-;\r
-; Local utility proc for x_file_RLEncode - write cx to file\r
-;\r
-; Entry:\r
-; es:dx -> output buffer\r
-; cx = word to write\r
-;\r
-;\r
-put_cl proc near\r
- push ds ; preserve critical registers\r
- push ax\r
- push bx\r
- mov ax,ds ; set up DS to output buffers segment\r
- mov ds,ax\r
- mov byte ptr [RLEbuff],cl\r
- mov ah,40h ; select "write to file or device" DOS service\r
- mov bx,[handle] ; select handle of file to write\r
- mov cx,1 ; sending 1 byte\r
- int 21h ; call DOS service\r
- pop bx ; recover registers\r
- pop ax\r
- pop ds\r
- ret\r
-put_cl endp\r
-\r
-\r
-;****************************************************************\r
-;*\r
-;* NAME: x_file_RLEncode\r
-;*\r
-;*\r
-;* RLE Compresses a source buffer to an output file returning\r
-;* the size of the resultant compressed data or 0 if it fails.\r
-;*\r
-;* C PROTOTYPE:\r
-;*\r
-;* extern unsigned int x_file_RLEncode(int handle,\r
-;* char far * source_buff,unsigned int count);\r
-;*\r
-;* source_buff - The buffer to compress\r
-;* handle - The file handler\r
-;* count - The size of the source data in bytes\r
-;*\r
-;*\r
-proc _x_file_RLEncode\r
-ARG handle:word,src:dword,count:word\r
-LOCAL filesize:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk\r
- push ds\r
- push si\r
- push di\r
-\r
- mov [filesize],0\r
- mov dx,offset [RLEbuff]\r
- mov ax,ds\r
- mov es,ax\r
- lds si,[src]\r
- mov di,[count]\r
-\r
- lodsb ; Load first byte into BL\r
- mov bl,al\r
- xor cx,cx ; Set number characters packed to zero\r
- cld ; All moves are forward\r
-\r
-@@RepeatByte:\r
- lodsb ; Get byte into AL\r
- inc cx ; Increment compressed byte count\r
- sub di,1 ; Decrement bytes left\r
- je @@LastByte ; Finished when di = 1\r
- cmp cx,7fh ; Filled block yet\r
- jne @@NotFilled ; Nope!\r
-\r
- or cl,80h ; Set bit to indicate value is repeat count\r
- mov ch,bl\r
- add [filesize],2\r
- call put_cx\r
- jb @@FileError ; if carry set then file I/O error\r
- xor cx,cx ; clear compressed byte count\r
-\r
-@@NotFilled:\r
- cmp al,bl ; hase there been a byte transition ?\r
- je @@RepeatByte ; No!\r
-\r
- cmp cl,1 ; do we have a unique byte ?\r
- jne @@NotUnique ; No\r
-\r
- test bl,80h ; Can this byte be mistaken for repeat count\r
- jz @@Unambiguous ; No ! Dont bother with repeat count\r
-\r
-@@NotUnique:\r
- or cl,80h ; Set bit to indicate value is repeat count\r
- inc [filesize]\r
- call put_cl ; store it\r
- jb @@FileError ; if carry set then file I/O error\r
-@@Unambiguous:\r
-\r
- mov cl,bl ; store byte to be repeated\r
- inc [filesize]\r
- call put_cl\r
- jb @@FileError ; if carry set then file I/O error\r
- mov bl,al ; move latest byte into bl\r
- xor cx,cx ; clear compressed byte count\r
- jmp short @@RepeatByte\r
-\r
-@@FileError:\r
- mov ax,0\r
- jmp short @@exit\r
-\r
-@@LastByte:\r
- cmp cl,1 ; Is this a unique byte\r
- jne @@FinalCount ; No\r
-\r
- test bl,80h ; Can this byte be mistaken for repeat count\r
- jz @@FinalByte ; No, so dont bother with the repeat count\r
-\r
-@@FinalCount: ; Output the repeat count\r
- or cl,80h\r
- inc [filesize]\r
- call put_cl\r
- jb @@FileError ; if carry set then file I/O error\r
-\r
-@@FinalByte:\r
- mov cl,bl\r
- mov ch,80h\r
- add [filesize],2\r
- call put_cx ; store terminating null length\r
- jb @@FileError ; if carry set then file I/O error\r
-\r
- mov ax,[filesize]\r
- jmp short @@exit\r
-\r
-@@exit:\r
- pop di\r
- pop si\r
- pop ds\r
- mov sp,bp\r
- pop bp\r
- ret\r
-_x_file_RLEncode endp\r
-\r
-\r
-\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-;\r
-; GET_BYTE\r
-;\r
-; macro to read a byte from the input file into al\r
-;\r
-GET_BYTE macro\r
- push bx\r
- mov ah,3fh ; select "read from file or device" DOS service\r
- mov bx,[handle] ; Select handle of file to close\r
- mov cx,1 ; Want to read 1 byte\r
- int 21h ; call DOS service\r
- pop bx\r
- jb @@FileError ; failed if carry flag set\r
- mov al,[RLEbuff]\r
- endm\r
-\r
-\r
-;****************************************************************\r
-;*\r
-;* NAME: x_file_RLDecode\r
-;*\r
-;*\r
-;* Expands an RLE compresses file to a destination RAM buffer.\r
-;* returns the size of the resultant uncompressed data.\r
-;*\r
-;* C PROTOTYPE:\r
-;*\r
-;* extern unsigned int x_buff_RLDecode(int handle,\r
-;* char far * dest_buff);\r
-;*\r
-;* handle - Input file handle\r
-;* dest_buff - The destination buffer\r
-;*\r
-;*\r
-proc _x_file_RLDecode\r
-ARG handle:word,dest:dword\r
- push bp\r
- mov bp,sp\r
- push si\r
- push di\r
-\r
-\r
- mov bx,-1 ; zero output data buffer size - 1 (compensate for\r
- ; terminating null RL)\r
- mov dx,offset [RLEbuff] ; setup DS:DX -> RLEBuffer\r
- xor cx,cx ; clear CX\r
- cld ; Move forward\r
-\r
- les di,[dest] ; point es:di -> uncompressed buffer\r
-\r
-@@UnpackLoop:\r
-\r
- GET_BYTE ; Load a byte from file into AL\r
-\r
- cmp al,80h ; is it terminating null RL code\r
- je @@done ; if so jump\r
-\r
- test al,80h ; is AL a RL code (is high bit set ?)\r
- jz @@NoRepeats ; if not the no RL encoding for this byte, jump\r
-\r
- mov cl,al ; set CL to RL (run length) taking care\r
- xor cl,80h ; to remove the bit identifying it as a RL\r
- add bx,cx ; increment buffer size\r
- mov si,cx ; save the CX value\r
- GET_BYTE ; Load a byte from file into AL\r
- mov cx,si ; restore CX value\r
- shr cx,1 ; divide RL by 2 to use word stos\r
- jcxz @@NoRepeats ; result is zero, jump\r
-\r
- mov ah,al ; copy data byte to AH since going to use stosw\r
- rep stosw ; copy AX to outbut buffer RL times\r
- jnb @@UnpackLoop ; when we shifted the RL if we had a carry =>\r
- ; we had an odd number of repeats so store the\r
- ; last BYTE if carry was set otherwise jump\r
- stosb ; store AL in destination buffer\r
- jmp short @@UnpackLoop\r
-\r
-@@NoRepeats:\r
- inc bx\r
- stosb ; store AL in destination buffer\r
- jmp short @@UnpackLoop\r
-\r
-@@FileError:\r
- mov ax,0\r
- jmp short @@exit\r
-\r
-@@done:\r
- mov ax,bx\r
-@@exit:\r
- pop di\r
- pop si\r
- pop bp\r
- ret\r
-_x_file_RLDecode endp\r
-\r
- end\r
-\r
-\1a
\ No newline at end of file
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XRLETOOL - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-;-----------------------------------------------------------------------*/\r
-\r
-#ifndef _XRLETOOL_H_\r
-#define _XRLETOOL_H_\r
-\r
-extern unsigned int RLE_last_buff_offs;\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-extern unsigned int x_buff_RLEncode( /* Compress data buffer */\r
- char far * source_buff,\r
- char far * dest_buff,\r
- unsigned int count);\r
-\r
-extern unsigned int x_buff_RLE_size( /* Calculate buffer's compressed size */\r
- char far * source_buff,\r
- unsigned int count);\r
-\r
-\r
-extern unsigned int x_buff_RLDecode( /* Uncompress data buffer */\r
- char far * source_buff,\r
- char far * dest_buff);\r
-\r
-extern int x_file_RLEncode( /* Compress data buffer to file */\r
- int handle,\r
- char far * src_buff,\r
- unsigned int count);\r
-\r
-extern int x_file_RLDecode( /* Uncompress data file */\r
- int file_handle,\r
- char far * dest_buff);\r
-\r
-\r
-#endif\r
-\r
-\r
-\1a
\ No newline at end of file
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XRLETOOL - Include file\r
-;\r
-; XRLETOOL.ASM export functions\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
- global _x_buff_RLEncode :proc\r
- global _x_buff_RLE_size :proc\r
- global _x_buff_RLDecode :proc\r
- global _x_file_RLEncode :proc\r
- global _x_file_RLDecode :proc\r
-\r
- global _RLE_last_buff_offs :word\r
- \r
-\1a
\ No newline at end of file
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XTEXT\r
-;\r
-; Point functions all MODE X 256 Color resolutions\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
-include xlib.inc\r
-include xtext.inc\r
-\r
-.data\r
-\r
-_FontDriverActive db 0\r
-\r
-\r
-_CharHeight db 0\r
-_CharWidth db 0\r
-_FontPtr dw 2 dup (0)\r
-_FirstChar db 0\r
-\r
-_UserFontPtr dw 2 dup (0)\r
-_UserChHeight db 0\r
-_UserChWidth db 0\r
-_UserFirstCh db 0\r
-\r
-\r
-F8x8Ptr dw 2 dup (0)\r
-F8x14Ptr dw 2 dup (0)\r
-\r
-; This is a look up table for the mirror image of a byte eg\r
-; a byte with the value 11001010 has a corresponding byte in the table\r
-; 01010011. This is necessary as the VGA rom font bits are the reverse\r
-; order of what we need for the Mode X. If you know a better-faster way\r
-; TELL ME!\r
-\r
-MirrorTable label byte\r
- db 0,128, 64,192, 32,160, 96,224, 16,144, 80,208, 48,176,112,240\r
- db 8,136, 72,200, 40,168,104,232, 24,152, 88,216, 56,184,120,248\r
- db 4,132, 68,196, 36,164,100,228, 20,148, 84,212, 52,180,116,244\r
- db 12,140, 76,204, 44,172,108,236, 28,156, 92,220, 60,188,124,252\r
- db 2,130, 66,194, 34,162, 98,226, 18,146, 82,210, 50,178,114,242\r
- db 10,138, 74,202, 42,170,106,234, 26,154, 90,218, 58,186,122,250\r
- db 6,134, 70,198, 38,166,102,230, 22,150, 86,214, 54,182,118,246\r
- db 14,142, 78,206, 46,174,110,238, 30,158, 94,222, 62,190,126,254\r
- db 1,129, 65,193, 33,161, 97,225, 17,145, 81,209, 49,177,113,241\r
- db 9,137, 73,201, 41,169,105,233, 25,153, 89,217, 57,185,121,249\r
- db 5,133, 69,197, 37,165,101,229, 21,149, 85,213, 53,181,117,245\r
- db 13,141, 77,205, 45,173,109,237, 29,157, 93,221, 61,189,125,253\r
- db 3,131, 67,195, 35,163, 99,227, 19,147, 83,211, 51,179,115,243\r
- db 11,139, 75,203, 43,171,107,235, 27,155, 91,219, 59,187,123,251\r
- db 7,135, 71,199, 39,167,103,231, 23,151, 87,215, 55,183,119,247\r
- db 15,143, 79,207, 47,175,111,239, 31,159, 95,223, 63,191,127,255\r
-\r
-MirrorTableOffs dw ?\r
-.code\r
-\r
-;----------------------------------------------------------------------\r
-; x_text_init - Initializes the Mode X text driver and sets the\r
-; default font (VGA ROM 8x8)\r
-;\r
-; C caller:\r
-;\r
-; x_text_init()\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_text_init proc\r
- push bp\r
-\r
- mov [_FontDriverActive],TRUE\r
- mov ax,1130h ; AH = BIOS generator function\r
- ; AL = BIOS get font pointer subfunction\r
- push ax ; Save Video interrupt function parameters\r
- mov bh,3 ; Select 8x8 VGA ROM font\r
- int 10h ; Call BIOS video interrupt\r
- mov word ptr [F8x8Ptr],bp ; Save 8x8 Font address in FontPtr table\r
- mov word ptr [F8x8Ptr+2],es\r
-\r
- mov word ptr [_FontPtr],bp ; Default font = 8x8 ROM font\r
- mov word ptr [_FontPtr+2],es\r
-\r
- pop ax ; Recall Video interrupt function parameters\r
- mov bh,2 ; Select 8x14 VGA ROM font\r
- int 10h ; Call BIOS video interrupt\r
- mov word ptr [F8x14Ptr],bp ; Save 8x14 Font address in FontPtr table\r
- mov word ptr [F8x14Ptr+2],es\r
-\r
-\r
- mov al,8\r
- mov [_CharHeight],al ; Set the font character heights\r
- mov [_CharWidth] ,al ; Set the font character widths\r
-\r
- mov dx,offset MirrorTable ; Initialize mirror table offset\r
- mov [MirrorTableOffs],dx\r
-\r
- pop bp\r
- ret\r
-_x_text_init endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_set_font - Mode X Set current font for text drawing\r
-;\r
-; C caller:\r
-;\r
-; x_set_font(int FontID)\r
-;\r
-; PARAMETERS FontID 0 = VGA ROM 8x8\r
-; 1 = VGA ROM 8x14\r
-; 2 = User defined bitmapped font\r
-;\r
-;\r
-; WARNING: A user font must be registered before setting FontID 2\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-\r
-_x_set_font proc\r
- ARG FontID:word\r
- push bp\r
- mov bp,sp\r
-\r
- xor dx,dx ; Clear DX - Mirror table offset (0 for non ROM fonts)\r
- mov cx,FontID\r
- cmp cx,2\r
-\r
- jne @@not_userfont ; Do we have a user font\r
- mov ax,[_UserFontPtr] ; Yes - Activate it\r
- mov [_FontPtr],ax\r
-\r
- mov ax,[_UserFontPtr+2]\r
- mov [_FontPtr+2],ax\r
-\r
- mov al,[_UserChHeight]\r
- mov [_CharHeight],al ; Set the font character heights\r
-\r
- mov al,[_UserChWidth]\r
- mov [_CharWidth],al ; Set the font character heights\r
-\r
- mov al,[_UserFirstCh]\r
- mov [_FirstChar],al\r
- jmp short @@done\r
-\r
-@@not_userfont: ; We have a ROM font\r
-\r
- mov dx,offset MirrorTable\r
- mov [_CharWidth],8 ; Set the font character widths\r
- mov [_FirstChar],0 ; Character sets start at ascii 0\r
- cmp cx,1 ; Do we have an 8x14 ROM font\r
- jne @@not_8x14font ; No, we have 8x8 - jump\r
-\r
- mov ax,[F8x14Ptr] ; Yes Activate it\r
- mov [_FontPtr],ax\r
-\r
- mov ax,[F8x14Ptr+2]\r
- mov [_FontPtr+2],ax\r
-\r
- mov [_CharHeight],14 ; Set the font character heights\r
- jmp short @@done\r
-\r
-@@not_8x14font:\r
- mov ax,[F8x8Ptr] ; Activate the 8x8 ROM Font\r
- mov [_FontPtr],ax\r
-\r
- mov ax,[F8x8Ptr+2]\r
- mov [_FontPtr+2],ax\r
-\r
- mov [_CharHeight],8 ; Set the font character heights\r
-\r
-@@done:\r
- mov [MirrorTableOffs],dx\r
-\r
- pop bp\r
- ret\r
-_x_set_font endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_register_userfont - Mode X register user font\r
-;\r
-; C caller:\r
-;\r
-; x_register_userfont(void far *user_font)\r
-;\r
-;\r
-; NOTES registering a user font deregisters the previous user font\r
-; User fonts may be at most 8 pixels wide\r
-;\r
-;\r
-; USER FONT STRUCTURE\r
-;\r
-; Word: ascii code of first char in font\r
-; Byte: Height of chars in font\r
-; Byte: Width of chars in font\r
-; n*h*Byte: the font data where n = number of chars and h = height\r
-; of chars\r
-;\r
-; WARNING: The onus is on the program to ensure that all characters\r
-; drawn whilst this font is active, are within the range of\r
-; characters defined.\r
-;\r
-;\r
-; UPDATE: Variable width fonts are now available (up to 8 pixels max)\r
-; If the Width byte in the font header is 0 then it is assumed that\r
-; the font is variable width. For variable width fonts each characters\r
-; data is followed by one byte representing the characters pixel width.\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_register_userfont proc\r
- ARG FontToRegister:dword\r
- push bp\r
- mov bp,sp\r
- push si\r
-\r
- mov ax,word ptr [FontToRegister]\r
- mov bx,word ptr [FontToRegister+2]\r
- add ax,4\r
- mov [_UserFontPtr],ax\r
- mov [_UserFontPtr+2],bx\r
-\r
- push ds\r
- lds si,[FontToRegister]\r
- lodsw\r
- mov bx,ax\r
- lodsw\r
- pop ds\r
-\r
- mov [_UserChHeight],al\r
- mov [_UserChWidth],ah\r
- mov [_UserFirstCh],bl\r
- pop si\r
- pop bp\r
- ret\r
-_x_register_userfont endp\r
-\r
-\r
-_x_get_char_width proc\r
- ARG Chr:byte\r
- push bp\r
- mov bp,sp\r
-\r
- xor ah,ah\r
- mov al,[_CharWidth]\r
- or al,al\r
- jz @@NotFixed\r
- pop bp\r
- ret\r
-\r
-@@NotFixed:\r
- push si\r
- mov al,[_CharHeight]\r
- mov bx,ax\r
- inc al\r
- mov dl,[Chr] ; User fonts may have incomplete charsets\r
- sub dl,[_FirstChar] ; this compensates for fonts not starting at\r
- ; ascii value 0\r
- mul dl ; Mult AX by character to draw giving offset\r
- ; of first character byte in font table\r
- add ax,bx\r
- les si,dword ptr [_FontPtr]\r
- add si,ax\r
- xor ah,ah\r
- mov al,es:[si]\r
- pop si\r
- pop bp\r
- ret\r
-_x_get_char_width endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_char_put - Mode X Draw a text character at the specified location\r
-;\r
-;\r
-; C caller:\r
-;\r
-; x_char_put(char ch, int x, int y, unsigned ScrnOffs, unsigned Color)\r
-;\r
-; PARAMETERS ch char to draw\r
-; x,y screen coords at which to draw ch\r
-; ScrnOffs Starting offset of page on whih to draw\r
-; Color Color of the text\r
-;\r
-; NOTES: Uses the current font settings. See SetFont, InitTextDriver,\r
-; RegisterUserFont\r
-;\r
-; WARNING: InitTextDriver must be called before using this function\r
-;\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_char_put proc\r
- ARG Chr:byte,X:word,Y:word,ScrnOffs:word,Color:word\r
- LOCAL ScreenInc:word,Hold:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk\r
- push si\r
- push di\r
- push ds\r
-\r
- cld\r
- mov ax,[_ScrnLogicalByteWidth] ; AX = Virtual screen width\r
- mov bx,ax ; copy Virt screen width and decrement\r
- sub bx,3 ; by the max number of bytes (whole or part)\r
- ; that a character row may occupy on the screen\r
- mov [ScreenInc],bx ; Save it to the local stack var. SceenInc\r
- mul [Y] ; Find the starting dest. screen address of\r
- mov di,[X] ; the character to draw\r
- mov cx,di\r
- shr di,2\r
- add di,ax\r
- add di,[ScrnOffs] ; Dont forget to compensate for page\r
-\r
- mov ax,SCREEN_SEG ; ES:DI -> first screen dest. byte of char\r
- mov es,ax\r
-\r
- and cx,3 ; CH = 0, CL = Plane of first pixel\r
-\r
- mov bx,[MirrorTableOffs] ; set BX to offset of mirror table for XLAT\r
- mov al,[_CharHeight] ; AL = Character height, AH = 0\r
- xor ah,ah\r
- mov ch,al ; CH = Character height\r
-\r
- cmp [_CharWidth],0\r
- jne @@NoWidthByte\r
- inc al\r
-@@NoWidthByte:\r
-\r
- mov dl,[Chr] ; User fonts may have incomplete charsets\r
- sub dl,[_FirstChar] ; this compensates for fonts not starting at\r
- ; ascii value 0\r
- mul dl ; Mult AX by character to draw giving offset\r
- ; of first character byte in font table\r
-\r
- lds si,dword ptr [_FontPtr] ; DS:SI -> beggining of required font\r
- add si,ax ; DS:SI -> first byte of req. char\r
-\r
- mov dx,SC_INDEX ; Prepare for VGA out's\r
-\r
-@@MainLoop:\r
-\r
- lodsb ; load character byte into AL\r
- or al,al\r
- jz @@NoCharPixels ; Dont bother if no pixels to draw\r
-\r
- or bx,bx ; if BX=0 -> User font, so no need to mirror data\r
- jz @@DontMirror\r
- push ds\r
- mov dx,@data ; Set DS to the Mirror lookup table's segment\r
- mov ds,dx ; - BX should already contain the offset addr of table\r
- xlatb ; AL is now replaced by the corresponding table entry\r
- pop ds ; Restore previous data segment\r
- mov dx,SC_INDEX ; Restore DX\r
-\r
-@@DontMirror:\r
- xor ah,ah ; shift the byte for the dest plane and save it\r
- shl ax,cl\r
- mov [Hold],ax\r
-\r
- mov ah,al ; output high nibble of first byte of shifted char\r
- and ah,0fh ; 4 pixels at a time !\r
- jnz @@p1 ; if nibble has pixels, draw them\r
- inc di ; otherwise go to next nibble\r
- jmp @@SecondNibble\r
-\r
-@@p1:\r
- mov al,MAP_MASK\r
- out dx,ax\r
- mov al,byte ptr [Color]\r
- stosb\r
-\r
-@@SecondNibble:\r
- ; output low nibble of first byte of shifted char\r
- mov ax,[Hold]\r
- shl ax,4\r
- and ah,0fh\r
- jnz @@p2\r
- inc di\r
- jmp @@ThirdNibble\r
-\r
-@@p2:\r
- mov al,MAP_MASK\r
- out dx,ax\r
- mov al,byte ptr [Color]\r
- stosb\r
-\r
-@@ThirdNibble:\r
- mov ax,[Hold] ; output high nibble of last byte of shifted char\r
- and ah,0fh\r
- jnz @@p3\r
- inc di\r
- jmp short @@NextCharRow\r
-\r
-@@p3:\r
- mov al,MAP_MASK ; completing the drawing of one character row\r
- out dx,ax\r
- mov al,byte ptr [Color]\r
- stosb\r
-\r
-@@NextCharRow:\r
- add di,[ScreenInc] ; Now move to the next screen row and do the same\r
- dec ch ; any remaining character bytes\r
- jnz @@MainLoop\r
-\r
-@@done:\r
- pop es\r
- mov ah,0\r
- mov al,es:[_CharWidth] ; return the character width (for string fuctions\r
- or al,al\r
- jnz @@FixedSpacing ; using this character drawing function).\r
- lodsb\r
-@@FixedSpacing:\r
-\r
- mov bx,es\r
- mov ds,bx\r
-\r
- pop di\r
- pop si\r
- mov sp,bp\r
- pop bp\r
- ret\r
-\r
-@@NoCharPixels:\r
- add di,3\r
- add di,[ScreenInc] ; Now move to the next screen row and do the same\r
- dec ch ; any remaining character bytes\r
- jnz @@MainLoop\r
- jmp short @@done\r
-\r
-_x_char_put endp\r
-\r
-\r
-end\r
-\r
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XTEXT - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;-----------------------------------------------------------------------*/\r
-\r
-#ifndef _XTEXT_H_\r
-#define _XTEXT_H_\r
-\r
-\r
-#define FONT_8x8 0\r
-#define FONT_8x15 1\r
-#define FONT_USER 2\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-WORD x_text_init(void); /* Initialize text functionns */\r
-\r
-void x_set_font(\r
- WORD FontId); /* Set the font style */\r
-\r
-void x_register_userfont( /* register a user defined font */\r
- char far *UserFontPtr);\r
-\r
-unsigned int x_char_put( /* Draw a text character using */\r
- char ch, /* the currently active font */\r
- WORD X,\r
- WORD Y,\r
- WORD PgOffs,\r
- WORD Color);\r
-\r
-\r
-unsigned int x_get_char_width( /* Get the character width */\r
- char ch);\r
-\r
-\r
-/* the folowing function is from xprintf.c but is included due to its */\r
-/* close relationship with this module */\r
-\r
-void x_printf( /* formatted text output */\r
- WORD x,\r
- WORD y,\r
- WORD ScrnOffs,\r
- WORD color,\r
- char *ln,...);\r
-\r
-void x_bgprintf( /* formatted text output */\r
- WORD x,\r
- WORD y,\r
- WORD ScrnOffs,\r
- WORD fgcolor,\r
- WORD bgcolor,\r
- char *ln,...);\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-\r
-/* VARIABLES =========================================================== */\r
-\r
-extern BYTE CharHeight; /* Char height of currently active font */\r
-extern BYTE CharWidth; /* Char width of currently active font */\r
-extern BYTE FirstChar; /* First char in the curr. active font */\r
-\r
-extern BYTE UserCharHeight; /* Char height of currentle regist'd user font */\r
-extern BYTE UserCharWidth; /* Char height of currentle regist'd user font */\r
-extern BYTE UserFirstChar; /* First char of the curr. regist'd usera font */\r
-\r
-\r
-#endif\r
-\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XPOINT - Include file\r
-;\r
-; XPOINT.ASM export functions\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
- global _x_text_init :proc\r
- global _x_set_font :proc\r
- global _x_char_put :proc\r
- global _x_register_userfont :proc\r
- global _x_get_char_width :proc\r
-\r
- global _CharHeight :byte\r
- global _CharWidth :byte\r
- global _FontPtr :word:2\r
- global _FirstChar :byte\r
- global _UserFontPtr :word:2\r
- global _UserChHeight :byte\r
- global _UserChWidth :byte\r
- global _UserFirstCh :byte\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XVBITMAP\r
-;\r
-; Video Bitmap functions - Video Ram <-> Video Ram\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-COMMENT $\r
-\r
-The XVBITMAP module implements yet another type of bitmap to complement\r
-planar and compiled bitmaps, VRAM based bitmaps. If a 4 cylinder car is\r
-analagous to planar bitmaps, that is thrifty on memory consumption but low\r
-performance and and a V8 is analagous to Compiled bitmaps, memory guzzlers\r
-that really fly, then VRAM based bitmaps are the 6 cylinder modest performers\r
-with acceptable memory consumption.\r
-\r
-To summarise their selling points, VBM's are moderately fast with fair memory\r
-consumption, and unlike compiled bitmaps, can be clipped. The disadvantages\r
-are that they are limited by the amount of free video ram and have a complex\r
-structure.\r
-\r
-The VRAM bitmap format is rather complex consisting of components stored in\r
-video ram and components in system ram working together. This complexity\r
-necessitates the existence of a creation function "x_make_vbm" which takes\r
-an input linear bitmap and generates the equivalent VBM (VRAM Bit Map).\r
-\r
-VBM structure:\r
-\r
- WORD 0 Size Total size of this VBM structure in bytes\r
- WORD 1 ImageWidth Width in bytes of the image (for all alignments)\r
- WORD 2 ImageHeight Height in scan lines of the image\r
-\r
- WORD 3 Alignment 0 ImagePtr Offset in VidRAM of this aligned image\r
- +--WORD 4 MaskPtr Offset (within this structure's DS) of\r
- | . alignment masks\r
- | .\r
- | .\r
- | WORD 9 Alignment 3 ImagePtr Offset in VidRAM of this aligned image\r
- +|--WORD 10 MaskPtr Offset (within this structure's DS) of\r
- || alignment masks\r
- ||\r
- |+->BYTE 21 (WORD 11) -------+-- Image masks for alignment 0\r
- | . |\r
- | . |\r
- | BYTE 21 + ImageWidth*ImageHeight -----+\r
- |\r
- | .\r
- | . (similaly for alignments 1 - 2 )\r
- | .\r
- |\r
- +-->BYTE 21 + 3*ImageWidth*ImageHeight + 1-+-- Image masks for alignment 3\r
- . |\r
- . |\r
- BYTE 21 + 4*(ImageWidth*ImageHeight) --+\r
-\r
- .\r
- .\r
- << Similarly for alignments 2 and 3 >>\r
- .\r
- .\r
- BYTE 21 + 4*(ImageWidth*ImageHeight)\r
- -------------\r
-\r
- (And dont forget the corresponding data in video ram)\r
-\r
-$\r
-\r
-\r
-include xlib.inc\r
-include xvbitmap.inc\r
-\r
-VBM_info_struc struc\r
- Size dw ?\r
- ImageWidth dw ?\r
- ImageHeight dw ?\r
-; AlignData dw ?\r
-VBM_info_struc ends\r
-\r
-AlignData equ 6\r
-\r
-VBM_alignment_struc struc\r
- ImagePtr dw ?\r
- MaskPtr dw ?\r
-VBM_alignment_struc ends\r
-\r
-\r
- .code\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_store_vbm_image\r
-;\r
-; Store the linear bitmap in video RAM using the specified alignment and\r
-; start address. Returns number video ram bytes used.\r
-;\r
-; THIS FUNCTION IS FOR USE BY x_make_masked_vbm\r
-;\r
-; Prototype:\r
-;\r
-; x_store_vbm_image(unsigned int vramoffs, unsigned int Align,\r
-; char far *lbm);\r
-;\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_store_vbm_image proc\r
- ARG VramOffs:word,Align:word,LBitmap:dword\r
- LOCAL BMWidth:byte=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
-\r
- mov ax,SCREEN_SEG ; Point ES to screen segment\r
- mov es,ax\r
- mov di,[VramOffs] ; Point ES:DI to VRAM dest start\r
- mov bx,[Align] ; Set BL to first pixel plane align\r
- and bl,03h\r
-\r
- lds si,[LBitmap] ; DS:SI -> source linear Bitmap\r
- lodsw ; Al = B.M. width (bytes) AH = B.M.\r
- mov bh,ah ; Save source bitmap dimensions\r
- mov [BMWidth],al ;\r
-\r
- mov dx,SC_INDEX ; Initialize Map Mask for plane\r
- mov al,MAP_MASK ; selection\r
- out dx,al\r
- inc dx\r
- xor ch,ch ; clear CH\r
-@@RowLoop:\r
- mov cl,bl ; Set initial plane for current\r
- mov ah,11h ; allignment\r
- shl ah,cl\r
-\r
- mov cl,[BMWidth] ; Initialize column counter\r
-@@ColLoop:\r
- mov al,ah\r
- out dx,al ; set vga write plane\r
- lodsb ; load next LBM pixel\r
- mov es:[di],al ; store it in Video Ram\r
- shl ah,1 ; rotate plane mask\r
- jnb @@NoAddrIncr ; Time to increment dest address ?\r
- inc di ; Yes: increment addr and reset\r
- mov ah,11h ; plane mask to plane 0\r
-@@NoAddrIncr:\r
- loop @@ColLoop ; Loop to next pixel column\r
- cmp ah,11h\r
-; je @@skip\r
- inc di ; Increment dest addr\r
-;@@skip:\r
- dec bh ; Decrement row counter\r
- jnz @@RowLoop ; Jump if more rows to go\r
- mov ax,di ; calculate video RAM consumed and\r
- sub ax,[VramOffs] ; return value\r
-\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_store_vbm_image endp\r
-\r
-\r
-_x_put_masked_vbm proc\r
- ARG X:word,Y:word,ScrnOffs:word,SrcVBM:dword\r
- LOCAL VBMWidth:word,VBMHeight:word,NextLineIncr:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
-\r
- mov ax,SCREEN_SEG ; Point es to VGA segment\r
- mov es,ax\r
- mov ax,[Y] ; Calculate dest screen row\r
- mov cx,[_ScrnLogicalByteWidth] ; by mult. dest Y coord by Screen\r
- mul cx ; width then adding screen offset\r
-\r
- mov di,[ScrnOffs] ; store result in DI\r
- add di,ax\r
- mov si,[X] ; Load X coord into CX and make a\r
- mov bx,si ; copy in DX\r
- shr bx,2 ; Find starting byte in dest row\r
- add di,bx ; add to DI giving screen offset of\r
- ; first pixel's byte\r
-\r
- and si,3 ; get pixel alignment in si\r
-\r
- lds bx,[SrcVBM] ; DS:BX -> VBM data structure\r
- shl si,2 ; si = offset of data for curr\r
- ; alignment\r
-\r
- mov ax,word ptr [bx+ImageHeight] ; Get image height\r
- mov [VBMHeight],ax\r
- mov ax,word ptr [bx+ImageWidth] ; Get image width\r
- mov [VBMWidth],ax\r
-\r
- sub cx,ax ; NextLineIncr = bytes to the begin.\r
- mov [NextLineIncr],cx ; of bitmaps next row on screen\r
- mov dx,[bx+MaskPtr+AlignData+si] ; DS:SI -> mask data\r
- mov bx,[bx+ImagePtr+AlignData+si] ; ES:BX -> source video bitmap\r
- mov si,dx\r
-\r
- mov dx,GC_INDEX ; Set bit mask for all bits from\r
- mov ax,BIT_MASK ; VGA latches and none from CPU\r
- out dx,ax\r
-\r
- mov dx,SC_INDEX ; Point SC register to map mask\r
- mov al,MAP_MASK ; in preperation for masking data\r
- out dx,al\r
- inc dx ; Point dx to SC data register\r
- mov ah,byte ptr [VBMHeight] ; AH = Scanline loop counter\r
-\r
-@@RowLoop:\r
- mov cx,[VBMWidth] ; Width in bytes across\r
-\r
-@@ColumnLoop:\r
- lodsb\r
- out dx,al\r
- mov al,es:[bx] ; load latches from source bitmap\r
- stosb ; store latches to dest. bitmap\r
- inc bx\r
- loop @@ColumnLoop\r
-\r
- add di,[NextLineIncr] ; point to start of next dest row\r
- dec ah ; decrement scan line counter\r
- jnz @@RowLoop ; jump if more scanlines left\r
-\r
- mov dx,GC_INDEX+1 ; Restore bitmask to the default -\r
- mov al,0ffh ; all data from cpu\r
- out dx,al\r
-\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_put_masked_vbm endp\r
-\r
-\r
-_x_put_masked_vbm_clipx proc\r
-ARG X:word,Y:word,ScrnOffs:word,SrcVBM:dword\r
-LOCAL DataInc,LeftSkip,VBMWidth,VBMHeight,NextLineIncr:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
-\r
- mov di,[X] ; load X coord int DI and make a\r
- mov si,di ; copy in SI\r
- sar di,2 ; Find Byte offset of X coord\r
-\r
- and si,3 ; Calculate pixels plane alignment\r
- shl si,2 ; Prepare to lookup mask & data\r
- les bx,[SrcVBM] ; ES:BX -> begining of VBM data\r
-\r
- mov cx,es:[bx+ImageWidth] ; Get image width and save in CX\r
-\r
-\r
-\r
- ;;;;; CLIP PROCESSING FOR LEFT CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
- mov dx,[_LeftClip]\r
- sub dx,di\r
- jle @@NotLeftClip\r
- cmp dx,cx\r
- jnl @@NotVisible\r
- add di,dx\r
- mov [LeftSkip],dx\r
- mov [DataInc],dx\r
- sub cx,dx\r
- jmp short @@HorizClipDone\r
-\r
- ;;;; EXIT FOR COMPLETELY OBSCURED V.B.M's ;;;;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotVisible:\r
- mov ax,1\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-\r
- ;;;;; CLIP PROCESSING FOR RIGHT CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotLeftClip:\r
- mov dx,[_RightClip]\r
- sub dx,di\r
- js @@NotVisible\r
- mov [LeftSkip],0\r
- mov [DataInc],0\r
- cmp dx,cx\r
- jge @@HorizClipDone\r
- inc dx\r
- sub cx,dx\r
- mov [DataInc],cx\r
- mov cx,dx\r
-\r
-@@HorizClipDone:\r
-\r
-\r
- add di,[ScrnOffs] ; Add the current page offset\r
- mov [VBMWidth],cx\r
- mov ax,es:[bx+ImageHeight] ; Get image height and save in AX\r
- mov [VBMHeight],ax\r
-\r
-\r
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-\r
- mov ax,[Y] ; Calculate dest screen row\r
- mov cx,[_ScrnLogicalByteWidth] ; by mult. dest Y coord by Screen\r
- mul cx ; width then adding screen offset\r
- add di,ax ; Add Dest Screen Row to di\r
- sub cx,[VBMWidth]\r
- mov [NextLineIncr],cx\r
-\r
- mov ax,es ; copy ES to DS\r
- mov ds,ax\r
- mov ax,SCREEN_SEG ; Point es to VGA segment\r
- mov es,ax\r
-\r
- mov ax,[bx+MaskPtr+AlignData+si] ; DS:SI -> mask data\r
- mov bx,[bx+ImagePtr+AlignData+si] ; ES:BX -> source video bitmap\r
- mov si,ax\r
-\r
- mov ax,[LeftSkip] ; Skip data/mask bytes in\r
- add bx,ax ; each row that have been clipped\r
- add si,ax ; by the L.H.S border\r
-\r
-\r
- mov dx,GC_INDEX ; Set bit mask for all bits from\r
- mov ax,BIT_MASK ; VGA latches and none from CPU\r
- out dx,ax\r
- mov dx,SC_INDEX ; Point SC register to map mask\r
- mov al,MAP_MASK ; in preperation for masking data\r
- out dx,al\r
- inc dx ; Point dx to SC data register\r
- mov ah,byte ptr [VBMHeight] ; AH = Scanline loop counter\r
-\r
-@@RowLoop:\r
- mov cx,[VBMWidth] ; Width in bytes across\r
-\r
-@@ColumnLoop:\r
- lodsb\r
- out dx,al\r
- mov al,es:[bx] ; load latches from source bitmap\r
- stosb ; store latches to dest. bitmap\r
- inc bx\r
- loop @@ColumnLoop\r
- add bx,[DataInc]\r
- add si,[DataInc]\r
- add di,[NextLineIncr] ; point to start of next dest row\r
- dec byte ptr ah ; decrement scan line counter\r
- jnz @@RowLoop ; jump if more scanlines left\r
-\r
- mov dx,GC_INDEX+1 ; Restore bitmask to the default -\r
- mov al,0ffh ; all data from cpu\r
- out dx,al\r
- xor ax,ax\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_put_masked_vbm_clipx endp\r
-\r
-\r
-_x_put_masked_vbm_clipy proc\r
-ARG X:word,Y:word,ScrnOffs:word,SrcVBM:dword\r
-LOCAL VBMWidth,VBMHeight,TopRow,NextLineIncr:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
-\r
- mov di,[X] ; load X coord int DI and make a\r
- mov si,di ; copy in SI\r
-\r
-\r
- and si,3 ; Calculate pixels plane alignment\r
- shl si,2 ; Prepare to lookup mask & data\r
- les bx,[SrcVBM] ; ES:BX -> begining of VBM data\r
-\r
-\r
- mov ax,es:[bx+ImageHeight] ; Get image height and save in AX\r
-\r
-\r
-\r
- ;;;;; CLIP PROCESSING FOR TOP CLIP BORDER ;;;;;;;;;;;;;;;;;;;;;\r
-\r
- mov dx,[_TopClip] ; Compare u.l. Y coord with Top\r
- sub dx,[Y] ; clipping border\r
- jle @@NotTopClip ; jump if VBM not clipped from above\r
- cmp dx,ax\r
- jnl @@NotVisible ; jump if VBM is completely obscured\r
- mov [TopRow],dx\r
- sub ax,dx\r
- add [Y],dx\r
- jmp short @@VertClipDone\r
-\r
- ;;;; EXIT FOR COMPLETELY OBSCURED V.B.M's ;;;;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotVisible:\r
- mov ax,1\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-\r
- ;;;;; CLIP PROCESSING FOR BOTTOM CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotTopClip:\r
- mov dx,[_BottomClip]\r
- sub dx,[Y]\r
- js @@NotVisible\r
- mov [TopRow],0\r
- cmp dx,ax\r
- jg @@VertClipDone\r
- inc dx\r
- mov ax,dx\r
-\r
-@@VertClipDone:\r
-\r
-\r
- shr di,2 ; Find Byte offset of X coord\r
- add di,[ScrnOffs] ; Add the current page offset\r
- mov cx,es:[bx+ImageWidth] ; Get image width and save in CX\r
- mov [VBMWidth],cx\r
- mov [VBMHeight],ax\r
-\r
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-\r
- mov ax,[Y] ; Calculate dest screen row\r
- mov cx,[_ScrnLogicalByteWidth] ; by mult. dest Y coord by Screen\r
- mul cx ; width then adding screen offset\r
- add di,ax ; Add Dest Screen Row to di\r
- sub cx,[VBMWidth]\r
- mov [NextLineIncr],cx\r
-\r
- mov ax,es ; copy ES to DS\r
- mov ds,ax\r
- mov ax,SCREEN_SEG ; Point es to VGA segment\r
- mov es,ax\r
-\r
- mov ax,[bx+MaskPtr+AlignData+si] ; DS:SI -> mask data\r
- mov bx,[bx+ImagePtr+AlignData+si] ; ES:BX -> source video bitmap\r
- mov si,ax\r
-\r
-\r
-\r
- mov ax,[VBMWidth] ; Increment DS:BX and DS:SI to\r
- mul [TopRow] ; skip image/mask data that has\r
- add bx,ax ; been clipped by the top border\r
- add si,ax\r
-\r
-\r
- mov dx,GC_INDEX ; Set bit mask for all bits from\r
- mov ax,BIT_MASK ; VGA latches and none from CPU\r
- out dx,ax\r
- mov dx,SC_INDEX ; Point SC register to map mask\r
- mov al,MAP_MASK ; in preperation for masking data\r
- out dx,al\r
- inc dx ; Point dx to SC data register\r
- mov ah,byte ptr [VBMHeight] ; AH = Scanline loop counter\r
-\r
-@@RowLoop:\r
- mov cx,[VBMWidth] ; Width in bytes across\r
-\r
-@@ColumnLoop:\r
- lodsb\r
- out dx,al\r
- mov al,es:[bx] ; load latches from source bitmap\r
- stosb ; store latches to dest. bitmap\r
- inc bx\r
- loop @@ColumnLoop\r
- add di,[NextLineIncr] ; point to start of next dest row\r
- dec byte ptr ah ; decrement scan line counter\r
- jnz @@RowLoop ; jump if more scanlines left\r
-\r
- mov dx,GC_INDEX+1 ; Restore bitmask to the default -\r
- mov al,0ffh ; all data from cpu\r
- out dx,al\r
-\r
- xor ax,ax\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_put_masked_vbm_clipy endp\r
-\r
-_x_put_masked_vbm_clipxy proc\r
-ARG X:word,Y:word,ScrnOffs:word,SrcVBM:dword\r
-LOCAL DataInc,LeftSkip,VBMWidth,VBMHeight,TopRow,NextLineIncr:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
-\r
- mov di,[X] ; load X coord int DI and make a\r
- mov si,di ; copy in SI\r
- sar di,2 ; Find Byte offset of X coord\r
- and si,3 ; Calculate pixels plane alignment\r
- shl si,2 ; Prepare to lookup mask & data\r
- les bx,[SrcVBM] ; ES:BX -> begining of VBM data\r
-\r
- mov cx,es:[bx+ImageWidth] ; Get image width and save in CX\r
- mov ax,es:[bx+ImageHeight] ; Get image height and save in AX\r
-\r
-\r
-\r
- ;;;;; CLIP PROCESSING FOR TOP CLIP BORDER ;;;;;;;;;;;;;;;;;;;;;\r
-\r
- mov dx,[_TopClip] ; Compare u.l. Y coord with Top\r
- sub dx,[Y] ; clipping border\r
- jle @@NotTopClip ; jump if VBM not clipped from above\r
- cmp dx,ax\r
- jnl @@NotVisible ; jump if VBM is completely obscured\r
- mov [TopRow],dx\r
- sub ax,dx\r
- add [Y],dx\r
- jmp short @@VertClipDone\r
-\r
- ;;;; EXIT FOR COMPLETELY OBSCURED V.B.M's ;;;;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotVisible:\r
- mov ax,1\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-\r
- ;;;;; CLIP PROCESSING FOR BOTTOM CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotTopClip:\r
- mov dx,[_BottomClip]\r
- sub dx,[Y]\r
- js @@NotVisible\r
- mov [TopRow],0\r
- cmp dx,ax\r
- jg @@VertClipDone\r
- inc dx\r
- mov ax,dx\r
-\r
-@@VertClipDone:\r
-\r
- ;;;;; CLIP PROCESSING FOR LEFT CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
-\r
- mov dx,[_LeftClip]\r
- sub dx,di\r
- jle @@NotLeftClip\r
- cmp dx,cx\r
- jnl @@NotVisible\r
- add di,dx\r
- mov [LeftSkip],dx\r
- mov [DataInc],dx\r
- sub cx,dx\r
- jmp short @@HorizClipDone\r
-\r
- ;;;;; CLIP PROCESSING FOR RIGHT CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotLeftClip:\r
- mov dx,[_RightClip]\r
- sub dx,di\r
- js @@NotVisible\r
- mov [LeftSkip],0\r
- mov [DataInc],0\r
- cmp dx,cx\r
- jge @@HorizClipDone\r
- inc dx\r
- sub cx,dx\r
- mov [DataInc],cx\r
- mov cx,dx\r
-\r
-@@HorizClipDone:\r
-\r
- add di,[ScrnOffs] ; Add the current page offset\r
- mov [VBMWidth],cx\r
- mov [VBMHeight],ax\r
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-\r
- mov ax,[Y] ; Calculate dest screen row\r
- mov cx,[_ScrnLogicalByteWidth] ; by mult. dest Y coord by Screen\r
- mul cx ; width then adding screen offset\r
- add di,ax ; Add Dest Screen Row to di\r
- sub cx,[VBMWidth]\r
- mov [NextLineIncr],cx\r
-\r
- mov ax,es ; copy ES to DS\r
- mov ds,ax\r
- mov ax,SCREEN_SEG ; Point es to VGA segment\r
- mov es,ax\r
-\r
- mov ax,[bx+MaskPtr+AlignData+si] ; DS:SI -> mask data\r
- mov bx,[bx+ImagePtr+AlignData+si] ; ES:BX -> source video bitmap\r
- mov si,ax\r
-\r
-\r
-\r
- mov ax,[VBMWidth] ; Increment DS:BX and DS:SI to\r
- add ax,[DataInc] ; skip image/mask data that has\r
- mul [TopRow] ; been clipped by the top border\r
- add ax,[LeftSkip] ; Skip also data/mask bytes in\r
- add bx,ax ; each row that have been clipped\r
- add si,ax ; by the L.H.S border\r
-\r
-\r
- mov dx,GC_INDEX ; Set bit mask for all bits from\r
- mov ax,BIT_MASK ; VGA latches and none from CPU\r
- out dx,ax\r
- mov dx,SC_INDEX ; Point SC register to map mask\r
- mov al,MAP_MASK ; in preperation for masking data\r
- out dx,al\r
- inc dx ; Point dx to SC data register\r
- mov ah,byte ptr [VBMHeight] ; AH = Scanline loop counter\r
-\r
-@@RowLoop:\r
- mov cx,[VBMWidth] ; Width in bytes across\r
-\r
-@@ColumnLoop:\r
- lodsb\r
- out dx,al\r
- mov al,es:[bx] ; load latches from source bitmap\r
- stosb ; store latches to dest. bitmap\r
- inc bx\r
- loop @@ColumnLoop\r
- add bx,[DataInc]\r
- add si,[DataInc]\r
- add di,[NextLineIncr] ; point to start of next dest row\r
- dec byte ptr ah ; decrement scan line counter\r
- jnz @@RowLoop ; jump if more scanlines left\r
-\r
- mov dx,GC_INDEX+1 ; Restore bitmask to the default -\r
- mov al,0ffh ; all data from cpu\r
- out dx,al\r
- xor ax,ax\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_put_masked_vbm_clipxy endp\r
-\r
-\r
- end\r
-\r
-\1a
\ No newline at end of file
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XVBITMAP - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;-----------------------------------------------------------------------*/\r
-\r
-#ifndef _XVBITMAP_H_\r
-#define _XVBITMAP_H_\r
-\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-\r
-\r
-void x_put_masked_vbm( /* Copy a planar bitmap from SRAM masking */\r
- int X, /* only non zero pixels to VRAM */\r
- int Y,\r
- WORD ScrnOffs,\r
- BYTE far * VBitmap);\r
-\r
-int x_put_masked_vbm_clipx(/* Copy a planar bitmap from SRAM masking */\r
- int X, /* only non zero pixels to VRAM. Clip X */\r
- int Y,\r
- WORD ScrnOffs,\r
- BYTE far * VBitmap);\r
-\r
-int x_put_masked_vbm_clipy(/* Copy a planar bitmap from SRAM masking */\r
- int X, /* only non zero pixels to VRAM. Clip Y */\r
- int Y,\r
- WORD ScrnOffs,\r
- BYTE far * VBitmap);\r
-\r
-int x_put_masked_vbm_clipxy(/* Copy a planar bitmap from SRAM masking */\r
- int X, /* only non zero pixels to VRAM. Clip X & Y */\r
- int Y,\r
- WORD ScrnOffs,\r
- BYTE far * VBitmap);\r
-\r
-char far * x_make_vbm(\r
- char far *lbm,\r
- WORD *VramStart);\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-\r
-#endif\r
-\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XVBITMAP - Include file\r
-;\r
-; XVBITMAP.ASM export functions\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
- global _x_store_vbm_image :proc\r
- global _x_put_masked_vbm :proc\r
- global _x_put_masked_vbm_clipx :proc\r
- global _x_put_masked_vbm_clipy :proc\r
- global _x_put_masked_vbm_clipxy :proc\r
-\1a
\ No newline at end of file
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XVBMTOOL - Include file\r
-;\r
-; XVBMTOOL.ASM export functions\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-; ****** Aeronautical Research Laboratory ****************\r
-; ****** Defence Science and Technology Organisation ****************\r
-; ****** Australia ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
- global _x_store_vbm_image :proc\r
-\1a
\ No newline at end of file
+++ /dev/null
-; MODULE XVSYNC\r
-; Xlib comptible vsync handler\r
-; Written by Tore Bastiansen\r
-; based on REND386 by Dave Stampe and Bernie Roehl\r
-\r
-include xlib.inc\r
-include xmain.inc\r
-include xvsync.inc\r
-\r
-\r
-TIMER_VECT equ 08h\r
-\r
-PIC_CMD equ 20h\r
-NONSPEC_EOI equ 20h\r
-TIMER_MODE equ 34h\r
-TIMER_CONTROL equ 43h\r
-TIMER_0 equ 40h\r
-\r
-LATCH_COUNT equ 00h\r
-\r
-INT_IN_ADVANCE equ 100\r
-\r
-DOS_GETVECT equ 3500h\r
-DOS_SETVECT equ 2500h\r
-\r
-\r
-.data\r
-_TicksPerSecond dw 0\r
-_VsyncIntTicks label dword\r
-VsyncIntTicksLo dw 0\r
-VsyncIntTicksHi dw 0\r
-_VsyncPeriod dw 0 ;Time (in clicks) between each vsync\r
- ;1 click = 1.193 microseconds\r
-\r
-ClockRate dw 0 ;Clock rate (in clicks) for timer 0\r
-ClockCounter dw 0 ;Counts total clicks modulo 65536\r
-UserVsyncHandler label dword ;Pointer to user routine called\r
-UserVsyncOffs dw 0 ;called once each vsync period.\r
-UserVsyncSeg dw 0\r
-InUserHandler dw 0\r
- db 100h dup(?)\r
-LocalStack label byte ;Local stack for user handler\r
-StackSeg dw 0\r
-StackPtr dw 0\r
-\r
-\r
-ElapsedVrts dw 0\r
-VrtsToSkip dw 1\r
-\r
-.code\r
-get_vsync_period proc near\r
- mov al,TIMER_MODE ;Start timer\r
- out TIMER_CONTROL,al\r
- mov al,0\r
- out TIMER_0,al\r
- out TIMER_0,al\r
-\r
- WaitVsyncStart\r
-\r
- mov al,LATCH_COUNT\r
- out TIMER_CONTROL,al\r
- in al,TIMER_0\r
- mov cl,al\r
- in al,TIMER_0\r
- mov ch,al ;cx=65536-clicks\r
-\r
- WaitVsyncStart\r
-\r
- mov al,LATCH_COUNT\r
- out TIMER_CONTROL,al\r
- in al,TIMER_0\r
- mov dl,al\r
- in al,TIMER_0\r
- mov dh,al ;dx=65536-clicks\r
-\r
- sub cx,dx ;cx=clicks between two vsyncs\r
- mov ax,cx ;return in ax\r
- ret\r
-get_vsync_period endp\r
-\r
-vsync_int proc far\r
- pusha ;Save regs\r
- push ds\r
- push es\r
-\r
- mov ax,@data ;Set the right datasegment\r
- mov ds,ax\r
- add [VsyncIntTicksLo],1 ;Increment _VsyncIntTicks\r
- adc [VsyncIntTicksHi],0\r
-\r
- inc [ElapsedVrts]\r
- mov cx,[ElapsedVrts]\r
- cmp cx,[VrtsToSkip]\r
- jl @@StopClock\r
-\r
- cmp [_StartAddressFlag],1 ;Change in start address\r
- jne @@StopClock\r
-\r
- mov dx,CRTC_INDEX ;Yes, set start address\r
- mov ax,[_WaitingStartLow]\r
- mov bx,[_WaitingStartHigh]\r
- out dx,ax\r
- mov ax,bx\r
- out dx,ax\r
-\r
-@@StopClock:\r
- cli\r
- mov al,TIMER_MODE ;Stop the timer\r
- out TIMER_CONTROL,al ;Dont want any interrupts\r
- mov al,255\r
- out TIMER_0,al\r
- out TIMER_0,al\r
- sti\r
-\r
- cli\r
- mov dx,INPUT_STATUS_0 ;Wait for vsync\r
-@@WaitVS:\r
- in al,dx\r
- test al,08h\r
- jz @@WaitVS\r
-\r
- mov al,TIMER_MODE ;Start timer again\r
- out TIMER_CONTROL,al\r
- mov ax,[ClockRate]\r
- out TIMER_0,al\r
- mov al,ah\r
- out TIMER_0,al\r
-\r
- cmp cx,[VrtsToSkip]\r
- jl @@PaletteInt\r
-\r
- cmp [_StartAddressFlag],1 ;Any change in start address ?\r
- jne @@PaletteInt\r
-\r
- xor cx,cx\r
- mov [ElapsedVrts],cx\r
-\r
- mov ax,[_WaitingPelPan] ;Yes, set pel pan register\r
- mov dx,AC_INDEX\r
- out dx,al\r
- mov al,ah\r
- out dx,al\r
- mov [_StartAddressFlag],0\r
-\r
-@@PaletteInt:\r
- cmp [_VsyncPaletteCount],0 ;Any changes in the palette\r
- je @@MouseInt\r
- mov si, offset _VsyncPaletteBuffer ;Yes\r
- mov cx, [_VsyncPaletteCount]\r
- mov ax, [_VsyncPaletteStart]\r
- mov dx, DAC_WRITE_INDEX\r
- out dx, al\r
- mov dx, DAC_DATA\r
-\r
-@@DacOutLoop:\r
- outsb\r
- outsb\r
- outsb\r
- loop @@DacOutLoop\r
- mov [_VsyncPaletteCount],0\r
-\r
-@@MouseInt:\r
- cmp [_MouseRefreshFlag],1 ; Does the mouse need refresh\r
- jne @@UserInt\r
- call dword ptr [_MouseVsyncHandler] ; Yes\r
- ;(this is not yet implemented)\r
-\r
-@@UserInt:\r
- cmp [UserVsyncSeg], 0 ;Is the a user interrupt routine?\r
- je short @@Sim182\r
- cmp [InUserHandler],0 ;Yes, but is it already active?\r
- jne short @@Sim182\r
- mov [InUserHandler],1 ;No, mark it as active\r
- mov [StackSeg],ss ;make a local stack\r
- mov [StackPtr],sp\r
- push ds\r
- pop ss\r
- mov sp, offset LocalStack\r
- sti\r
- call dword ptr [UserVsyncHandler]\r
- cli\r
- mov sp, [StackPtr] ;Restore old stack\r
- mov ss, [StackSeg]\r
- mov [InUserHandler],0 ;Mark as not active\r
-\r
-; SIM 18.2 Hz\r
-@@Sim182:\r
- mov ax,[_VsyncPeriod] ;Count number of clicks\r
- add [ClockCounter],ax ;If it is bigger than 65536\r
- jnc short @@DontChainOld\r
- pop es ;more than 1/18.2 secs has gone\r
- pop ds\r
- popa\r
- sti\r
- db 0eah ; jmp instruction\r
- OldTimerInt dd 0 ; Pointer to old int8 routine\r
- ; Selfmodyfiing code\r
- ;jmp dword ptr [OldTimerInt] Chain to old\r
-@@DontChainOld:\r
-\r
-; CLEAN UP AND RETURN\r
- mov al,NONSPEC_EOI\r
- out PIC_CMD,al\r
-\r
-\r
- pop es\r
- pop ds\r
- popa\r
- sti\r
- iret\r
-vsync_int endp\r
-\r
-\r
-_x_install_vsync_handler proc\r
-ARG VrtSkipCount:word\r
- push bp\r
- mov bp,sp\r
- mov ax,[VrtSkipCount]\r
- or ax,ax\r
- jnz @@NonZeroCount\r
- mov ax,1\r
-@@NonZeroCount:\r
- mov [VrtsToSkip],ax\r
- mov [ElapsedVrts],0\r
- cmp [_VsyncHandlerActive],TRUE ;Is it already active\r
- je short @@Return\r
- call get_vsync_period ;no, get the vsync period\r
-\r
- mov [_VsyncPeriod],ax\r
- sub ax,INT_IN_ADVANCE ;We need a little extra\r
- mov [ClockRate],ax ;time\r
-\r
- mov dx,18 ;dx:ax=1193000\r
- mov ax,13352\r
- idiv [_VsyncPeriod]\r
- mov [_TicksPerSecond],ax ;1193/_VsyncPeriod\r
-\r
- mov word ptr [_VsyncIntTicks],0\r
- mov word ptr [_VsyncIntTicks+2],0\r
-\r
- cli\r
- mov ax, DOS_GETVECT+TIMER_VECT ;Get address of old timer int\r
- int 21h\r
- mov ax,es\r
- mov word ptr cs:[OldTimerInt],bx ;Store in OldTimerInt\r
- mov word ptr cs:[OldTimerInt+2],ax\r
-\r
- mov [_VsyncHandlerActive],TRUE ;Mark handler as active\r
- mov ax,DOS_SETVECT+TIMER_VECT ;Set the new timer int\r
- push ds\r
- mov dx,seg vsync_int\r
- mov ds,dx\r
- mov dx,offset vsync_int\r
- int 21h\r
- pop ds\r
-\r
- mov al,TIMER_MODE ;Reprogram timer 0\r
- out TIMER_CONTROL,al\r
- mov ax,ClockRate\r
- out TIMER_0,al\r
- mov al,ah\r
- out TIMER_0,al\r
- sti\r
-@@Return:\r
- pop bp\r
- ret\r
-_x_install_vsync_handler endp\r
-\r
-_x_remove_vsync_handler proc\r
- cmp [_VsyncHandlerActive],FALSE\r
- je short @@Return\r
- mov dx, word ptr cs:[OldTimerInt]\r
- mov ax, word ptr cs:[OldTimerInt+2]\r
- push ds\r
- mov ds,ax\r
- mov ax,DOS_SETVECT+TIMER_VECT ;Restore the old timer int\r
- cli\r
- int 21h\r
- pop ds\r
- mov al,TIMER_MODE ;Restore timer 0\r
- out TIMER_CONTROL,al\r
- mov al,0\r
- out TIMER_0,al\r
- out TIMER_0,al\r
- sti\r
-@@Return:\r
- ret\r
-_x_remove_vsync_handler endp\r
-\r
-\r
-; WARNING: The user vsync handler cannot use the 386 specific registers\r
-; (EAX,EBX,ECX,EDX,ESI,EDI,ESP,EBP,FS,GS)\r
-; whithout saving them first.\r
-; It must not do any drawing.\r
-; Only 256 butes of stack is provided.\r
-\r
-_x_set_user_vsync_handler proc\r
-ARG handler_proc:dword\r
- push bp\r
- mov bp,sp\r
- mov ax, word ptr [handler_proc]\r
- mov dx, word ptr [handler_proc+2]\r
- cli\r
- mov word ptr [UserVsyncHandler],ax\r
- mov word ptr [UserVsyncHandler+2],dx\r
- sti\r
- pop bp\r
- ret\r
-_x_set_user_vsync_handler endp\r
-\r
-end\r
+++ /dev/null
-#ifndef _XVSYNC_H_\r
-#define _XVSYNC_H_\r
-\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
- void x_install_vsync_handler(int skipcount);\r
- void x_remove_vsync_handler(void);\r
- void x_set_user_vsync_handler(void far (*)());\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-\r
-extern WORD TicksPerSecond;\r
-extern volatile long VsyncIntTicks;\r
-extern WORD VsyncPeriod;\r
-\r
-#endif\r
+++ /dev/null
-global _x_install_vsync_handler :proc\r
-global _x_remove_vsync_handler :proc\r
-global _x_set_user_vsync_handler :proc\r
-global _TicksPerSecond :word\r
-global _VsyncIntTicks :dword\r
-global _VsyncPeriod :word\r
+++ /dev/null
-pkzip -a xlib06.zip MAKEFILE\r
-\r
-pkzip -a xlib06.zip XBEZIER.ASM\r
-pkzip -a xlib06.zip XBMTOOLS.ASM\r
-pkzip -a xlib06.zip XCBITMAP.ASM\r
-pkzip -a xlib06.zip XCOMPPBM.ASM\r
-pkzip -a xlib06.zip XDETECT.ASM\r
-pkzip -a xlib06.zip XFILEIO.ASM\r
-pkzip -a xlib06.zip XLINE.ASM\r
-pkzip -a xlib06.zip XMAIN.ASM\r
-pkzip -a xlib06.zip XMOUSE.ASM\r
-pkzip -a xlib06.zip XPAL.ASM\r
-pkzip -a xlib06.zip XPBITMAP.ASM\r
-pkzip -a xlib06.zip XPBMCLIP.ASM\r
-pkzip -a xlib06.zip XPOINT.ASM\r
-pkzip -a xlib06.zip XRECT.ASM\r
-pkzip -a xlib06.zip XRLETOOL.ASM\r
-pkzip -a xlib06.zip XTEXT.ASM\r
-pkzip -a xlib06.zip XVBITMAP.ASM\r
-pkzip -a xlib06.zip XCIRCLE.ASM\r
-pkzip -a xlib06.zip XCLIPPBM.ASM\r
-pkzip -a xlib06.zip XPOLYGON.ASM\r
-pkzip -a xlib06.zip XFILL.ASM\r
-pkzip -a xlib06.zip XVSYNC.ASM\r
-\r
-pkzip -a xlib06.zip XCBITM32.C\r
-pkzip -a xlib06.zip DEMO1.C\r
-pkzip -a xlib06.zip DEMO2.C\r
-pkzip -a xlib06.zip DEMO3.C\r
-pkzip -a xlib06.zip DEMO4.C\r
-pkzip -a xlib06.zip DEMO5.C\r
-pkzip -a xlib06.zip DEMO6.C\r
-pkzip -a xlib06.zip DEMO7.C\r
-pkzip -a xlib06.zip DEMO8.C\r
-pkzip -a xlib06.zip DEMO9.C\r
-pkzip -a xlib06.zip DEMO10.CPP\r
-\r
-pkzip -a xlib06.zip XMAKEVBM.C\r
-pkzip -a xlib06.zip XPRINTF.C\r
-pkzip -a xlib06.zip UPDATES.DOC\r
-pkzip -a xlib06.zip XLIBREF1.DOC\r
-pkzip -a xlib06.zip XLIBREF2.DOC\r
-pkzip -a xlib06.zip DEMO7.EXE\r
-pkzip -a xlib06.zip DEMO1.EXE\r
-pkzip -a xlib06.zip DEMO2.EXE\r
-pkzip -a xlib06.zip DEMO3.EXE\r
-pkzip -a xlib06.zip DEMO4.EXE\r
-pkzip -a xlib06.zip DEMO5.EXE\r
-pkzip -a xlib06.zip DEMO6.EXE\r
-pkzip -a xlib06.zip DEMO8.EXE\r
-pkzip -a xlib06.zip DEMO9.EXE\r
-pkzip -a xlib06.zip DEMO10.EXE\r
-\r
-pkzip -a xlib06.zip FIXED6X8.FNT\r
-pkzip -a xlib06.zip VAR6X8.FNT\r
-pkzip -a xlib06.zip VARSWISL.FNT\r
-pkzip -a xlib06.zip VARSWISB.FNT\r
-pkzip -a xlib06.zip TIMPANI.FNT\r
-pkzip -a xlib06.zip MODERNB.FNT\r
-pkzip -a xlib06.zip CRISP6X9.FNT\r
-pkzip -a xlib06.zip TINY4.FNT\r
-pkzip -a xlib06.zip SMALTHIN.FNT\r
-\r
-pkzip -a xlib06.zip XBEZIER.H\r
-pkzip -a xlib06.zip XBMTOOLS.H\r
-pkzip -a xlib06.zip XCBITMAP.H\r
-pkzip -a xlib06.zip XCOMPPBM.H\r
-pkzip -a xlib06.zip XDETECT.H\r
-pkzip -a xlib06.zip XFILEIO.H\r
-pkzip -a xlib06.zip XLIB.H\r
-pkzip -a xlib06.zip XLIB_ALL.H\r
-pkzip -a xlib06.zip XLINE.H\r
-pkzip -a xlib06.zip XMOUSE.H\r
-pkzip -a xlib06.zip XPAL.H\r
-pkzip -a xlib06.zip XPBITMAP.H\r
-pkzip -a xlib06.zip XPBMCLIP.H\r
-pkzip -a xlib06.zip XPOINT.H\r
-pkzip -a xlib06.zip XRECT.H\r
-pkzip -a xlib06.zip XRLETOOL.H\r
-pkzip -a xlib06.zip XTEXT.H\r
-pkzip -a xlib06.zip XVBITMAP.H\r
-pkzip -a xlib06.zip XCIRCLE.H\r
-pkzip -a xlib06.zip XCLIPPBM.H\r
-pkzip -a xlib06.zip XPOLYGON.H\r
-pkzip -a xlib06.zip XFILL.H\r
-pkzip -a xlib06.zip XVSYNC.H\r
-pkzip -a xlib06.zip XCBITM32.H\r
-\r
-pkzip -a xlib06.zip MODEL.INC\r
-pkzip -a xlib06.zip XBEZIER.INC\r
-pkzip -a xlib06.zip XBMTOOLS.INC\r
-pkzip -a xlib06.zip XCBITMAP.INC\r
-pkzip -a xlib06.zip XCOMPPBM.INC\r
-pkzip -a xlib06.zip XDETECT.INC\r
-pkzip -a xlib06.zip XFILEIO.INC\r
-pkzip -a xlib06.zip XLIB.INC\r
-pkzip -a xlib06.zip XLINE.INC\r
-pkzip -a xlib06.zip XMAIN.INC\r
-pkzip -a xlib06.zip XPAL.INC\r
-pkzip -a xlib06.zip XPBITMAP.INC\r
-pkzip -a xlib06.zip XPBMCLIP.INC\r
-pkzip -a xlib06.zip XPOINT.INC\r
-pkzip -a xlib06.zip XRECT.INC\r
-pkzip -a xlib06.zip XRLETOOL.INC\r
-pkzip -a xlib06.zip XTEXT.INC\r
-pkzip -a xlib06.zip XVBITMAP.INC\r
-pkzip -a xlib06.zip XVBMTOOL.INC\r
-pkzip -a xlib06.zip XCIRCLE.INC\r
-pkzip -a xlib06.zip XCLIPPBM.INC\r
-pkzip -a xlib06.zip XPOLYGON.INC\r
-pkzip -a xlib06.zip XFILL.INC\r
-pkzip -a xlib06.zip XVSYNC.INC\r
-\r
-pkzip -a xlib06.zip XLIB04S.LIB\r
-pkzip -a xlib06.zip XLIB04C.LIB\r
-pkzip -a xlib06.zip XLIB04L.LIB\r
-pkzip -a xlib06.zip ZIP.BAT\r
-\r
+++ /dev/null
-/* VERY QUICK AND ULTRA-DIRTY DEMO USING XLIB */\r
-\r
-/* Simple Demo of MODE X Split screen and panning */\r
-/* Compile using Turbo C and Tasm */\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <conio.h>\r
-#include <ctype.h>\r
-#include <alloc.h>\r
-#include <dos.h>\r
-#include "Xlib_all.h"\r
-\r
-#define MAX_OBJECTS 10\r
-\r
-static char *texttest[6] =\r
- {"This is a demonstration of the fonts ",\r
- "available in XLIB. Notice fixed and ",\r
- "variabe spaced fonts are supported but",\r
- "are limited to a maximum of 8 pixels in",\r
- "width. Height of the characters is ",\r
- "ofcourse unlimited..."};\r
-\r
-typedef struct {\r
- int X,Y,Width,Height,XDir,YDir,XOtherPage,YOtherPage;\r
- char far * Image;\r
- char far * bg;\r
- char far * bgOtherPage;\r
-} AnimatedObject;\r
-\r
-AnimatedObject objects[MAX_OBJECTS];\r
-int object_count=0;\r
-\r
-static char bm[] = {4,12,\r
- /* plane 0 */\r
- 2,2,2,2,2,1,1,1,2,1,1,1,2,3,3,1,\r
- 2,0,0,3,2,0,0,3,2,0,0,3,2,0,0,3,\r
- 2,3,3,1,2,1,1,1,2,1,1,1,2,2,2,2,\r
- /* plane 1 */\r
- 2,2,2,2,1,1,1,1,1,1,1,1,1,3,3,1,\r
- 1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,\r
- 1,3,3,1,1,1,1,1,1,1,1,1,2,2,2,2,\r
- /* plane 2 */\r
- 2,2,2,2,1,1,1,1,1,1,1,1,1,3,3,1,\r
- 1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,\r
- 1,3,3,1,1,1,1,1,1,1,1,1,2,2,2,2,\r
- /* plane 3 */\r
- 2,2,2,2,1,1,1,2,1,1,1,2,1,3,3,2,\r
- 3,0,0,2,3,0,0,2,3,0,0,2,3,0,0,2,\r
- 1,3,3,2,1,1,1,2,1,1,1,2,2,2,2,2};\r
-\r
-static char bm2[] = {4,12,\r
- /* plane 0 */\r
- 2,2,2,2,2,4,4,4,2,4,4,4,2,2,2,4,\r
- 2,0,0,2,2,0,0,2,2,0,0,2,2,0,0,2,\r
- 2,2,2,4,2,4,4,4,2,4,4,4,2,2,2,2,\r
- /* plane 1 */\r
- 2,2,2,2,4,4,4,4,4,4,4,4,4,2,2,4,\r
- 4,0,0,4,4,0,0,4,4,0,0,4,4,0,0,4,\r
- 4,2,2,4,4,4,4,4,4,4,4,4,2,2,2,2,\r
- /* plane 2 */\r
- 2,2,2,2,4,4,4,4,4,4,4,4,4,2,2,4,\r
- 4,0,0,4,4,0,0,4,4,0,0,4,4,0,0,4,\r
- 4,2,2,4,4,4,4,4,4,4,4,4,2,2,2,2,\r
- /* plane 2 */\r
- 2,2,2,2,4,4,4,2,4,4,4,2,4,2,2,2,\r
- 2,0,0,2,2,0,0,2,2,0,0,2,2,0,0,2,\r
- 4,2,2,2,4,4,4,2,4,4,4,2,2,2,2,2};\r
-\r
-int textwindow_x=0,textwindow_y=0;\r
-char far * pal,far * pal2;\r
-char palscrolldir=1;\r
-char far * userfnt1;\r
-\r
-\r
-\r
-void drawtext(int height){\r
- int i;\r
- for (i=0;i<6;i++)\r
- x_printf(textwindow_x+5,50+i*(height+2),VisiblePageOffs,9,texttest[i]);\r
-}\r
-\r
-/* initialize a new object */\r
-void init_object(int x,int y,int width, int height, int xdir, int ydir,\r
- char far * image){\r
- int i;\r
- objects[object_count].X = objects[object_count].XOtherPage = x;\r
- objects[object_count].Y = objects[object_count].YOtherPage = y;\r
- objects[object_count].Width = width;\r
- objects[object_count].Height = height;\r
- objects[object_count].XDir = xdir;\r
- objects[object_count].YDir = ydir;\r
- objects[object_count].Image = image;\r
- objects[object_count].bg = (char far *) farmalloc(4*width*height+20);\r
- objects[object_count].bgOtherPage = (char far *) farmalloc(4*width*height+20);\r
- x_get_pbm(x,y,(unsigned)width,height,VisiblePageOffs,\r
- objects[object_count].bg);\r
- x_get_pbm(x,y,(unsigned)width,height,HiddenPageOffs,\r
- objects[object_count].bgOtherPage);\r
- object_count++;\r
-}\r
-\r
-/* Move the specified object, bouncing at the edges of the screen and\r
- remembering where the object was before the move for erasing next time */\r
-void MoveObject(AnimatedObject * ObjectToMove) {\r
- int X, Y;\r
- char far *cptr;\r
- X = ObjectToMove->X + ObjectToMove->XDir;\r
- Y = ObjectToMove->Y + ObjectToMove->YDir;\r
- if ((X < 0) || (X > (ScrnLogicalPixelWidth-((ObjectToMove->Width)<<2)))) {\r
- ObjectToMove->XDir = -ObjectToMove->XDir;\r
- X = ObjectToMove->X + ObjectToMove->XDir;\r
- }\r
- if ((Y < 0) || (Y > (ScrnLogicalHeight-ObjectToMove->Height))) {\r
- ObjectToMove->YDir = -ObjectToMove->YDir;\r
- Y = ObjectToMove->Y + ObjectToMove->YDir;\r
- }\r
- /* Remember previous location for erasing purposes */\r
- ObjectToMove->XOtherPage = ObjectToMove->X;\r
- ObjectToMove->YOtherPage = ObjectToMove->Y;\r
- ObjectToMove->X = X; /* set new location */\r
- ObjectToMove->Y = Y;\r
- cptr = ObjectToMove->bg;\r
- ObjectToMove->bg = ObjectToMove->bgOtherPage;\r
- ObjectToMove->bgOtherPage = cptr;\r
-}\r
-\r
-void animate(void){\r
- int i;\r
- for(i=object_count-1;i>=0;i--){\r
- x_put_pbm(objects[i].XOtherPage,objects[i].YOtherPage,\r
- HiddenPageOffs,objects[i].bgOtherPage);\r
- }\r
- for(i=0;i<object_count;i++){\r
- MoveObject(&objects[i]);\r
-\r
- x_get_pbm(objects[i].X,objects[i].Y,\r
- (unsigned)objects[i].Width,objects[i].Height,HiddenPageOffs,\r
- objects[i].bg);\r
- x_put_masked_pbm(objects[i].X,objects[i].Y,HiddenPageOffs,\r
- objects[i].Image);\r
- }\r
-}\r
-\r
-void clear_objects(void){\r
- int i;\r
- for(i=object_count-1;i>=0;i--){\r
- x_put_pbm(objects[i].XOtherPage,objects[i].YOtherPage,\r
- HiddenPageOffs,objects[i].bgOtherPage);\r
- }\r
-}\r
-\r
-\r
-void textwindow(int Margin){\r
- int x0=0+Margin;\r
- int y0=0+Margin;\r
- int x1=ScrnPhysicalPixelWidth-Margin;\r
- int y1=ScrnPhysicalHeight-Margin;\r
- x_rect_fill(x0, y0, x1,y1,VisiblePageOffs,1);\r
- x_line(x0,y0,x1,y0,2,VisiblePageOffs);\r
- x_line(x0,y1,x1,y1,2,VisiblePageOffs);\r
- x_line(x0,y0,x0,y1,2,VisiblePageOffs);\r
- x_line(x1,y0,x1,y1,2,VisiblePageOffs);\r
- x_line(x0+2,y0+2,x1-2,y0+2,2,VisiblePageOffs);\r
- x_line(x0+2,y1-2,x1-2,y1-2,2,VisiblePageOffs);\r
- x_line(x0+2,y0+2,x0+2,y1-2,2,VisiblePageOffs);\r
- x_line(x1-2,y0+2,x1-2,y1-2,2,VisiblePageOffs);\r
- textwindow_x=x0;\r
- textwindow_y=y0;\r
-\r
-}\r
-\r
-\r
-void wait_for_keypress(void){\r
- x_show_mouse();\r
- while(kbhit()) getch();\r
- palscrolldir^=1;\r
-\r
- do {\r
- x_rot_pal_struc(pal,palscrolldir);\r
- MouseFrozen=1;\r
- x_put_pal_struc(pal);\r
- x_update_mouse();\r
- } while (!kbhit() && !(MouseButtonStatus==LEFT_PRESSED));\r
- while(MouseButtonStatus==LEFT_PRESSED);\r
- while(kbhit()) getch();\r
-\r
-}\r
-\r
-\r
-void exitfunc(void){\r
- x_mouse_remove();\r
- x_remove_vsync_handler();\r
- x_text_mode();\r
- printf("Thanks to everyone who assisted in the development of XLIB.\n");\r
- printf("\nSpecial thanks to Matthew Mackenzie for contributing \n");\r
- printf("lots of code, documentation and ideas.\n\n");\r
- printf("If you make any money using this code and you're the generous\n");\r
- printf("type please send us some, or at least a copy of your program!\n");\r
-}\r
-\r
-int terminate(void){\r
- exit(0);\r
-}\r
-\r
-void intro_1(void){\r
- x_set_rgb(1,40,40,40); /* BG Gray */\r
- x_set_rgb(2,63,63,0); /* Bright Yellow */\r
- x_set_rgb(3,63,0,0); /* Bright Red */\r
- x_set_rgb(4,0,63,0); /* Bright Green */\r
- x_set_rgb(5,0,0,63); /* Bright Blue */\r
- x_set_rgb(6,0,0,28); /* Dark Blue */\r
- x_set_rgb(7,0,28,0); /* Dark Green */\r
- x_set_rgb(8,28,0,0); /* Dark red */\r
- x_set_rgb(9,0,0,38); /* Med Blue */\r
-\r
- textwindow(20);\r
- x_set_font(1);\r
- x_printf(textwindow_x+54,textwindow_y+4,VisiblePageOffs,6," XLIB Version 6.0");\r
- x_printf(textwindow_x+53,textwindow_y+3,VisiblePageOffs,2," XLIB Version 6.0");\r
- x_set_font(0);\r
- x_printf(textwindow_x+24,textwindow_y+18,VisiblePageOffs,6," Not the Unix version");\r
- x_printf(textwindow_x+23,textwindow_y+17,VisiblePageOffs,2," Not the Unix version");\r
-\r
- x_printf(textwindow_x+24,168,VisiblePageOffs,6," Press any key to continue");\r
- x_printf(textwindow_x+23,167,VisiblePageOffs,2," Press any key to continue");\r
-}\r
-\r
-void subsequent_page(void){\r
- x_hide_mouse();\r
- textwindow(20);\r
- x_set_font(1);\r
- x_printf(textwindow_x+54,textwindow_y+4,VisiblePageOffs,6," XLIB Version 6.0");\r
- x_printf(textwindow_x+53,textwindow_y+3,VisiblePageOffs,2," XLIB Version 6.0");\r
- x_set_font(0);\r
- x_printf(textwindow_x+24,168,VisiblePageOffs,6," Press any key to continue");\r
- x_printf(textwindow_x+23,167,VisiblePageOffs,2," Press any key to continue");\r
-}\r
-\r
-void load_user_fonts(void){\r
- FILE *f;\r
- f=fopen("var6x8.fnt","rb");\r
- /* read char by char as fread wont read to far pointers in small model */\r
- { int i; char c;\r
- for (i=0;i<256*8+4;i++){\r
- fread(&c,1,1,f);\r
- *(userfnt1+i)=c;\r
- }\r
- }\r
-\r
- fclose(f);\r
-\r
- x_register_userfont(userfnt1);\r
-\r
-}\r
-\r
-\r
-\r
-void main(){\r
- int i, j, xinc, yinc, Margin;\r
- char ch;\r
- WORD curr_x=0, curr_y=0;\r
-\r
- pal = (char far *) farmalloc(256*3);\r
- pal2 = (char far *) farmalloc(256*3);\r
- userfnt1 = (char far *) farmalloc(256*16+4);\r
-\r
-\r
- /* INITIALIZE XLIB */\r
-\r
- /* we set up Mode X 360x200x256 with a logical width of ~ 500 */\r
- /* pixels; we actually get 496 due to the fact that the width */\r
- /* must be divisible by 8 */\r
-\r
- x_text_mode(); /* make sure VGA is in color mode, if possible */\r
- x_set_mode(X_MODE_360x200,500); /* actually is set to 496 */\r
- x_install_vsync_handler(2);\r
- x_set_splitscreen(ScrnPhysicalHeight-60); /* split screen 60 pixels high */\r
- x_set_doublebuffer(220);\r
- x_text_init();\r
- x_hide_splitscreen();\r
- x_mouse_init();\r
- MouseColor=2;\r
- atexit(exitfunc);\r
-\r
- /* DRAW BACKGROUND LINES */\r
-\r
- for(j=0;j<ScrnPhysicalHeight;j++){\r
- x_line(0,j,ScrnLogicalPixelWidth,j,16+(j%239),VisiblePageOffs);\r
- }\r
-\r
- ctrlbrk(terminate);\r
- x_get_pal_struc(pal, 240,16);\r
- load_user_fonts();\r
-\r
- intro_1();\r
- x_set_font(2);\r
- x_hide_mouse();\r
- x_printf(textwindow_x+5,50 ,VisiblePageOffs,9, " Hi, folks. This is yet another FREEWARE Mode X");\r
- x_printf(textwindow_x+5,50+8 ,VisiblePageOffs,9, " graphics library. It is by no means complete,");\r
- x_printf(textwindow_x+5,50+16,VisiblePageOffs,9, " but I believe it contains a rich enough set of");\r
- x_printf(textwindow_x+5,50+24,VisiblePageOffs,9, " functions to achieve its design goal - to be");\r
- x_printf(textwindow_x+5,50+32,VisiblePageOffs,9, " a game development oriented library for");\r
- x_printf(textwindow_x+5,50+40,VisiblePageOffs,9, " Borland TC/BC/BC++ and TASM programmers.");\r
-\r
- x_printf(textwindow_x+5,50+48,VisiblePageOffs,9, " This library comes with TASM and C sources.");\r
- x_printf(textwindow_x+5,50+56,VisiblePageOffs,9, " It was inspired by the DDJ Graphics column and");\r
- x_printf(textwindow_x+5,50+64,VisiblePageOffs,9, " many INTERNET and USENET authors who, unlike the");\r
- x_printf(textwindow_x+5,50+72,VisiblePageOffs,9, " majority of programmers (you know who you are!),");\r
- x_printf(textwindow_x+5,50+80,VisiblePageOffs,9, " willingly share their code and ideas with others.");\r
-\r
- x_printf(textwindow_x+5,50+88,VisiblePageOffs,9, " I can't afford, nor do I want, to copyright");\r
- x_printf(textwindow_x+5,50+96,VisiblePageOffs,9, " this code - but if you use it, some credit would ");\r
- x_printf(textwindow_x+5,50+104,VisiblePageOffs,9," be appreciated. ");\r
-\r
- wait_for_keypress();\r
-\r
- subsequent_page();\r
- x_set_font(0);\r
- x_printf(textwindow_x+24,textwindow_y+18,VisiblePageOffs,6,"Supported 256 colour resolutions.");\r
- x_printf(textwindow_x+23,textwindow_y+17,VisiblePageOffs,3,"Supported 256 colour resolutions.");\r
- x_set_font(2);\r
- x_printf(textwindow_x+5,50 ,VisiblePageOffs,9, " 320x200 Standard for games ~ 4 pages");\r
- x_printf(textwindow_x+5,50+8 ,VisiblePageOffs,9, " 320x240 DDJ Mode X square pixels ~ 3.5 pages");\r
- x_printf(textwindow_x+5,50+16,VisiblePageOffs,9, " 360x200 My favourite for games ~ 3 pages ");\r
- x_printf(textwindow_x+5,50+24,VisiblePageOffs,9, " 360x240 ~ 2.8 pages");\r
- x_printf(textwindow_x+5,50+32,VisiblePageOffs,9, " 320x400 ~ 2 pages ");\r
- x_printf(textwindow_x+5,50+40,VisiblePageOffs,9, " 320x480 All subsequent modes support");\r
- x_printf(textwindow_x+5,50+48,VisiblePageOffs,9, " 360x400 less than two pages.");\r
- x_printf(textwindow_x+5,50+56,VisiblePageOffs,9, " 360x480");\r
- x_printf(textwindow_x+5,50+64,VisiblePageOffs,9, " 376x282,360x360,376x308,376x564,256x200,256x240");\r
- x_printf(textwindow_x+5,50+72,VisiblePageOffs,9, " Phew! and they'll run on all VGA cards and ");\r
- x_printf(textwindow_x+5,50+80,VisiblePageOffs,9, " monitors (some of the weird ones are best suited");\r
- x_printf(textwindow_x+5,50+88,VisiblePageOffs,9, " to monitors with both vert & horiz adjustments)");\r
- x_printf(textwindow_x+5,50+98,VisiblePageOffs,2, " ");\r
- x_printf(textwindow_x+5,50+106,VisiblePageOffs,2," Overkill? Maybe!! ");\r
-\r
-\r
- wait_for_keypress();\r
-\r
- subsequent_page();\r
- x_printf(textwindow_x+24,textwindow_y+18,VisiblePageOffs,6," Text display functions.");\r
- x_printf(textwindow_x+23,textwindow_y+17,VisiblePageOffs,3," Text display functions.");\r
- x_set_font(2);\r
- x_printf(textwindow_x+5,50 ,VisiblePageOffs,9, " Several text printing functions are provided.");\r
- x_printf(textwindow_x+5,50+8 ,VisiblePageOffs,9, " They support the VGA ROM 8x14 and 8x8 fonts as");\r
- x_printf(textwindow_x+5,50+16,VisiblePageOffs,9, " well as user-defined fonts (like this 6x8 font).");\r
- x_printf(textwindow_x+5,50+24,VisiblePageOffs,9, " Furthermore, a function similar to printf is");\r
- x_printf(textwindow_x+5,50+32,VisiblePageOffs,9, " included which provides formatted text output.");\r
- x_printf(textwindow_x+5,50+40,VisiblePageOffs,9, " User defined fonts may be proportionally spaced");\r
- x_printf(textwindow_x+5,50+58,VisiblePageOffs,9, " but have a maximum width of 8 pixels.");\r
-\r
-\r
- wait_for_keypress();\r
-\r
- subsequent_page();\r
- x_printf(textwindow_x+24,textwindow_y+18,VisiblePageOffs,6," Advanced screen functions.");\r
- x_printf(textwindow_x+23,textwindow_y+17,VisiblePageOffs,3," Advanced screen functions.");\r
- x_set_font(2);\r
- x_printf(textwindow_x+5,50 ,VisiblePageOffs,9, " The library supports virtual screens larger");\r
- x_printf(textwindow_x+5,50+8 ,VisiblePageOffs,9, " than the physical screen, panning of such");\r
- x_printf(textwindow_x+5,50+16,VisiblePageOffs,9, " screens, and a split screen option.");\r
- x_printf(textwindow_x+5,50+24,VisiblePageOffs,9, " These functions can be used together or");\r
- x_printf(textwindow_x+5,50+32,VisiblePageOffs,9, " in isolation, and in the lower resolutions");\r
- x_printf(textwindow_x+5,50+40,VisiblePageOffs,9, " double buffering can also be accomplished.");\r
-\r
- x_rect_fill(0, 0, ScrnPhysicalPixelWidth,60,SplitScrnOffs,5);\r
- x_line(0,0,ScrnPhysicalPixelWidth,0,2,SplitScrnOffs);\r
- x_set_font(1);\r
- x_printf(10,10,SplitScrnOffs,2, " This is a split screen, tops for scores.");\r
- x_set_font(0);\r
- for (i=ScrnPhysicalHeight;i>ScrnPhysicalHeight-60;i--){\r
- x_adjust_splitscreen(i);\r
- }\r
- x_printf(10,25,SplitScrnOffs,2, " Even better for scrolling games etc.");\r
-\r
- x_cp_vid_rect(0,0,ScrnLogicalPixelWidth,ScrnLogicalHeight,0,0,\r
- VisiblePageOffs,HiddenPageOffs,\r
- ScrnLogicalPixelWidth,ScrnLogicalPixelWidth);\r
-\r
-\r
- x_show_mouse();\r
- wait_for_keypress();\r
-\r
- curr_x=curr_y=0;\r
-\r
-\r
- init_object(60,90,4, 12, -1, 1, MK_FP(FP_SEG(bm2),FP_OFF(bm2)));\r
- init_object(30,30,4, 12, 1, 1, MK_FP(FP_SEG(bm),FP_OFF(bm)));\r
- init_object(80,120,4, 12, 2, 1, MK_FP(FP_SEG(bm),FP_OFF(bm)));\r
- init_object(300,200,4, 12, 1, -2, MK_FP(FP_SEG(bm),FP_OFF(bm)));\r
- init_object(360,30,4, 12, -1, -1, MK_FP(FP_SEG(bm),FP_OFF(bm)));\r
- init_object(360,10,4, 12, -2, 2, MK_FP(FP_SEG(bm),FP_OFF(bm)));\r
-\r
- x_hide_mouse();\r
-\r
- while (!kbhit()&& !(MouseButtonStatus==LEFT_PRESSED)){\r
- animate();\r
- if (objects[0].X>=curr_x+ScrnPhysicalPixelWidth-32 &&\r
- curr_x < MaxScrollX) curr_x++;\r
- else if (objects[0].X < curr_x+16 && curr_x > 0) curr_x--;\r
- if (objects[0].Y>=curr_y+ScrnPhysicalHeight-92 &&\r
- curr_y < MaxScrollY) curr_y++;\r
- else if (objects[0].Y < curr_y+16 && curr_y > 0) curr_y--;\r
- x_page_flip(curr_x,curr_y);\r
- while(StartAddressFlag);\r
- }\r
- while(MouseButtonStatus==LEFT_PRESSED);\r
- while(kbhit()) getch();\r
-\r
- clear_objects();\r
- x_page_flip(curr_x,curr_y);\r
- while(StartAddressFlag);\r
-\r
-\r
- x_set_start_addr(0,0);\r
-\r
-\r
- for (j=0;j<4;j++){\r
- x_hide_splitscreen();\r
- delay(100);\r
- x_show_splitscreen();\r
- delay(100);\r
- }\r
-\r
-\r
- for (i=ScrnPhysicalHeight-60;i<=ScrnPhysicalHeight;i++){\r
- x_adjust_splitscreen(i);\r
- }\r
-\r
- x_hide_mouse();\r
- subsequent_page();\r
- x_printf(textwindow_x+24,textwindow_y+18,VisiblePageOffs,6," Palette functions.");\r
- x_printf(textwindow_x+23,textwindow_y+17,VisiblePageOffs,3," Palette functions.");\r
- x_set_font(2);\r
- x_printf(textwindow_x+5,50 ,VisiblePageOffs,9, " A number of palette manipulation functions");\r
- x_printf(textwindow_x+5,50+8 ,VisiblePageOffs,9, " are provided. You have already seen some of");\r
- x_printf(textwindow_x+5,50+16,VisiblePageOffs,9, " them in action. Another common operation is");\r
- x_printf(textwindow_x+5,50+24,VisiblePageOffs,9, " palette fading. ");\r
-\r
- i=0;\r
- ch=255;\r
- while (x_cpcontrast_pal_struc(pal, pal2,ch-=2)){\r
- x_put_pal_struc(pal2);\r
- x_rot_pal_struc(pal,palscrolldir);\r
- i++;\r
- };\r
- for (j=0;j<i;j++){\r
- x_cpcontrast_pal_struc(pal, pal2,ch+=2);\r
- x_put_pal_struc(pal2);\r
- x_rot_pal_struc(pal,palscrolldir);\r
- };\r
- wait_for_keypress();\r
-\r
- subsequent_page();\r
- x_printf(textwindow_x+24,textwindow_y+18,VisiblePageOffs,6," NEW Version 3.0 Functions!");\r
- x_printf(textwindow_x+23,textwindow_y+17,VisiblePageOffs,3," NEW Version 3.0 Functions!");\r
- x_set_font(2);\r
- x_printf(textwindow_x+5,50 ,VisiblePageOffs,9, " NEW functions not demonstrated here include:");\r
- x_printf(textwindow_x+5,50+10,VisiblePageOffs,9, " - RLE data compression");\r
- x_printf(textwindow_x+5,50+20,VisiblePageOffs,9, " - FAST compiled masked bitmaps");\r
- x_printf(textwindow_x+5,50+30,VisiblePageOffs,9, " - Hardware detection");\r
-\r
- x_show_mouse();\r
- wait_for_keypress();\r
-\r
- x_hide_mouse();\r
- for (i = 0; i < 150; i++) {\r
- x_circle(0, 0, i, 181 - i, VisiblePageOffs);\r
- x_circle(360 - i, 0, i, i + 30, VisiblePageOffs);\r
- x_circle(0, 200 - i, i, i + 30, VisiblePageOffs);\r
- x_circle(360 - i, 200 - i, i, 181 - i, VisiblePageOffs);\r
- }\r
- for (i = 0; i < 100; i++)\r
- x_filled_circle(80 + i, i, 201 - (i << 1), 30+i, VisiblePageOffs);\r
- x_show_mouse();\r
- wait_for_keypress();\r
-\r
- subsequent_page();\r
- x_printf(textwindow_x+24,textwindow_y+18,VisiblePageOffs,6," NEW Version 4.0 Functions!");\r
- x_printf(textwindow_x+23,textwindow_y+17,VisiblePageOffs,3," NEW Version 4.0 Functions!");\r
- x_set_font(2);\r
- x_printf(textwindow_x+5,50 ,VisiblePageOffs,9, " NEW functions not demonstrated here include:");\r
- x_printf(textwindow_x+5,50+10,VisiblePageOffs,9, " - FAST VRAM-based masked bitmaps, including");\r
- x_printf(textwindow_x+5,50+18,VisiblePageOffs,9, " support for clipping regions");\r
- x_printf(textwindow_x+5,50+28,VisiblePageOffs,9, " - Faster, smaller compiled bitmaps");\r
- x_printf(textwindow_x+5,50+38,VisiblePageOffs,9, " - Improved planar bitmap performance and");\r
- x_printf(textwindow_x+5,50+46,VisiblePageOffs,9, " additional support for clipping");\r
- x_printf(textwindow_x+5,50+56,VisiblePageOffs,9, " - mouse module");\r
- x_printf(textwindow_x+5,50+66,VisiblePageOffs,9, " - Detection of math co-processor and mouse");\r
- x_printf(textwindow_x+5,50+76,VisiblePageOffs,9, " - Bezier curve module");\r
- x_printf(textwindow_x+5,50+86,VisiblePageOffs,9, " - Four new resolutions, including one with");\r
- x_printf(textwindow_x+5,50+94,VisiblePageOffs,9, " square pixels (376x282)");\r
- x_printf(textwindow_x+5,50+104,VisiblePageOffs,9, " - More bug fixes");\r
-\r
- wait_for_keypress();\r
-\r
- subsequent_page();\r
- x_printf(textwindow_x+24,textwindow_y+18,VisiblePageOffs,6," NEW Version 5.0 Functions!");\r
- x_printf(textwindow_x+23,textwindow_y+17,VisiblePageOffs,3," NEW Version 5.0 Functions!");\r
- x_set_font(2);\r
- x_printf(textwindow_x+5,50 ,VisiblePageOffs,9, " - *FAST* filled and clipped triangles ideal for");\r
- x_printf(textwindow_x+5,50+10,VisiblePageOffs,9, " 3D work. Thanks to S. Dollins for the code.");\r
- x_printf(textwindow_x+5,50+20,VisiblePageOffs,9, " - Filled and clipped polygons, C++ Compatible");\r
- x_printf(textwindow_x+5,50+30,VisiblePageOffs,9, " - header files, and of course bug fixes!");\r
-\r
- x_show_mouse();\r
- wait_for_keypress();\r
-\r
- subsequent_page();\r
- x_printf(textwindow_x+24,textwindow_y+18,VisiblePageOffs,6," NEW Version 6.0 Functions!");\r
- x_printf(textwindow_x+23,textwindow_y+17,VisiblePageOffs,3," NEW Version 6.0 Functions!");\r
- x_set_font(2);\r
- x_printf(textwindow_x+5,50 ,VisiblePageOffs,9, " - Fast flood filling functions ");\r
- x_printf(textwindow_x+5,50+10,VisiblePageOffs,9, " - New pbm flipping put functions.");\r
- x_printf(textwindow_x+5,50+20,VisiblePageOffs,9, " - Timer synchronized vertical retrace");\r
- x_printf(textwindow_x+5,50+30,VisiblePageOffs,9, " - Tripple buffering extensions");\r
- x_printf(textwindow_x+5,50+40,VisiblePageOffs,9, " Checkout demo 9 and 10 for previews");\r
- \r
-\r
-\r
- x_show_mouse();\r
- wait_for_keypress();\r
-\r
-\r
- randomize();\r
- x_hide_mouse();\r
- while(kbhit()) getch();\r
- palscrolldir^=1;\r
- do {\r
- int x0,x1,x2,y0,y1,y2,i;\r
- i=random(256);\r
- x0=random(ScrnLogicalPixelWidth);\r
- x1=random(ScrnLogicalPixelWidth);\r
- x2=random(ScrnLogicalPixelWidth);\r
- y0=random(ScrnPhysicalHeight);\r
- y1=random(ScrnPhysicalHeight);\r
- y2=random(ScrnPhysicalHeight);\r
- x_triangle(x0,y0,x1,y1,x2,y2,i,VisiblePageOffs);\r
- } while (!kbhit() && !(MouseButtonStatus==LEFT_PRESSED));\r
- while(MouseButtonStatus==LEFT_PRESSED);\r
- while(kbhit()) getch();\r
- x_show_mouse();\r
-\r
- subsequent_page();\r
- x_printf(textwindow_x+24,textwindow_y+18,VisiblePageOffs,6," PLEASE...");\r
- x_printf(textwindow_x+23,textwindow_y+17,VisiblePageOffs,3," PLEASE...");\r
- x_set_font(2);\r
- x_printf(textwindow_x+5,50 ,VisiblePageOffs,9, " Please mention my name in programs that use XLIB");\r
- x_printf(textwindow_x+5,50+8 ,VisiblePageOffs,9, " just to make me feel it was worth the effort.");\r
- x_printf(textwindow_x+5,50+16,VisiblePageOffs,9, " If you have any bug to report please feel free to");\r
- x_printf(textwindow_x+5,50+24,VisiblePageOffs,9, " mail me a message. Any hints, suggestions and");\r
- x_printf(textwindow_x+5,50+32,VisiblePageOffs,9, " contributions are welcome and encouraged.");\r
- x_printf(textwindow_x+5,50+52,VisiblePageOffs,9, " I have contributed this code to the public domain.");\r
- x_printf(textwindow_x+5,50+60,VisiblePageOffs,9, " Please respect my wishes and leave it there.");\r
-\r
- x_printf(textwindow_x+5,50+80,VisiblePageOffs,9, " Finally, I hope you all find this stuff useful,");\r
- x_printf(textwindow_x+5,50+96,VisiblePageOffs,9, " Themie Gouthas - EGG@DSTOS3.DSTO.GOV.AU");\r
-\r
- wait_for_keypress();\r
-\r
- x_hide_mouse();\r
-\r
- x_shift_rect (27, 27, 360-27, 177, 27, 23, VisiblePageOffs);\r
- x_rect_fill(25, 173, 335, 176, VisiblePageOffs, 1);\r
- for (i = 0; i < 50; i++) {\r
- x_shift_rect (27, 26, 360-27, 177 - (i * 3), 27, 23, VisiblePageOffs);\r
- }\r
-}\r
-\r
-\r
+++ /dev/null
-/*************************************************************************\r
-\r
-DEMO 2\r
-\r
-Demonstrates the speed difference between compiled bitmap, conventional\r
-masked planar bitmap, and video bitmap blits.\r
-\r
-**************************************************************************/\r
-\r
-\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <conio.h>\r
-#include <ctype.h>\r
-#include <alloc.h>\r
-#include <dos.h>\r
-#include "xlib.h"\r
-#include "xcbitmap.h"\r
-#include "xpbitmap.h"\r
-#include "xvbitmap.h"\r
-#include "xbmtools.h"\r
-#include "xtext.h"\r
-#include "xrect.h"\r
-#include "xrect.h"\r
-\r
-/* Macro to make pointer parameters model independent */\r
-#define FARPTR(x) (MK_FP(FP_SEG(x),FP_OFF(x)))\r
-\r
-char turtle[] = {\r
- 20,30,\r
-/* | . | . | . | . */\r
- 8,14, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 8, 2,14, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 8, 2, 2, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 8, 0, 2,14, 0, 0,14,14,14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 8, 0, 2, 5, 0, 4, 4, 4, 4,14,14, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 8, 0, 2, 2, 4, 4, 0, 4, 4, 0, 4,14, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 2, 4, 4, 4, 0, 4, 4, 0, 4, 4,14, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 2, 4, 4, 4, 0, 0, 0, 0, 4, 4,14, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 4, 0, 4, 4, 4, 0, 0, 0, 4, 0, 0, 2, 2, 0, 0, 0,\r
- 0, 0, 0, 4, 0, 4, 4, 4, 0, 4, 4, 4, 0,14, 0, 0, 2, 2, 0, 0,\r
- 0, 0, 0, 4, 4, 0, 0, 0, 4, 4, 0, 4, 0, 4, 2, 2, 2, 2, 0, 0,\r
- 0, 0, 0, 4, 4, 4, 0, 4, 4, 0, 4, 4, 0, 4,14, 2, 2, 2, 0, 0,\r
- 0, 0, 0, 4, 4, 4, 0, 0, 0, 4, 4, 0, 4, 0, 0, 2, 2, 0, 0, 0,\r
- 0, 0, 0, 2, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4,14, 2, 0, 0, 0, 0,\r
- 0, 0, 2, 2, 0, 4, 4, 4, 4, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0,\r
- 2, 2, 2, 2, 4, 0, 0, 4, 4, 0, 4, 4, 0, 4,14, 0, 0, 0, 0, 0,\r
- 0, 2, 2, 0, 4, 4, 4, 0, 0, 4, 4, 0, 4, 0, 2, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 4, 4, 0, 4, 4, 4, 0, 4, 4, 2,14, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 0, 4, 0, 2, 2,14,14, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 4, 4, 2, 2, 2, 2, 2,14, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 5,14, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 0, 0, 2, 2, 2, 0, 2,14,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 2, 2, 2,14,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 2, 2, 2,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
- };\r
-\r
-\r
-char far *pbm, far *vbm;\r
-char far *newfnt;\r
-\r
-char far *\r
-AllocatedSprite(int width, int height, int logical_width, char far * bitmap)\r
-{\r
- char far * result;\r
- int size;\r
-\r
- pbm = farmalloc(width * height + 2);\r
- x_bm_to_pbm(bitmap,pbm);\r
-\r
- result = farmalloc((width * height * 7) / 2 + 25);\r
- if (result == 0)\r
- return(0);\r
- size = x_compile_bitmap(logical_width, bitmap, result);\r
-\r
- return farrealloc(result, size);\r
-}\r
-\r
-\r
-\r
-void load_user_fonts(){\r
- FILE *f;\r
- int i; char c;\r
-// f=fopen("c:\\font.fnt","rb");\r
- f=fopen("smalbold.fnt","rb");\r
- newfnt = farmalloc(256*16+4);\r
- for (i=0;i<256*16+4;i++){\r
- fread(&c,1,1,f);\r
- *(newfnt+i)=c;\r
- }\r
- fclose(f);\r
- x_text_init();\r
- x_register_userfont(newfnt);\r
- x_set_font(2);\r
-}\r
-\r
-void\r
-main()\r
-{\r
- int i,j,k;\r
-\r
- double ratio,ratio2;\r
- struct time pbm_t0,pbm_t1,cbm_t0,cbm_t1,vbm_t0,vbm_t1;\r
- long vbm_ticks,pbm_ticks,cbm_ticks;\r
- char far * TurtleSprite;\r
-\r
- x_set_mode(X_MODE_320x240,360);\r
-\r
- TurtleSprite = AllocatedSprite(20, 30, 90,FARPTR(turtle));\r
-\r
- vbm = x_make_vbm(MK_FP(_DS,turtle),&NonVisual_Offs);\r
- if (!vbm) {\r
- sound(1000);\r
- delay(100);\r
- nosound();\r
- }\r
-\r
- load_user_fonts();\r
- x_bgprintf(0,0,0,14,0,\r
- "This is a demo to show the speed difference between");\r
- x_bgprintf(0,8,0,14,0,\r
- "compiled, planar and video bitmaps. The bitmap:");\r
-\r
- x_put_cbitmap(140, 18, 0, TurtleSprite);\r
-\r
- x_bgprintf(0,48,0,14,0,\r
- "This demo uses the NON CLIPPED, MASKED versions of");\r
- x_bgprintf(0,56,0,14,0,\r
- " 'PBM' and VBM' put functions");\r
- x_bgprintf(0,78,0,14,0,\r
- "Press a key to start with PLANAR BITMAP demo");\r
-\r
- getch();\r
- x_rect_fill(0,0,ScrnPhysicalPixelWidth,ScrnPhysicalHeight,0,0);\r
-\r
-\r
- gettime(&pbm_t0);\r
- for (k=0;k<3;k++)\r
- for (j=0;j<(ScrnPhysicalHeight/30);j++)\r
- for (i=0;i<(ScrnPhysicalPixelWidth/20);i++)\r
- x_put_masked_pbm(i*20, j*30, 0, pbm);\r
- gettime(&pbm_t1);\r
- pbm_ticks = (((long)pbm_t1.ti_hund\r
- +((long)pbm_t1.ti_sec*100)\r
- +((long)pbm_t1.ti_min*6000)) -\r
- (((long)pbm_t0.ti_hund\r
- +((long)pbm_t0.ti_sec*100)\r
- +((long)pbm_t0.ti_min*6000))));\r
-\r
-\r
- x_bgprintf(0,0,0,14,0,\r
- "Press a key to start with the VIDEO BITMAP demo");\r
-\r
- getch();\r
- x_rect_fill(0,0,ScrnPhysicalPixelWidth,ScrnPhysicalHeight,0,0);\r
-\r
-\r
- gettime(&vbm_t0);\r
- for (k=0;k<3;k++)\r
- for (j=0;j<(ScrnPhysicalHeight/30);j++)\r
- for (i=0;i<(ScrnPhysicalPixelWidth/20);i++)\r
- x_put_masked_vbm(i*20, j*30, 0, vbm);\r
- gettime(&vbm_t1);\r
- vbm_ticks = (((long)vbm_t1.ti_hund\r
- +((long)vbm_t1.ti_sec*100)\r
- +((long)vbm_t1.ti_min*6000)) -\r
- (((long)vbm_t0.ti_hund\r
- +((long)vbm_t0.ti_sec*100)\r
- +((long)vbm_t0.ti_min*6000))));\r
-\r
-\r
-\r
-\r
- x_bgprintf(0,0,0,14,0,\r
- "Now Press a key to start with COMPILED BITMAP demo");\r
-\r
- getch();\r
- x_rect_fill(0,0,ScrnPhysicalPixelWidth,ScrnPhysicalHeight,0,0);\r
-\r
- gettime(&cbm_t0);\r
- for (k=0;k<3;k++)\r
- for (j=0;j<(ScrnPhysicalHeight/30);j++)\r
- for (i=0;i<(ScrnPhysicalPixelWidth/20);i++)\r
- x_put_cbitmap(i*20, j*30, 0, TurtleSprite);\r
- gettime(&cbm_t1);\r
- cbm_ticks = (((long)cbm_t1.ti_hund\r
- +((long)cbm_t1.ti_sec*100)\r
- +((long)cbm_t1.ti_min*6000)) -\r
- (((long)cbm_t0.ti_hund\r
- +((long)cbm_t0.ti_sec*100)\r
- +((long)cbm_t0.ti_min*6000))));\r
- if (cbm_ticks==0){\r
- cbm_ticks=1;\r
- pbm_ticks+=1;\r
- vbm_ticks+=1;\r
- }\r
- ratio = pbm_ticks*(double)1.0/cbm_ticks;\r
- ratio2 = vbm_ticks*(double)1.0/cbm_ticks;\r
-\r
- x_set_font(1);\r
- x_bgprintf(0,ScrnPhysicalHeight-30,0,14,0,\r
- "s/100 PBM=%ld VBM=%ld CBM=%ld - %4.1lf:%4.1lf:1",\r
- pbm_ticks,vbm_ticks,cbm_ticks,ratio,ratio2);\r
- x_set_font(2);\r
- x_bgprintf(0,ScrnPhysicalHeight-16,0,14,0,\r
- "Timing is rough but still, quite impressive ! ");\r
- x_bgprintf(0,ScrnPhysicalHeight-8,0,14,0,\r
- "Clipping slows things down considerably. ");\r
-\r
-\r
- getch();\r
- x_text_mode();\r
-}\r
-\r
+++ /dev/null
-#include <stdio.h>\r
-#include "xlib.h"\r
-#include "xdetect.h"\r
-int processor;\r
-void main(void){\r
- printf("Hardware detection demo...\n\n");\r
- printf("Graphics Card : ");\r
- switch (x_graphics_card()){\r
- case NoGraphics: printf("None\n"); break;\r
- case MDA: printf("MDA\n"); break;\r
- case CGA: printf("CGA\n"); break;\r
- case EGAMono: printf("EGA Mono\n"); break;\r
- case EGAColor: printf("EGA Color\n"); break;\r
- case VGAMono: printf("VGA Mono\n");\r
- case VGAColor: printf("VGA Color\n"); break;\r
- case MCGAMono: printf("MCGA mono\n"); break;\r
- case MCGAColor: printf("MCGA Color\n"); break;\r
- };\r
- printf("Processor : ");\r
- switch (processor=x_processor()){\r
- case I8086: printf("8088 or 8086\n"); break;\r
- case I80186: printf("80186\n"); break;\r
- case I80286: printf("80286\n"); break;\r
- case I80386SX: printf("80386-SX\n"); break;\r
- case I80386DX: printf("80386-DX\n"); break;\r
- };\r
-\r
- if (processor==I80486){\r
- if (x_coprocessor()) printf("80486-DX or 80486-SX+FPU\n");\r
- else printf("80486-SX\n");\r
- } else {\r
- printf("Math Co-Processor: ");\r
- switch (x_coprocessor()){\r
- case 0: printf("8088 Assumed\n"); break;\r
- case 1: switch (processor=x_processor()){\r
- case I8086: printf("80287 Assumed\n"); break;\r
- case I80186: printf("80187 Assumed\n"); break;\r
- case I80286: printf("0287 Assumed\n"); break;\r
- case I80386SX:\r
- case I80386DX: printf("80387 Assumed\n"); break;\r
- };\r
- };\r
- };\r
- printf("Mouse Driver : ");\r
- switch (x_mousedriver()){\r
- case 0: printf("not installed\n"); break;\r
- case 1: {\r
- printf("installed (Mouse Driver vers %d.%d)\n",\r
- (MouseVersion>>8),(MouseVersion&0xff));\r
- printf(" ");\r
- switch (MouseType) {\r
- case BUS_MOUSE: printf("Bus Mouse on IRQ");break;\r
- case SERIAL_MOUSE: printf("Serial Mouse on IRQ ");break;\r
- case INPORT_MOUSE: printf("Inport Mouse on IRQ ");break;\r
- case PS2_MOUSE: printf("PS/2 Mouse on IRQ ");break;\r
- case HP_MOUSE: printf("HP Mouse on IRQ ");break;\r
- default : printf("Unknown Mouse on IRQ ");break;\r
- }\r
- printf("%d with %d buttons.",MouseIRQ, MouseButtonCount);\r
- }\r
- }\r
- }
\ No newline at end of file
+++ /dev/null
-/*************************************************************************\r
-\r
-DEMO 4\r
-\r
-Demonstrates RLE encoding to file QUICK and DIRTY\r
-**************************************************************************/\r
-\r
-\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <conio.h>\r
-#include <ctype.h>\r
-#include <alloc.h>\r
-#include <dos.h>\r
-#include "xlib.h"\r
-#include "xvbitmap.h"\r
-#include "xbmtools.h"\r
-#include "xtext.h"\r
-#include "xrect.h"\r
-#include "xrletool.h"\r
-#include "xfileio.h"\r
-/* Macro to make pointer parameters model independent */\r
-#define FARPTR(x) (MK_FP(FP_SEG(x),FP_OFF(x)))\r
-\r
-char turtle[] = {\r
- 20,30,\r
-/* | . | . | . | . */\r
- 8,14, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 8, 2,14, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 8, 2, 2, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 8, 0, 2,14, 0, 0,14,14,14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 8, 0, 2, 5, 0, 4, 4, 4, 4,14,14, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 8, 0, 2, 2, 4, 4, 0, 4, 4, 0, 4,14, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 2, 4, 4, 4, 0, 4, 4, 0, 4, 4,14, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 2, 4, 4, 4, 0, 0, 0, 0, 4, 4,14, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 4, 0, 4, 4, 4, 0, 0, 0, 4, 0, 0, 2, 2, 0, 0, 0,\r
- 0, 0, 0, 4, 0, 4, 4, 4, 0, 4, 4, 4, 0,14, 0, 0, 2, 2, 0, 0,\r
- 0, 0, 0, 4, 4, 0, 0, 0, 4, 4, 0, 4, 0, 4, 2, 2, 2, 2, 0, 0,\r
- 0, 0, 0, 4, 4, 4, 0, 4, 4, 0, 4, 4, 0, 4,14, 2, 2, 2, 0, 0,\r
- 0, 0, 0, 4, 4, 4, 0, 0, 0, 4, 4, 0, 4, 0, 0, 2, 2, 0, 0, 0,\r
- 0, 0, 0, 2, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4,14, 2, 0, 0, 0, 0,\r
- 0, 0, 2, 2, 0, 4, 4, 4, 4, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0,\r
- 2, 2, 2, 2, 4, 0, 0, 4, 4, 0, 4, 4, 0, 4,14, 0, 0, 0, 0, 0,\r
- 0, 2, 2, 0, 4, 4, 4, 0, 0, 4, 4, 0, 4, 0, 2, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 4, 4, 0, 4, 4, 4, 0, 4, 4, 2,14, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 0, 4, 0, 2, 2,14,14, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 4, 4, 2, 2, 2, 2, 2,14, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 5,14, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 0, 0, 2, 2, 2, 0, 2,14,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 2, 2, 2,14,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 2, 2, 2,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
- };\r
-\r
-\r
-char far *pbm;\r
-char far *newfnt;\r
-int far *buffsize;\r
-\r
-void error(char * string){\r
- x_text_mode();\r
- printf("%s\n",string);\r
- exit(0);\r
-}\r
-\r
-void load_user_fonts(){\r
- FILE *f;\r
- int i; char c;\r
- f=fopen("var6x8.fnt","rb");\r
- newfnt = farmalloc(256*16+4);\r
- for (i=0;i<256*16+4;i++){\r
- fread(&c,1,1,f);\r
- *(newfnt+i)=c;\r
- }\r
- fclose(f);\r
- x_text_init();\r
- x_register_userfont(newfnt);\r
- x_set_font(2);\r
-}\r
-\r
-void main(){\r
- int i,j,handle,size,comp_size;\r
- char far * tempbuff,far * diskbuff;\r
-\r
- pbm = farmalloc(20 * 30 + 2);\r
- x_bm_to_pbm( MK_FP(FP_SEG(turtle),FP_OFF(turtle)), pbm);\r
-\r
- x_set_mode(X_MODE_360x240,360);\r
- load_user_fonts();\r
-\r
- x_bgprintf(0,0,0,14,0,\r
- "This is a demo of RLE compression of 360x240 video screen to ");\r
- x_bgprintf(0,8,0,14,0,\r
- "disk. Uncompressed, this screen requires a file of size ");\r
- x_bgprintf(0,16,0,14,0,"86400 (360x240) bytes.");\r
- x_bgprintf(0,48,0,14,0,\r
- "Press a key to draw the image and save it to screen:");\r
-\r
- getch();\r
- x_rect_fill(0,0,ScrnPhysicalPixelWidth,ScrnPhysicalHeight,0,0);\r
-\r
- for (j=0;j<(ScrnPhysicalHeight/30);j++)\r
- for (i=0;i<(ScrnPhysicalPixelWidth/20);i++)\r
- x_put_masked_pbm(i*20, j*30, 0, pbm);\r
-\r
- x_set_start_addr(0,240);\r
-\r
- x_bgprintf(0,0,240*90,14,0,\r
- "Now compressing and writing to file 'screen.dat'.");\r
- x_bgprintf(0,8,240*90,14,0,"Please wait... ");\r
-\r
-\r
- if((handle=f_open("screen.dat",F_WRONLY))==FILE_ERR)\r
- error("Unable to open 'screen.dat' for writing.");\r
- size=0;\r
- tempbuff=farmalloc(90*240);\r
- diskbuff=farmalloc(90*240);\r
- buffsize=(int far *)farmalloc(2);\r
-\r
- for (i=0;i<4;i++){\r
- x_select_default_plane(i);\r
- if (!(j=x_buff_RLEncode(MK_FP(0xA000,0),tempbuff,90*240)))\r
- error("Error buff compressing");\r
- *buffsize=j;\r
- f_writefar(handle,(char far *)buffsize,2);\r
- f_writefar(handle,tempbuff,j);\r
- size+=j;\r
- }\r
- comp_size=size;\r
- f_close(handle);\r
-\r
- if((handle=f_open("screen.raw",F_WRONLY))==FILE_ERR)\r
- error("Unable to open 'screen.dat' for writing.");\r
- for (i=0;i<4;i++){\r
- x_select_default_plane(i);\r
- f_writefar(handle,MK_FP(0xA000,0),90*240);\r
- }\r
- f_close(handle);\r
-\r
- x_bgprintf(0,8,240*90,14,0,"Done. Press a key to restore.");\r
- getch();\r
-\r
- x_rect_fill(0,0,ScrnPhysicalPixelWidth,ScrnPhysicalHeight,0,0);\r
- x_set_start_addr(0,0);\r
-\r
- if((handle=f_open("screen.dat",F_RDONLY))==FILE_ERR)\r
- error("Unable to open 'screen.dat' for reading.");\r
-\r
- size=0;\r
- for (i=0;i<4;i++){\r
- x_select_default_plane(i);\r
- f_readfar(handle,(char far *)buffsize,2);\r
- f_readfar(handle,diskbuff,*buffsize);\r
- j=x_buff_RLDecode(diskbuff,MK_FP(0xA000,0));\r
- size+=j;\r
- }\r
- f_close(handle);\r
-\r
- getch();\r
- x_text_mode();\r
- printf("screen size = 86400 compressed = %u",comp_size);\r
-}\r
-\r
-\1a
\ No newline at end of file
+++ /dev/null
-/*************************************************************************\r
-\r
-DEMO 5\r
-\r
-Demonstrates Planar Bitmap Clipping Functions\r
-\r
-Themie Gouthas\r
-**************************************************************************/\r
-\r
-\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <conio.h>\r
-#include <ctype.h>\r
-#include <alloc.h>\r
-#include <dos.h>\r
-#include "xlib.h"\r
-#include "xpbitmap.h"\r
-#include "xpbmclip.h"\r
-#include "xrect.h"\r
-#include "xbmtools.h"\r
-#include "xline.h"\r
-#include "xtext.h"\r
-/* Macro to make pointer parameters model independent */\r
-#define FARPTR(x) (MK_FP(FP_SEG(x),FP_OFF(x)))\r
-\r
-int i,j;\r
-\r
-char turtle[] = {\r
- 20,30,\r
-/* | . | . | . | . */\r
- 8,14, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 8, 2,14, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 8, 2, 2, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 8, 0, 2,14, 0, 0,14,14,14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 8, 0, 2, 5, 0, 4, 4, 4, 4,14,14, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 8, 0, 2, 2, 4, 4, 0, 4, 4, 0, 4,14, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 2, 4, 4, 4, 0, 4, 4, 0, 4, 4,14, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 2, 4, 4, 4, 0, 0, 0, 0, 4, 4,14, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 4, 0, 4, 4, 4, 0, 0, 0, 4, 0, 0, 2, 2, 0, 0, 0,\r
- 0, 0, 0, 4, 0, 4, 4, 4, 0, 4, 4, 4, 0,14, 0, 0, 2, 2, 0, 0,\r
- 0, 0, 0, 4, 4, 0, 0, 0, 4, 4, 0, 4, 0, 4, 2, 2, 2, 2, 0, 0,\r
- 0, 0, 0, 4, 4, 4, 0, 4, 4, 0, 4, 4, 0, 4,14, 2, 2, 2, 0, 0,\r
- 0, 0, 0, 4, 4, 4, 0, 0, 0, 4, 4, 0, 4, 0, 0, 2, 2, 0, 0, 0,\r
- 0, 0, 0, 2, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4,14, 2, 0, 0, 0, 0,\r
- 0, 0, 2, 2, 0, 4, 4, 4, 4, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0,\r
- 2, 2, 2, 2, 4, 0, 0, 4, 4, 0, 4, 4, 0, 4,14, 0, 0, 0, 0, 0,\r
- 0, 2, 2, 0, 4, 4, 4, 0, 0, 4, 4, 0, 4, 0, 2, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 4, 4, 0, 4, 4, 4, 0, 4, 4, 2,14, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 0, 4, 0, 2, 2,14,14, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 4, 4, 2, 2, 2, 2, 2,14, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 5,14, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 0, 0, 2, 2, 2, 0, 2,14,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 2, 2, 2,14,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 2, 2, 2,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
- };\r
-\r
-\r
-char far *vbm;\r
-\r
-void error(char * string){\r
- x_text_mode();\r
- printf("%s\n",string);\r
- exit(0);\r
-}\r
-\r
-typedef struct {\r
- unsigned int size; /* valid only for the first header */\r
- unsigned char ImageWidth;\r
- unsigned char ImageHeight;\r
- unsigned int ImagePtr;\r
- unsigned int MaskPtr;\r
-} alignment_header;\r
-\r
-\r
-void main(){\r
- int i,j,k,handle,size,comp_size;\r
- char far *bm;\r
-\r
- alignment_header far * tempbuff;\r
- x_set_mode(X_MODE_360x240,360);\r
- ;NonVisual_Offs=16384;\r
-\r
- x_text_init();\r
- x_set_font(FONT_8x15);\r
- x_bgprintf(0,0,0,14,0," This is a demo of PBM clipping.");\r
- getch();\r
-\r
- bm=farmalloc(20*30+2);\r
- x_bm_to_pbm(MK_FP(_DS,turtle),bm);\r
-\r
- x_set_cliprect(4,5,50,150);\r
-\r
- x_line(0,TopClip-1,320,TopClip-1,23,0);\r
- x_line(0,BottomClip+1,320,BottomClip+1,23,0);\r
- x_line((LeftClip<<2)-1,0,(LeftClip<<2)-1,200,23,0);\r
- x_line((RightClip<<2)+4,0,(RightClip<<2)+4,200,23,0);\r
-\r
- for (k=0;k<8;k++){\r
- for (j=1;j<ScrnPhysicalHeight;j+=30)\r
- for (i=0;i<ScrnPhysicalPixelWidth-20;i+=20)\r
- x_put_pbm(i+k+1,j,0,bm);\r
- }\r
-\r
- x_line(0,TopClip-1,320,TopClip-1,23,0);\r
- x_line(0,BottomClip+1,320,BottomClip+1,23,0);\r
- x_line((LeftClip<<2)-1,0,(LeftClip<<2)-1,200,23,0);\r
- x_line((RightClip<<2)+4,0,(RightClip<<2)+4,200,23,0);\r
-\r
- x_rect_fill((LeftClip<<2),TopClip,(RightClip<<2)+3,BottomClip,0,0);\r
-\r
- x_bgprintf(0,BottomClip+4,0,14,0," Now the clipping...");\r
- getch();\r
-\r
- for (k=0;k<8;k++){\r
- for (j=1;j<ScrnPhysicalHeight;j+=30)\r
- for (i=0;i<ScrnPhysicalPixelWidth-20;i+=20)\r
- x_put_pbm_clipxy(i+k+1,j,0,bm);\r
- }\r
- for (k=0;k<8;k++){\r
- for (j=1;j<ScrnPhysicalHeight;j+=30)\r
- for (i=0;i<ScrnPhysicalPixelWidth-20;i+=20)\r
- x_put_pbm_clipxy(i+7+1,j+k,0,bm);\r
- }\r
- for (k=7;k>=0;k--){\r
- for (j=1;j<ScrnPhysicalHeight;j+=30)\r
- for (i=0;i<ScrnPhysicalPixelWidth-20;i+=20)\r
- x_put_pbm_clipxy(i+k+1,j+7,0,bm);\r
- }\r
- for (k=7;k>=0;k--){\r
- for (j=1;j<ScrnPhysicalHeight;j+=30)\r
- for (i=0;i<ScrnPhysicalPixelWidth-20;i+=20)\r
- x_put_pbm_clipxy(i+1,j+k,0,bm);\r
- }\r
-\r
- getch();\r
- x_text_mode();\r
- printf("%d %d %d %d\n",LeftClip,TopClip,RightClip,BottomClip);\r
-\r
-}\r
-\r
+++ /dev/null
-#include <conio.h>\r
-\r
-#include "xlib.h"\r
-#include "xcircle.h"\r
-\r
-void main(void)\r
-{\r
- int i;\r
-\r
- x_set_mode(1, 320);\r
- for (i = 0; i < 120; i++) {\r
- x_circle(0, 0, i, 121 - i, 0);\r
- x_circle(319 - i, 0, i, i - 20, 0);\r
- x_circle(0, 239 - i, i, i - 20, 0);\r
- x_circle(319 - i, 239 - i, i, 121 - i, 0);\r
- x_filled_circle(40 + i, i, 241 - (i << 1), i+1, 0);\r
- }\r
- getch();\r
-\r
- x_text_mode();\r
-}\r
-\1a
\ No newline at end of file
+++ /dev/null
-/* Program to demonstrate Bezier curves */\r
-\r
-#include <conio.h>\r
-\r
-#include "xlib.h"\r
-#include "xbezier.h"\r
-#include "xpal.h"\r
-\r
-void main(void)\r
-{\r
- int i, r, g, b;\r
-\r
- x_set_mode(X_MODE_360x480, 360);\r
-\r
- for (b = 0; b < 6; b++)\r
- for (g = 0; g < 6; g++)\r
- for (r = 0; r < 6; r++)\r
- x_set_rgb(b + 6 * g + 36 * r,\r
- 12 * b + 3, 12 * g + 3, 12 * r + 3);\r
- for (i = 216; i < 256; i++)\r
- x_set_rgb(i, i - 193, i - 193, 279 - i);\r
-\r
- for (i = 0; i <= 1080; i++) {\r
- x_bezier(i, 240, 90, i, 270, 479-i, 359 - i, 240,\r
- 6, i ,0);\r
- }\r
- for (i = 720; i >= 0; i--) {\r
- x_bezier(360 - i, i/3, 360 - i, i, i, i, i, i/3,\r
- 4, i ,0);\r
- x_bezier(360 - i, 479-i/3, 360 - i, 479-i, i, 479-i, i, 479-i/3,\r
- 4, i ,0);\r
- }\r
-\r
- getch();\r
-\r
- x_text_mode();\r
-}\r
-\r
+++ /dev/null
-/*************************************************************************\r
-\r
-DEMO 2\r
-\r
-Demonstrates the speed difference between compiled bitmap, conventional\r
-masked planar bitmap, and video bitmap blits.\r
-\r
-**************************************************************************/\r
-\r
-\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <conio.h>\r
-#include <ctype.h>\r
-#include <alloc.h>\r
-#include <dos.h>\r
-#include <dir.h>\r
-#include <string.h>\r
-\r
-#include "xlib.h"\r
-#include "xtext.h"\r
-#include "xrect.h"\r
-\r
-/* Macro to make pointer parameters model independent */\r
-#define FARPTR(x) (MK_FP(FP_SEG(x),FP_OFF(x)))\r
-\r
-char *swidth[10]={"0","1","2","3","4","5","6","7","8","9"};\r
-char far *fonts[20];\r
-char names[20][20];\r
-int i,fcount=0;\r
- char c;\r
-\r
-typedef struct {\r
- int dummy;\r
- char height;\r
- char width;\r
-} header;\r
-\r
-void load_user_fonts(){\r
- FILE *f;\r
- long len;\r
- struct ffblk ffblock;\r
-\r
- if(findfirst("*.fnt",&ffblock,0)!=0){\r
- printf("No Fonts found in current directory!\n");\r
- exit(0);\r
- };\r
- do {\r
- printf("Loading font \"%s\"...\n",ffblock.ff_name);\r
- strncpy(names[fcount],ffblock.ff_name,14);\r
-\r
- f=fopen(ffblock.ff_name,"rb");\r
-\r
- fseek(f,0,SEEK_END);\r
- len=ftell(f);\r
- fseek(f,0,SEEK_SET);\r
-\r
- fonts[fcount] = farmalloc(len);\r
- if (!fonts[fcount]){\r
- printf("Out of memory");\r
- if (fcount!=0){\r
- printf("- No more fonts can be loaded\n");\r
- fclose(f);\r
- goto NoMoreFonts;\r
- } else printf("\n");\r
-\r
- exit(0);\r
- };\r
-\r
- for (i=0;i<len;i++){\r
- fread(&c,1,1,f);\r
- *(fonts[fcount]+i)=c;\r
- }\r
-\r
- fclose(f);\r
- fcount++;\r
-\r
- } while (!findnext(&ffblock));\r
-\r
-NoMoreFonts:\r
- printf("\n Press 'v' to view, any other key to quit\n");\r
- c=getch();\r
- if (c!='V' && c!='v'){\r
- x_text_mode();\r
- exit(0);\r
- }\r
-\r
- x_text_init();\r
- x_set_mode(X_MODE_320x240,0);\r
- x_register_userfont(fonts[0]);\r
- x_set_font(2);\r
-}\r
-\r
- //......................................//\r
-char *text[30] = {"EXTRACT: Stephen King's \"SALEM'S LOT\" ",\r
- "",\r
- "The memory rose up in almost total ",\r
- "sensory reference, and for the moment ",\r
- "of its totality he was paralyzed. He ",\r
- "could even smell the plaster and the ",\r
- "wild odour of nesting animals. It ",\r
- "seemed to him that the plain varnished",\r
- "door of Matt Burke's guest room stood ",\r
- "between him and all the secrets of ",\r
- "Hell. Then he twisted the knob and ",\r
- "pushed the door handle inwards... ",\r
- "",\r
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ ",\r
- "abcdefghijklmnopqrstuvwxyz 0123456789 ",\r
- "~!@#$%^&*()_+|`-=\\{}[]:\";'<>?,./ ",\r
- NULL};\r
-\r
-\r
-\r
-\r
-\r
-void main(){\r
- int textline;\r
- int strindex;\r
- int height;\r
- load_user_fonts();\r
-\r
-\r
-\r
- for (i=0;i<fcount;i++){\r
- x_set_font(FONT_8x8);\r
- x_rect_fill(0, 0, 319, 239, 0, 0);\r
- x_line(0,9,319,9,14,0);\r
- x_line(0,ScrnPhysicalHeight-10,319,ScrnPhysicalHeight-10,14,0);\r
-\r
- x_bgprintf(0,0,0,14,0,"Font \"%s\" H=%d,W=%s",names[i],\r
- (int)*(fonts[i]+2),\r
- (*(fonts[i]+3)==0)?"Variable":swidth[*(fonts[i]+3)]);\r
- x_bgprintf(0,ScrnPhysicalHeight-8,0,14,0,\r
- "Press a key for next font...");\r
-\r
- x_register_userfont(fonts[i]);\r
- x_set_font(FONT_USER);\r
-\r
- height=(int)*(fonts[i]+2)+1;\r
- textline=12;\r
- strindex=0;\r
- while(text[strindex]){\r
- x_printf(0,textline,0,14,text[strindex++]);\r
- textline+=height;\r
- }\r
-\r
- getch();\r
- }\r
-\r
- x_text_mode();\r
-}\r
-\r
+++ /dev/null
-# makefile MAKE V2.0 or higher\r
-\r
-\r
-# Set the required model here, either s, c or l (LOWER CASE ONLY)\r
-#\r
-\r
-MODEL=h\r
-\r
-XLIB_VERSION=06\r
-\r
-# Set the compiler: either BCC or TCC\r
-#\r
-CC=wcc\r
-\r
-TLIB=wlib\r
-\r
-AFLAGS = /ml /zi /d$(MODEL)\r
-CFLAGS = -m$(MODEL)\r
-CPPFLAGS= -m$(MODEL)\r
-LDFLAGS = -m$(MODEL)\r
-\r
-\r
-%.o: %.c\r
- $(CC) -c $(CFLAGS) $<\r
-\r
-%.o: *.asm\r
- wasm $(AFLAGS) $* \\r
-\r
-\r
-XLIBOBJS= xprintf.o xpoint.o xline.o xmain.o xpal.o xpbitmap.o \\r
- xrect.o xtext.o xcbitmap.o xdetect.o xbmtools.o \\r
- xfileio.o xrletool.o xbezier.o xpbmclip.o xvbitmap.o \\r
- xmakevbm.o xmouse.o xcircle.o xclippbm.o xcomppbm.o \\r
- xpolygon.o xvsync.o xfill.o xcbitm32.o\r
-\r
-\r
-all: demo1.exe demo2.exe demo3.exe demo4.exe demo5.exe demo6.exe demo7.exe \\r
- demo8.exe demo9.exe demo10.exe\r
-\r
-demo1.exe : demo1.o $(XLIBOBJS) xlib$(XLIB_VERSION)$(MODEL).lib\r
- $(CC) $(CFLAGS) demo1.o xlib$(XLIB_VERSION)$(MODEL).lib\r
-\r
-demo2.exe : demo2.o $(XLIBOBJS) xlib$(XLIB_VERSION)$(MODEL).lib\r
- $(CC) $(CFLAGS) demo2.o xlib$(XLIB_VERSION)$(MODEL).lib\r
-\r
-demo3.exe : demo3.o $(XLIBOBJS) xlib$(XLIB_VERSION)$(MODEL).lib\r
- $(CC) $(CFLAGS) demo3.o xlib$(XLIB_VERSION)$(MODEL).lib\r
-\r
-demo4.exe : demo4.o $(XLIBOBJS) xlib$(XLIB_VERSION)$(MODEL).lib\r
- $(CC) $(CFLAGS) demo4.o xlib$(XLIB_VERSION)$(MODEL).lib\r
-\r
-demo5.exe : demo5.o $(XLIBOBJS) xlib$(XLIB_VERSION)$(MODEL).lib\r
- $(CC) $(CFLAGS) demo5.o xlib$(XLIB_VERSION)$(MODEL).lib\r
-\r
-demo6.exe : demo6.o $(XLIBOBJS) xlib$(XLIB_VERSION)$(MODEL).lib\r
- $(CC) $(CFLAGS) demo6.o xlib$(XLIB_VERSION)$(MODEL).lib\r
-\r
-demo7.exe : demo7.o $(XLIBOBJS) xlib$(XLIB_VERSION)$(MODEL).lib\r
- $(CC) $(CFLAGS) demo7.o xlib$(XLIB_VERSION)$(MODEL).lib\r
-\r
-demo8.exe : demo8.o $(XLIBOBJS) xlib$(XLIB_VERSION)$(MODEL).lib\r
- $(CC) $(CFLAGS) demo8.o xlib$(XLIB_VERSION)$(MODEL).lib\r
-\r
-demo9.exe : demo9.o $(XLIBOBJS) xlib$(XLIB_VERSION)$(MODEL).lib\r
- $(CC) $(CFLAGS) demo9.o xlib$(XLIB_VERSION)$(MODEL).lib\r
-\r
-demo10.exe : demo10.o $(XLIBOBJS) xlib$(XLIB_VERSION)$(MODEL).lib\r
- $(CC) $(CFLAGS) demo10.o xlib$(XLIB_VERSION)$(MODEL).lib\r
-\r
-\r
-xlib$(XLIB_VERSION)$(MODEL).lib: $(XLIBOBJS)\r
- $(TLIB) xlib$(XLIB_VERSION)$(MODEL).lib \\r
- -+xmain -+xpoint -+xline -+xpal -+xrect -+xtext -+xprintf -+xbezier -+xfill -+xcbitm32\r
- $(TLIB) xlib$(XLIB_VERSION)$(MODEL).lib \\r
- -+xpbitmap -+xcbitmap -+xdetect -+xbmtools -+xfileio -+xrletool -+xpbmclip\r
- $(TLIB) xlib$(XLIB_VERSION)$(MODEL).lib \\r
- -+xvbitmap -+xmakevbm -+xmouse -+xcircle -+xclippbm -+xcomppbm -+xpolygon -+xvsync\r
-\r
-# Object modules\r
-\r
-xprintf.o : xprintf.c\r
-xpoint.o : xpoint.asm xpoint.inc xlib.inc model.inc\r
-xline.o : xline.asm xline.inc xlib.inc model.inc\r
-xmain.o : xmain.asm xmain.inc xlib.inc model.inc\r
-xpal.o : xpal.asm xpal.inc xlib.inc model.inc\r
-xpbitmap.o: xpbitmap.asm xpbitmap.inc xlib.inc model.inc\r
-xpbmclip.o: xpbmclip.asm xpbmclip.inc xlib.inc model.inc\r
-xclippbm.o: xclippbm.asm xclippbm.inc xlib.inc model.inc\r
-xrect.o : xpal.asm xpal.inc xlib.inc model.inc\r
-xtext.o : xtext.asm xtext.inc xlib.inc model.inc\r
-xcbitmap.o: xcbitmap.asm xcbitmap.inc xlib.inc model.inc\r
-xcomppbm.o: xcomppbm.asm xcomppbm.inc xlib.inc model.inc\r
-xcbitm32.o: xcbitm32.c \r
-xdetect.o : xdetect.asm xdetect.inc model.inc\r
-xbmtools.o: xbmtools.asm xbmtools.inc model.inc\r
-xfileio.o : xfileio.asm xfileio.inc model.inc\r
-xrletool.o: xrletool.asm xrletool.inc model.inc\r
-xvbitmap.o: xvbitmap.asm xvbitmap.inc xlib.inc model.inc\r
-xmakevbm.o: xmakevbm.c xvbitmap.h\r
-xmouse.o : xmouse.asm xlib.inc model.inc\r
-xcircle.o : xcircle.asm xcircle.inc xlib.inc model.inc\r
-xpolygon.o: xpolygon.asm xpolygon.inc xlib.inc model.inc\r
-xvsync.o : xvsync.asm xvsync.inc xlib.inc model.inc\r
-xfill.o : xfill.asm xfill.inc xlib.inc model.inc\r
+++ /dev/null
-IFDEF s\r
- DISPLAY "XLIB04 Small Model"\r
- .model small\r
-ELSE\r
- IFDEF c\r
- DISPLAY "XLIB04 Compact Model"\r
- .model compact\r
- ELSE\r
- IFDEF l\r
- DISPLAY "XLIB04 Large Model"\r
- .model large\r
- ELSE\r
- DISPLAY "WARNING: Model was not defined at the command line."\r
- DISPLAY " Using default small model ie /ds "\r
- DISPLAY " Include in TASM commandline either /ds, /dc or /dl"\r
- .model small\r
- ENDIF\r
- ENDIF\r
-ENDIF\r
-\r
-\1a
\ No newline at end of file
+++ /dev/null
-This is XLIB the mode X graphics library. There is no organization to the\r
-files in this archive; that is left up to each users preferences.\r
-\r
-Famous last words ;-)\r
-\r
-"This is the last version I intend to release, unless of course someone has\r
-something really nifty they'd like to contribute."\r
-\r
-MOUSE TIP:\r
-\r
-Theres a slight design flaw in the mouse driver and lots of people have had\r
-problems with mouse droppings in the lower RH corner of the screen. This \r
-happens under some circulstances because the code does not clip the saved\r
-background as is done for the cursor graphic itself so bits of the mouse \r
-graphic stored in the video ram just below the visual page get picked up into \r
-the background.\r
-\r
-To bypass this problem is simple when you know how. If you are having this \r
-problem insert NonVisual_Offs+=ScrnLogicalByteWidth*14 just before the call\r
-to x_init_mouse.\r
-\r
-Sorry about not fixing the problem more elegantly, but I didn't want to \r
-do any major work on the mouse driver.\r
-\r
-Themie\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
+++ /dev/null
-Xlib version 2 modifications\r
-\r
-Files modified:\r
- XLIB.INC\r
- XMAIN.ASM\r
- DEMO.C\r
-\r
-\r
-26-09-92 - PRIMARILY JUST ADDED SUPPORT FOR PEL PANNING\r
-\r
- Pel panning code added to allow for panning to any pixel\r
- coordinates.\r
- Functions affected:\r
- x_set_splitscreen\r
- Split screen pel panning suppression code added.\r
- Functionally unchanged.\r
- x_set_start_addr,x_page_flip\r
- Pel panning code added. The x parameter now expects\r
- a pixel coordinate where previously a byte coordinate\r
- was expected.\r
-\r
- Original files modified\r
- -----------------------\r
- XLIB.INC\r
- XMAIN.ASM\r
- DEMO.C\r
- Aknowledgements\r
- ---------------\r
- Thanks to Robert Schmidt for contributed PEL panning sample\r
- code and everyone else who responded to my rec.games.programmer\r
- post.\r
-\r
-Xlib version 3 modifications\r
-\r
-10-10-92 - BUG ERADICATION AND ADDITION OF NEW MODULES AND MINOR CODE\r
- EXTENSIONS\r
-\r
- MaxScrollX and MaxScrollY were not always set correctly, now\r
- that's fixed (I Think)\r
- Added variable "SplitScrnVisibleHeight" needed for above fix.\r
- Some miscellaneous code changes\r
- Included XCBITMAP module generously donated by Matthew MacKenzie\r
- Added support for the LARGE memory model\r
- Added a make file to simplify compilation\r
- Library modules now compiled into .LIB files\r
- Added a documentation file\r
- Added XBMTOOLS module containing bitmap type conversion\r
- Added XDETECT module containing hardware detection functions\r
- Added C header files for all modules\r
- ADDED XFILEIO module\r
- ADDED XRLETOOL module\r
-\r
- Original files modified\r
- -----------------------\r
- XLIB.INC\r
- XMAIN.ASM\r
- DEMO.C\r
- XTEXT.INC\r
- XTEXT.ASM\r
-\r
- Aknowledgements\r
- ---------------\r
- Special thanks to Matthew Mackenzie for an excellent module\r
- and Darren Lyon for putting together a C header file for XLIB.\r
- Again thanks also to everyone else who supported this software.\r
-\r
-Xlib version 4 modifications\r
-\r
-\r
-30-10-92 EXTENSIONS TO XLIB 3 AND BUG FIXES\r
-\r
- Files Modified\r
- --------------\r
- Assume all have been modified\r
-\r
- Modifications/Additions\r
- ------------------------\r
- **** Fixed ATI VGA incompatibility problem **** 4\r
- **** Fixed Large Model problems ***************\r
- Manual : The ref. manual has been split ito two files for\r
- those editors that cannot cope with file > 64k\r
- XDETECT: added numeric co-pro detection\r
- added mouse driver detection\r
- XMAIN : added new resolution tweaks\r
- added clipping rectangle setting proc and vars\r
- further bug fixes (I can't remember exactly what)\r
- XCBITMAP:Improved performance of compilation and compiled bitmaps\r
- and added a function to calculate mem required for\r
- a bitmap compilation\r
- XPBITMAP:Improved performance of planar bitmaps\r
- XRECT :Added "x_shift_rect" function\r
- XPBMTOOL:Added several utility macros\r
-\r
- New Modules\r
- -----------\r
- XPBMCLIP:Implements clipping versions of functions in XPBITMAP\r
- XVBITMAP:Video based masked bitmap functions. Contains standard\r
- and clipping versions of all functions.\r
- XMAKEVBM:Support module for XVBITMAP\r
- XMOUSE :Basic mouse support module\r
- XBEZIER :Fast Bezier curves (For scalable fonts etc..)\r
-\r
-\r
-Xlib version 4b modifications\r
-\r
-10-12-92 BUG FIX RELEASE\r
-\r
- Files Modified\r
- --------------\r
-\r
- XMAIN.*\r
- XPBMCLIP.*\r
- XVBMCLIP.*\r
- XCLIPPBM.*\r
-\r
- Modifications/Additions\r
- ------------------------\r
- Some minor fixes and modifications in xmain.asm\r
- fixed the split screen starting scan line problem\r
-\r
- This fix is a cludge - Sam Thompson has suggested a more\r
- elegant fix but I just dont have much time these days\r
-\r
- changed mode setting code to allow 320x200 mode to have same\r
- aspect ratio as mode 13h\r
-\r
- The clipped functions were modified to return 1 if the image being\r
- clipped was completely off the logical screen.\r
- Minor clipping bugs which gave inconsistent results when clipping\r
- to the left and right screen borders were fixed in the XPBMCLIP &\r
- VBMCLIP modules.\r
- A bug in demo 2 which caused crashing on 486 machines was also\r
- fixed. (The speed of the 486 resulted in 0 time delay which inturn\r
- caused a division by zero error)\r
-\r
-28-12-92 Modified PEL panning code to be smoother on snail paced PC's\r
- Added quick & dirty planar bitmap compiler\r
-\r
-\r
-15-2-93 Converted text module to allow variable width user fonts\r
-\r
- Added a function x_get_char_width in module xtext\r
- Added fonts var6x8.fnt varswisl.fnt varswisb.fnt\r
- Clened up virt screen start address setting code in xmain.asm\r
-\r
- Added demo 8 to preview user defined fonts\r
-\r
- Added x_wait_vsync in module xmain\r
-\r
- Fixed a bug with mode sets on some VGA bios'es that dont\r
- preserve CX on an int 10h\r
-\r
-18-8-93 XLIB05 Final Release\r
- -----------------------------------------------\r
-\r
- GENERAL:\r
- Added C++ compatability in header files\r
- Added new fonts \r
- XDETECT: now can differentiate between 386sx 386dx and 486\r
- (486sx can be verified by absence of FPU)\r
- XMOUSE:\r
- Fixed x_mouse_position bug and general xmouse improvements\r
- Added x_mouse_window function\r
- XFILEIO:\r
- Modified f_read and f_write functions xfileio module\r
- f_read - now reads into near buffer reguardless of model\r
- f_readfar " " " far " " " "\r
- f_write " writes " near " " " "\r
- f_writefar " " " far " " " "\r
- Added f_tell function to get file position. I beleive I\r
- improved the error handling a little but I cant remember\r
- for sure.\r
- XMAIN:\r
- Added 2 new resolutions 256x200 & 256x240.\r
- I dont know why you'd want them but theyre there if you do.\r
- These came from Draeden of VLA (Did you write them Ben ?)\r
- I think they may have originally been posted on R.G.P ???\r
- XRECT:\r
- Added x_rect_fill_clipped & x_rect_pattern_clipped, probably\r
- useless but what the heck!\r
- XPOLYGON:\r
- New function x_triangle - a fast clipped and filled trinagle\r
- function ideal for 3D work.\r
- x_polygon - a clipped and filled polygon function (convex\r
- polygons only). This one's not the fastest - it splits\r
- polygons into component triangles and uses the above\r
- triangle routine to draw them, but still it should\r
- perform fast enough for most 3D applications.\r
- MISCELLANEOUS:\r
- xdiscuss.zip: Included Robert Schmidt's excellent mode X article\r
- for those interested in the hows and why's of Mode X progamming\r
- xlibtl02.zip: Some bitmap conversion code and a TSR bitmap\r
- capture program.\r
-\r
-\r
- Aknowledgements\r
- ---------------\r
- Gerald Dalley - For getting me off my butt and doing\r
- this release.\r
-\r
- Steve Dollins - Never returned my mail asking for\r
- permission to use his code so I\r
- assumed it'd be OK ;)\r
-\r
- Christian Harms - For suggesting xdetect improvements and\r
- promising to make XLIB for T.P. freeware\r
- when its complete. good on ya mate!\r
-\r
- Jason Truong - For spotting the bug in xmouse and\r
- general suggestions for improvements\r
-\r
- Chris Kirby - For suggestion to make .h files C++\r
- compliant\r
-\r
- Robert Scmidt - For his mode X article.\r
-\r
- jeremi@ee.ualberta.ca - Thanks for the xtext suggestions\r
- (name unknown) even if they didnt make this release\r
-\r
- And others whom I may have forgotten.\r
-\r
- Also Greetings to my internet pals,\r
- Mat Mackenzie, Jari Karjala, Draeden, Victor Putz,\r
- Josh Jensen, Chicken and the rest of you dudes...\r
- Thanks for helping my productivity live up to\r
- "Public Servant" standards ;-))\r
-\r
-5-10-93\r
- -----------------------------------------------\r
- XCBITM32:\r
- 32 bit compiled bitmaps, originally developed by Matthew\r
- Mackenzie for our game. NOTE: The compiler is written in C -\r
- conversion to assembler is left as an excersise for the user :-)\r
- \r
- XMOUSE: Finished x_mouse_window this time. I had overlooked\r
- its semi-completed x_mouse_window function in the last release.\r
-\r
- XPBITMAP:\r
- Added x_flip_pbm and x_flip_masked_pbm\r
- Identical to x_put_pbm and x_put_masked_pbm but have an\r
- extra parameter which indicates whether the bitmap is flipped\r
- from left to right as drawn or not - Ideal for saving bitmap\r
- memory.\r
-\r
- XFILL:\r
- Added a new module containing 2 flood fill variants. Both return\r
- the number of pixels filled.\r
-\r
- XVSYNC:\r
- New module to synchronise timer 0 to the vertical retrace. This\r
- allows for smoother animation due to the elimination of\r
- unnecessary vsync waiting.\r
-\r
- XMAIN:\r
- Modifications to allow standard vsync polling or optional\r
- timer0/vsync synchronization and new support for tripple\r
- buffering for super-smooth animation. This stuff's way cool!\r
-\r
- BUGS:\r
- fixed the odd bug here and there - nothing too serious.\r
-\r
-\r
- Aknowledgements:\r
-\r
- Tiaan A Geldenhuys - for pointing out that I forgot to finish\r
- some code in xmouse.asm, for the new cursor shape and stuff.\r
-\r
- Thanks to Tore Jahn Bastiansen (toreba@ifi.uio.no) for the\r
- tripple buffering extensions to XMAIN and the excellent\r
- Timer vsync sunchronization which is the highlight of this\r
- release. This module is a "MUST HAVE" if youre going to do\r
- any animation.\r
-\r
- Also thanks to any others, whom I may have lost track of,\r
- for bug fixes'n stuff.\r
-\r
- Apologies to the person who sent me the pbm flipping code.\r
+++ /dev/null
-\r
-;-----------------------------------------------------------------------\r
-; MODULE XBEZIER\r
-;\r
-;\r
-; Compile with TASM.\r
-; C near-callable.\r
-;\r
-; This module was written by Matthew MacKenzie\r
-; matm@eng.umd.edu\r
-;-----------------------------------------------------------------------\r
-include xlib.inc\r
-include xbezier.inc\r
-\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-; _x_bezier\r
-;\r
-; Plot a Bezier curve, which is described by a box of two endpoints\r
-; and two control points:\r
-; C1--------C2\r
-; / \\r
-; / \\r
-; E1..............E2\r
-;\r
-; All coordinates must be in the range -1024 to 3071.\r
-; No clipping is performed.\r
-;\r
-; C near-callable as:\r
-; x_bezier (int E1x, int E1y, int C1x, int C1y, int C2x, int C2y,\r
-; int E2x, int E2y, int levels, char color,\r
-; unsigned int PageOffset);\r
-;\r
-; All four main registers are totaled.\r
-; This function may use as many as 162 bytes of stack space.\r
-\r
-; Bezier curves need 32-bit precision, so we'll define macros and\r
-; constants for operations on 32-bit virtual registers V0, V1, and V2.\r
-; V0 is made up of DI and AX, V1 of SI and BX, and V2 of CX and DX.\r
-\r
-LowWord equ 0\r
-HighWord equ 2\r
-\r
-; to load data --\r
-\r
-LoadV0 macro loc, field\r
- mov ax, word ptr [bp + loc + field + LowWord]\r
- mov di, word ptr [bp + loc + field + HighWord]\r
- endm\r
-\r
-LoadV1 macro loc, field\r
- mov bx, word ptr [bp + loc + field + LowWord]\r
- mov si, word ptr [bp + loc + field + HighWord]\r
- endm\r
-\r
-LoadV2 macro loc, field\r
- mov dx, word ptr [bp + loc + field + LowWord]\r
- mov cx, word ptr [bp + loc + field + HighWord]\r
- endm\r
-\r
-; to store data --\r
-\r
-StoreV0 macro loc, field\r
- mov word ptr [bp + loc + field + LowWord], ax\r
- mov word ptr [bp + loc + field + HighWord], di\r
- endm\r
-\r
-StoreV1 macro loc, field\r
- mov word ptr [bp + loc + field + LowWord], bx\r
- mov word ptr [bp + loc + field + HighWord], si\r
- endm\r
-\r
-\r
-; to take the average of two registers (result is in first register) --\r
-\r
-AverageV0nV1 macro\r
- add ax, bx\r
- adc di, si\r
- shr di, 1\r
- rcr ax, 1\r
- endm\r
-\r
-AverageV0nV2 macro\r
- add ax, dx\r
- adc di, cx\r
- shr di, 1\r
- rcr ax, 1\r
- endm\r
-\r
-AverageV1nV2 macro\r
- add bx, dx\r
- adc si, cx\r
- shr si, 1\r
- rcr bx, 1\r
- endm\r
-\r
-\r
-; to take the average of a register and data --\r
-\r
-AverageV1nData macro loc, field\r
- add bx, word ptr [bp + loc + field + LowWord]\r
- adc si, word ptr [bp + loc + field + HighWord]\r
- shr si, 1\r
- rcr bx, 1\r
- endm\r
-\r
-AverageV2nData macro loc, field\r
- add dx, word ptr [bp + loc + field + LowWord]\r
- adc cx, word ptr [bp + loc + field + HighWord]\r
- shr cx, 1\r
- rcr dx, 1\r
- endm\r
-\r
-\r
-; to turn a 32-bit fixed point data into a regular integer --\r
-\r
-Extract macro reg, source, field\r
- mov reg, word ptr [bp + source + field + HighWord]\r
- shr reg, 3\r
- adc reg, 0 ; round\r
- endm\r
-\r
-\r
-; to turn an integer argument into a 32-bit fixed point number\r
-; and store it as local data --\r
-\r
-Convert macro source, dest, field\r
- mov ax, source\r
- add ax, 1024\r
- shl ax, 3\r
- push ax\r
- push 0\r
- endm\r
-\r
-\r
-; useful numbers for dealing with Bezier boxes (sets of four points) --\r
-\r
-XCoord equ 4\r
-YCoord equ 0\r
-\r
-; stack offsets for splitting boxes\r
-E1Src equ 48\r
-C1Src equ 40\r
-C2Src equ 32\r
-E2Src equ 24\r
-\r
-E1Dest equ 48\r
-P1Dest equ 40\r
-P4Dest equ 32\r
-P6Dest equ 24\r
-P5Dest equ 16\r
-P2Dest equ 8\r
-E2Dest equ 0\r
-\r
-; stack offsets for drawing boxes\r
-E1Draw equ 24\r
-C1Draw equ 16\r
-C2Draw equ 8\r
-E2Draw equ 0\r
-\r
- .data\r
-\r
- align 2\r
-\r
-; depth of recursion at which to plot\r
-WhenToDraw label byte\r
- db 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4\r
- db 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5\r
-\r
-\r
-; since we'll be moving bp and sp in our recursion,\r
-; we need to put local storage in the data segment\r
-level dw (?)\r
-gencount dw (?)\r
-AdjustedOffs dw (?)\r
-p1xt dw (?)\r
-p1yt dw (?)\r
-p2xt dw (?)\r
-p2yt dw (?)\r
-p4xt dw (?)\r
-p4yt dw (?)\r
-p5xt dw (?)\r
-p5yt dw (?)\r
-c1xt dw (?)\r
-c1yt dw (?)\r
-c2xt dw (?)\r
-c2yt dw (?)\r
-xdiff dw (?)\r
-ydiff dw (?)\r
-moveline dw (?)\r
-stepper dw (?)\r
-bptemp dw (?)\r
-\r
-; by the same token we need a copy of this argument\r
-Colort dw (?)\r
-\r
-\r
-ColumnMasks label byte\r
- db 011h, 022h, 044h, 088h\r
-\r
- .code\r
-\r
- align 2\r
-_x_bezier proc\r
-ARG E1x, E1y, C1x, C1y, C2x, C2y, E2x, E2y, Levels, Color, PageOffs:word\r
-\r
- push bp\r
- mov bp, sp ; caller's stack frame\r
- push si\r
- push di\r
- push es\r
-\r
- ; set local variables\r
- mov ax, -1024 ; 1024 rows\r
- imul [_ScrnLogicalByteWidth]\r
- add ax, PageOffs\r
- sub ax, 256 ; 1024 columns\r
- mov AdjustedOffs, ax ; subtract 1024 rows and 1024 columns\r
-\r
-; copy color into data segment so we can change bp & sp\r
- mov ax, Color\r
- mov Colort, ax\r
-\r
- mov cx, Levels\r
- dec cx ; gencount (number of boxes we will actually plot) =\r
- mov ax,1 ; 2^(Levels - 1)\r
- shl ax,cl\r
- dec ax\r
- mov gencount, ax\r
-\r
- mov [level], 0 ; variable to tell us where we are in the stack\r
- mov bptemp, bp ; when the dust settles at the end\r
-\r
-; translate coordinates for adjusted offset, convert 'em to fixed-point\r
-; with 13 bits for the integer part and 19 for the fractional part,\r
-; and push them onto the stack in the right order to for a Bezier box\r
-\r
- Convert E2x\r
- Convert E2y\r
-\r
- Convert C2x\r
- Convert C2y\r
-\r
- Convert C1x\r
- Convert C1y\r
-\r
- Convert E1x\r
- Convert E1y\r
-\r
- mov bp, sp ; we are using them as basically one pointer\r
-\r
- mov ax, 0a000h ; point extra segment to VGA memory\r
- mov es, ax\r
-\r
- mov dx, SC_INDEX\r
- mov al, MAP_MASK\r
- out dx, al\r
-\r
-MainLoop:\r
- mov si, gencount\r
- mov ax, 0\r
- mov al, WhenToDraw[si]\r
- cmp ax, level ; are we at a terminal curve?\r
- jne Recurse\r
- jmp PlotCurve\r
-\r
-Recurse:\r
-; not at a terminal -- so expand this curve into two more and recurse\r
-\r
-; start with:\r
-; C1___C2\r
-; | |\r
-; E1...E2\r
-;\r
-; stack looks like: E1 C1 C2 E2\r
-\r
-; expand like this:\r
-; C1.....P3.....C2\r
-; . . . .\r
-; . _P4_P6__P5_ .\r
-; P1- .. .. P2\r
-; | .. .. |\r
-; |.. ..|\r
-; E1............E2\r
-;\r
-; stack looks like: E1 P1 P4 P6 P5 P2 E2\r
-; Since P6 is part of both new boxes, we use it twice.\r
-\r
- sub sp, 24\r
- sub bp, 24\r
-\r
-; new points for X --\r
- LoadV0 E1Src, XCoord\r
- LoadV1 E2Src, XCoord\r
- StoreV1 E2Dest, XCoord\r
- LoadV2 C1Src, XCoord\r
- AverageV0nV2\r
- StoreV0 P1Dest, XCoord\r
- AverageV1nData C2Src, XCoord\r
- StoreV1 P2Dest, XCoord\r
- AverageV2nData C2Src, XCoord\r
- AverageV0nV2\r
- StoreV0 P4Dest, XCoord\r
- AverageV1nV2\r
- StoreV1 P5Dest, XCoord\r
- AverageV0nV1\r
- StoreV0 P6Dest, XCoord\r
-\r
-; same thing for Y --\r
- LoadV0 E1Src, YCoord\r
- LoadV1 E2Src, YCoord\r
- StoreV1 E2Dest, YCoord\r
- LoadV2 C1Src, YCoord\r
- AverageV0nV2\r
- StoreV0 P1Dest, YCoord\r
- AverageV1nData C2Src, YCoord\r
- StoreV1 P2Dest, YCoord\r
- AverageV2nData C2Src, YCoord\r
- AverageV0nV2\r
- StoreV0 P4Dest, YCoord\r
- AverageV1nV2\r
- StoreV1 P5Dest, YCoord\r
- AverageV0nV1\r
- StoreV0 P6Dest, YCoord\r
-\r
- inc level ; one level further into stack\r
- jmp MainLoop\r
-\r
-PlotCurve:\r
-; pull 16-bit coordinates back out of 32-bit fixed-point coordinates;\r
-; integer part is highest 13 bits\r
-\r
- Extract cx, C1Draw, XCoord\r
- Extract di, E1Draw, XCoord\r
- mov c1xt, cx\r
- add cx, di\r
- shr cx, 1\r
- mov p1xt, cx\r
-\r
- Extract ax, C1Draw, YCoord\r
- Extract si, E1Draw, YCoord\r
- mov c1yt, ax\r
- add ax, si\r
- shr ax, 1\r
- mov p1yt, ax\r
- call ShortLine ; line from P1 to E1\r
-\r
- Extract cx, E2Draw, XCoord\r
- Extract di, C2Draw, XCoord\r
- mov c2xt, di\r
- add di, cx\r
- shr di, 1\r
- mov p2xt, di\r
-\r
- Extract ax, E2Draw, YCoord\r
- Extract si, C2Draw, YCoord\r
- mov c2yt, si\r
- add si, ax\r
- shr si, 1\r
- mov p2yt, si\r
- call ShortLine ; line from E2 to P2\r
-\r
-; P3 is not in any line we draw, so we'll use it now to find both P5\r
-; for the line after this on, and P4 for this line, then discard it --\r
- mov bx, c1xt\r
- add bx, c2xt\r
- shr bx, 1\r
- mov dx, c1yt\r
- add dx, c2yt\r
- shr dx, 1\r
-\r
-; find P5 x and save for later lines\r
- mov cx, p2xt\r
- add cx, bx\r
- shr cx, 1\r
- mov p5xt, cx\r
-; find P4 x for this line\r
- mov cx, p1xt\r
- add cx, bx\r
- shr cx, 1\r
- mov p4xt, cx\r
- mov di, p1xt\r
-\r
-; find P5 y and save for later lines\r
- mov ax, p2yt\r
- add ax, dx\r
- shr ax, 1\r
- mov p5yt, ax\r
-; find P4 y for this line\r
- mov ax, p1yt\r
- add ax, dx\r
- shr ax, 1\r
- mov p4yt, ax\r
- mov si, p1yt\r
- call ShortLine ; line from P4 to P1 -- finally!\r
-\r
-; we've already done all the work for these last two --\r
- mov cx, p2xt\r
- mov di, p5xt\r
- mov ax, p2yt\r
- mov si, p5yt\r
- call ShortLine ; line from P2 to P5\r
-\r
- mov cx, p5xt\r
- mov di, p4xt\r
- mov ax, p5yt\r
- mov si, p4yt\r
- call ShortLine ; line from P5 to P4\r
-\r
-; we've drawn our five lines; this bezier box\r
-; can be dropped off the stack\r
- add bp, 24\r
- add sp, 24\r
-\r
- dec gencount\r
- mov cx, gencount\r
- cmp cx, -1\r
-\r
- je WrapUp ; if we've generated all the terminal nodes we\r
- ; are supposed to, we pack our bags and go.\r
- dec level\r
- jmp MainLoop\r
-\r
-WrapUp:\r
-; plot the final point, which is simply the original E1\r
-\r
- mov bp, bptemp ; back where we started\r
- mov ax, E1y\r
- add ax, 1024\r
- mul [_ScrnLogicalByteWidth]\r
- mov di, E1x\r
- add di, 1024\r
- mov si, di\r
- shr di, 2\r
- add di, ax\r
- add di, AdjustedOffs\r
- and si, 3\r
- mov al, ColumnMasks[si]\r
- mov ah, byte ptr Color\r
- mov dx, SC_INDEX + 1\r
- out dx, al\r
- mov es:[di], ah\r
-\r
- pop es\r
- pop di\r
- pop si\r
- mov sp, bp\r
- pop bp\r
- ret ; git\r
-\r
-; ShortLine subfunction --\r
-;\r
-; This is designed for short line segments. For longer lines,\r
-; especially horizontal ones, the x_line routine in the XLINE module\r
-; would be faster. But calling that from here it would be a lot of\r
-; extra complication. This is part of the x_bezier routine because\r
-; it has no particular outside use, and we can call it much faster\r
-; through registers than through the stack.\r
-;\r
-; Since our line segments overlap, the second endpoint is not drawn.\r
-; These routines are all out of order for the sake of conditional jumps.\r
-\r
-LRHorz:\r
- dec di\r
-LRHorzLoop:\r
- rol al, 1\r
- adc bx, 0\r
- out dx, al\r
- mov es:[bx], ah\r
- sub di, 1\r
- jg LRHorzLoop\r
- retn\r
-\r
-; You are in a maze of little subroutines, all alike...\r
-\r
-\r
-LR45Deg:\r
- dec si\r
-LR45DegLoop:\r
- add bx, cx\r
- rol al, 1\r
- adc bx, 0\r
- out dx, al\r
- mov es:[bx], ah\r
- sub si, 1\r
- jg LR45DegLoop\r
- retn\r
-\r
-\r
-LRXMajor:\r
- mov cx, di\r
- dec cx\r
- shr di, 1\r
-LRXMajorLoop:\r
- sub di, si\r
- jge LRXMajorIterate\r
- add di, xdiff\r
- add bx, moveline\r
-LRXMajorIterate:\r
- rol al, 1\r
- adc bx, 0\r
- out dx, al\r
- mov es:[bx], ah\r
- sub cx, 1\r
- jg LRXMajorLoop\r
- retn\r
-\r
-\r
-LeftToRight:\r
- mov xdiff, di ; store distance across line\r
-\r
- mov cx, [_ScrnLogicalByteWidth]\r
- cmp si, 0 ; check if height is positive, negative, or zero\r
- je LRHorz\r
- jg LRTopToBottom\r
- neg si\r
- neg cx\r
-LRTopToBottom:\r
- mov ydiff, si\r
- mov moveline, cx\r
- cmp di, si\r
- jg LRXMajor\r
- je LR45Deg\r
-\r
-\r
-LRYMajor:\r
- mov cx, si\r
- dec cx\r
- shr si, 1\r
-LRYMajorLoop:\r
- add bx, moveline\r
- sub si, di\r
- jge LRYMajorIterate\r
- add si, ydiff\r
- rol al, 1\r
- adc bx, 0\r
-LRYMajorIterate:\r
- out dx, al\r
- mov es:[bx], ah\r
- sub cx, 1\r
- jg LRYMajorLoop\r
- retn\r
-\r
-\r
-; This is the actual starting point.\r
-; On entry, registers look like this:\r
-; X1: cx\r
-; Y1: ax\r
-; X2: di\r
-; Y2: si\r
-ShortLine:\r
- sub si, ax ; height goes out in si\r
- sub di, cx ; width goes out in di\r
-\r
- mul [_ScrnLogicalByteWidth]\r
- mov dx, cx\r
- shr dx, 2\r
- add ax, dx\r
- add ax, AdjustedOffs\r
- mov bx, ax ; starting byte of X1, Y1 goes out in bx\r
- and cx, 3\r
- mov ax, 011h\r
- shl al, cl ; column mask goes out in al\r
- mov dx, SC_INDEX + 1\r
- mov ah, byte ptr Colort; color goes out in ah\r
- out dx, al\r
- mov es:[bx], ah ; plot first point\r
-\r
- cmp di, 0\r
-\r
- jg LeftToRight\r
- je VerticalLine\r
-\r
-\r
-RightToLeft:\r
- neg di ; much more useful this way\r
- mov xdiff, di\r
-\r
- mov cx, [_ScrnLogicalByteWidth]\r
- cmp si, 0 ; check if height is positive, negative, or zero\r
- je RLHorz\r
- jg RLTopToBottom\r
- neg si\r
- neg cx\r
-RLTopToBottom:\r
- mov ydiff, si\r
- mov moveline, cx\r
- cmp di, si\r
- jg RLXMajor\r
- je RL45Deg\r
-\r
-\r
-RLYMajor:\r
- mov cx, si\r
- dec cx\r
- shr si, 1\r
-RLYMajorLoop:\r
- add bx, moveline\r
- sub si, di\r
- jge RLYMajorIterate\r
- add si, ydiff\r
- ror al, 1\r
- sbb bx, 0\r
-RLYMajorIterate:\r
- out dx, al\r
- mov es:[bx], ah\r
- sub cx, 1\r
- jg RLYMajorLoop\r
- retn\r
-\r
-\r
-VerticalLine:\r
- mov cx, [_ScrnLogicalByteWidth]\r
- cmp si, 0 ; check if height is positive\r
- jg VTopToBottom\r
- neg si\r
- neg cx\r
-VTopToBottom:\r
- dec si\r
-VLoop:\r
- add bx, cx\r
- mov es:[bx], ah\r
- sub si, 1\r
- jg VLoop\r
- retn\r
-\r
-\r
-RLHorz:\r
- dec di\r
-RLHorzLoop:\r
- ror al, 1\r
- sbb bx, 0\r
- out dx, al\r
- mov es:[bx], ah\r
- sub di, 1\r
- jg RLHorzLoop\r
- retn\r
-\r
-\r
-RL45Deg:\r
- dec si\r
-RL45DegLoop:\r
- add bx, cx\r
- ror al, 1\r
- sbb bx, 0\r
- out dx, al\r
- mov es:[bx], ah\r
- sub si, 1\r
- jg RL45DegLoop\r
- retn\r
-\r
-\r
-RLXMajor:\r
- mov cx, di\r
- dec cx\r
- shr di, 1\r
-RLXMajorLoop:\r
- sub di, si\r
- jge RLXMajorIterate\r
- add di, xdiff\r
- add bx, moveline\r
-RLXMajorIterate:\r
- ror al, 1\r
- sbb bx, 0\r
- out dx, al\r
- mov es:[bx], ah\r
- sub cx,1\r
- jg RLXMajorLoop\r
- retn\r
-\r
-\r
-_x_bezier endp\r
-\r
- end\r
-\r
+++ /dev/null
-/*********************************************************************\\r
-| XBEZIER header file\r
-|\r
-|\r
-| This module was written by Matthew MacKenzie\r
-| matm@eng.umd.edu\r
-\*********************************************************************/\r
-\r
-#ifndef _XBEZIER_H_\r
-#define _XBEZIER_H_\r
-#ifdef __cplusplus\r
-\r
-extern "C" {\r
-#endif\r
-\r
-void x_bezier (int E1x, int E1y, int C1x, int C1y, int C2x, int C2y,\r
- int E2x, int E2y, int levels, char color,\r
- unsigned PageOffset);\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; XBEZIER include file\r
-;\r
-;\r
-; This module was written by Matthew MacKenzie\r
-; matm@eng.umd.edu\r
-;-----------------------------------------------------------------------\r
-\r
-global _x_bezier : proc\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XBMTOOLS\r
-;\r
-; Bitmap conversion / manipulation tools\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-COMMENT $\r
-\r
- This module implements a set of functions to manipulate both planar\r
- bitmaps and linear bitmaps (as used by x_compile_bitmap):\r
-\r
- PLANAR BITMAPS\r
-\r
- Planar bitmaps as used by these functions have the following structure:\r
-\r
- BYTE 0 The bitmap width in bytes (4 pixel groups) range 1..255\r
- BYTE 1 The bitmap height in rows range 1..255\r
- BYTE 2..n1 The plane 0 pixels width*height bytes\r
- BYTE n1..n2 The plane 1 pixels width*height bytes\r
- BYTE n2..n3 The plane 2 pixels width*height bytes\r
- BYTE n3..n4 The plane 3 pixels width*height bytes\r
-\r
- LINEAR BITMAPS\r
-\r
- Linear bitmaps have the following structure:\r
-\r
- BYTE 0 The bitmap width in pixels range 1..255\r
- BYTE 1 The bitmap height in rows range 1..255\r
- BYTE 2..n The width*height bytes of the bitmap\r
-\r
-\r
-\r
-$\r
-\r
-LOCALS\r
-.286\r
-\r
-include model.inc\r
-include xbmtools.inc\r
-\r
- .code\r
-\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; x_pbm_to_bm\r
-;\r
-; This function converts a bitmap in the planar format to the linear format\r
-; as used by x_compile_bitmap.\r
-;\r
-; WARNING: the source and destination bitmaps must be pre - allocated\r
-;\r
-; NOTE: This function can only convert planar bitmaps that are suitable.\r
-; If the source planar bitmap's width (per plane) is >= 256/4\r
-; it cannot be converted. In this situation an error code\r
-; BM_WIDTH_ERROR. On successful conversion 0 is returned.\r
-;\r
-; C callable as:\r
-; int x_pbm_to_bm(char far * source_pbm, char far * dest_bm);\r
-;\r
-; Written By Themie Gouthas\r
-\r
-proc _x_pbm_to_bm\r
-ARG src_pbm:dword,dest_bm:dword\r
- push bp ; Preserve caller's stack frame\r
- mov bp,sp\r
- push ds\r
- push di\r
- push si\r
-\r
- les di,[dest_bm] ; es:di -> destination bitmap\r
- lds si,[src_pbm] ; ds:si -> source planar bitmap\r
- lodsb ; load AL with source pbm pixel width per plane\r
- mov bl,al ; save in CL\r
- xor ah,ah ; convert to word\r
- shl ax,2 ; mult by 4 giving source image width\r
- cmp ax,255 ; if the result > 255 then we have exceeded\r
- ja @@WidthError ; the max width of linear bm.\r
-\r
- stosb ; write do dest_bm\r
-\r
- lodsb ; tranfer source pbm height in pixels to\r
- stosb ; dest_bm\r
-\r
- xor ah,ah ; convert to word\r
- mul bl ; AX = AX * BL ie. total no. pixels per plane\r
- mov dx,di ; save DI, the pointer to the destination bm\r
- mov bl,3 ; set plane loop counter (BL)\r
-\r
-@@PlaneLoop:\r
- mov cx,ax ; set CX to total number of pixels per plane\r
-\r
-@@PixelLoop:\r
- movsb ; transfer pixel\r
- add di,3 ; increment destination to compensate for plane\r
- loop @@PixelLoop\r
-\r
- inc dx ; increment original di for next pixel plane\r
- mov di,dx ; and restore di from incremented original\r
- dec bl ; decrement plane counter\r
- jns @@PlaneLoop ; loop if more planes left\r
- xor ax,ax\r
- jmp short @@Done\r
-@@WidthError:\r
- mov ax,1\r
-\r
-@@Done:\r
- pop si\r
- pop di\r
- pop ds\r
- pop bp ;restore caller's stack frame\r
- ret\r
-_x_pbm_to_bm endp\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; x_bm_to_pbm\r
-;\r
-; This function converts a bitmap in the linear format as used by\r
-; x_compile_bitmap to the planar formap.\r
-;\r
-; WARNING: the source and destination bitmaps must be pre - allocated\r
-;\r
-; NOTE: This function can only convert linear bitmaps that are suitable.\r
-; If the source linear bitmap's width is not a multiple of 4\r
-; it cannot be converted. In this situation an error code\r
-; BM_WIDTH_ERROR. On successful conversion 0 is returned.\r
-;\r
-;\r
-; C callable as:\r
-; int x_bm_to_pbm(char far * source_pbm, char far * dest_bm);\r
-;\r
-; Written By Themie Gouthas\r
-\r
-proc _x_bm_to_pbm\r
-ARG src_bm:dword,dest_pbm:dword\r
- push bp ; Preserve caller's stack frame\r
- mov bp,sp\r
- push ds\r
- push di\r
- push si\r
-\r
- les di,[dest_pbm] ; es:di -> destination planar bitmap\r
- lds si,[src_bm] ; ds:si -> source bitmap\r
- lodsb ; load AX with source bitmap width\r
- test al,03h ; Check that width is a multiple of 4\r
- jnz @@WidthIncompatible\r
- shr al,2 ; divide by 4 giving width of plane\r
- stosb ; store destination planar bitmap width\r
- mov bl,al ; and copy to bl\r
- lodsb\r
- stosb ; Transfer source bitmap height to dest pbm\r
- xor ah,ah ; Conver height to word\r
- mul bl ; calculate the total no. of pixels / plane\r
- mov dx,si ; save source offset\r
- mov bl,3\r
-\r
-@@PlaneLoop:\r
- mov cx,ax ; set CX to total number of pixels per plane\r
-\r
-@@PixelLoop:\r
- movsb ; transfer pixel\r
- add si,3 ; increment src offset to compensate for plane\r
- loop @@PixelLoop\r
-\r
- inc dx ; increment original si for next pixel plane\r
- mov si,dx ; and restore si from incremented original\r
- dec bl ; decrement plane counter\r
- jns @@PlaneLoop ; loop if more planes left\r
- xor ax,ax\r
- jmp short @@Done\r
-@@WidthIncompatible:\r
- mov ax,1\r
-\r
-@@Done:\r
- pop si\r
- pop di\r
- pop ds\r
- pop bp ;restore caller's stack frame\r
- ret\r
-_x_bm_to_pbm endp\r
-\r
-\r
- end\r
-\r
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XPOINT - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; Macros written by Mathew Mackenzie\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;-----------------------------------------------------------------------*/\r
-\r
-#ifndef _XBMTOOLS_H_\r
-#define _XBMTOOLS_H_\r
-\r
-#define BM_WIDTH_ERROR 1\r
-\r
-#define LBMHeight(lbitmap) lbitmap[1]\r
-#define LBMWidth(lbitmap) lbitmap[0]\r
-#define PBMHeight(pbitmap) pbitmap[1]\r
-#define PBMWidth(pbitmap) (pbitmap[0]<<2)\r
-#define PBMByteWidth(pbitmap) pbitmap[0]\r
-\r
-#define LBMPutPix(x,y,lbitmap,color) \\r
- lbitmap[2 + (x) + (y) * LBMWidth(lbitmap)] = color\r
-\r
-#define LBMGetPix(x,y,lbitmap) \\r
- (lbitmap[2 + (x) + (y) * LBMWidth(lbitmap)])\r
-\r
-\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
- int x_pbm_to_bm( /* Convert from planar bitmap to linear */\r
- char far * source_pbm,\r
- char far * dest_bm);\r
-\r
- int x_bm_to_pbm( /* Convert from linear bitmap to planar */\r
- char far * source_pbm,\r
- char far * dest_bm);\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-\r
-#endif\r
-\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XBMTOOLS - Include file\r
-;\r
-; XBMTOOLS.ASM export functions\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
- global _x_pbm_to_bm :proc\r
- global _x_bm_to_pbm :proc\r
-\1a
\ No newline at end of file
+++ /dev/null
-#include "xbmtools.h"\r
-\r
-/* these are here instead of the header file because they're not part\r
- of the library interface */\r
-\r
-// rol al\r
-#define ROL_AL 0xc0d0\r
-// mov [si + disp8], imm8\r
-#define SHORT_STORE_8 0x44c6\r
-// mov [si + disp16], imm8\r
-#define STORE_8 0x84c6\r
-// mov [si + disp8], imm16\r
-#define SHORT_STORE_16 0x44c7\r
-// mov [si + disp16], imm16\r
-#define STORE_16 0x84c7\r
-// adc si, imm8\r
-#define ADC_SI_IMMED 0xd683\r
-// out dx, al\r
-#define OUT_AL 0xee\r
-// ret\r
-#define RETURN 0xcb\r
-// 32-bit prefix\r
-#define DWORD_PREFIX 0x66\r
-\r
-#define Emitb(x) *(output + output_used) = (x); output_used++\r
-\r
-#define Emitw(x) *(output + output_used) = (x) & 255; \\r
- *(output + output_used + 1) = (x) >> 8; \\r
- output_used += 2\r
-\r
-\r
-int x_compile_bitmap_32 (int logical_screen_width, char far * bitmap,\r
- char far * output)\r
-{\r
- int pix0, pix1, pix2, pix3, numpix, pos;\r
- int column = 0, set_column = 0;\r
- int scanx = 0, scany = 0;\r
- int output_used = 0;\r
-\r
- int height = LBMHeight(bitmap);\r
- int width = LBMWidth(bitmap);\r
- int margin = width - 1;\r
- int margin2 = margin - 4;\r
- int margin4 = margin - 12;\r
-\r
- while (column < 4) {\r
- numpix = 1;\r
- pix0 = LBMGetPix(scanx, scany, bitmap);\r
- if (pix0 != 0) {\r
- if (set_column != column) {\r
- do {\r
- Emitw (ROL_AL);\r
- Emitw (ADC_SI_IMMED);\r
- Emitb (0);\r
- set_column++;\r
- } while (set_column != column);\r
- Emitb (OUT_AL);\r
- }\r
- if (scanx <= margin2) {\r
- pix1 = LBMGetPix(scanx + 4, scany, bitmap);\r
- if ((pix1 != 0)\r
- &&(scanx <= margin4)) {\r
- numpix = 2;\r
- pix2 = LBMGetPix(scanx + 8, scany, bitmap);\r
- pix3 = LBMGetPix(scanx + 12, scany, bitmap);\r
- if ((pix2 != 0) && (pix3 != 0)) {\r
- numpix = 4;\r
- Emitb (DWORD_PREFIX);\r
- }\r
- }\r
- }\r
- pos = (scany * logical_screen_width) + (scanx >> 2) - 128;\r
- if ((pos >= -128) && (pos <= 127)) {\r
- if (numpix == 1) {\r
- Emitw (SHORT_STORE_8);\r
- Emitb (pos);\r
- Emitb (pix0);\r
- } else {\r
- Emitw (SHORT_STORE_16);\r
- Emitb (pos);\r
- Emitb (pix0);\r
- Emitb (pix1);\r
- if (numpix == 4) {\r
- Emitb (pix2);\r
- Emitb (pix3);\r
- }\r
- }\r
- } else {\r
- if (numpix == 1) {\r
- Emitw (STORE_8);\r
- Emitw (pos);\r
- Emitb (pix0);\r
- } else {\r
- Emitw (STORE_16);\r
- Emitw (pos);\r
- Emitb (pix0);\r
- Emitb (pix1);\r
- if (numpix == 4) {\r
- Emitb (pix2);\r
- Emitb (pix3);\r
- }\r
- }\r
- }\r
- }\r
- scanx += (numpix << 2);\r
- if (scanx > margin) {\r
- scanx = column;\r
- scany++;\r
- if (scany == height) {\r
- scany = 0;\r
- column++;\r
- }\r
- }\r
- }\r
- Emitb(RETURN);\r
- return(output_used);\r
-}\r
-\r
-\r
-int x_sizeof_cbitmap_32 (int logical_screen_width, char far * bitmap)\r
-{\r
- int pix0, pix1, pix2, pix3, numpix, pos;\r
- int column = 0, set_column = 0;\r
- int scanx = 0, scany = 0;\r
- int output_used = 1;\r
-\r
- int height = LBMHeight(bitmap);\r
- int width = LBMWidth(bitmap);\r
- int margin = width - 1;\r
- int margin2 = margin - 4;\r
- int margin4 = margin - 12;\r
-\r
- while (column < 4) {\r
- numpix = 1;\r
- pix0 = LBMGetPix(scanx, scany, bitmap);\r
- if (pix0 != 0) {\r
- if (set_column != column) {\r
- do {\r
- output_used += 5;\r
- set_column++;\r
- } while (set_column != column);\r
- output_used++;\r
- }\r
- if (scanx <= margin2) {\r
- pix1 = LBMGetPix(scanx + 4, scany, bitmap);\r
- if ((pix1 != 0)\r
- &&(scanx <= margin4)) {\r
- numpix = 2;\r
- pix2 = LBMGetPix(scanx + 8, scany, bitmap);\r
- pix3 = LBMGetPix(scanx + 12, scany, bitmap);\r
- if ((pix2 != 0) && (pix3 != 0)) {\r
- numpix = 4;\r
- output_used++;\r
- }\r
- }\r
- }\r
- pos = (scany * logical_screen_width) + (scanx >> 2) - 128;\r
- if ((pos >= -128) && (pos <= 127)) {\r
- if (numpix == 1) {\r
- output_used += 4;\r
- } else {\r
- output_used += 5;\r
- if (numpix == 4)\r
- output_used += 2;\r
- }\r
- } else {\r
- if (numpix == 1) {\r
- output_used += 5;\r
- } else {\r
- output_used += 6;\r
- if (numpix == 4)\r
- output_used += 2;\r
- }\r
- }\r
- }\r
- scanx += (numpix << 2);\r
- if (scanx > margin) {\r
- scanx = column;\r
- scany++;\r
- if (scany == height) {\r
- scany = 0;\r
- column++;\r
- }\r
- }\r
- }\r
- return(output_used);\r
-}\r
-\r
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XCBITM32 - header file\r
-;\r
-; This module was written by Matthew MacKenzie\r
-; matm@eng.umd.edu\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-;----------------------------------------------------------------------*/\r
-/* Notice that there is no function in this module to plot a\r
- compiled bitmap. Use x_put_cbitmap in module XCBITMAP. */\r
-\r
-/* This module is only for 386+ class computers. */\r
-\r
-#ifndef _XCBITM32_H_\r
-#define _XCBITM32_H_\r
-\r
-extern int x_compile_bitmap_32 ( /* Compile a linear bitmap to generate */\r
- WORD logical_screen_width, /* machine code to plot it at any */\r
- char far * bitmap, /* required screen coordinates FAST. */\r
- char far * output);\r
-\r
-extern int x_sizeof_cbitmap_32 ( /* Find the size of the code which a */\r
- WORD logical_screen_width, /* bitmap would result in, if it */\r
- char far * bitmap); /* were compiled (used for allocation). */\r
-\r
-#endif\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XCBITMAP\r
-; This module was written by Matthew MacKenzie\r
-; matm@eng.umd.edu\r
-;\r
-; Compiled bitmap functions all MODE X 256 Color resolutions\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-; ****** Aeronautical Research Laboratory ****************\r
-; ****** Defence Science and Technology Organisation ****************\r
-; ****** Australia ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-include xlib.inc\r
-include xcbitmap.inc\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-; _x_compile_bitmap\r
-;\r
-; Compile a linear bitmap to generate machine code to plot it\r
-; at any required screen coordinates FAST. Faster than blits\r
-; using planar bitmaps as in module XPBIITMAP\r
-;\r
-; C near-callable as:\r
-; int x_compile_bitmap (WORD logical_screen_width,\r
-; char far * bitmap, char far * output);\r
-;\r
-; The logical width is in bytes rather than pixels.\r
-;\r
-; All four main registers are totaled.\r
-;\r
-; The source linear bitmaps have the following structure:\r
-;\r
-; BYTE 0 The bitmap width in pixels range 1..255\r
-; BYTE 1 The bitmap height in rows range 1..255\r
-; BYTE 2..n The width*height bytes of the bitmap in\r
-; cloumn row order\r
-;\r
-; The returned value is the size of the compiled bitmap, in bytes.\r
-\r
-\r
-; accessory macros to save typing (what else?)\r
-Emitb macro arg\r
- mov byte ptr es:[di],&arg&\r
- inc di\r
- endm\r
-\r
-Emitw macro arg\r
- mov word ptr es:[di],&arg&\r
- add di,2\r
- endm\r
-\r
-; opcodes emitted by _x_compile_sprite\r
-ROL_AL equ 0c0d0h ; rol al\r
-SHORT_STORE_8 equ 044c6h ; mov [si]+disp8, imm8\r
-STORE_8 equ 084c6h ; mov [si]+disp16, imm8\r
-SHORT_STORE_16 equ 044c7h ; mov [si]+disp8, imm16\r
-STORE_16 equ 084c7h ; mov [si]+disp16, imm16\r
-ADC_SI_IMMED equ 0d683h ; adc si,imm8\r
-OUT_AL equ 0eeh ; out dx,al\r
-RETURN equ 0cbh ; ret\r
-\r
-\r
-.data\r
-\r
-align 2\r
-ColumnMask db 011h,022h,044h,088h\r
-\r
-\r
-.code\r
-\r
- align 2\r
-_x_compile_bitmap proc\r
-ARG logical_width:word,bitmap:dword,output:dword\r
-LOCAL bwidth,scanx,scany,outputx,outputy,column,set_column,input_size:word=LocalStk\r
- push bp\r
- mov bp, sp ; caller's stack frame\r
- sub sp,LocalStk ; local space\r
- push si\r
- push di\r
- push ds\r
-\r
- mov word ptr [scanx],0\r
- mov word ptr [scany],0\r
- mov word ptr [outputx],0\r
- mov word ptr [outputy],0\r
- mov word ptr [column],0\r
- mov word ptr [set_column],0\r
-\r
- lds si,[bitmap] ; 32-bit pointer to source bitmap\r
-\r
- les di,[output] ; 32-bit pointer to destination stream\r
-\r
- lodsb ; load width byte\r
- xor ah, ah ; convert to word\r
- mov [bwidth], ax ; save for future reference\r
- mov bl, al ; copy width byte to bl\r
- lodsb ; load height byte -- already a word since ah=0\r
- mul bl ; mult height word by width byte\r
- mov [input_size], ax; to get pixel total \r
-\r
-@@MainLoop:\r
- mov bx, [scanx] ; position in original bitmap\r
- add bx, [scany]\r
-\r
- mov al, [si+bx] ; get pixel\r
- or al, al ; skip empty pixels\r
- jnz @@NoAdvance\r
- jmp @@Advance\r
-@@NoAdvance:\r
-\r
- mov dx, [set_column]\r
- cmp dx, [column]\r
- je @@SameColumn\r
-@@ColumnLoop:\r
- Emitw ROL_AL ; emit code to move to new column\r
- Emitw ADC_SI_IMMED\r
- Emitb 0\r
-\r
- inc dx\r
- cmp dx, [column]\r
- jl @@ColumnLoop\r
-\r
- Emitb OUT_AL ; emit code to set VGA mask for new column\r
- mov [set_column], dx\r
-@@SameColumn:\r
- mov dx, [outputy] ; calculate output position\r
- add dx, [outputx]\r
- sub dx, 128\r
-\r
- add word ptr [scanx], 4\r
- mov cx, [scanx] ; within four pixels of right edge?\r
- cmp cx, [bwidth]\r
- jge @@OnePixel\r
-\r
- inc word ptr [outputx]\r
- mov ah, [si+bx+4] ; get second pixel\r
- or ah, ah\r
- jnz @@TwoPixels\r
-@@OnePixel:\r
- cmp dx, 127 ; can we use shorter form?\r
- jg @@OnePixLarge\r
- cmp dx, -128\r
- jl @@OnePixLarge\r
- Emitw SHORT_STORE_8\r
- Emitb dl ; 8-bit position in output\r
- jmp @@EmitOnePixel\r
-@@OnePixLarge:\r
- Emitw STORE_8\r
- Emitw dx ; position in output\r
-@@EmitOnePixel:\r
- Emitb al\r
- jmp short @@Advance\r
-@@TwoPixels:\r
- cmp dx, 127\r
- jg @@TwoPixLarge\r
- cmp dx, -128\r
- jl @@TwoPixLarge\r
- Emitw SHORT_STORE_16\r
- Emitb dl ; 8-bit position in output\r
- jmp @@EmitTwoPixels\r
-@@TwoPixLarge:\r
- Emitw STORE_16\r
- Emitw dx ; position in output\r
-@@EmitTwoPixels:\r
- Emitw ax\r
-\r
-@@Advance:\r
- inc word ptr [outputx]\r
- mov ax, [scanx]\r
- add ax, 4\r
- cmp ax, [bwidth]\r
- jl @@AdvanceDone\r
- mov dx, [outputy]\r
- add dx, [logical_width]\r
- mov cx, [scany]\r
- add cx, [bwidth]\r
- cmp cx, [input_size]\r
- jl @@NoNewColumn\r
- inc word ptr [column]\r
- mov cx, [column]\r
- cmp cx, 4\r
- je @@Exit ; Column 4: there is no column 4.\r
- xor cx, cx ; scany and outputy are 0 again for\r
- mov dx, cx ; the new column\r
-@@NoNewColumn:\r
- mov [outputy], dx\r
- mov [scany], cx\r
- mov word ptr [outputx], 0\r
- mov ax,[column]\r
-@@AdvanceDone:\r
- mov [scanx], ax\r
- jmp @@MainLoop\r
-\r
-@@Exit:\r
- Emitb RETURN\r
- mov ax,di\r
- sub ax,word ptr [output] ; size of generated code\r
-\r
- pop ds\r
- pop di\r
- pop si\r
- mov sp, bp\r
- pop bp\r
-\r
- ret\r
-_x_compile_bitmap endp\r
-\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-; _x_sizeof_cbitmap\r
-;\r
-; This function follows the same algorithm as the one above,\r
-; but does not generate a new object. Its sole purpose is to\r
-; determine how much space the compiled bitmap will require.\r
-;\r
-; C near-callable as:\r
-; int x_sizeof_cbitmap (WORD logical_screen_width,\r
-; char far * bitmap);\r
-;\r
-; The logical width is in bytes rather than pixels.\r
-;\r
-; All four main registers are totaled.\r
-;\r
-; The source linear bitmaps have the following structure:\r
-;\r
-; BYTE 0 The bitmap width in pixels range 1..255\r
-; BYTE 1 The bitmap height in rows range 1..255\r
-; BYTE 2..n The width*height bytes of the bitmap in\r
-; cloumn row order\r
-;\r
-; The returned value is the size of the compiled bitmap, in bytes.\r
-\r
-\r
- align 2\r
-_x_sizeof_cbitmap proc\r
-ARG logical_width:word,bitmap:dword\r
-LOCAL bwidth,scanx,scany,outputx,outputy,column,set_column,input_size:word=LocalStk\r
- push bp\r
- mov bp, sp ; caller's stack frame\r
- sub sp,LocalStk ; local space\r
- push si\r
- push di\r
- push ds\r
-\r
- mov word ptr [scanx], 0\r
- mov word ptr [scany], 0\r
- mov word ptr [outputx], 0\r
- mov word ptr [outputy], 0\r
- mov word ptr [column], 0\r
- mov word ptr [set_column], 0\r
-\r
- lds si,[bitmap] ; 32-bit pointer to source bitmap\r
-\r
- mov di, 1 ; initial size is just the size of the far RET\r
-\r
- lodsb ; load width byte\r
- xor ah, ah ; convert to word\r
- mov [bwidth], ax ; save for future reference\r
- mov bl, al ; copy width byte to bl\r
- lodsb ; load height byte -- already a word since ah=0\r
- mul bl ; mult height word by width byte\r
- mov [input_size], ax; to get pixel total\r
-\r
-@@MainLoop:\r
- mov bx, [scanx] ; position in original bitmap\r
- add bx, [scany]\r
-\r
- mov al, [si+bx] ; get pixel\r
- or al, al ; skip empty pixels\r
- jnz @@NoAdvance\r
- jmp @@Advance\r
-@@NoAdvance:\r
-\r
- mov dx, [set_column]\r
- cmp dx, [column]\r
- je @@SameColumn\r
-@@ColumnLoop:\r
- add di, 5 ; size of code to move to new column\r
- inc dx\r
- cmp dx,[column]\r
- jl @@ColumnLoop\r
-\r
- inc di ; size of code to set VGA mask\r
- mov [set_column], dx\r
-@@SameColumn:\r
- mov dx, [outputy] ; calculate output position\r
- add dx, [outputx]\r
- sub dx, 128\r
-\r
- add word ptr [scanx], 4\r
- mov cx, [scanx] ; within four pixels of right edge?\r
- cmp cx, [bwidth]\r
- jge @@OnePixel\r
-\r
- inc word ptr [outputx]\r
- mov ah,[si+bx+4] ; get second pixel\r
- or ah, ah\r
- jnz @@TwoPixels\r
-@@OnePixel:\r
- cmp dx, 127 ; can we use shorter form?\r
- jg @@OnePixLarge\r
- cmp dx, -128\r
- jl @@OnePixLarge\r
- add di, 4 ; size of 8-bit position in output plus one pixel\r
- jmp @@EmitOnePixel\r
-@@OnePixLarge:\r
- add di, 5 ; size of position in output plus one pixels\r
-@@EmitOnePixel:\r
- jmp short @@Advance\r
-@@TwoPixels:\r
- cmp dx, 127\r
- jg @@TwoPixLarge\r
- cmp dx, -128\r
- jl @@TwoPixLarge\r
- add di, 5 ; size of 8-bit position in output plus two pixels\r
- jmp @@EmitTwoPixels\r
-@@TwoPixLarge:\r
- add di, 6 ; size of 16-bit position in output plus two pixels\r
-@@EmitTwoPixels:\r
-\r
-@@Advance:\r
- inc word ptr [outputx]\r
- mov ax, [scanx]\r
- add ax,4\r
- cmp ax, [bwidth]\r
- jl @@AdvanceDone\r
- mov dx, [outputy]\r
- add dx, [logical_width]\r
- mov cx, [scany]\r
- add cx, [bwidth]\r
- cmp cx, [input_size]\r
- jl @@NoNewColumn\r
- inc word ptr [column]\r
- mov cx, [column]\r
- cmp cx, 4\r
- je @@Exit ; Column 4: there is no column 4.\r
- xor cx,cx ; scany and outputy are 0 again for\r
- mov dx,cx ; the new column\r
-@@NoNewColumn:\r
- mov [outputy], dx\r
- mov [scany], cx\r
- mov word ptr [outputx], 0\r
- mov ax,[column]\r
-@@AdvanceDone:\r
- mov [scanx], ax\r
- jmp @@MainLoop\r
-\r
-@@Exit:\r
- mov ax, di ; size of generated code\r
-\r
- pop ds\r
- pop di\r
- pop si\r
- mov sp,bp\r
- pop bp\r
-\r
- ret\r
-_x_sizeof_cbitmap endp\r
-\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-; _x_put_cbitmap\r
-;\r
-; Displays a compiled bitmap generated by x_compile_bitmap at given\r
-; coordinates, on a given screen page.\r
-;\r
-; C near-callable as:\r
-; void x_put_cbitmap (int XPos, int YPos,\r
-; unsigned int PageOffset, char far * Sprite);\r
-; ax, bx, cx, and dx are squashed like insignificant insects.\r
-\r
- align 2\r
-_x_put_cbitmap proc\r
-ARG XPos:word,YPos:word,PageOffset:word,Sprite:dword\r
-\r
- push bp\r
- mov bp, sp\r
- push si\r
- push ds\r
-\r
- mov ax, [_ScrnLogicalByteWidth] ; global Xlib variable\r
- mul word ptr [YPos] ; height in bytes\r
- mov si, [XPos]\r
- mov bx, si\r
- sar si, 2 ; width in bytes\r
- add si, ax\r
- add si, [PageOffset]; (YPos * screen width) +\r
- add si, 128 ; (Xpos / 4) + page base + 128 ==> starting pos\r
-\r
- and bx, 3\r
- mov ah, ColumnMask[bx]\r
-\r
- mov dx, SC_INDEX\r
- mov al, MAP_MASK\r
- out dx, ax\r
- inc dx ; ready to send out other masks as bytes\r
- mov al, ah\r
-\r
- mov bx, SCREEN_SEG\r
- mov ds, bx ; We do this so the compiled shape won't need\r
- ; segment overrides.\r
-\r
- call dword ptr [Sprite] ; the business end of the routine\r
-\r
- pop ds\r
- pop si\r
- pop bp\r
-\r
- ret\r
-_x_put_cbitmap endp\r
-\r
-end\r
-\r
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XCBITMAP - header file\r
-;\r
-; This module was written by Matthew MacKenzie\r
-; matm@eng.umd.edu\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-;----------------------------------------------------------------------*/\r
-\r
-#ifndef _XCBITMAP_H_\r
-#define _XCBITMAP_H_\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-\r
-\r
- int x_compile_bitmap ( /* Compile a linear bitmap to generate */\r
- WORD logical_screen_width, /* machine code to plot it at any */\r
- char far * bitmap, /* required screen coordinates FAST. */\r
- char far * output);\r
-\r
- int x_sizeof_cbitmap ( /* Find the size of the code which a */\r
- WORD logical_screen_width, /* bitmap would result in, if it */\r
- char far * bitmap); /* were compiled (used for allocation). */\r
-\r
- void x_put_cbitmap ( /* Displays a compiled bitmap generated */\r
- WORD XPos, /* by x_compile_bitmap. */\r
- WORD YPos,\r
- WORD PageOffset,\r
- char far * CompiledBitmap);\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-\r
-#endif\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XCBITMAP - Include file\r
-; This module was written by Matthew MacKenzie\r
-; matm@eng.umd.edu\r
-;\r
-; XCBITMAP.ASM export functions\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-global _x_compile_bitmap : proc\r
-global _x_sizeof_cbitmap : proc\r
-global _x_put_cbitmap : proc\r
-\r
-\1a
\ No newline at end of file
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; MODULE XCIRCLE\r
-;\r
-; This module was written by Matthew MacKenzie\r
-; matm@eng.umd.edu\r
-;\r
-; Circles, full and empty.\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-include xlib.inc\r
-include xcircle.inc\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-; _x_circle\r
-;\r
-; Draw a circle.\r
-;\r
-; C near-callable as:\r
-; int x_circle (WORD Left, WORD Top, WORD Diameter,\r
-; WORD Color, WORD ScreenOffs);\r
-;\r
-; No clipping is performed.\r
-;\r
-; ax, bx, cx, and dx bite the dust, as Homer would say.\r
-\r
-; we plot into eight arcs at once:\r
-; 4 0\r
-; 6 \|/ 2\r
-; --*--\r
-; 7 /|\ 3\r
-; 5 1\r
-;\r
-; 0, 1, 4, and 5 are considered x-major; the rest, y-major.\r
-;\r
-; The x-major plots grow out from the top and bottom of the circle,\r
-; while the y-major plots start at the left and right edges.\r
-\r
- .data\r
-\r
- align 2\r
-\r
-ColumnMask db 011h,022h,044h,088h\r
-\r
- .code\r
-\r
- public _x_circle\r
- align 2\r
-_x_circle proc\r
-ARG Left:word, Top:word, Diameter:word, Color:word, ScreenOffs:word\r
-LOCAL offset0,offset1,offset2,offset3,offset4,offset5,offset6,offset7,mask0n1,mask2n3,mask4n5,mask6n7,shrunk_radius,diameter_even,error:word=LocalStk\r
-; Tasm 1.0 does not allow the \ line continuation\r
-;LOCAL offset0:word, offset1:word, offset2:word, offset3:word, \\r
-; offset4:word, offset5:word, offset6:word, offset7:word, \\r
-; mask0n1:word, mask2n3:word, mask4n5:word, mask6n7:word, \\r
-; shrunk_radius:word, diameter_even:word, error:word=LocalStk\r
-\r
- push bp\r
- mov bp, sp\r
- sub sp, LocalStk\r
- push si\r
- push di\r
- push ds\r
-\r
-; find starting locations of plots 2, 3, 6, and 7\r
- mov di, _ScrnLogicalByteWidth\r
- xor dx, dx\r
-\r
- mov ax, Diameter ; find vertical midpoint\r
- dec ax\r
- shr ax, 1\r
- adc dx, 0 ; remember if it's rounded\r
- mov shrunk_radius, ax ; radius, rounded down for adding\r
- mov diameter_even, dx ; (diameter - 1) & 1, effectively\r
- add ax, Top\r
- mul di ; vertical midpoint in bytes\r
- add ax, ScreenOffs\r
-\r
- mov bx, Left\r
- mov cx, bx ; save for later\r
- mov si, bx\r
- shr si, 2\r
- add si, ax\r
- mov offset6, si\r
- and bx, 3 ; column of left side\r
- mov bl, ColumnMask[bx]\r
- mov mask6n7, bx\r
-\r
- add cx, Diameter\r
- dec cx\r
- mov bx, cx\r
- shr cx, 2\r
- add cx, ax\r
- mov offset2, cx\r
- and bx, 3 ; column of right side\r
- mov bl, ColumnMask[bx]\r
- mov mask2n3, bx\r
-\r
- cmp diameter_even, 1\r
- jne @@MiddlePlotsOverlap\r
- add si, di\r
- add cx, di\r
-@@MiddlePlotsOverlap:\r
- mov offset7, si\r
- mov offset3, cx\r
-\r
-; starting locations of 0, 1, 4, and 5\r
- mov bx, Left\r
- add bx, shrunk_radius ; find horizontal midpoint\r
-\r
- mov ax, Top ; top in bytes\r
- mul di\r
- add ax, ScreenOffs\r
- mov si, ax\r
-\r
- mov ax, Diameter ; bottom in bytes\r
- dec ax\r
- mul di\r
- add ax, si\r
-\r
- mov di, bx ; horizontal midpoint in bytes\r
- shr di, 2\r
- add si, di ; top midpoint in bytes\r
- mov offset4, si\r
- add di, ax ; bottom midpoint in bytes\r
- mov offset5, di\r
- and bx, 3 ; column of horizontal midpoint\r
- mov bl, ColumnMask[bx]\r
- mov mask4n5, bx\r
-\r
- cmp diameter_even, 1\r
- jne @@TopAndBottomPlotsOverlap\r
- rol bl, 1\r
- jnc @@TopAndBottomPlotsOverlap\r
- inc si\r
- inc di\r
-@@TopAndBottomPlotsOverlap:\r
- mov offset0, si\r
- mov offset1, di\r
- mov mask0n1, bx\r
-\r
-; we've got our eight plots in their starting positions, so\r
-; it's time to sort out the registers\r
- mov bx, _ScrnLogicalByteWidth\r
-\r
- mov dx, SCREEN_SEG\r
- mov ds, dx\r
-\r
- mov dx, SC_INDEX ; set VGA to accept column masks\r
- mov al, MAP_MASK\r
- out dx, al\r
- inc dx ; gun the engine...\r
-\r
- mov si, Diameter ; initial y is radius -- 2 #s per pixel\r
- inc si\r
-\r
- mov cx, si\r
- neg cx\r
- add cx, 2\r
- mov error, cx ; error = -y + one pixel since we're a step ahead\r
-\r
- xor cx, cx ; initial x = 0\r
- mov ah, byte ptr Color\r
- jmp @@CircleCalc ; let's actually put something on the screen!\r
-\r
-; move the x-major plots horizontally and the y-major plots vertically\r
-@@NoAdvance:\r
- mov al, byte ptr mask0n1\r
- out dx, al\r
- mov di, offset0 ; plot 0\r
- mov [di], ah\r
- rol al, 1 ; advance 0 right\r
- mov byte ptr mask0n1, al\r
- adc di, 0\r
- mov offset0, di\r
- mov di, offset1\r
- mov [di], ah ; plot 1\r
- ror al, 1 ; what was that bit again?\r
- adc di, 0 ; advance 1 right\r
- mov offset1, di\r
-\r
- mov al, byte ptr mask2n3\r
- out dx, al\r
- mov di, offset2\r
- mov [di], ah ; plot 2\r
- sub di, bx ; advance 2 up\r
- mov offset2, di\r
- mov di, offset3\r
- mov [di], ah ; plot 3\r
- add di, bx ; advance 3 down\r
- mov offset3, di\r
-\r
- mov al, byte ptr mask4n5\r
- out dx, al\r
- mov di, offset4\r
- mov [di], ah\r
- ror al, 1\r
- mov byte ptr mask4n5, al\r
- sbb di, 0\r
- mov offset4, di\r
- mov di, offset5\r
- mov [di], ah\r
- rol al, 1\r
- sbb di, 0\r
- mov offset5, di\r
-\r
- mov al, byte ptr mask6n7\r
- out dx, al\r
- mov di, offset6\r
- mov [di], ah\r
- sub di, bx\r
- mov offset6, di\r
- mov di, offset7\r
- mov [di], ah\r
- add di, bx\r
- mov offset7, di\r
-\r
- jmp @@CircleCalc\r
-\r
-; move all plots diagonally\r
-@@Advance:\r
- mov al, byte ptr mask0n1\r
- out dx, al\r
- mov di, offset0\r
- mov [di], ah ; plot 0\r
- rol al, 1 ; advance 0 right and down\r
- mov byte ptr mask0n1, al\r
- adc di, bx\r
- mov offset0, di\r
- mov di, offset1\r
- mov [di], ah ; plot 1\r
- ror al, 1 ; what was that bit again?\r
- adc di, 0 ; advance 1 right and up\r
- sub di, bx\r
- mov offset1, di\r
-\r
- mov al, byte ptr mask2n3\r
- out dx, al\r
- mov di, offset2\r
- mov [di], ah ; plot 2\r
- ror al, 1 ; advance 2 up and left\r
- mov byte ptr mask2n3, al\r
- sbb di, bx\r
- mov offset2, di\r
- mov di, offset3\r
- mov [di], ah ; plot 3\r
- rol al, 1\r
- sbb di, 0 ; advance 3 down and left\r
- add di, bx\r
- mov offset3, di\r
-\r
- mov al, byte ptr mask4n5\r
- out dx, al\r
- mov di, offset4\r
- mov [di], ah\r
- ror al, 1\r
- mov byte ptr mask4n5, al\r
- sbb di, 0\r
- add di, bx\r
- mov offset4, di\r
- mov di, offset5\r
- mov [di], ah\r
- rol al, 1\r
- sbb di, bx\r
- mov offset5, di\r
-\r
- mov al, byte ptr mask6n7\r
- out dx, al\r
- mov di, offset6\r
- mov [di], ah\r
- rol al, 1\r
- mov byte ptr mask6n7, al\r
- adc di, 0\r
- sub di, bx\r
- mov offset6, di\r
- mov di, offset7\r
- mov [di], ah\r
- ror al, 1\r
- adc di, bx\r
- mov offset7, di\r
-\r
-; do you realize the entire function has been set up for this little jot?\r
-; keep in mind that radii values are 2 per pixel\r
-@@CircleCalc:\r
- add cx, 2 ; x += 1\r
- mov di, error\r
- add di, cx ; error += (2 * x) + 1\r
- inc di\r
- jl @@CircleNoError\r
- cmp cx, si ; x > y?\r
- ja @@FleeFlyFlowFum\r
- sub si, 2 ; y -= 1\r
- sub di, si ; error -= (2 * y)\r
- mov error, di\r
- jmp @@Advance\r
-@@CircleNoError:\r
- mov error, di\r
- jmp @@NoAdvance\r
-\r
-@@FleeFlyFlowFum:\r
- pop ds\r
- pop di\r
- pop si\r
- mov sp,bp\r
- pop bp\r
-\r
- ret\r
-\r
-_x_circle endp\r
-\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-; _x_filled_circle\r
-;\r
-; Draw a disc.\r
-;\r
-; C near-callable as:\r
-; int x_filled_circle (WORD Left, WORD Top, WORD Diameter,\r
-; WORD Color, WORD ScreenOffs);\r
-;\r
-; No clipping is performed.\r
-;\r
-; ax, bx, cx, dx, and es bite the dust, as Homer would say.\r
-; DF is set to 0 (strings go forward).\r
-\r
- .data\r
-\r
- align 2\r
-\r
-; the only entries of these tables which are used are positions\r
-; 1, 2, 4, and 8\r
-LeftMaskTable db 0, 0ffh, 0eeh, 0, 0cch, 0, 0, 0, 088h\r
-RightMaskTable db 0, 011h, 033h, 0, 077h, 0, 0, 0, 0ffh\r
-\r
- .code\r
-\r
- public _x_filled_circle\r
- align 2\r
-_x_filled_circle proc\r
-ARG Left:word, Top:word, Diameter:word, Color:word, ScreenOffs:word\r
-; Tasm 1.0 does not allow the \ line continuation\r
-;LOCAL offset0:word, offset1:word, offset2:word, offset3:word, \\r
-; offset4:word, offset5:word, offset6:word, offset7:word, \\r
-; mask0n1:word, mask2n3:word, mask4n5:word, mask6n7:word, \\r
-; shrunk_radius:word, diameter_even:word, error:word, \\r
-; jump_vector:word=LocalStk\r
-LOCAL offset0,offset1,offset2,offset3,offset4,offset5,offset6,offset7,mask0n1,mask2n3,mask4n5,mask6n7,shrunk_radius,diameter_even,error,jump_vector:word=LocalStk\r
-\r
- push bp\r
- mov bp, sp\r
- sub sp, LocalStk\r
- push si\r
- push di\r
-\r
- cld ; strings march forward\r
-\r
-; this first part is identical to the other function --\r
-; the only differences, in fact, are in the drawing and moving around\r
-\r
-; find starting locations of plots 2, 3, 6, and 7\r
- mov di, _ScrnLogicalByteWidth\r
- xor dx, dx\r
-\r
- mov ax, Diameter ; find vertical midpoint\r
- dec ax\r
- shr ax, 1\r
- adc dx, 0 ; remember if it's rounded\r
- mov shrunk_radius, ax ; radius, rounded down for adding\r
- mov diameter_even, dx ; (diameter - 1) & 1, effectively\r
- add ax, Top\r
- mul di ; vertical midpoint in bytes\r
- add ax, ScreenOffs\r
-\r
- mov bx, Left\r
- mov cx, bx ; save for later\r
- mov si, bx\r
- shr si, 2\r
- add si, ax\r
- mov offset6, si\r
- and bx, 3 ; column of left side\r
- mov bl, ColumnMask[bx]\r
- mov mask6n7, bx\r
-\r
- add cx, Diameter\r
- dec cx\r
- mov bx, cx\r
- shr cx, 2\r
- add cx, ax\r
- mov offset2, cx\r
- and bx, 3 ; column of right side\r
- mov bl, ColumnMask[bx]\r
- mov mask2n3, bx\r
-\r
- cmp diameter_even, 1\r
- jne @@MiddlePlotsOverlap\r
- add si, di\r
- add cx, di\r
-@@MiddlePlotsOverlap:\r
- mov offset7, si\r
- mov offset3, cx\r
-\r
-; starting locations of 0, 1, 4, and 5\r
- mov bx, Left\r
- add bx, shrunk_radius ; find horizontal midpoint\r
-\r
- mov ax, Top ; top in bytes\r
- mul di\r
- add ax, ScreenOffs\r
- mov si, ax\r
-\r
- mov ax, Diameter ; bottom in bytes\r
- dec ax\r
- mul di\r
- add ax, si\r
-\r
- mov di, bx ; horizontal midpoint in bytes\r
- shr di, 2\r
- add si, di ; top midpoint in bytes\r
- mov offset4, si\r
- add di, ax ; bottom midpoint in bytes\r
- mov offset5, di\r
- and bx, 3 ; column of horizontal midpoint\r
- mov bl, ColumnMask[bx]\r
- mov mask4n5, bx\r
-\r
- cmp diameter_even, 1\r
- jne @@TopAndBottomPlotsOverlap\r
- rol bl, 1\r
- jnc @@TopAndBottomPlotsOverlap\r
- inc si\r
- inc di\r
-@@TopAndBottomPlotsOverlap:\r
- mov offset0, si\r
- mov offset1, di\r
- mov mask0n1, bx\r
-\r
-; we've got our eight plots in their starting positions, so\r
-; it's time to sort out the registers\r
- mov bx, _ScrnLogicalByteWidth\r
-\r
- mov dx, SCREEN_SEG\r
- mov es, dx\r
-\r
- mov dx, SC_INDEX ; set VGA to accept column masks\r
- mov al, MAP_MASK\r
- out dx, al\r
- inc dx ; gun the engine...\r
-\r
- mov si, Diameter ; initial y is radius -- 2 #s per pixel\r
- inc si\r
-\r
- mov cx, si\r
- neg cx\r
- add cx, 2\r
- mov error, cx ; error = -y + one pixel since we're a step ahead\r
-\r
- xor cx, cx ; initial x = 0\r
- mov ah, byte ptr Color\r
- jmp @@FilledCircleCalc ; let's actually put something on the screen!\r
-\r
-\r
-; plotting is completely different from in the other function (naturally)\r
-@@PlotLines:\r
- push cx ; we'll need cx for string stores\r
-\r
-; draw x-major horz. lines, from plot 4 to plot 0 and from plot 5 to plot 1\r
- mov di, mask0n1\r
- and di, 0000fh ; we only want the lower nybble for the mask table\r
- mov al, RightMaskTable[di]\r
- mov di, offset0 ; left and right offsets the same?\r
- cmp di, offset4\r
- jne @@PlotXMajorNontrivial ; try and say this one 10 times fast!\r
- mov di, mask4n5\r
- and di, 0000fh\r
- and al, LeftMaskTable[di] ; intersection of left & right masks\r
- out dx, al ; set mask\r
- mov di, offset4\r
- mov es:[di], ah\r
- mov di, offset5\r
- mov es:[di], ah\r
- jmp @@PlotYMajor\r
-@@PlotXMajorNontrivial:\r
- out dx, al ; draw right edge\r
- mov es:[di], ah\r
- mov di, offset1\r
- mov es:[di], ah\r
-\r
- mov di, mask4n5 ; draw left edge\r
- and di, 0000fh\r
- mov al, LeftMaskTable[di]\r
- out dx, al\r
- mov di, offset4\r
- mov es:[di], ah\r
- mov di, offset5\r
- mov es:[di], ah\r
-\r
- mov al, 0ffh ; set mask for middle chunks\r
- out dx, al\r
- mov al, ah ; ready to store two pixels at a time\r
- inc di ; move string start past left edge\r
- mov cx, offset1 ; store line from plot 5 to plot 1, exclusive\r
- sub cx, di ; width of section in bytes\r
- push cx\r
- shr cx, 1 ; draw midsection eight pixels at a time\r
- rep stosw\r
- adc cx, 0 ; draw last four pixels, if such there are\r
- rep stosb\r
-\r
- mov di, offset4 ; draw line from plot 4 to plot 0\r
- inc di ; move past left edge\r
- pop cx\r
- shr cx, 1\r
- rep stosw\r
- adc cx, 0\r
- rep stosb\r
-\r
-@@PlotYMajor:\r
-; draw y-major horz. lines, from plot 6 to plot 2 and from plot 7 to plot 3\r
- mov di, mask2n3\r
- and di, 0000fh ; we only want the lower nybble for the mask table\r
- mov al, RightMaskTable[di]\r
- mov di, offset2 ; left and right offsets the same?\r
- cmp di, offset6\r
- jne @@PlotYMajorNontrivial ; try and say this one 10 times fast!\r
- mov di, mask6n7\r
- and di, 0000fh\r
- and al, LeftMaskTable[di] ; intersection of left & right masks\r
- out dx, al ; set mask\r
- mov di, offset6\r
- mov es:[di], ah\r
- mov di, offset7\r
- mov es:[di], ah\r
- jmp @@ClimaxOfPlot\r
-@@PlotYMajorNontrivial:\r
- out dx, al ; draw right edge\r
- mov es:[di], ah\r
- mov di, offset3\r
- mov es:[di], ah\r
-\r
- mov di, mask6n7 ; draw left edge\r
- and di, 0000fh\r
- mov al, LeftMaskTable[di]\r
- out dx, al\r
- mov di, offset6\r
- mov es:[di], ah\r
- mov di, offset7\r
- mov es:[di], ah\r
-\r
- mov al, 0ffh ; set mask for middle chunks\r
- out dx, al\r
- mov al, ah ; ready to store two pixels at a time\r
-\r
- inc di ; move string start past left edge\r
- mov cx, offset3 ; draw line from plot 7 to plot 3, exclusive\r
- sub cx, di ; width of section in bytes\r
- push cx\r
- shr cx, 1 ; store midsection\r
- rep stosw\r
- adc cx, 0\r
- rep stosb\r
-\r
- mov di, offset6 ; draw line from plot 6 to plot 2\r
- inc di ; move past left edge\r
- pop cx\r
- shr cx, 1\r
- rep stosw\r
- adc cx, 0\r
- rep stosb\r
-\r
-@@ClimaxOfPlot:\r
- pop cx\r
- jmp [jump_vector] ; either @@Advance or @@NoAdvance\r
-\r
-\r
-; unlike their counterparts in the other function, these do not draw --\r
-; they only move the eight pointers\r
-\r
-; move the x-major plots horizontally and the y-major plots vertically\r
-@@NoAdvance:\r
- mov al, byte ptr mask0n1 ; advance left x-major plots\r
- mov di, offset0\r
- rol al, 1 ; advance 0 right\r
- mov byte ptr mask0n1, al\r
- adc di, 0\r
- mov offset0, di\r
- mov di, offset1\r
- ror al, 1 ; what was that bit again?\r
- adc di, 0 ; advance 1 right\r
- mov offset1, di\r
-\r
- mov al, byte ptr mask4n5 ; advance left x-major plots\r
- mov di, offset4\r
- ror al, 1\r
- mov byte ptr mask4n5, al\r
- sbb di, 0\r
- mov offset4, di\r
- mov di, offset5\r
- rol al, 1\r
- sbb di, 0\r
- mov offset5, di\r
-\r
- mov al, byte ptr mask2n3\r
- mov di, offset2\r
- sub di, bx ; advance 2 up\r
- mov offset2, di\r
- mov di, offset3\r
- add di, bx ; advance 3 down\r
- mov offset3, di\r
-\r
- mov al, byte ptr mask6n7\r
- mov di, offset6\r
- sub di, bx\r
- mov offset6, di\r
- mov di, offset7\r
- add di, bx\r
- mov offset7, di\r
-\r
- jmp @@FilledCircleCalc\r
-\r
-; move all plots diagonally\r
-@@Advance:\r
- mov al, byte ptr mask0n1\r
- mov di, offset0\r
- rol al, 1 ; advance 0 right and down\r
- mov byte ptr mask0n1, al\r
- adc di, bx\r
- mov offset0, di\r
- mov di, offset1\r
- ror al, 1 ; what was that bit again?\r
- adc di, 0 ; advance 1 right and up\r
- sub di, bx\r
- mov offset1, di\r
-\r
- mov al, byte ptr mask2n3\r
- mov di, offset2\r
- ror al, 1 ; advance 2 up and left\r
- mov byte ptr mask2n3, al\r
- sbb di, bx\r
- mov offset2, di\r
- mov di, offset3\r
- rol al, 1\r
- sbb di, 0 ; advance 3 down and left\r
- add di, bx\r
- mov offset3, di\r
-\r
- mov al, byte ptr mask4n5\r
- mov di, offset4\r
- ror al, 1\r
- mov byte ptr mask4n5, al\r
- sbb di, 0\r
- add di, bx\r
- mov offset4, di\r
- mov di, offset5\r
- rol al, 1\r
- sbb di, bx\r
- mov offset5, di\r
-\r
- mov al, byte ptr mask6n7\r
- mov di, offset6\r
- rol al, 1\r
- mov byte ptr mask6n7, al\r
- adc di, 0\r
- sub di, bx\r
- mov offset6, di\r
- mov di, offset7\r
- ror al, 1\r
- adc di, bx\r
- mov offset7, di\r
-\r
-; do you realize the entire function has been set up around this little jot?\r
-; keep in mind that radii values are 2 per pixel\r
-@@FilledCircleCalc:\r
- add cx, 2 ; x += 1\r
- mov di, error\r
- add di, cx ; error += (2 * x) + 1\r
- inc di\r
- jl @@FilledCircleNoError\r
- cmp cx, si ; x > y?\r
- ja @@FleeFlyFlowFum\r
- sub si, 2 ; y -= 1\r
- sub di, si ; error -= (2 * y)\r
- mov error, di\r
- mov jump_vector, offset @@Advance\r
- jmp @@PlotLines\r
-@@FilledCircleNoError:\r
- mov error, di\r
- mov jump_vector, offset @@NoAdvance\r
- jmp @@PlotLines\r
-\r
-@@FleeFlyFlowFum:\r
- pop di\r
- pop si\r
- mov sp,bp\r
- pop bp\r
-\r
- ret\r
-\r
-_x_filled_circle endp\r
-\r
- end\r
-\r
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XCIRCLE - header file\r
-;\r
-; This module was written by Matthew MacKenzie\r
-; matm@eng.umd.edu\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-;----------------------------------------------------------------------*/\r
-\r
-#ifndef _XCIRCLE_H_\r
-#define _XCIRCLE_H_\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-\r
- void x_circle (WORD Left, WORD Top, WORD Diameter,\r
- WORD Color, WORD ScreenOffs);\r
-\r
- void x_filled_circle (WORD Left, WORD Top, WORD Diameter,\r
- WORD Color, WORD ScreenOffs);\r
-\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-\r
-#endif\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XCIRCLE - Include file\r
-;\r
-; This module was written by Matthew MacKenzie\r
-; matm@eng.umd.edu\r
-;\r
-; XCIRCLE.ASM export functions\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
- global _x_circle : proc\r
- global _x_filled_circle : proc\r
-\r
-\1a
\ No newline at end of file
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XCLIPPBM\r
-;\r
-; This module was written by Matthew MacKenzie\r
-; matm@eng.umd.edu\r
-;\r
-; Clipped transfer of planar bitmaps from system memory to video memory.\r
-;\r
-; Compile with TASM.\r
-; C near-callable.\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-include xlib.inc\r
-include xclippbm.inc\r
-\r
-\r
- .data\r
-\r
- align 2\r
-\r
-; global clipping variables\r
-_TopBound dw (?)\r
-_BottomBound dw (?)\r
-_LeftBound dw (?)\r
-_RightBound dw (?)\r
-\r
-; VGA plane masks\r
-ColumnMask db 011h,022h,044h,088h\r
-\r
-; bit delay timers\r
-LeftDelay db 0, 1, 2, 4\r
-RightDelay db 0, 4, 2, 1\r
-\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-; _x_clip_pbm\r
-;\r
-; C near-callable as:\r
-;\r
-; void x_clip_pbm (int X, int Y, int ScreenOffs, char far * Bitmap);\r
-;\r
-; Bitmap is a planar bitmap, in the regular Xlib format.\r
-;\r
-; ax, bx, cx, and dx go south.\r
-\r
- .code\r
-\r
- public _x_clip_pbm\r
- align 2\r
-_x_clip_pbm proc\r
-ARG X:word, Y:word, ScreenOffs:word, Bitmap:dword\r
-LOCAL left_counter, right_counter,column,clipped_height,clipped_width,screen_pos,bitmap_pos,bitmap_size,VGA_mask,width_copy,height_temp,screen_width:word=LocalStk\r
-; Tasm 1.0 does not allow the \ line continuation\r
-;LOCAL left_counter:word, right_counter:word, \\r
-; column:word, clipped_height:word, clipped_width:word, \\r
-; screen_pos:word, bitmap_pos:word, bitmap_size:word, \\r
-; VGA_mask:word, width_copy, height_temp:word, \\r
-; screen_width:word=LocalStk\r
-\r
- push bp\r
- mov bp, sp\r
- sub sp, LocalStk\r
- push si\r
- push di\r
- push ds\r
-\r
-; sociopathic cases: are the clipping bounds out of order?\r
- mov ax, _TopBound\r
- cmp ax, _BottomBound\r
- jg @@GetOut\r
- mov ax, _LeftBound\r
- cmp ax, _RightBound\r
- jle @@ReasonableAndProper\r
-@@GetOut: ; return a 1 -- no image drawn\r
- pop ds\r
- pop di\r
- pop si\r
- mov ax, 1\r
- mov sp, bp\r
- pop bp\r
- ret\r
-\r
-@@ReasonableAndProper:\r
-\r
-; we need to use both the tables in ds and the height and width of the bitmap\r
- les si, Bitmap\r
-\r
-; vertical position\r
- xor cx, cx\r
- mov cl, byte ptr es:[si + 1] ; height of bitmap\r
- xor ax, ax\r
- mov al, byte ptr es:[si] ; width of bitmap\r
- mul cx\r
- mov bitmap_size, ax\r
- mov ax, Y\r
- cmp ax, _BottomBound ; top edge below clipping box?\r
- jg @@GetOut\r
-\r
- mov bx, cx\r
- add bx, ax\r
- dec bx ; bottom edge = Y + height - 1\r
- cmp bx, _TopBound\r
- jl @@GetOut\r
- sub bx, _BottomBound ; bottom margin = bottom edge - BottomBound\r
- jle @@NoBottomBound\r
- sub cx, bx ; clip bottom margin from height\r
-@@NoBottomBound:\r
- mov bx, _TopBound\r
- sub bx, ax ; top margin = TopBound - Y\r
- jle @@NoTopBound\r
- add ax, bx ; top edge = Y + top margin\r
- sub cx, bx ; clip top margin from height\r
- jmp @@KeepMargin\r
-@@NoTopBound:\r
- xor bx, bx\r
-@@KeepMargin:\r
- mov clipped_height, cx\r
-\r
- mul _ScrnLogicalByteWidth\r
- mov di, ax\r
- add di, ScreenOffs ; row of upper-left corner of blit\r
-\r
- mov cl, byte ptr es:[si] ; width of bitmap (ch is still 0 from height)\r
- mov ax, cx\r
- mul bx\r
- add si, ax\r
- add si, 2 ; starting position in bitmap\r
-\r
-; horizontal position\r
- mov width_copy, cx\r
- mov dx, X\r
- cmp dx, _RightBound\r
- jg @@GetOut\r
- mov dx, 0 ; unclipped value for right delay\r
-\r
- mov ax, cx\r
- shl ax, 2 ; width in pixels\r
- add ax, X\r
- dec ax ; right edge = X + width in pixels - 1\r
- cmp ax, _LeftBound\r
- jl @@GetOut\r
- sub ax, _RightBound ; right margin = right edge - RightBound\r
- jle @@NoRightBound\r
- mov bx, ax\r
- and bx, 3\r
- mov dl, RightDelay[bx]\r
- shr ax, 2\r
- sub cx, ax ; subtract clipped bytes from width\r
-@@NoRightBound:\r
- mov right_counter, dx\r
- mov dx, 0 ; unclipped value for left delay\r
- mov ax, _LeftBound\r
- sub ax, X ; left margin = LeftBound - X\r
- jle @@NoLeftBound\r
- mov bx, ax\r
- and bx, 3\r
- mov dl, LeftDelay[bx]\r
- add ax, 3\r
- shr ax, 2 ; left margin/4, rounded up\r
- sub cx, ax ; subtract clipped bytes from width\r
- add si, ax ; move starting position in bitmap past margin\r
- add di, ax ; move starting position on screen past margin\r
-@@NoLeftBound:\r
- mov left_counter, dx\r
- mov clipped_width, cx\r
-\r
- mov ax, X ; add x coordinate to screen position\r
- mov bx, ax\r
- sar ax, 2\r
- add di, ax\r
-\r
- mov dx, SC_INDEX\r
- mov al, MAP_MASK\r
- out dx, al\r
- inc dx\r
-\r
- and bx, 3 ; initial mask\r
- xor ax, ax\r
- mov al, ColumnMask[bx]\r
- mov VGA_mask, ax\r
- out dx, al ; initial mask\r
-\r
- mov column, 4\r
- mov bitmap_pos, si\r
- mov screen_pos, di\r
- mov ax, _ScrnLogicalByteWidth\r
- mov screen_width, ax ; since we move ds\r
-\r
-; we've used all our tables, so we can change ds to point to the bitmap,\r
-; and es to point to the screen\r
- mov ds, word ptr [Bitmap + 2]\r
- mov ax, SCREEN_SEG\r
- mov es, ax\r
-\r
- cld ; strings go forward\r
- mov bx, width_copy\r
- sub bx, clipped_width ; bytes to advance one line in bitmap\r
-\r
-; let's actually draw something for a change\r
-@@WritePlane:\r
- mov ax, clipped_height\r
- mov height_temp, ax\r
- mov dx, screen_width\r
- sub dx, clipped_width ; bytes to advance one line across screen\r
-\r
-@@WriteLine:\r
- mov cx, clipped_width\r
- shr cx, 1\r
- rep movsw ; in they went, two by two...\r
- adc cx, 0\r
- rep movsb ; catch stray last byte, if it's there\r
- add si, bx ; advance one bitmap line\r
- add di, dx ; advance one screen line\r
-\r
- dec height_temp\r
- jnz @@WriteLine\r
-\r
- dec column\r
- jz @@OuttaHere ; only four columns per customer, please\r
- mov dx, SC_INDEX + 1\r
- rol byte ptr VGA_mask, 1\r
- adc screen_pos, 0 ; add to location if we've wrapped to plane 0\r
- mov al, byte ptr VGA_mask\r
- out dx, al ; set VGA for next column\r
-\r
- shr right_counter, 1\r
- jnc @@NoRightCounter\r
- dec clipped_width ; cut off right edge for later planes\r
- inc bx\r
-@@NoRightCounter:\r
- shr left_counter, 1\r
- jnc @@NoLeftCounter\r
- inc clipped_width ; add to left edge for later planes\r
- dec bx\r
- dec bitmap_pos\r
- dec screen_pos\r
-@@NoLeftCounter:\r
- mov si, bitmap_pos\r
- add si, bitmap_size\r
- mov bitmap_pos, si\r
- mov di, screen_pos\r
- jmp @@WritePlane\r
-\r
-@@OuttaHere: ; return a 0 -- something was inside the boundary\r
- pop ds\r
- pop di\r
- pop si\r
- mov ax, 0\r
- mov sp, bp\r
- pop bp\r
- ret\r
-_x_clip_pbm endp\r
-\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-; _x_clip_masked_pbm\r
-;\r
-; C near-callable as:\r
-;\r
-; void x_clip_masked_pbm (int X, int Y, int ScreenOffs, char far * Bitmap);\r
-;\r
-; Bitmap is a planar bitmap, in the regular Xlib format.\r
-; The width of the bitmap cannot be greater than 90 bytes, however.\r
-; Ain't that just criminal?\r
-;\r
-; ax, bx, cx, and dx go south.\r
-\r
-\r
-; one branch per pixel is more than enough -- we'll unroll the line-writing\r
-; loop all the way to try to get a little speed (at the expense, as usual,\r
-; of a chunk of memory)\r
-\r
-MaskedPoint macro offset\r
- mov al, [si + offset]\r
- or al, al\r
- jz $+6\r
- mov es:[di + offset], al\r
- endm\r
-\r
-MaskedPointSize equ 11\r
-\r
- public _x_clip_masked_pbm\r
- align 2\r
-_x_clip_masked_pbm proc\r
-ARG X:word, Y:word, ScreenOffs:word, Bitmap:dword\r
-; Tasm 1.0 does not allow the \ line continuation\r
-LOCAL left_counter,right_counter,column:word,clipped_height,screen_pos,bitmap_pos,bitmap_size,VGA_mask,width_copy,height_temp,screen_width:word=LocalStk\r
-;LOCAL left_counter:word, right_counter:word, \\r
-; column:word, clipped_height:word, \\r
-; screen_pos:word, bitmap_pos:word, bitmap_size:word, \\r
-; VGA_mask:word, width_copy, height_temp:word, \\r
-; screen_width:word=LocalStk\r
- push bp\r
- mov bp, sp\r
- sub sp, LocalStk\r
- push si\r
- push di\r
- push ds\r
-\r
-; sociopathic cases: are the clipping bounds out of order?\r
- mov ax, _TopBound\r
- cmp ax, _BottomBound\r
- jg @@GetOut\r
- mov ax, _LeftBound\r
- cmp ax, _RightBound\r
- jle @@ReasonableAndProper\r
-@@GetOut: ; return a 1 -- no image drawn\r
- pop ds\r
- pop di\r
- pop si\r
- mov ax, 1\r
- mov sp, bp\r
- pop bp\r
- ret\r
-\r
-@@ReasonableAndProper:\r
-\r
-; we need to use both the tables in ds and the height and width of the bitmap\r
- les si, Bitmap\r
-\r
-; vertical position\r
- xor cx, cx\r
- mov cl, byte ptr es:[si + 1] ; height of bitmap\r
- xor ax, ax\r
- mov al, byte ptr es:[si] ; width of bitmap\r
- mul cx\r
- mov bitmap_size, ax\r
- mov ax, Y\r
- cmp ax, _BottomBound ; top edge below clipping box?\r
- jg @@GetOut\r
-\r
- mov bx, cx\r
- add bx, ax\r
- dec bx ; bottom edge = Y + height - 1\r
- cmp bx, _TopBound\r
- jl @@GetOut\r
- sub bx, _BottomBound ; bottom margin = bottom edge - BottomBound\r
- jle @@NoBottomBound\r
- sub cx, bx ; clip bottom margin from height\r
-@@NoBottomBound:\r
- mov bx, _TopBound\r
- sub bx, ax ; top margin = TopBound - Y\r
- jle @@NoTopBound\r
- add ax, bx ; top edge = Y + top margin\r
- sub cx, bx ; clip top margin from height\r
- jmp @@KeepMargin\r
-@@NoTopBound:\r
- xor bx, bx\r
-@@KeepMargin:\r
- mov clipped_height, cx\r
-\r
- mul _ScrnLogicalByteWidth\r
- mov di, ax\r
- add di, ScreenOffs ; row of upper-left corner of blit\r
-\r
- mov cl, byte ptr es:[si] ; width of bitmap (ch is still 0 from height)\r
- mov ax, cx\r
- mul bx\r
- add si, ax\r
- add si, 2 ; starting position in bitmap\r
-\r
-; horizontal position\r
- mov width_copy, cx\r
- mov dx, X\r
- cmp dx, _RightBound\r
- jg @@GetOut\r
- mov dx, 0 ; unclipped value for right delay\r
-\r
- mov ax, cx\r
- shl ax, 2 ; width in pixels\r
- add ax, X\r
- dec ax ; right edge = X + width in pixels - 1\r
- cmp ax, _LeftBound\r
- jl @@GetOut\r
- sub ax, _RightBound ; right margin = right edge - RightBound\r
- jle @@NoRightBound\r
- mov bx, ax\r
- and bx, 3\r
- mov dl, RightDelay[bx]\r
- shr ax, 2\r
- sub cx, ax ; subtract clipped bytes from width\r
-@@NoRightBound:\r
- mov right_counter, dx\r
- mov dx, 0 ; unclipped value for left delay\r
- mov ax, _LeftBound\r
- sub ax, X ; left margin = LeftBound - X\r
- jle @@NoLeftBound\r
- mov bx, ax\r
- and bx, 3\r
- mov dl, LeftDelay[bx]\r
- add ax, 3\r
- shr ax, 2 ; left margin/4, rounded up\r
- sub cx, ax ; subtract clipped bytes from width\r
- add si, ax ; move starting position in bitmap past margin\r
- add di, ax ; move starting position on screen past margin\r
-@@NoLeftBound:\r
- mov left_counter, dx\r
- mov ax, cx\r
- imul ax, (-1 * MaskedPointSize)\r
- add ax, offset @@LineDone + 2\r
- mov cx, ax ; jump offset for plotting\r
-\r
- mov ax, X ; add x coordinate to screen position\r
- mov bx, ax\r
- shr ax, 2\r
- add di, ax\r
-\r
- mov dx, SC_INDEX\r
- mov al, MAP_MASK\r
- out dx, al\r
- inc dx\r
-\r
- and bx, 3 ; initial mask\r
- xor ax, ax\r
- mov al, ColumnMask[bx]\r
- mov VGA_mask, ax\r
- out dx, al\r
-\r
- mov column, 4\r
- mov bitmap_pos, si\r
- mov screen_pos, di\r
- mov ax, _ScrnLogicalByteWidth\r
- mov screen_width, ax ; since we move ds\r
-\r
-; we've used all our tables, so we can change ds to point to the bitmap,\r
-; and es to point to the screen\r
- mov ds, word ptr [Bitmap + 2]\r
- mov ax, SCREEN_SEG\r
- mov es, ax\r
-\r
- mov bx, width_copy\r
-\r
-; let's actually draw something for a change\r
- mov ax, clipped_height\r
- mov height_temp, ax\r
- mov dx, screen_width\r
- jmp cx\r
-\r
-; 90 bottles of beer on the wall...\r
- PointLoop = 89\r
- rept 89\r
- MaskedPoint PointLoop\r
- PointLoop = PointLoop - 1\r
- endm\r
-; one bottle of beer...\r
-\r
-; final point needs a different branch offset, so we don't use MaskedPoint\r
- mov al, [si]\r
- or al, al\r
- jz @@LineDone\r
- mov es:[di], al\r
-\r
-@@LineDone:\r
- add si, bx ; advance one bitmap line\r
- add di, dx ; advance one screen line\r
- dec height_temp\r
- jz @@PlaneDone\r
- jmp cx\r
-\r
-@@PlaneDone:\r
- dec column\r
- jz @@OuttaHere ; only four columns per customer, please\r
- mov dx, SC_INDEX + 1\r
- rol byte ptr VGA_mask, 1\r
- adc screen_pos, 0 ; move to new column if we've wrapped to plane 0\r
- mov al, byte ptr VGA_mask\r
- out dx, al ; set VGA for next column\r
-\r
- shr right_counter, 1\r
- jnc @@NoRightCounter\r
- add cx, MaskedPointSize ; cut off right edge for later planes\r
-@@NoRightCounter:\r
- shr left_counter, 1\r
- jnc @@NoLeftCounter\r
- sub cx, MaskedPointSize ; add to left edge for later planes\r
- dec bitmap_pos\r
- dec screen_pos\r
-@@NoLeftCounter:\r
- mov si, bitmap_pos\r
- add si, bitmap_size\r
- mov bitmap_pos, si\r
- mov di, screen_pos\r
-\r
- mov ax, clipped_height\r
- mov height_temp, ax\r
- mov dx, screen_width\r
- jmp cx\r
-\r
-@@OuttaHere: ; return a 0 -- something was inside the boundary\r
- pop ds\r
- pop di\r
- pop si\r
- mov ax, 0\r
- mov sp, bp\r
- pop bp\r
- ret\r
-_x_clip_masked_pbm endp\r
-\r
- end\r
-\r
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-; MODULE XCLIPPBM\r
-;\r
-; This module was written by Matthew MacKenzie\r
-; matm@eng.umd.edu\r
-;\r
-; Clipped transfer of planar bitmaps from system memory to video memory.\r
-;\r
-; Compile with TASM.\r
-; C near-callable.\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;----------------------------------------------------------------------*/\r
-\r
-#ifndef _XCLIPPBM_H_\r
-#define _XCLIPPBM_H_\r
-\r
-/* unlike most global variables in Xlib, these are meant to be written to;\r
- in fact they start off uninitialized -- all values are in pixels */\r
-extern int TopBound;\r
-extern int BottomBound;\r
-extern int LeftBound;\r
-extern int RightBound;\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-\r
-/* for both functions, a return value of 1 indicates that the entire\r
-bitmap was outside the bounding box, while a value of 0 means that\r
-something may have ended up on the screen */\r
-\r
-/* copies a planar bitmap from SRAM to VRAM, with clipping */\r
-\r
- int x_clip_pbm (int X, int Y, int ScreenOffs, char far * Bitmap);\r
-\r
-/* copies a planar bitmap from SRAM to VRAM, with clipping -- 0 bytes\r
- in the bitmap are not copied */\r
-\r
- int x_clip_masked_pbm (int X, int Y, int ScreenOffs, char far * Bitmap);\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-\r
-#endif\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XPBITMAP - Include file\r
-;\r
-; This module was written by Matthew MacKenzie\r
-; matm@eng.umd.edu\r
-;\r
-; XPBITMAP.ASM export functions\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
- global _x_clip_masked_pbm :proc\r
- global _x_clip_pbm :proc\r
-\r
- global _LeftBound :word\r
- global _RightBound :word\r
- global _TopBound :word\r
- global _BottomBound :word\r
-\r
-\1a
\ No newline at end of file
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; module XCOMPPBM\r
-;\r
-; This module contains only the compiler and sizeof routines --\r
-; use the plotter from XCBITMAP.\r
-;\r
-;-----------------------------------------------------------------------\r
-\r
-include xlib.inc\r
-include xcomppbm.inc\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-; _x_compile_pbm\r
-;\r
-; I only changed five instructions, instead of rewriting this\r
-; for PBMs. So it is amazingly inefficient. But, what the hell,\r
-; It's only a game :).\r
-;\r
-\r
-; accessory macros to save typing (what else?)\r
-Emitb macro arg\r
- mov byte ptr es:[di],&arg&\r
- inc di\r
- endm\r
-\r
-Emitw macro arg\r
- mov word ptr es:[di],&arg&\r
- add di,2\r
- endm\r
-\r
-; opcodes emitted by _x_compile_pbm\r
-ROL_AL equ 0c0d0h ; rol al\r
-SHORT_STORE_8 equ 044c6h ; mov [si]+disp8, imm8\r
-STORE_8 equ 084c6h ; mov [si]+disp16, imm8\r
-SHORT_STORE_16 equ 044c7h ; mov [si]+disp8, imm16\r
-STORE_16 equ 084c7h ; mov [si]+disp16, imm16\r
-ADC_SI_IMMED equ 0d683h ; adc si,imm8\r
-OUT_AL equ 0eeh ; out dx,al\r
-RETURN equ 0cbh ; ret\r
-\r
-\r
-.data\r
-\r
-align 2\r
-ColumnMask db 011h,022h,044h,088h\r
-\r
-\r
-.code\r
-\r
- align 2\r
-_x_compile_pbm proc\r
-ARG logical_width:word,bitmap:dword,output:dword\r
-LOCAL bwidth,scanx,scany,outputx,outputy,column,set_column,input_size:word=LocalStk\r
- push bp\r
- mov bp, sp ; caller's stack frame\r
- sub sp,LocalStk ; local space\r
- push si\r
- push di\r
- push ds\r
-\r
- mov word ptr [scanx],0\r
- mov word ptr [scany],0\r
- mov word ptr [outputx],0\r
- mov word ptr [outputy],0\r
- mov word ptr [column],0\r
- mov word ptr [set_column],0\r
-\r
- lds si,[bitmap] ; 32-bit pointer to source bitmap\r
-\r
- les di,[output] ; 32-bit pointer to destination stream\r
-\r
- lodsb ; load width byte\r
- xor ah, ah ; convert to word\r
- mov [bwidth], ax ; save for future reference\r
- mov bl, al ; copy width byte to bl\r
- lodsb ; load height byte -- already a word since ah=0\r
- mul bl ; mult height word by width byte\r
- mov [input_size], ax; to get pixel total\r
-\r
-@@MainLoop:\r
- mov bx, [scanx] ; position in original bitmap\r
- add bx, [scany]\r
-\r
- mov al, [si+bx] ; get pixel\r
- or al, al ; skip empty pixels\r
- jnz @@NoAdvance\r
- jmp @@Advance\r
-@@NoAdvance:\r
-\r
- mov dx, [set_column]\r
- cmp dx, [column]\r
- je @@SameColumn\r
-@@ColumnLoop:\r
- Emitw ROL_AL ; emit code to move to new column\r
- Emitw ADC_SI_IMMED\r
- Emitb 0\r
-\r
- inc dx\r
- cmp dx, [column]\r
- jl @@ColumnLoop\r
-\r
- Emitb OUT_AL ; emit code to set VGA mask for new column\r
- mov [set_column], dx\r
-@@SameColumn:\r
- mov dx, [outputy] ; calculate output position\r
- add dx, [outputx]\r
- sub dx, 128\r
-\r
- inc word ptr [scanx]\r
- mov cx, [scanx] ; within four pixels of right edge?\r
- cmp cx, [bwidth]\r
- jge @@OnePixel\r
-\r
- inc word ptr [outputx]\r
- mov ah, [si+bx+1] ; get second pixel\r
- or ah, ah\r
- jnz @@TwoPixels\r
-@@OnePixel:\r
- cmp dx, 127 ; can we use shorter form?\r
- jg @@OnePixLarge\r
- cmp dx, -128\r
- jl @@OnePixLarge\r
- Emitw SHORT_STORE_8\r
- Emitb dl ; 8-bit position in output\r
- jmp @@EmitOnePixel\r
-@@OnePixLarge:\r
- Emitw STORE_8\r
- Emitw dx ; position in output\r
-@@EmitOnePixel:\r
- Emitb al\r
- jmp short @@Advance\r
-@@TwoPixels:\r
- cmp dx, 127\r
- jg @@TwoPixLarge\r
- cmp dx, -128\r
- jl @@TwoPixLarge\r
- Emitw SHORT_STORE_16\r
- Emitb dl ; 8-bit position in output\r
- jmp @@EmitTwoPixels\r
-@@TwoPixLarge:\r
- Emitw STORE_16\r
- Emitw dx ; position in output\r
-@@EmitTwoPixels:\r
- Emitw ax\r
-\r
-@@Advance:\r
- inc word ptr [outputx]\r
- mov ax, [scanx]\r
- inc ax\r
- cmp ax, [bwidth]\r
- jl @@AdvanceDone\r
- mov dx, [outputy]\r
- add dx, [logical_width]\r
- mov cx, [scany]\r
- add cx, [bwidth]\r
- cmp cx, [input_size]\r
- jl @@NoNewColumn\r
- inc word ptr [column]\r
- mov cx, [column]\r
- cmp cx, 4\r
- je @@Exit ; Column 4: there is no column 4.\r
- xor cx, cx ; scany and outputy are 0 again for\r
- mov dx, cx ; the new column\r
- add si, [input_size]\r
-@@NoNewColumn:\r
- mov [outputy], dx\r
- mov [scany], cx\r
- xor ax, ax\r
- mov word ptr [outputx], 0\r
-@@AdvanceDone:\r
- mov [scanx], ax\r
- jmp @@MainLoop\r
-\r
-@@Exit:\r
- Emitb RETURN\r
- mov ax,di\r
- sub ax,word ptr [output] ; size of generated code\r
-\r
- pop ds\r
- pop di\r
- pop si\r
- mov sp, bp\r
- pop bp\r
-\r
- ret\r
-_x_compile_pbm endp\r
-\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-; _x_sizeof_cpbm\r
-;\r
-\r
-\r
- align 2\r
-_x_sizeof_cpbm proc\r
-ARG logical_width:word,bitmap:dword\r
-LOCAL bwidth,scanx,scany,outputx,outputy,column,set_column,input_size:word=LocalStk\r
- push bp\r
- mov bp, sp ; caller's stack frame\r
- sub sp,LocalStk ; local space\r
- push si\r
- push di\r
- push ds\r
-\r
- mov word ptr [scanx], 0\r
- mov word ptr [scany], 0\r
- mov word ptr [outputx], 0\r
- mov word ptr [outputy], 0\r
- mov word ptr [column], 0\r
- mov word ptr [set_column], 0\r
-\r
- lds si,[bitmap] ; 32-bit pointer to source bitmap\r
-\r
- mov di, 1 ; initial size is just the size of the far RET\r
-\r
- lodsb ; load width byte\r
- xor ah, ah ; convert to word\r
- mov [bwidth], ax ; save for future reference\r
- mov bl, al ; copy width byte to bl\r
- lodsb ; load height byte -- already a word since ah=0\r
- mul bl ; mult height word by width byte\r
- mov [input_size], ax; to get pixel total\r
-\r
-@@MainLoop:\r
- mov bx, [scanx] ; position in original bitmap\r
- add bx, [scany]\r
-\r
- mov al, [si+bx] ; get pixel\r
- or al, al ; skip empty pixels\r
- jnz @@NoAdvance\r
- jmp @@Advance\r
-@@NoAdvance:\r
-\r
- mov dx, [set_column]\r
- cmp dx, [column]\r
- je @@SameColumn\r
-@@ColumnLoop:\r
- add di, 5 ; size of code to move to new column\r
- inc dx\r
- cmp dx,[column]\r
- jl @@ColumnLoop\r
-\r
- inc di ; size of code to set VGA mask\r
- mov [set_column], dx\r
-@@SameColumn:\r
- mov dx, [outputy] ; calculate output position\r
- add dx, [outputx]\r
- sub dx, 128\r
-\r
- inc word ptr [scanx]\r
- mov cx, [scanx] ; within four pixels of right edge?\r
- cmp cx, [bwidth]\r
- jge @@OnePixel\r
-\r
- inc word ptr [outputx]\r
- mov ah,[si+bx+1] ; get second pixel\r
- or ah, ah\r
- jnz @@TwoPixels\r
-@@OnePixel:\r
- cmp dx, 127 ; can we use shorter form?\r
- jg @@OnePixLarge\r
- cmp dx, -128\r
- jl @@OnePixLarge\r
- add di, 4 ; size of 8-bit position in output plus one pixel\r
- jmp @@EmitOnePixel\r
-@@OnePixLarge:\r
- add di, 5 ; size of position in output plus one pixels\r
-@@EmitOnePixel:\r
- jmp short @@Advance\r
-@@TwoPixels:\r
- cmp dx, 127\r
- jg @@TwoPixLarge\r
- cmp dx, -128\r
- jl @@TwoPixLarge\r
- add di, 5 ; size of 8-bit position in output plus two pixels\r
- jmp @@EmitTwoPixels\r
-@@TwoPixLarge:\r
- add di, 6 ; size of 16-bit position in output plus two pixels\r
-@@EmitTwoPixels:\r
-\r
-@@Advance:\r
- inc word ptr [outputx]\r
- mov ax, [scanx]\r
- inc ax\r
- cmp ax, [bwidth]\r
- jl @@AdvanceDone\r
- mov dx, [outputy]\r
- add dx, [logical_width]\r
- mov cx, [scany]\r
- add cx, [bwidth]\r
- cmp cx, [input_size]\r
- jl @@NoNewColumn\r
- inc word ptr [column]\r
- mov cx, [column]\r
- cmp cx, 4\r
- je @@Exit ; Column 4: there is no column 4.\r
- xor cx,cx ; scany and outputy are 0 again for\r
- mov dx,cx ; the new column\r
- add si, [input_size]\r
-@@NoNewColumn:\r
- mov [outputy], dx\r
- mov [scany], cx\r
- xor ax, ax\r
- mov word ptr [outputx], ax\r
-@@AdvanceDone:\r
- mov [scanx], ax\r
- jmp @@MainLoop\r
-\r
-@@Exit:\r
- mov ax, di ; size of generated code\r
-\r
- pop ds\r
- pop di\r
- pop si\r
- mov sp,bp\r
- pop bp\r
-\r
- ret\r
-_x_sizeof_cpbm endp\r
-\r
-end\r
-\r
+++ /dev/null
-#ifndef _XCOMPPBM_H_\r
-#define _XCOMPPBM_H_\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-\r
- int x_compile_pbm ( /* Compile a planar bitmap to generate */\r
- WORD logical_screen_width, /* machine code to plot it at any */\r
- char far * bitmap, /* required screen coordinates FAST. */\r
- char far * output);\r
-\r
- int x_sizeof_cpbm ( /* Find the size of the code which a */\r
- WORD logical_screen_width, /* pbm would result in, if it */\r
- char far * bitmap); /* were compiled (used for allocation). */\r
-\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif\r
+++ /dev/null
-global _x_compile_pbm : proc\r
-global _x_sizeof_cpbm : proc\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XDETECT\r
-;\r
-; Hardware detection module\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-LOCALS\r
-.286\r
-\r
-include model.inc\r
-include xdetect.inc\r
-\r
- .data\r
-\r
-_MouseButtonCount dw 0\r
-_MouseVersion dw 0\r
-_MouseType db 0\r
-_MouseIRQ db 0\r
-\r
- .code\r
-\r
-\r
-i86 equ 0\r
-i186 equ 1\r
-i286 equ 2\r
-i386sx equ 3\r
-i386dx equ 4\r
-i486 equ 5\r
-\r
-\r
-NONE equ 0\r
-MDA equ 1\r
-CGA equ 2\r
-EGAMono equ 3\r
-EGAColor equ 4\r
-VGAMono equ 5\r
-VGAColor equ 6\r
-MCGAMono equ 7\r
-MCGAColor equ 8\r
-\r
-PS2_CARDS db 0,1,2,2,4,3,2,5,6,2,8,7,8\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; PC Graphics detection routine. Returns graphics card type\r
-;\r
-; C callable as:\r
-; unsigned int x_graphics_card();\r
-;\r
-;\r
-\r
-proc _x_graphics_card\r
- push bp ; Preserve caller's stack frame\r
- mov bp,sp\r
- mov ax,1A00h ; Try calling VGA Identity Adapter function\r
- int 10h\r
- cmp al,1Ah ; Do we have PS/2 video bios ?\r
- jne @@not_PS2 ; No!\r
-\r
- cmp bl,0Ch ; bl > 0Ch => CGA hardware\r
- jg @@is_CGA ; Jump if we have CGA\r
- xor bh,bh\r
- xor ah,ah\r
- mov al,cs:PS2_CARDS[bx] ; Load ax from PS/2 hardware table\r
- jmp short @@done ; return ax\r
-@@is_CGA:\r
- mov ax,CGA ; Have detected CGA, return id\r
- jmp short @@done\r
-@@not_PS2: ; OK We don't have PS/2 Video bios\r
- mov ah,12h ; Set alternate function service\r
- mov bx,10h ; Set to return EGA information\r
- int 10h ; call video service\r
- cmp bx,10h ; Is EGA there ?\r
- je @@simple_adapter ; Nop!\r
- mov ah,12h ; Since we have EGA bios, get details\r
- mov bl,10h\r
- int 10h\r
- or bh,bh ; Do we have colour EGA ?\r
- jz @@ega_color ; Yes\r
- mov ax,EGAMono ; Otherwise we have Mono EGA\r
- jmp short @@done\r
-@@ega_color:\r
- mov ax,EGAColor ; Have detected EGA Color, return id\r
- jmp short @@done\r
-@@simple_adapter:\r
- int 11h ; Lets try equipment determination service\r
- and al,30h\r
- shr al,4\r
- xor ah,ah\r
- or al,al ; Do we have any graphics card at all ?\r
- jz @@done ; No ? This is a stupid machine!\r
- cmp al,3 ; Do We have a Mono adapter\r
- jne @@is_CGA ; No\r
- mov ax,MDA ; Have detected MDA, return id\r
-@@done:\r
- pop bp ;restore caller's stack frame\r
- ret\r
-_x_graphics_card endp\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; PC Processor detection routine\r
-;\r
-; C callable as:\r
-; unsigned int x_processor();\r
-;\r
-;\r
-proc _x_processor\r
- push bp\r
- mov bp,sp\r
- pushf ; Save flags\r
- xor ax,ax ; Clear AX\r
- push ax ; Push it on the stack\r
- popf ; Zero the flags\r
- pushf ; Try to zero bits 12-15\r
- pop ax ; Recover flags\r
- and ax,0F000h ; If bits 12-15 are 1 => i86 or i286\r
- cmp ax,0F000h\r
- jne @@1\r
-\r
- push cx ; save CX\r
- mov ax,0FFFFh ; Set all AX bits\r
- mov cl,33 ; Will shift once on 80186\r
- shl ax,cl ; or 33 x on 8086\r
- pop cx\r
- mov ax,i186\r
- jnz @@done\r
- mov ax,i86 ; 0 => 8086/8088\r
- jmp short @@done\r
-\r
-@@1:\r
- mov ax,07000h ; Try to set bits 12-14\r
- push ax\r
- popf\r
- pushf\r
- pop ax\r
- and ax,07000h ; If bits 12-14 are 0 => i286\r
- mov ax,i286\r
- jz @@done\r
-\r
- ;; 386/486 resolution code taken from WHATCPU.ASM by\r
- ;; Dave M. Walker\r
-\r
-\r
- P386\r
- mov eax,cr0\r
- mov ebx,eax ;Original CR0 into EBX\r
- or al,10h ;Set bit\r
- mov cr0,eax ;Store it\r
- mov eax,cr0 ;Read it back\r
- mov cr0,ebx ;Restore CR0\r
- test al,10h ;Did it set?\r
- mov ax,i386sx\r
- jz @@done ;Jump if 386SX\r
-\r
- ;*** Test AC bit in EFLAGS (386DX won't change)\r
- mov ecx,esp ;Original ESP in ECX\r
- pushfd ;Original EFLAGS in EBX\r
- pop ebx\r
- and esp,not 3 ;Align stack to prevent 486\r
- ; fault when AC is flipped\r
- mov eax,ebx ;EFLAGS => EAX\r
- xor eax,40000h ;Flip AC flag\r
- push eax ;Store it\r
- popfd\r
- pushfd ;Read it back\r
- pop eax\r
- push ebx ;Restore EFLAGS\r
- popfd\r
- mov esp,ecx ;Restore ESP\r
- cmp eax,ebx ;Compare old/new AC bits\r
- mov ax,i386dx\r
- je @@done\r
-is_486: ;Until the Pentium appears...\r
- mov ax,i486\r
-@@done:\r
- popf\r
- .286\r
- pop bp\r
- ret\r
-_x_processor endp\r
-\r
-.8086\r
-;-----------------------------------------------------------------------\r
-; PC Numeric coprocessor detection routine\r
-;\r
-; C callable as:\r
-; unsigned int x_coprocessor();\r
-;\r
-; Based on an article in PC Tech Journal, Aug 87 by Ted Forgeron\r
-;\r
-; Returns 1 if coprocessor found, zero otherwise\r
-\r
-_x_coprocessor proc\r
-ARG control:word=StkSize\r
- push bp\r
- mov bp,sp\r
- sub sp,StkSize\r
-\r
- fninit ; try to initialize the copro.\r
- mov [control],0 ; clear control word variable\r
- fnstcw control ; put control word in memory\r
- mov ax,[control] ;\r
- cmp ah,03h ; do we have a coprocessor ?\r
- je @@HaveCopro ; jump if yes!\r
- xor ax,ax ; return 0 since nothing found\r
- jmp short @@done\r
-@@HaveCopro:\r
- mov ax,1\r
-@@done:\r
- mov sp,bp\r
- pop bp\r
- ret\r
-_x_coprocessor endp\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; PC Mouse Driver detection routine\r
-;\r
-; C callable as:\r
-; unsigned int x_mousedriver();\r
-;\r
-;\r
-; Returns 1 if mouse driver found, zero otherwise\r
-_x_mousedriver proc\r
- push bp\r
- mov bp,sp\r
- mov ax,3533h ; Get int 33 interrupt vector\r
- int 21h ; Call dos\r
- xor cx,cx ; Clear "found" flag\r
- mov ax,es ; Is the vector null (ES==0 && BX==0) ?\r
- or bx,ax\r
- jz @@NoMouseDriver ; Yes! No mouse driver installed - Jump\r
-\r
- ; Just make absolutely sure the vector points to the mouse\r
- ; driver (just in case)\r
-\r
- xor ax,ax ; FUNC 0: Mouse Initialization\r
- int 33h\r
- or ax,ax ; Do we have an installed mouse driver ?\r
- jz @@NoMouseDriver; No ?\r
- mov [_MouseButtonCount],bx\r
-\r
- mov ax,24h\r
- int 33h\r
- mov [_MouseVersion],bx\r
- mov [_MouseType],ch\r
- mov [_MouseIRQ],cl\r
-\r
- mov cx,1 ; Yes! set flag\r
-\r
-@@NoMouseDriver:\r
- mov ax,cx ; Return "found" flag\r
- pop bp\r
- ret\r
-_x_mousedriver endp\r
-\r
-\r
-end
\ No newline at end of file
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XDETECT - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;-----------------------------------------------------------------------*/\r
-\r
-#ifndef _XDETECT_H_\r
-#define _XDETECT_H_\r
-\r
-#define I8086 0\r
-#define I80186 1\r
-#define I80286 2\r
-#define I80386SX 3\r
-#define I80386DX 4\r
-#define I80486 5\r
-\r
-#define NoGraphics 0\r
-#define MDA 1\r
-#define CGA 2\r
-#define EGAMono 3\r
-#define EGAColor 4\r
-#define VGAMono 5\r
-#define VGAColor 6\r
-#define MCGAMono 7\r
-#define MCGAColor 8\r
-\r
-#define BUS_MOUSE 1\r
-#define SERIAL_MOUSE 2\r
-#define INPORT_MOUSE 3\r
-#define PS2_MOUSE 4\r
-#define HP_MOUSE 5\r
-\r
-/* VARIABLES =========================================================== */\r
-\r
-extern WORD MouseButtonCount; /* number of mouse buttons */\r
-extern WORD MouseVersion; /* mouse driver version */\r
-extern WORD MouseType; /* mouse type */\r
-extern WORD MouseIRQ; /* mouse IRQ number */\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
- int x_graphics_card(void); /* Detect installed Graphics card type */\r
- int x_processor(void); /* Detect processor type */\r
- int x_coprocessor(void); /* Detect math co-processor type */\r
- int x_mousedriver(void); /* Detect math co-processor type */\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif\r
-\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XDETECT - Include file\r
-;\r
-; XDETECT.ASM export functions\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
- global _MouseButtonCount :word\r
- global _MouseVersion :word\r
- global _MouseType :byte\r
- global _MouseIRQ :byte\r
-\r
-\r
- global _x_graphics_card :proc\r
- global _x_processor :proc\r
- global _x_coprocessor :proc\r
- global _x_mousedriver :proc\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XFILEIO\r
-;\r
-; Sequential binary file I/O functions\r
-;\r
-; Some functions based on a r.g.p post by Joshua Jensen\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-COMMENT $\r
-\r
-\r
-$\r
-\r
-LOCALS\r
-.286\r
-\r
-include model.inc\r
-include xfileio.inc\r
- .data\r
-\r
- _file_err dw (?) ; error value\r
-\r
- .code\r
-\r
-PUSH_DS macro\r
- IFNDEF s\r
- push ds\r
- ENDIF\r
- endm\r
-\r
-POP_DS macro\r
- IFNDEF s\r
- pop ds\r
- ENDIF\r
- endm\r
-\r
-LDS_M macro arg1,arg2\r
- IFNDEF s\r
- lds &arg1&,&arg2&\r
- ELSE\r
- mov &arg1&,word ptr &arg2&\r
- ENDIF\r
- endm\r
-\r
-\r
-\r
-;****************************************************************\r
-;\r
-; name: f_open\r
-;\r
-; C Prototype:\r
-;\r
-; extern int f_open(char * filename, char access)\r
-;\r
-; Opens a file according to the access char:\r
-;\r
-; 0 = read only - If doesnt exist return error\r
-; 1 = write only - If doesnt exist create it otherwise clear it\r
-; 2 = read/write - If doesnt exist create it\r
-;\r
-; Returns the file handle on success, -1 on failure\r
-;\r
-;\r
-proc _f_open\r
-IFNDEF s\r
- ARG filename:dword,access:byte\r
-ELSE\r
- ARG filename:word,access:byte\r
-ENDIF\r
- push bp ; Preserve caller's stack frame\r
- mov bp,sp\r
- PUSH_DS\r
- LDS_M dx,[filename] ; point DS:DX to file name string\r
- mov [_file_err],0\r
- cmp [access],1\r
- je @@creat\r
-\r
- mov ah,3dh ; select "open file" DOS service\r
- mov al,[access] ; select access type code\r
- int 21h ; call DOS service\r
- jnb @@Done ; If carry flag set we have failed\r
-\r
-\r
- cmp [access],2\r
- jne @@error\r
-@@creat:\r
- mov ah,3ch ; select "creat file" DOS service\r
- mov cx,0\r
- int 21h ; call DOS service\r
- jnb @@Done ; If carry flag set we have failed\r
-@@error:\r
- mov [_file_err],ax\r
- mov ax,-1 ; indicate failure\r
-@@Done: ; otherwise return file handle\r
- POP_DS\r
- pop bp ;restore caller's stack frame\r
- ret\r
-_f_open endp\r
-\r
-\r
-;****************************************************************\r
-;\r
-; name: f_close\r
-;\r
-; C Prototype:\r
-;\r
-; extern int f_close(int handle)\r
-;\r
-; Closes the file associated with the specified handle\r
-;\r
-; Returns 0 on success, -1 on failure\r
-;\r
-proc _f_close\r
-ARG handle:word\r
- push bp ; Preserve caller's stack frame\r
- mov bp,sp\r
-\r
- mov [_file_err],0 ; Clear error\r
- mov ah,3eh ; select "close file handle" DOS service\r
- mov bx,[handle] ; select handle of file to close\r
- int 21h ; call DOS service\r
- jnb @@Fix ; failed if carry flag set\r
- mov [_file_err],ax;\r
- mov ax,-1 ; return error\r
- jmp short @@Done\r
-@@Fix: ; otherwise\r
- xor ax,ax ; return 0\r
-@@Done:\r
- pop bp ;restore caller's stack frame\r
- ret\r
-_f_close endp\r
-\r
-\r
-;****************************************************************\r
-;\r
-; name: f_read\r
-;\r
-; C Prototype:\r
-;\r
-; extern int f_read(int handle, char *buffer, int count)\r
-;\r
-; Reads a block of count bytes from the file specified by the handle\r
-; into the buffer\r
-;\r
-; Returns count on success, failure is detectable via _file_err\r
-;\r
-proc _f_read\r
-IFNDEF s\r
- ARG handle:word,buffer:dword,count:word\r
-ELSE\r
- ARG handle:word,buffer:word,count:word\r
-ENDIF\r
- push bp ; Preserve caller's stack frame\r
- mov bp,sp\r
- PUSH_DS\r
-\r
- mov [_file_err],0 ; Clear error\r
- mov ah,3fh ; select "read from file or device" DOS service\r
- mov bx,[handle] ; select handle of file to close\r
- mov cx,[count]\r
- LDS_M dx,[buffer]\r
- int 21h ; call DOS service\r
- jnb @@Done ; failed if carry flag set\r
- mov [_file_err],ax\r
- xor ax,ax ; return error\r
- jmp short @@Done\r
-@@Done:\r
- POP_DS\r
- pop bp ;restore caller's stack frame\r
- ret\r
-_f_read endp\r
-\r
-;****************************************************************\r
-;\r
-; name: f_write\r
-;\r
-; C Prototype:\r
-;\r
-; extern int f_write(int handle, char *buffer, int count)\r
-;\r
-; Writes a block of count bytes to the file specified by the handle\r
-; from the buffer\r
-;\r
-; Returns count on success, error is indicated by _file_err iff count = 0\r
-;\r
-proc _f_write\r
-IFNDEF s\r
- ARG handle:word,buffer:dword,count:word\r
-ELSE\r
- ARG handle:word,buffer:word,count:word\r
-ENDIF\r
- push bp ; Preserve caller's stack frame\r
- mov bp,sp\r
- PUSH_DS\r
-\r
- mov [_file_err],0 ; Clear error\r
- mov ah,40h ; select "write to file or device" DOS service\r
- mov bx,[handle] ; select handle of file to write\r
- mov cx,[count]\r
- LDS_M dx,[buffer]\r
- int 21h ; call DOS service\r
- jnb @@Done ; has the function failed ?\r
- mov [_file_err],ax\r
- xor ax,ax ; yes, return error\r
- jmp short @@Done\r
-@@Done: ; otherwise return bytes written\r
- POP_DS\r
- pop bp ; restore caller's stack frame\r
- ret\r
-_f_write endp\r
-\r
-;****************************************************************\r
-;\r
-; name: f_readfar\r
-;\r
-; C Prototype:\r
-;\r
-; extern int f_readfar(int handle, char far * buffer, int count)\r
-;\r
-; Reads a block of count bytes from the file specified by the handle\r
-; into the buffer\r
-;\r
-; Returns count on success, failure is detectable via _file_err\r
-;\r
-proc _f_readfar\r
-ARG handle:word,buffer:dword,count:word\r
- push bp ; Preserve caller's stack frame\r
- mov bp,sp\r
- push ds\r
-\r
- mov [_file_err],0 ; Clear error\r
- mov ah,3fh ; select "read from file or device" DOS service\r
- mov bx,[handle] ; select handle of file to close\r
- mov cx,[count]\r
- lds dx,[buffer]\r
- int 21h ; call DOS service\r
- jnb @@Done ; failed if carry flag set\r
- mov [_file_err],ax\r
- xor ax,ax ; return error\r
- jmp short @@Done\r
-@@Done:\r
- pop ds\r
- pop bp ;restore caller's stack frame\r
- ret\r
-_f_readfar endp\r
-\r
-;****************************************************************\r
-;\r
-; name: f_writefar\r
-;\r
-; C Prototype:\r
-;\r
-; extern int f_writefar(int handle, char far * buffer, int count)\r
-;\r
-; Writes a block of count bytes to the file specified by the handle\r
-; from the buffer\r
-;\r
-; Returns count on success, error is indicated by _file_err iff count = 0\r
-;\r
-proc _f_writefar\r
-ARG handle:word,buffer:dword,count:word\r
- push bp ; Preserve caller's stack frame\r
- mov bp,sp\r
- push ds\r
-\r
- mov [_file_err],0 ; Clear error\r
- mov ah,40h ; select "write to file or device" DOS service\r
- mov bx,[handle] ; select handle of file to write\r
- mov cx,[count]\r
- lds dx,[buffer]\r
- int 21h ; call DOS service\r
- jnb @@Done ; has the function failed ?\r
- mov [_file_err],ax\r
- xor ax,ax ; yes, return error\r
- jmp short @@Done\r
-@@Done: ; otherwise return bytes written\r
- pop ds\r
- pop bp ; restore caller's stack frame\r
- ret\r
-_f_writefar endp\r
-\r
-\r
-\r
-;****************************************************************\r
-;\r
-; name: f_seek\r
-;\r
-; C Prototype:\r
-;\r
-; extern long int f_seek(int handle, long int position, char method_code)\r
-;\r
-; Moves the file pointer according to the position and method code\r
-;\r
-; Returns file pointer position on success, -1 on failure\r
-;\r
-proc _f_seek\r
-ARG handle:word,position:dword,method_code:byte\r
- push bp ; Preserve caller's stack frame\r
- mov bp,sp\r
-\r
- mov [_file_err],0 ; Clear error\r
- mov ah,42h ; select "move file pointer" DOS service\r
- mov bx,[handle] ; select handle of file to close\r
- mov al,[method_code]\r
- mov cx,word ptr [position+2]\r
- mov dx,word ptr [position]\r
- int 21h ; call DOS service\r
- jnb @@Done ; has the function failed ?\r
- mov [_file_err],ax\r
- mov ax,-1 ; yes, return error\r
- mov dx,-1 ;\r
- jmp short @@Done\r
-@@Done: ; otherwise return bytes written\r
- pop bp ; restore caller's stack frame\r
- ret\r
-_f_seek endp\r
-\r
-;****************************************************************\r
-;\r
-; name: f_tell\r
-;\r
-; C Prototype:\r
-;\r
-; extern long int f_tell(int handle)\r
-;\r
-; Returns file pointer position on success, -1 on failure\r
-;\r
-proc _f_tell\r
-ARG handle:word,position:dword,method_code:byte\r
- push bp ; Preserve caller's stack frame\r
- mov bp,sp\r
-\r
- mov [_file_err],0 ; Clear error\r
- mov ah,42h ; select "move file pointer" DOS service\r
- mov bx,[handle] ; select handle of file to close\r
- xor dx,dx\r
- mov cx,dx\r
- int 21h\r
- jnb @@Done\r
- mov [_file_err],ax\r
- mov ax,-1 ; yes, return error\r
- mov dx,-1 ;\r
- jmp short @@Done\r
-@@Done: ; otherwise return bytes written\r
- pop bp ; restore caller's stack frame\r
- ret\r
-_f_tell endp\r
-\r
-\r
-;****************************************************************\r
-;\r
-; name: f_filelength\r
-;\r
-; C Prototype:\r
-;\r
-; extern long int f_filelength(int handle)\r
-;\r
-; Returns the length of the file associated with the specified handle\r
-;\r
-; Returns file length on success, -1 on failure\r
-;\r
-proc _f_filelength\r
-ARG handle:word\r
-LOCAL low:word,high:word=LocalStk\r
- push bp ; Preserve caller's stack frame\r
- mov bp,sp\r
- sub sp,LocalStk\r
-\r
- mov [_file_err],0 ; Clear error\r
-\r
- ; Get ptr's current location in file and save it\r
-\r
- mov ah,42h ; select "move file pointer" DOS service\r
- mov al,1 ; select "from current location" method\r
- mov bx,[handle] ; select handle of file to close\r
- xor cx,cx\r
- xor dx,dx\r
- int 21h\r
- jb @@Error\r
- mov [low],ax\r
- mov [high],dx\r
-\r
- ; Get ptr's value at end of file\r
-\r
- mov ah,42h ; select "move file pointer" DOS service\r
- mov al,2 ; select "from end of file" method\r
- mov bx,[handle] ; select handle of file to close\r
- xor cx,cx\r
- xor dx,dx\r
- int 21h\r
- jb @@Error\r
-\r
- ; Save the results while returning pointer to its previous location\r
-\r
- push ax\r
- push dx\r
-\r
- mov ah,42h ; select "move file pointer" DOS service\r
- mov al,0 ; select "from start of file" method\r
- mov bx,[handle] ; select handle of file to close\r
- mov cx,[high]\r
- mov dx,[low]\r
- int 21h\r
-\r
- ; restore resultant length\r
-\r
- pop dx\r
- pop ax\r
-\r
- jnb @@Done ; Was the operation a success ?\r
-@@Error:\r
- mov [_file_err],ax\r
- mov ax,-1 ; no, return error\r
- mov dx,-1 ;\r
-@@Done: ; otherwise return bytes written\r
- mov sp,bp\r
- pop bp ; restore caller's stack frame\r
- ret\r
-_f_filelength endp\r
-\r
-\r
- end\r
-\r
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XFILEIO - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;-----------------------------------------------------------------------*/\r
-\r
-#ifndef _XFILEIO_H_\r
-#define _XFILEIO_H_\r
-\r
-#define F_RDONLY 0\r
-#define F_WRONLY 1\r
-#define F_RDWR 2\r
-\r
-#define SEEK_START 0\r
-#define SEEK_CURR 1\r
-#define SEEK_END 2\r
-\r
-#define FILE_ERR -1\r
-\r
-#define FIO_INVALID_METHOD 1\r
-#define FIO_FILE_NOT_FOUND 2\r
-#define FIO_PATH_NOT_FOUND 3\r
-#define FIO_HANDLE_UNAVAIL 4\r
-#define FIO_ACCESS_DENIED 5\r
-#define FIO_INVALID_HANDLE 6\r
-\r
-extern int file_err;\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-\r
- int f_open( /* Open a file returning its handle */\r
- char * filename,\r
- char access);\r
-\r
- int f_close( /* Close a file */\r
- int handle);\r
-\r
- int f_read( /* Read a block of data from a file */\r
- int handle,\r
- char * buffer,\r
- int count);\r
-\r
- int f_write( /* Write a block of data to a file */\r
- int handle,\r
- char * buffer,\r
- int count);\r
-\r
- int f_readfar( /* Read a block of data from a file */\r
- int handle,\r
- char far * buffer,\r
- int count);\r
-\r
- int f_writefar( /* Write a block of data to a file */\r
- int handle,\r
- char far * buffer,\r
- int count);\r
-\r
- long int f_seek( /* Position the file pointer */\r
- int handle,\r
- long int position,\r
- char method_code);\r
-\r
- long int f_tell( /* return position the file pointer */\r
- int handle);\r
-\r
- long int f_filelength( /* Return the length of the file */\r
- int handle);\r
-\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-\r
-#endif\r
-\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XFILEIO - Include file\r
-;\r
-; XFILEIO.ASM export functions\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
- global _f_open :proc\r
- global _f_close :proc\r
- global _f_read :proc\r
- global _f_write :proc\r
- global _f_readfar :proc\r
- global _f_writefar :proc\r
- global _f_seek :proc\r
- global _f_tell :proc\r
- global _f_filelength :proc\r
-\r
- global _file_err :word
\ No newline at end of file
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XFILL\r
-;\r
-; Point functions all MODE X 256 Color resolutions\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-COMMENT $\r
-\r
- This code is my interpretation of a simple "C" flood filling algorithm\r
- titled:\r
-\r
- * A Seed Fill Algorithm\r
- * by Paul Heckbert\r
- * from "Graphics Gems", Academic Press, 1990\r
-\r
- The original C source is readily available at numerous internet archive\r
- sites.\r
-\r
- Its been modified and optimized for tweaked 13h modes (Mode X derrivatives).\r
- The most fundamental change is that it fills a column at a time rather\r
- than a row at a time to minimize the number of plane setting "out"s.\r
- And of course the border fill variant was a logical and useful further\r
- modification.\r
-\r
- Both functions return the number of pixels filled..\r
-\r
- WARNING: These fill functions make heavy use of the stack and no stack\r
- checking is performed, so caution is advised.\r
-\r
-$\r
-\r
-\r
-include xlib.inc\r
-include xfill.inc\r
-\r
- .code\r
-\r
-_x_flood_fill proc\r
- ARG X:word,Y:word,PgOfs:word,Color:word\r
- LOCAL len:word,y1:word,y2:word,deltax:word,floodval:word,\\r
- stackptr:word,FillCount:word=STK\r
- push bp\r
- mov bp,sp\r
- sub sp,STK\r
- mov [FillCount],0\r
- push di si\r
- mov si,[Y]\r
- mov ax,[_ScrnLogicalByteWidth]\r
- mul si ;offset of pixel's scan line in page\r
- mov di,[X]\r
- mov bx,di\r
- shr di,2 ;X/4 = offset of pixel in scan line\r
- add di,ax ;offset of pixel in page\r
- add di,[PgOfs] ;offset of pixel in display memory\r
- mov ax,SCREEN_SEG\r
- mov es,ax ;point ES:DI to the pixel's address\r
-\r
- ;---- Select read plane ------\r
-\r
- mov ah,bl\r
- and ah,011b ;AH = pixel's plane\r
- mov al,READ_MAP ;AL = index in GC of the Read Map reg\r
- mov dx,GC_INDEX ;set the Read Map to read the pixel's\r
- out dx,ax ; plane\r
-\r
- mov al,es:[di] ;read the pixel's color\r
- cmp al,byte ptr Color ;Is dest pixel the same color as the flood?\r
- je @@Done2 ; if it is abort.\r
-\r
- mov cx,_LeftClip ; Is the dest. pixel out of the clipping window?\r
- sal cx,2 ; if not abort.\r
- cmp bx,cx\r
- jl @@Done2\r
-\r
- mov cx,_RightClip\r
- sal cx,2\r
- cmp bx,cx\r
- jg @@Done2\r
-\r
- mov floodval,ax ; store the color to flood\r
-\r
- ;-- Push fill segment ---\r
-\r
- push bx ; X\r
- push si ; Y\r
- push si ; Y\r
- mov cx,1 ; deltaX (either 1 or -1 indicating direction)\r
- push cx\r
- mov stackptr,1\r
-\r
- mov deltax,-1 ; Initialize first column scan\r
- mov y1,si ; then bypass some of the preliminary crap in\r
- mov y2,si ; the main fill loop\r
- jmp short @@entry\r
-\r
-@@Done2:mov ax,[FillCount]\r
- pop si di\r
- mov sp,bp\r
- pop bp\r
- ret\r
-\r
-@@NextScanCol:\r
- dec stackptr\r
- js @@Done2\r
-\r
-@@WhileLoop:\r
- pop cx ; get fill segment from stack\r
- mov deltax,cx ; ie deltaX, Y1, Y2, X\r
- pop ax\r
- mov y2,ax\r
- pop si\r
- mov y1,si\r
- pop bx\r
-\r
- sub ax,si ; Acculmulate number of filled pixels\r
- jns @@PositiveY\r
- neg ax\r
-@@PositiveY:\r
- add FillCount,ax\r
-\r
-\r
- add bx,cx ; move to new column according to deltaX\r
-\r
- mov ax,bx ; Make sure the column is within the clipping\r
- sar ax,2 ; rectangle\r
- cmp ax,_LeftClip\r
- jl @@NextScanCol\r
-\r
- cmp ax,_RightClip\r
- jg @@NextScanCol\r
-\r
-\r
- ;---- Select read plane ------\r
-\r
- mov ah,bl\r
- and ah,011b ;AH = pixel's plane\r
- mov al,READ_MAP ;AL = index in GC of the Read Map reg\r
- mov dx,GC_INDEX ;set the Read Map to read the pixel's\r
- out dx,ax ; plane\r
-\r
-@@entry:\r
-\r
- ;---- Select write plane ------\r
-\r
- mov cl,bl\r
- and cl,011b ;CL = pixel's plane\r
- mov ax,0100h + MAP_MASK ;AL = index in SC of Map Mask reg\r
- shl ah,cl ;set only the bit for the pixel's\r
- ; plane to 1\r
- mov dx,SC_INDEX ;set the Map Mask to enable only the\r
- out dx,ax ; pixel's plane\r
-\r
- mov ax,_ScrnLogicalByteWidth ; store logical width in CX\r
- mov cx,ax ; get offset of scan row\r
- mul si ; set ES:DI ->\r
- mov di,bx ; address of pixel at x,y1\r
- shr di,2\r
- add di,ax\r
- add di,PgOfs ;ES:DI->first pixel of column segment to fill\r
- mov dx,di ; save y1 offset for after upward fill\r
-\r
- mov al,byte ptr Color\r
- mov ah,byte ptr floodval\r
-\r
-@@FillColUpward:\r
- cmp si,_TopClip ; Dont fill beyond clip boundaries\r
- jl @@UpwardFillDone\r
-\r
- cmp es:[di],ah ; if flood pixel color then replace\r
- jne @@UpwardFillDone ; with new color otherwise column is done\r
-\r
- mov es:[di],al\r
- sub di,cx\r
- dec si\r
- jmp short @@FillColUpward\r
-\r
-@@UpwardFillDone:\r
- cmp si,y1\r
- jge @@Skip\r
-\r
- inc si\r
- mov len,si\r
-\r
- cmp si,y1\r
- jge @@AtColumnTop\r
-\r
- push bx ; queue an upward leak check\r
- push si\r
- mov ax,y1\r
- dec ax\r
- push ax\r
- mov ax,deltax\r
- neg ax\r
- push ax\r
- inc stackptr\r
-\r
-@@AtColumnTop:\r
- mov si,y1\r
- mov di,dx\r
- add di,cx\r
- inc si\r
-\r
-\r
-@@ColumnLoop:\r
- mov ah,byte ptr floodval\r
- mov al,byte ptr Color\r
-\r
-@@DownwardFill:\r
- cmp si,_BottomClip\r
- jg @@DownwardFillDone\r
- cmp es:[di],ah\r
- jne @@DownwardFillDone\r
- mov es:[di],al\r
- add di,cx\r
- inc si\r
- jmp short @@DownwardFill\r
-\r
-@@DownwardFillDone:\r
-\r
- push bx ; queue an upward leak check\r
- mov ax,len\r
- push ax\r
- mov ax,si\r
- dec ax\r
- push ax\r
- mov ax,deltax\r
- push ax\r
- inc stackptr\r
-\r
- mov ax,y2\r
- inc ax\r
- cmp si,ax\r
- jle @@Skip\r
-\r
- push bx ; queue a downward leak check\r
- push ax\r
- mov ax,si\r
- dec ax\r
- push ax\r
- mov ax,deltax\r
- neg ax\r
- push ax\r
- inc stackptr\r
-\r
-@@Skip:\r
- mov ah,byte ptr floodval\r
- mov dx,y2\r
-\r
-@@Backtrack:\r
- add di,cx\r
- inc si\r
- cmp si,dx\r
- jg @@BacktrackDone\r
-\r
- cmp byte ptr es:[di],ah\r
- jne @@Backtrack\r
-\r
-@@BacktrackDone:\r
- mov len,si\r
- cmp si,dx\r
- jle @@ColumnLoop\r
-\r
- dec stackptr\r
- js @@Done\r
- jmp @@WhileLoop\r
-@@Done:\r
- mov ax,[FillCount]\r
- pop si di\r
- mov sp,bp\r
- pop bp\r
- ret\r
-_x_flood_fill endp\r
-\r
-\r
-_x_boundary_fill proc\r
- ARG X:word,Y:word,PgOfs:word,BoundaryColor:word,Color:word\r
- LOCAL len:word,y1:word,y2:word,deltax:word,y1_offs:word,\\r
- stackptr:word,FillCount:word=STK\r
- push bp\r
- mov bp,sp\r
- sub sp,STK\r
- mov [FillCount],0\r
- push di si\r
- mov si,[Y]\r
- mov ax,[_ScrnLogicalByteWidth]\r
- mul si ;offset of pixel's scan line in page\r
- mov di,[X]\r
- mov bx,di\r
- shr di,2 ;X/4 = offset of pixel in scan line\r
- add di,ax ;offset of pixel in page\r
- add di,[PgOfs] ;offset of pixel in display memory\r
- mov ax,SCREEN_SEG\r
- mov es,ax ;point ES:DI to the pixel's address\r
-\r
- ;---- Select read plane ------\r
-\r
- mov ah,bl\r
- and ah,011b ;AH = pixel's plane\r
- mov al,READ_MAP ;AL = index in GC of the Read Map reg\r
- mov dx,GC_INDEX ;set the Read Map to read the pixel's\r
- out dx,ax ; plane\r
-\r
- mov al,es:[di] ;read the pixel's color\r
- cmp al,byte ptr Color ;Is dest pixel the same color as the flood?\r
- je @@Done2\r
-\r
- cmp al,byte ptr BoundaryColor ;Is dest pixel the same color\r
- je @@Done2 ; as the boundary color?\r
-\r
-\r
- mov cx,_LeftClip ; Is the dest. pixel out of the clipping window?\r
- sal cx,2\r
- cmp bx,cx\r
- jl @@Done2\r
-\r
- mov cx,_RightClip\r
- sal cx,2\r
- cmp bx,cx\r
- jg @@Done2\r
-\r
- push bx ; X\r
- push si ; Y\r
- push si ; Y\r
- mov cx,1 ; DX\r
- push cx\r
- mov stackptr,1\r
- mov al,byte ptr BoundaryColor\r
- mov byte ptr [Color+1],al\r
-\r
- mov deltax,-1\r
- mov y1,si\r
- mov y2,si\r
- jmp short @@entry\r
-\r
-@@Done2:mov ax,[FillCount]\r
- pop si di\r
- mov sp,bp\r
- pop bp\r
- ret\r
-\r
-@@NextScanCol:\r
- dec stackptr\r
- js @@Done2\r
-\r
-@@WhileLoop:\r
- pop cx\r
- mov deltax,cx\r
- pop ax\r
- mov y2,ax\r
- pop si\r
- mov y1,si\r
- pop bx\r
- add bx,cx ; bx = X\r
-\r
- sub ax,si ; Acculmulate number of filled pixels\r
- jns @@PositiveY\r
- neg ax\r
-@@PositiveY:\r
- add FillCount,ax\r
-\r
-\r
-\r
- mov ax,bx ; Make sure the column is within the clipping\r
- sar ax,2 ; rectangle\r
- cmp ax,_LeftClip\r
- jl @@NextScanCol\r
- cmp ax,_RightClip\r
- jg @@NextScanCol\r
-\r
-\r
- ;---- Select read plane ------\r
-\r
- mov ah,bl\r
- and ah,011b ;AH = pixel's plane\r
- mov al,READ_MAP ;AL = index in GC of the Read Map reg\r
- mov dx,GC_INDEX ;set the Read Map to read the pixel's\r
- out dx,ax ; plane\r
-\r
-@@entry:\r
-\r
- ;---- Select write plane ------\r
-\r
- mov cl,bl\r
- and cl,011b ;CL = pixel's plane\r
- mov ax,0100h + MAP_MASK ;AL = index in SC of Map Mask reg\r
- shl ah,cl ;set only the bit for the pixel's\r
- ; plane to 1\r
- mov dx,SC_INDEX ;set the Map Mask to enable only the\r
- out dx,ax ; pixel's plane\r
-\r
- mov ax,_ScrnLogicalByteWidth ; store logical width in CX\r
- mov cx,ax ; get offset of scan row\r
- mul si ; set ES:DI ->\r
- mov di,bx ; address of pixel at x,y1\r
- shr di,2\r
- add di,ax\r
- add di,PgOfs\r
- mov y1_offs,di ; save y1 offset for after upward fill\r
-\r
- mov ax,Color ; al = Color ah = BoundaryColor\r
-\r
-@@FillColUpward:\r
- cmp si,_TopClip ; Dont fill beyond clip boundaries\r
- jl @@UpwardFillDone\r
-\r
- mov dl,es:[di]\r
- cmp dl,ah\r
- je @@UpwardFillDone\r
-\r
- cmp dl,al\r
- je @@UpwardFillDone\r
-\r
- mov es:[di],al\r
- sub di,cx\r
- dec si\r
- jmp short @@FillColUpward\r
-\r
-@@UpwardFillDone:\r
- cmp si,y1\r
- jge @@Skip\r
-\r
- inc si\r
- mov len,si\r
-\r
- cmp si,y1\r
- jge @@AtColumnTop\r
-\r
- push bx ; queue an upward leak check\r
- push si\r
- mov ax,y1\r
- dec ax\r
- push ax\r
- mov ax,deltax\r
- neg ax\r
- push ax\r
- inc stackptr\r
-\r
-@@AtColumnTop:\r
- mov si,y1\r
- mov di,y1_offs\r
- add di,cx\r
- inc si\r
-\r
-\r
-@@ColumnLoop:\r
- mov ax,Color ; al = Color ah = BoundaryColor\r
-\r
-@@DownwardFill:\r
- cmp si,_BottomClip\r
- jg @@DownwardFillDone\r
-\r
- cmp es:[di],ah\r
- je @@DownwardFillDone\r
-\r
- cmp es:[di],al\r
- je @@DownwardFillDone\r
-\r
- mov es:[di],al\r
- add di,cx\r
- inc si\r
- jmp short @@DownwardFill\r
-\r
-@@DownwardFillDone:\r
-\r
- push bx ; queue an upward leak check\r
- mov ax,len\r
- push ax\r
- mov ax,si\r
- dec ax\r
- push ax\r
- mov ax,deltax\r
- push ax\r
- inc stackptr\r
-\r
- mov ax,y2\r
- inc ax\r
- cmp si,ax\r
- jle @@Skip\r
-\r
- push bx ; queue a downward leak check\r
- push ax\r
- mov ax,si\r
- dec ax\r
- push ax\r
- mov ax,deltax\r
- neg ax\r
- push ax\r
- inc stackptr\r
-\r
-@@Skip:\r
- mov ax,Color ; al = Color ah = BoundaryColor\r
-\r
-@@Backtrack:\r
- add di,cx\r
- inc si\r
- cmp si,y2\r
- jg @@BacktrackDone\r
-\r
- mov dl,byte ptr es:[di]\r
- cmp dl,al\r
- je @@Backtrack\r
-\r
- cmp dl,ah\r
- je @@Backtrack\r
-\r
-@@BacktrackDone:\r
- mov len,si\r
- cmp si,y2\r
- jle @@ColumnLoop\r
-\r
- dec stackptr\r
- js @@Done\r
- jmp @@WhileLoop\r
-@@Done:\r
- mov ax,[FillCount]\r
- pop si di\r
- mov sp,bp\r
- pop bp\r
- ret\r
-_x_boundary_fill endp\r
-\r
-end\r
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XFILL - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;----------------------------------------------------------------------*/\r
-\r
-#ifndef _XFILL_H_\r
-#define _XFILL_H_\r
-\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-int x_flood_fill(int x,\r
- int y,\r
- unsigned ofs,\r
- int color\r
- );\r
-\r
-int x_boundary_fill(int x,\r
- int y,\r
- unsigned ofs,\r
- int boundary,\r
- int color\r
- );\r
-\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif\r
-\r
-\r
+++ /dev/null
-global _x_flood_fill:proc\r
-global _x_boundary_fill:proc
\ No newline at end of file
+++ /dev/null
-/*----------------------------------------------------------------------\r
-;\r
-; XLIB - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; Header file contributed by Darren Lyon (darren@nicky.DIALix.oz.au)\r
-;\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;----------------------------------------------------------------------*/\r
-\r
-#ifndef _XLIB_H_\r
-#define _XLIB_H_\r
-\r
-#define BYTE unsigned char\r
-#define WORD unsigned int\r
-\r
-\r
-#define X_MODE_320x200 0\r
-#define X_MODE_320x240 1\r
-#define X_MODE_360x200 2\r
-#define X_MODE_360x240 3\r
-#define X_MODE_376x282 4\r
-#define X_MODE_320x400 5\r
-#define X_MODE_320x480 6\r
-#define X_MODE_360x400 7\r
-#define X_MODE_360x480 8\r
-#define X_MODE_360x360 9\r
-#define X_MODE_376x308 10\r
-#define X_MODE_376x564 11\r
-#define X_MODE_256x400 12\r
-#define X_MODE_256x480 13\r
-\r
-\r
-#define BACKWARD 0\r
-#define FORWARD 1\r
-\r
-#define X_MODE_INVALID -1\r
-#define ERROR 1\r
-#define OK 0\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
- WORD x_set_mode(\r
- WORD mode, /* Initialize x mode */\r
- WORD WidthInPixels);\r
-\r
- void x_select_default_plane( /*Enables Read/Write access to a */\r
- BYTE plane); /* a specified plane */\r
-\r
- void x_set_splitscreen( /* set the split screen start */\r
- WORD line); /*scan line (initialize) */\r
-\r
- void x_set_start_addr(\r
- WORD X, /* Set the screen start */\r
- WORD Y); /* address in video ram */\r
-\r
- void x_hide_splitscreen(void); /* Disable the split screen (Split */\r
- /* Screen RAM remains reserved) */\r
-\r
- void x_show_splitscreen(void); /* Enable the split screen (given it */\r
- /* was previously "hidden") */\r
-\r
-\r
- void x_adjust_splitscreen( /* Adjust the start scan line of the */\r
- WORD line); /* split screen */\r
-\r
-\r
- WORD x_set_doublebuffer( /* Enable double buffering with a */\r
- WORD PageHeight); /* specified page height */\r
-\r
- WORD x_set_tripplebuffer( /* Enable tripple buffering with a */\r
- WORD PageHeight); /* specified page height */\r
-\r
-\r
- void x_page_flip( /* Swap visible page (only when double */\r
- WORD X, /* buffering is active) & sets virt start*/\r
- WORD Y);\r
-\r
- void x_set_cliprect( /* Define the clipping rectangle */\r
- WORD left, /* NOTE: left and right are in bytes */\r
- WORD top,\r
- WORD righ,\r
- WORD bottom);\r
-\r
- void x_text_mode(void); /* return to text mode */\r
- void x_wait_vsync(void); /* wait for vsync */\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-\r
-/* VARIABLES =========================================================== */\r
-\r
-extern BYTE InGraphics; /* non zero if in X graphics mode */\r
-extern WORD CurrXMode; /* contains current X graphics mode id */\r
-extern WORD ScrnPhysicalByteWidth; /* Physical screen width in bytes */\r
-extern WORD ScrnPhysicalPixelWidth; /* Physical screen width in pixels */\r
-extern WORD ScrnPhysicalHeight; /* Physical screen height in pixels */\r
-extern WORD ErrorValue; /* Error return value */\r
-extern WORD SplitScrnOffs; /* Offset in VRAM of split screen */\r
-extern WORD SplitScrnScanLine; /* Scan line split screen starts at */\r
- /* initially. Resizing the split scrn */\r
- /* using the other functions does not */\r
- /* change this value */\r
-extern WORD SplitScrnVisibleHeight; /* Height of the visible portion of the*/\r
- /* split screen. */\r
-extern WORD Page0_Offs; /* Offset in VRAM of main virt. screen */\r
-extern WORD Page1_Offs; /* Offset in VRAM of 2nd virt. screen */\r
-extern WORD Page2_Offs; /* Offset in VRAM of 3rd virt. screen */\r
-extern WORD ScrnLogicalByteWidth; /* Virtual screen width in bytes */\r
-extern WORD ScrnLogicalPixelWidth; /* Virtual screen width in pixels */\r
-extern WORD ScrnLogicalHeight; /* Virtual screen height in pixels */\r
-extern WORD MaxScrollX; /* Max X position of physical screen */\r
- /* within virtual screen */\r
-extern WORD MaxScrollY; /* Max Y position of physical screen */\r
- /* within virtual screen */\r
-extern WORD DoubleBufferActive; /* Indicates whether double buffering */\r
- /* is active */\r
-extern WORD TrippleBufferActive; /* Indicates whether tripple */\r
- /* buffering is active */\r
-extern WORD VisiblePageIdx; /* Index number of visible page 0 or 1 */\r
-extern WORD HiddenPageOffs; /* Offset of Hidden Pg | only valid */\r
-extern WORD VisiblePageOffs; /* Offset of Visible Pg| for D.B. mode */\r
-extern WORD WaitingPageOffs; /* Offset of Waiting Pg| for T.B. mode */\r
-extern WORD NonVisual_Offs; /* Offset of first non-visible VRAM */\r
-\r
-extern WORD StartAddressFlag;\r
-\r
-extern WORD TopClip; /* Clipping rectangle */\r
-extern WORD BottomClip;\r
-extern WORD LeftClip;\r
-extern WORD RightClip;\r
-\r
-extern WORD PhysicalStartPixelX; /* Coordinates of physical (visible) */\r
-extern WORD PhysicalStartByteX; /* screen relative to the virtual */\r
-extern WORD PhysicalStartY; /* screen's U.L. corner */\r
-\r
-extern char* VsyncPaletteBuffer;\r
-\r
-#endif\r
-\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XLIB - Include file\r
-;\r
-; Global equates and variables\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; MODIFICATIONS:\r
-; 26-9-92 : Pel panning code added\r
-; 23-10-92: Added clip rectangle code\r
-;-----------------------------------------------------------------------\r
-\r
-;\r
-\r
-LOCALS\r
-.286\r
-\r
-; First lets find out what memory model to use\r
-\r
-include model.inc\r
-\r
-\r
-AC_INDEX equ 03c0h ;Attribute controller index register\r
-MISC_OUTPUT equ 03c2h ;Miscellaneous Output register\r
-SC_INDEX equ 03c4h ;Sequence Controller Index\r
-GC_INDEX equ 03ceh ; Graphics controller Index\r
-CRTC_INDEX equ 03d4h ;CRT Controller Index\r
-DAC_READ_INDEX equ 03c7h ;\r
-DAC_WRITE_INDEX equ 03c8h ;\r
-DAC_DATA equ 03c9h ;\r
-INPUT_STATUS_0 equ 03dah ;Input status 0 register\r
-\r
-\r
-SCREEN_SEG equ 0a000h ;segment of display memory in mode X\r
-\r
-MAP_MASK equ 02h ;index in SC of Map Mask register\r
-READ_MAP equ 04h ;index in GC of the Read Map register\r
-BIT_MASK equ 08h ;index in GC of Bit Mask register\r
-\r
-OVERFLOW equ 07h ; CRTC overflow register index\r
-MAX_SCAN_LINE equ 09h ; CRTC maximum scan line register index\r
-ADDR_HIGH equ 0ch ;Index of Start Address High reg in CRTC\r
-ADDR_LOW equ 0dh ; Low\r
-CRTC_OFFSET equ 13h ; CRTC offset register index\r
-UNDERLINE equ 14h ; CRTC underline location register index\r
-MODE_CONTROL equ 17h ; CRTC mode control register index\r
-LINE_COMPARE equ 18h ; CRTC line compare reg. index (bits 0-7 of\r
- ; split screen scan line\r
-\r
-AC_MODE_CONTROL equ 10h ; Index of Mode COntrol register in AC\r
-PEL_PANNING equ 13h ; Pel panning register index in AC\r
-\r
-PATTERN_BUFFER equ 0fffch ;offset in screen memory of pattern buffer\r
-\r
-TRUE equ 1\r
-FALSE equ 0\r
-\r
-\r
-OK equ 0\r
-ERROR equ 1\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; Macro to wait for the vertical retrace leading edge\r
-\r
-WaitVsyncStart macro\r
- LOCAL WaitNotVsync,WaitVsync\r
- mov dx,INPUT_STATUS_0\r
-WaitNotVsync:\r
- in al,dx\r
- test al,08h\r
- jnz WaitNotVsync\r
-WaitVsync:\r
- in al,dx\r
- test al,08h\r
- jz WaitVsync\r
- endm\r
-\r
-;-----------------------------------------------------------------------\r
-; Macro to wait for the vertical retrace trailing edge\r
-\r
-WaitVsyncEnd macro\r
- LOCAL WaitNotVsync,WaitVsync\r
- mov dx,INPUT_STATUS_0\r
-WaitVsync2:\r
- in al,dx\r
- test al,08h\r
- jz WaitVsync2\r
-WaitNotVsync2:\r
- in al,dx\r
- test al,08h\r
- jnz WaitNotVsync2\r
- endm\r
-\r
-;--- Word out macro ------------------------------------------\r
-\r
- WORDOUT macro\r
- IFDEF nw\r
- out dx,al\r
- inc dx\r
- xchg al,ah\r
- out dx,al\r
- xchg al,ah\r
- dec dx\r
- ELSE\r
- out dx,al\r
- ENDIF\r
- endm\r
-\r
-;------------------------------------------------------------------------\r
-; Global variables - XMAIN exports\r
-;\r
- global _InGraphics :byte\r
- global _CurrXMode :word\r
- global _ScrnPhysicalByteWidth :word\r
- global _ScrnPhysicalPixelWidth :word\r
- global _ScrnPhysicalHeight :word\r
- global _ErrorValue :byte\r
-\r
- global _SplitScrnOffs :word\r
- global _SplitScrnScanLine :word\r
- global _SplitScrnVisibleHeight :word\r
- global _Page0_Offs :word\r
- global _Page1_Offs :word\r
- global _Page2_Offs :word\r
- global _ScrnLogicalByteWidth :word\r
- global _ScrnLogicalPixelWidth :word\r
- global _ScrnLogicalHeight :word\r
-\r
- global _MaxScrollX :word\r
- global _MaxScrollY :word\r
- global _DoubleBufferActive :word\r
- global _TrippleBufferActive :word\r
- global _VisiblePageIdx :word\r
- global _VisiblePageOffs :word\r
- global _HiddenPageOffs :word\r
- global _WaitingPageOffs :word\r
- global _NonVisual_Offs :word\r
- global _TopClip :word\r
- global _BottomClip :word\r
- global _LeftClip :word\r
- global _RightClip :word\r
-\r
- global _PhysicalStartByteX :word\r
- global _PhysicalStartPixelX :word\r
- global _PhysicalStartY :word\r
-\r
- global _VsyncHandlerActive :word\r
- global _MouseRefreshFlag :word\r
- global _MouseVsyncHandler :dword\r
- global _StartAddressFlag :word\r
- global _WaitingStartLow :word\r
- global _WaitingStartHigh :word\r
- global _WaitingPelPan :word\r
- global _VsyncPaletteStart :word\r
- global _VsyncPaletteCount :word\r
- global _VsyncPaletteBuffer :byte\r
-\r
-\r
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XLIB_ALL - header file\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;----------------------------------------------------------------------*/\r
-\r
-#include "XLIB.H"\r
-#include "XPOINT.H"\r
-#include "XRECT.H"\r
-#include "XLINE.H"\r
-#include "XPAL.H"\r
-#include "XTEXT.H"\r
-#include "XPBITMAP.H"\r
-#include "XCBITMAP.H"\r
-#include "XDETECT.H"\r
-#include "XBMTOOLS.H"\r
-#include "XFILEIO.H"\r
-#include "XRLETOOL.H"\r
-#include "XBEZIER.H"\r
-#include "XVBITMAP.H"\r
-#include "XMOUSE.H"\r
-#include "XPBMCLIP.H"\r
-#include "XCIRCLE.H"\r
-#include "XCLIPPBM.H"\r
-#include "XPOLYGON.H"\r
-#include "XVSYNC.H"\r
-#include "XFILL.H"\r
-#include "XCBITM32.H"\r
+++ /dev/null
-PART 1 of 2\r
------------------------------------------------------------------------------\r
-\r
- ********* XLIB - Mode X graphics library ****************\r
- ********* ****************\r
- ********* Written By Themie Gouthas ****************\r
- ********* ****************\r
- ********* egg@dstos3.dsto.gov.au ****************\r
- ********* teg@bart.dsto.gov.au ****************\r
-\r
- Some of the code in this library has been contributed by :\r
-\r
- Matthew MacKenzie - matm@eng.umd.edu\r
-\r
- and others. See individual modules.\r
-\r
- I informally reserve all rights to the code in XLIB\r
- Rights to contributed code is also assumed to be reserved by\r
- the original authors.\r
------------------------------------------------------------------------------\r
-\r
-DISCLAIMER\r
-\r
- This library is distributed AS IS. The author/s specifically disclaim\r
- any responsibility for any loss of profit or any incidental, consequen-\r
- tial or other damages.\r
-\r
----------------------------------------------------------------------------\r
-INTRODUCTION\r
----------------------------------------------------------------------------\r
-\r
-XLIB is a "user supported freeware" graphics library specifically designed\r
-with game programming in mind.\r
-\r
-It has been placed in the public domain for the benefit of all, and\r
-represents *MANY* hours of work so it is requested that all users comply\r
-with the the wishes of the author/s as specified in the individual modules\r
-and:\r
-a) To leave the code in the public domain\r
-b) Not distribute any modified or incomplete versions of this library\r
-\r
-New contribution and comments are welcome and hopefully there will be\r
-more releases as the code evolves.\r
-\r
-Finally, do not trust this excuse for a manual if in doubt, as this code has\r
-undergone several revisions. The place to get the answers is in the code\r
-itself.\r
-\r
-REQUIREMENTS\r
-\r
-Minimum requirements\r
- 286 processor,\r
- Turbo C 2.0 or higher, or BORLANDC\r
- MAKE 2.0 or higher\r
- TLIB 2.0 or higher\r
- Turbo Assembler 1.01 or higher\r
-\r
-\r
-GENERAL FEATURES\r
-\r
- Support for a number of 256 colour tweaked graphics mode resolutions\r
- 320x200 320x240 360x200 360x240 376x282 320x400 320x480 360x400 360x480\r
- 360x360 376x308 376x564\r
-\r
- Please note that some of the new resolutions best suit monitors with\r
- adjustable vertical height.\r
-\r
- Virtual screens larger than the physical screen (memory\r
- permitting) that can be panned at pixel resolution in all directions\r
-\r
- A split screen capability for status displays etc.\r
-\r
- Text functions supporting 8x8 and 8x14 ROM fonts and user defined fonts\r
-\r
- Support for page flipping\r
-\r
- Graphics primitives such as line and rectangle drawing functions and\r
- of course bit block manipulation functions\r
-\r
-MODULES COMPRISING XLIB\r
- XMAIN - Main module containig mode setting code and basic functions\r
- XPOINT - Pixel functions\r
- XRECT - Filled Rectangle and VRAM to VRAM block move functions\r
- XPAL - Palette functions\r
- XLINE - Line Functions\r
- XTEXT - Text and Font Functions\r
- XPRINTF - Printf style string output\r
- XPBITMAP - Planar Bitmap functions\r
- XCBITMAP - Compiled Bitmap functions\r
- XVBITMAP - Video Bitmap functions\r
- XPBMCLIP - Clipped Planar Bitmap functions\r
- XMAKEVBM - Support module for video bitmaps\r
- XBMTOOLS - Bitmap format conversion tools\r
- XDETECT - Hardware detection module\r
- XFILEIO - File I/O functions\r
- XRLETOOL - RLE encoding/decoding functions\r
- XMOUSE - Mouse functions\r
- XBEZIER - Bezier curve drawing\r
-\r
--------------------------------------------------------------------------\r
-BUILDING THE LIBRARIES\r
--------------------------------------------------------------------------\r
-\r
-Building the library had been made simple through the use of make.\r
-\r
-To build and examples for one of the two models:\r
-\r
-a) edit the makefile for the apropriate model (see note in the makefile)\r
-b) edit the makefile for the apropriate compiler (again see note in the\r
- makefile)\r
-c) type "make" at the dos prompt.\r
-\r
-It should be as simple as that. If problems are encountered then check\r
-to see if tasm, make, tlib, link and bcc (or tcc) are withinin your path.\r
-If not either change your path or specify the full path for these programs\r
-in the makefile. It is preferrable to have your path set correctly.\r
-\r
-Individual Compilation\r
-----------------------\r
-\r
-each ASM module can be compiled with the following commandline:\r
-\r
-tasm /ml /d<model> <asm module name>\r
-\r
-where <model> is s c or l. Where s = small model, c = compact model and\r
-l = large model.\r
-\r
-The resulting libraries are:\r
-\r
- xlib<version>s.lib - small model library\r
- xlib<version>c.lib - large model library\r
- xlib<version>l.lib - large model library\r
-\r
-To link the library with your programs just include the apropriate .lib\r
-file in your project file or on the BCC or TCC command line.\r
-\r
-Using the library with your programs\r
-------------------------------------\r
-\r
-Using the XLIB library in your programs is simple. Knowing the particular\r
-modules you require, just include the associated header files in your program\r
-and link your program modules with the library. If you don't want to wory\r
-about selecting the apropriate header file then just include "XLIB_ALL.H"\r
-which automatically includes all XLIB header files in your program.\r
-\r
-For example compilations see the supplied makefile.\r
-\r
---------------------------------------------------------------------------\r
-GLOBAL DEFINES (xlib.inc)\r
---------------------------------------------------------------------------\r
-\r
-Types\r
-\r
- BYTE unsigned char\r
- WORD unsigned int\r
-\r
-Available X mode resolutions\r
-\r
- X_MODE_320x200 0\r
- X_MODE_320x240 1\r
- X_MODE_360x200 2\r
- X_MODE_360x240 3\r
- X_MODE_360x282 4\r
- X_MODE_320x400 5\r
- X_MODE_320x480 6\r
- X_MODE_360x400 7\r
- X_MODE_360x480 8\r
- X_MODE_360x360 9\r
- X_MODE_376x308 10\r
- X_MODE_376x564 11\r
-\r
-Palette rotation direction directiion\r
-\r
- BACKWARD 0\r
- FORWARD 1\r
-\r
-\r
- X_MODE_INVALID -1\r
- ERROR 1\r
- OK 0\r
-\r
-\r
---------------------------------------------------------------------------\r
-MODULE XMAIN\r
---------------------------------------------------------------------------\r
-\r
-The Xmain module is the base module of the XLIB library. It contains the\r
-essential functions that initialize and customize the graphic environment.\r
-\r
-\r
-ASM SOURCES\r
-\r
- xmain.asm xmain.inc xlib.inc model.inc\r
-\r
-C HEADER FILE\r
-\r
- xlib.h\r
-\r
-EXPORTED VARIABLES\r
-\r
- NOTE: All variables are read only unless otherwise specified. If you modify\r
- them manually, the results may be unpredictable.\r
-\r
- InGraphics - BYTE - Flag indicating that the xlib graphics system is\r
- active. Set by function "x_set_mode".\r
-\r
- CurrXMode - WORD - If the xlib graphics system is active, contains the id\r
- of the x mode. Set by function "x_set_mode".\r
- See also defines (ie X_MODE_320x200 ... )\r
-\r
- ScrnPhysicalByteWidth - WORD - Physical screen width in bytes. Set by\r
- function "x_set_mode"\r
-\r
- ScrnPhysicalPixelWidth - WORD - Physical screen width in pixels. Set by\r
- function "x_set_mode"\r
-\r
- ScrnPhysicalHeight - WORD - Physical screen height in pixels. Set by\r
- function "x_set_mode".\r
-\r
- ErrorValue - WORD - Contains error value. General use variable to\r
- communicate the error status from several functions. The value\r
- in this variable usually is only valid for the the last\r
- function called that sets it.\r
-\r
- SplitScrnOffs - WORD - Offset in video ram of split screen. Set by\r
- function "x_set_splitscrn". The value is only valid if a split\r
- screen is active. See also global variable "SplitScrnActive".\r
-\r
- SplitScrnScanLine - WORD - Screen Scan Line the Split Screen starts at\r
- initially when set by function "x_set_splitscrn". The value is only\r
- valid if a split screen is active. See also global variable\r
- "SplitScrnActive".This variable is not updated by "x_hide_splitscrn",\r
- "x_adjust_splitscrn".\r
-\r
- SplitScrnVisibleHeight - WORD - The number of rows of the initial split\r
- screen which are currently displayed. Modified by "x_hide_splitscrn",\r
- "x_adjust_splitscrn" and "x_show_splitscrn".\r
-\r
- Page0_Offs - WORD - Offset in video ram of main virtual screen. Initially\r
- set by function "x_set_mode" but is updated by functions\r
- "x_set_splitscrn" and "x_set_doublebuffer".\r
-\r
- Page1_Offs - WORD - Offset in video ram of second virtual screen. Set by\r
- and only is valid after a call to "x_set_doublebuffer".\r
-\r
- ScrnLogicalByteWidth - WORD - Virtual screen width in bytes. Set by\r
- function "x_set_mode".\r
-\r
- ScrnLogicalPixelWidth - WORD - Virtual screen width in pixels. Set\r
- by function "x_set_mode".\r
-\r
- ScrnLogicalHeight - WORD - Virtual screen height in pixels. Set\r
- initially by function "x_set_mode" but is updated by functions\r
- "x_set_splitscrn" and "x_set_doublebuffer".\r
-\r
- MaxScrollX - WORD - Max X pixel position of physical screen within\r
- virtual screen. Set by function "x_set_mode".\r
-\r
- MaxScrollY - WORD - Max Y position of physical screen within virtual\r
- screen. Set initially by function "x_set_mode" but is updated by\r
- functions "x_set_splitscrn" and "x_set_doublebuffer".\r
-\r
- DoubleBufferActive - WORD - Indicates whether double-buffering is on. Set\r
- by function "x_set_doublebuffer".\r
-\r
- VisiblePageIdx - WORD - Index number of current visible page. Initially\r
- set by function "x_set_doublebuffer" but is updated by "x_page_flip".\r
- This variable is only used while double buffering is on.\r
-\r
- HiddenPageOffs - WORD - Offset of hidden page. Initially set by function\r
- "x_set_doublebuffer" but is updated by "x_page_flip". This variable\r
- is only used while double buffering is on.\r
-\r
- VisiblePageOffs - WORD - Offset of visible page. Initially set by function\r
- "x_set_doublebuffer" but is updated by "x_page_flip". This variable\r
- is only used while double buffering is on.\r
-\r
- NonVisual_Offs - WORD - Offset of first byte of non-visual ram, the ram\r
- that is available for bitmap storage etc. Set initially by function\r
- "x_set_mode" but is updated by functions "x_set_splitscrn" and\r
- "x_set_doublebuffer".\r
-\r
- TopClip, BottomClip, LeftClip RightClip - WORD - Define the clipping\r
- rectangle for Linear and Video clipped bitmap put functions. Set\r
- either manually or by "x_set_cliprect". Note X coordinates are in\r
- bytes as all clip functions clip to byte boundaries.\r
-\r
- PhysicalStartPixelX - WORD - X pixel Offset of physical (visible) screen\r
- relative to the upper left hand corner (0,0) of the virtual screen.\r
-\r
- PhysicalStartByteX - WORD - X byte Offset of physical (visible) screen\r
- relative to the upper left hand corner (0,0) of the virtual screen.\r
-\r
- PhysicalStartY - WORD - Y pixel Offset of physical (visible) screen\r
- relative to the upper left hand corner (0,0) of the virtual screen.\r
-\r
-EXPORTED FUNCTIONS\r
-\r
- x_set_mode\r
- ----------\r
- C Prototype: extern WORD x_set_mode(WORD mode,WORD WidthInPixels);\r
-\r
- mode - The required mode as defined by the "Available X Mode\r
- resolutions" set of defines in the xlib.h header file.\r
- WidthInPixels - The required virtual screen width.\r
- Returns - The actual width in pixels of the allocated virtual\r
- screen\r
-\r
- This function initialises the graphics system, setting the apropriate\r
- screen resolution and allocating a virtual screen. The virtual screen\r
- allocated may not necessarily be of the same size as specified in the\r
- "WidthInPixels" parameter as it is rounded down to the nearest\r
- multiple of 4.\r
-\r
- The function returns the actual width of the allocated virtual screen\r
- in pixels if a valid mode was selected otherwise returns\r
- X_MODE_INVALID.\r
-\r
- Saves virtual screen pixel width in "ScrnLogicalPixelWidth".\r
- Saves virtual screen byte width in "ScrnLogicalByteWidth".\r
- Physical screen dimensions are set in "ScrnPhysicalPixelWidth".\r
- "ScrnPhysicalByteWidth" and "ScrnPhysicalHeight". Other global\r
- variables set are "CurrXMode","MaxScrollX", "MaxScrollY",\r
- "InGraphics". The variable "SplitScrnScanline" is also initialized\r
- to zero.\r
-\r
- See also:\r
- Available X Mode resolutions\r
- What is Mode X\r
-\r
- x_select_default_plane\r
- ----------------------\r
-\r
- C Prototype: void x_select_default_plane(BYTE plane);\r
-\r
- Enables default Read/Write access to a specified plane\r
-\r
-\r
- x_set_splitscreen\r
- -----------------\r
-\r
- C Prototype: extern void x_set_splitscreen(WORD line);\r
-\r
- line - The starting scan line of the required split screen.\r
-\r
- This function activates Mode X split screen and sets starting scan\r
- line. The split screen resides on the bottom half of the screen and has\r
- a starting address of A000:0000 in video RAM.\r
-\r
- It also Updates Page0_Offs to reflect the existence of the split screen\r
- region ie "MainScrnOffset" is set to the offset of the first pixel\r
- beyond the split screen region. Other variable set are "Page1_Offs" which\r
- is set to the same value as "Page0_Offs" (see graphics call sequence\r
- below), "ScrnLogicalHeight","ScrnPhysicalHeight", "SplitScrnScanLine" and\r
- "MaxScrollY".\r
-\r
- This function cannot be called after double buffering has been activated,\r
- it will return an error. To configure your graphics environment the\r
- sequence of graphics calls is as follows although either or both steps b\r
- and c may be omitted:\r
- a) x_set_mode\r
- b) x_set_splitscreen\r
- c) x_set_doublebuffer\r
- Thus when you call this function successfully, double buffering is not\r
- active so "Page1_Offs" is set to the same address as "Page0_Offs".\r
-\r
- WARNING: If you use one of the high resolution modes (376x564 as an\r
- extreme example) you may not have enough video ram for split screen\r
- and double buffering options since VGA video RAM is restricted to\r
- 64K.\r
-\r
- See Also:\r
- What is a Split Screen ?\r
- What is double buffering ?\r
-\r
- x_set_doublebuffer\r
- ------------------\r
-\r
- C Prototype: extern WORD x_set_doublebuffer(WORD PageHeight);\r
-\r
- PageHeight - The height of the two double buffering virtual screens.\r
- Returns - The closest possible height to the specified.\r
-\r
- This function sets up two double buffering virtual pages. 'ErrorValue"\r
- is set according to the success or failure of this command.\r
-\r
- Other variables set are:\r
-\r
- _Page1_Offs Offset of second virtual page\r
- _NonVisual_Offs Offset of first non visible video ram byte\r
- _DoubleBufferActive Flag\r
- _PageAddrTable Table of Double buffering pages start offsets\r
- _ScrnLogicalHeight Logical height of the double buffering pages\r
- _MaxScrollY Max vertical start address of physical screen\r
- within the virtual screen\r
-\r
- WARNING: If you use one of the high resolution modes (376x564 as an\r
- extreme example) you may not have enough video ram for split screen\r
- and double buffering options since VGA video RAM is restricted to\r
- 64K.\r
-\r
- See Also:\r
- What is double buffering ?\r
-\r
- x_hide_splitscreen\r
- ------------------\r
-\r
- C Prototype: extern void x_hide_splitscreen(void);\r
-\r
-\r
- This function hides an existing split screen by setting its starting\r
- scan line to the last physical screen scan line.\r
- "ScreenPhysicalHeight" is adjusted but the "SplitScreenScanLine" is not\r
- altered as it is required for restoring the split screen at a later stage.\r
-\r
- WARNING: Only to be used if SplitScrnLine has been previously called\r
- Disabled for mode 5-11 (320x400-376x564). The memory for\r
- the initial split screen is reserved and the size limitations\r
- of these modes means any change in the split screen scan line\r
- will encroach on the split screen ram\r
- Update: Now disabled for these modes\r
-\r
- See Also:\r
-\r
- What is a split screen ?\r
-\r
- x_show_splitscreen\r
- ------------------\r
-\r
- C Prototype: extern void x_show_splitscreen(void);\r
-\r
- Restores split screen start scan line to the initial split screen\r
- starting scan line as set by "SplitScrnScanLine".\r
- "ScreenPhysicalHeight" is adjusted.\r
-\r
- WARNING: Only to be used if SplitScrnLine has been previously called\r
- Disabled for mode 4-10 (320x400-376x564). The memory for\r
- the initial split screen is reserved and the size limitations\r
- of these modes means any change in the split screen scan line\r
- will encroach on the split screen ram\r
-\r
-\r
- x_adjust_splitscreen\r
- --------------------\r
-\r
- C Prototype: extern void x_adjust_splitscreen(WORD line);\r
-\r
- line - The scan line at which the split screen is to start.\r
-\r
- Sets the split screen start scan line to a new scan line. Valid scan lines\r
- are between the initial split screen starting scan line and the last\r
- physical screen scan line. "ScreenPhysicalHeight" is also adjusted.\r
-\r
- WARNING: Only to be used if SplitScrnLine has been previously called\r
- Disabled for mode 4-10 (320x400-376x564). The memory for\r
- the initial split screen is reserved and the size limitations\r
- of these modes means any change in the split screen scan line\r
- will encroach on the split screen ram\r
-\r
- x_set_start_addr\r
- ----------------\r
-\r
- C Prototype: extern void x_set_start_addr(WORD X,WORD Y);\r
-\r
- X,Y - coordinates of top left corner of physical screen within current\r
- virtual screen.\r
-\r
- Set Mode X non split screen physical start address within current virtual\r
- page.\r
-\r
- X must not exceed (Logical screen width - Physical screen width)\r
- ie "MaxScrollX" and Y must not exceed (Logical screen height -\r
- Physical screen height) ie "MaxScrollY"\r
-\r
- x_page_flip\r
- -----------\r
-\r
- C Prototype: extern void x_page_flip(WORD X,WORD Y);\r
-\r
- X,Y - coordinates of top left corner of physical screen within the\r
- the hidden virtual screen if double buffering is active, or\r
- the current virtual screen otherwise.\r
-\r
- Sets the physical screen start address within currently hidden virtual\r
- page and then flips pages. If double buffering is not active then this\r
- function is functionally equivalent to "x_set_start_addr".\r
-\r
- X must not exceed (Logical screen width - Physical screen width)\r
- ie "MaxScrollX" and Y must not exceed (Logical screen height -\r
- Physical screen height) ie "MaxScrollY"\r
-\r
- x_text_mode\r
- -----------\r
-\r
- C Prototype: extern void x_text_mode(void);\r
-\r
- Disables graphics mode.\r
-\r
- x_set_cliprect\r
- --------------\r
-\r
- C Prototype: extern void x_set_cliprect(WORD left,WORD top,WORD right,\r
- WORD bottom);\r
-\r
- Defines the clipping rectangle for clipping versions of planar and video\r
- bitmap puts.\r
-\r
- NOTE: Compiled bitmaps cannot be clipped.\r
-\r
-\r
---------------------------------------------------------------------------\r
-MODULE XPOINT\r
---------------------------------------------------------------------------\r
-\r
- Point functions all MODE X 256 Color resolutions\r
-\r
- ASM SOURCES\r
-\r
- xpoint.asm xpoint.inc xlib.inc model.inc\r
-\r
- C HEADER FILE\r
-\r
- xpoint.h\r
-\r
- EXPORTED FUNCTIONS\r
-\r
- x_put_pix\r
- ---------\r
-\r
- C Prototype: extern void x_put_pix(WORD X,WORD Y,WORD PageOffset,\r
- WORD Color);\r
-\r
- Draw a point of specified colour at coordinates X,Y\r
- within the virtual page starting at offset PageOffset.\r
-\r
- x_get_pix\r
- ---------\r
-\r
- C Prototype: extern WORD x_get_pix(WORD X, WORD Y, WORD PageBase);\r
-\r
- Read a point of at coordinates X,Y within the virtual page starting\r
- at offset PageOffset.\r
-\r
-\r
---------------------------------------------------------------------------\r
-MODULE XRECT\r
---------------------------------------------------------------------------\r
-\r
- Screen rectangle display and manipulation functions\r
-\r
- ASM SOURCES\r
-\r
- xrect.asm xrect.inc xlib.inc model.inc\r
-\r
- C HEADER FILE\r
-\r
- xrect.h\r
-\r
-\r
- EXPORTED FUNCTIONS\r
-\r
- x_rect_pattern\r
- --------------\r
-\r
- C Prototype: extern void x_rect_pattern(WORD StartX, WORD StartY,\r
- WORD EndX, WORD EndY,\r
- WORD PageBase,BYTE far *Pattern);\r
-\r
- StartX,StartY - Coordinates of upper left hand corner of rectangle\r
- EndX,EndY - Coordinates of lower right hand corner of rectangle\r
- PageBase - Offset of virtual screen\r
- *Pattern - Pointer to the user defined pattern (16 bytes)\r
-\r
-\r
- Mode X rectangle 4x4 pattern fill routine.\r
-\r
- Upper left corner of pattern is always aligned to a multiple-of-4\r
- row and column. Works on all VGAs. Uses approach of copying the\r
- pattern to off-screen display memory, then loading the latches with\r
- the pattern for each scan line and filling each scan line four\r
- pixels at a time. Fills up to but not including the column at EndX\r
- and the row at EndY. No clipping is performed.\r
-\r
- Based on code originally published in DDJ Mag by M. Abrash\r
-\r
- Warning the VGA memory locations PATTERN_BUFFER (A000:FFFc) to\r
- A000:FFFF are reserved for the pattern buffer\r
-\r
-\r
- See Also:\r
- Doctor Dobbs Journal references.\r
-\r
-\r
- x_rect_pattern_clipped\r
- ----------------------\r
-\r
- As above but clipped.\r
-\r
- x_rect_fill\r
- -----------\r
-\r
- C Prototype: extern void x_rect_fill(WORD StartX,WORD StartY,\r
- WORD EndX,WORD EndY,\r
- WORD PageBase,WORD color);\r
-\r
- StartX,StartY - Coordinates of upper left hand corner of rectangle\r
- EndX,EndY - Coordinates of lower right hand corner of rectangle\r
- PageBase - Offset of virtual screen\r
- Color -color to use for fill\r
-\r
- Mode X rectangle solid color fill routine.\r
- Based on code originally published in DDJ Mag by M. Abrash\r
-\r
- See Also:\r
- Doctor Dobbs Journal references.\r
-\r
- x_rect_fill_clipped\r
- -------------------\r
-\r
- as above but clipped.\r
-\r
-\r
- x_cp_vid_rect\r
- -------------\r
-\r
- C Prototype: extern void x_cp_vid_rect(WORD SourceStartX,WORD SourceStartY,\r
- WORD SourceEndX,WORD SourceEndY,\r
- WORD DestStartX,WORD DestStartY,\r
- WORD SourcePageBase,WORD DestPageBase,\r
- WORD SourceBitmapWidth,WORD DestBitmapWidth);\r
-\r
- StartX,StartY- Coordinates of upper left hand corner of source rectangle\r
- EndX,EndY - Coordinates of lower right hand corner of source rectangle\r
- DestStartX,DestStartY - Coordinates of rectangle destination\r
- SourcePageBase - source rectangle page offset\r
- DestPageBase - destination rectangles page offset\r
- SourceBitmapWidth - width of bitmap within the source virtual screen\r
- containing the source rectangle\r
- DestBitmapWidth - width of bitmap within the dest. virtual screen\r
- containing the destination rectangle\r
-\r
- Mode X display memory to display memory copy\r
- routine. Left edge of source rectangle modulo 4 must equal left edge\r
- of destination rectangle modulo 4. Works on all VGAs. Uses approach\r
- of reading 4 pixels at a time from the source into the latches, then\r
- writing the latches to the destination. Copies up to but not\r
- including the column at SrcEndX and the row at SrcEndY. No\r
- clipping is performed. Results are not guaranteed if the source and\r
- destination overlap.\r
-\r
-\r
- Based on code originally published in DDJ Mag by M. Abrash\r
-\r
- See Also:\r
- Doctor Dobbs Journal references.\r
-\r
- x_shift_rect\r
- ------------\r
-\r
- C Prototype:\r
- extern void x_shift_rect (WORD SrcLeft, WORD SrcTop,\r
- WORD SrcRight, WORD SrcBottom,\r
- WORD DestLeft, WORD DestTop, WORD ScreenOffs);\r
-\r
- SrcLeft, SrcTop - Coordinates of upper left hand corner of rectangle\r
- SrcRight, SrcBottom - Coordinates of lower right hand corner of rectangle\r
- DestLeft, DestTop - Coordinates of upper left corner of destination\r
- ScreenOffs - Offset of virtual screen\r
-\r
- This function copies a rectangle of VRAM onto another area of VRAM,\r
- even if the destination overlaps with the source. It is designed\r
- for scrolling text up and down, and for moving large areas of screens\r
- around in tiling systems. It rounds all horizontal coordinates to\r
- the nearest byte (4-column chunk) for the sake of speed. This means\r
- that it can NOT perform smooth horizontal scrolling. For that,\r
- either scroll the whole screen (minus the split screen), or copy\r
- smaller areas through system memory using the functions in the\r
- XPBITMAP module.\r
-\r
- SrcRight is rounded up, and the left edges are rounded down, to\r
- ensure that the pixels pointed to by the arguments are inside the\r
- the rectangle. That is, SrcRight is treated as (SrcRight+3) >> 2,\r
- and SrcLeft as SrcLeft >> 2.\r
-\r
- The width of the rectangle in bytes (width in pixels / 4)\r
- cannot exceed 255.\r
-\r
----------------------------------------------------------------------------\r
-MODULE XPAL\r
----------------------------------------------------------------------------\r
-\r
- Palette functions for VGA 256 color modes.\r
-\r
- All the functions in this module operate on two variations of the\r
- pallete buffer, the raw and annotated buffers.\r
-\r
- All those functions ending in "raw" operate on the following palette\r
- structure:\r
-\r
- BYTE:r0,g0,b0,r1,g1,b1,...rn,gn,bn\r
-\r
- No reference to the starting colour index or number of colours stored\r
- is contained in the structure.\r
-\r
- All those functions ending in "struc" operate on the following palette\r
- structure:\r
-\r
- BYTE:c,BYTE:n,BYTE:r0,g0,b0,r1,g1,b1,...rn,gn,bn\r
-\r
- where c is the starting colour and n is the number of colours stored\r
-\r
-\r
- WARNING: There is no validity checking in these functions. The onus is\r
- on the user to supply valid parameters to the functions.\r
-\r
-\r
- ASM SOURCES\r
-\r
- xpal.asm xpal.inc xlib.inc model.inc\r
-\r
- C HEADER FILE:\r
-\r
- xpal.h\r
-\r
- EXPORTED FUNCTIONS\r
-\r
- x_get_pal_raw\r
- -------------\r
-\r
- C Prototype: extern void x_get_pal_raw(BYTE far * pal,WORD num_colrs,\r
- WORD start_index);\r
-\r
- Read DAC palette into raw buffer with interrupts disabled\r
- ie BYTE r1,g1,b1,r1,g2,b2...rn,gn,bn\r
-\r
- WARNING: Memory for the palette buffers must all be pre-allocated.\r
-\r
- x_get_pal_struc\r
- ---------------\r
-\r
- C Prototype: extern void x_get_pal_struc(BYTE far * pal,WORD num_colrs,\r
- WORD start_index);\r
-\r
- Read DAC palette into annotated type buffer with interrupts disabled\r
- ie BYTE colours to skip, BYTE colours to set, r1,g1,b1,r1,g2,b2...rn,gn,bn\r
-\r
- WARNING: memory for the palette buffers must all be pre-allocated\r
-\r
- x_put_pal_raw\r
- -------------\r
-\r
- C Prototype: extern void x_put_pal_raw(BYTE far * pal,WORD num_colrs,\r
- WORD start_index);\r
-\r
- Write DAC palette from raw buffer with interrupts disabled\r
- ie BYTE r1,g1,b1,r1,g2,b2...rn,gn,bn\r
-\r
- x_put_pal_struc\r
- --------------\r
-\r
- C Prototype: extern void x_put_pal_struc(BYTE far * pal);\r
-\r
- Write DAC palette from annotated type buffer with interrupts disabled\r
- ie BYTE colours to skip, BYTE colours to set, r1,g1,b1,r1,g2,b2...rn,gn,bn\r
-\r
- x_set_rgb\r
- ---------\r
-\r
- C Prototype: extern x_set_rgb(BYTE color,BYTE red_c,BYTE green_c,\r
- BYTE blue_c);\r
-\r
- Set the RGB components of a vga color\r
-\r
- x_rot_pal_struc\r
- ---------------\r
-\r
- C Prototype: extern void x_rot_pal_struc(BYTE far * pal,WORD direction);\r
-\r
- Rotate annotated palette buffer entries. Direction 0 = backward,\r
- 1 = forward.\r
-\r
- x_rot_pal_raw\r
- -------------\r
-\r
- C Prototype: extern x_rot_pal_raw(BYTE far * pal,WORD direction,\r
- WORD num_colrs);\r
-\r
- Rotate a raw palette buffer. Direction 0 = backward,\r
- 1 = forward.\r
-\r
- x_put_contrast_pal_struc\r
- ------------------------\r
-\r
- C Prototype: extern void x_put_contrast_pal_struc(BYTE far * pal,\r
- BYTE intensity);\r
-\r
- Write DAC palette from annotated type buffer with specified intensity\r
- adjustment (ie palette entries are decremented where possible by\r
- "intensity" units).\r
-\r
- Designed for fading in or out a palette without using an intermediate\r
- working palette buffer ! (Slow but memory efficient ... OK for small\r
- pal strucs}\r
-\r
-\r
- x_transpose_pal_struc\r
- ---------------------\r
-\r
- C Prototype: extern void x_transpose_pal_struc(BYTE far * pal,\r
- WORD StartColor);\r
-\r
- Write DAC palette from annotated type buffer with interrupts disabled\r
- starting at a new palette index.\r
-\r
-\r
- x_cpcontrast_pal_struc\r
- ----------------------\r
-\r
- C Prototype: extern WORD x_cpcontrast_pal_struc(BYTE far *src_pal,\r
- BYTE far *dest_pal,BYTE Intensity);\r
-\r
- Copy one annotated palette buffer to another making the intensity\r
- adjustment. Used in fading in and out fast and smoothly.\r
-\r
----------------------------------------------------------------------------\r
-MODULE XLINE\r
----------------------------------------------------------------------------\r
-\r
- Line Drawing functions.\r
-\r
- ASM SOURCES\r
-\r
- xline.asm xline.inc xlib.inc model.inc\r
-\r
- C HEADER FILE\r
-\r
- xline.h\r
-\r
- EXPORTED FUNCTIONS\r
-\r
- x_line\r
- ------\r
-\r
- C Prototype: extern void x_line(WORD x0,WORD y0,WORD x1,WORD y1,\r
- WORD color,WORD PageBase);\r
-\r
- Draw a line with the specified end points in the page starting at\r
- offset "PageBase".\r
-\r
- No Clipping is performed.\r
-\r
----------------------------------------------------------------------------\r
-MODULE XTEXT\r
----------------------------------------------------------------------------\r
-\r
- ASM SOURCES\r
-\r
- xtext.asm xtext.inc xlib.inc model.inc\r
-\r
- C HEADER FILE\r
-\r
- xtext.h\r
-\r
- MACROS\r
-\r
- FONT_8x8 0\r
- FONT_8x15 1\r
- FONT_USER 2\r
-\r
- EXPORTED VARIABLES\r
-\r
- NOTE: All variables are read only. I you modify them the results may\r
- be unpredictable.\r
-\r
- CharHeight - BYTE - Height of current inbuilt character set\r
-\r
- CharWidth - BYTE - Width of current inbuilt character set\r
-\r
- FirstChar - BYTE - First character of current inbuilt character set\r
-\r
- UserCharHeight - BYTE - Height of current user character set\r
-\r
- UserCharWidth - BYTE - Width of current user character set\r
-\r
- UserFirstCh - BYTE - First character of current user character set\r
-\r
-\r
- EXPORTED FUNCTIONS\r
-\r
- x_text_init\r
- -----------\r
-\r
- C Prototype: extern WORD x_text_init(void);\r
-\r
- Initializes the Mode X text driver and sets the default font (VGA ROM 8x8)\r
-\r
- x_set_font\r
- ----------\r
-\r
- C Prototype: extern void x_set_font(WORD FontId);\r
-\r
- Select the working font where 0 = VGA ROM 8x8, 1 = VGA ROM 8x14\r
- 2 = User defined bitmapped font.\r
-\r
- WARNING: A user font must be registered before setting FontID 2\r
-\r
- See Also:\r
-\r
- Defines for this module\r
-\r
- x_register_userfont\r
- -------------------\r
-\r
- C Prototype: extern void x_register_userfont(char far *UserFontPtr);\r
-\r
-\r
- Register a user font for later selection. Only one user font can be\r
- registered at any given time. Registering a user font deregisters the\r
- previous user font. User fonts may be at most 8 pixels wide.\r
-\r
- USER FONT STRUCTURE\r
-\r
- Word: ascii code of first char in font\r
- Byte: Height of chars in font\r
- Byte: Width of chars in font\r
- n*h*Byte: the font data where n = number of chars and h = height\r
- of chars\r
-\r
- WARNING: The onus is on the program to ensure that all characters\r
- drawn whilst this font is active, are within the range of\r
- characters defined.\r
-\r
- x_put_char\r
- ----------\r
-\r
- C Prototype: extern void x_put_char(char ch,WORD X,WORD Y,WORD PgOffs,\r
- WORD Color);\r
-\r
- Draw a text character at the specified location with the specified\r
- color.\r
-\r
- ch - char to draw\r
- x,y - screen coords at which to draw ch\r
- ScrnOffs - Starting offset of page on whih to draw\r
- Color - Color of the text\r
-\r
- WARNING: InitTextDriver must be called before using this function\r
-\r
-\r
- **** NOTE ****\r
-\r
- The file "xprintf.c" implements a printf style formatted output function\r
-\r
- x_printf\r
- --------\r
-\r
- C Prototype: void x_printf(int x,int y,unsigned ScrnOffs,int color,\r
- char *ln,...);\r
-\r
- x,y - screen coords at which to draw ch\r
- ScrnOffs - Starting offset of page on whih to draw\r
- Color - Color of the text\r
-\r
- Parameters beyond Color conform to the standard printf parameters.\r
-\r
- x_bgprintf\r
- ----------\r
-\r
- C Prototype: void x_bgprintf(int x,int y,unsigned ScrnOffs,int fgcolor,\r
- int bgcolor, char *ln,...);\r
-\r
- x,y - screen coords at which to draw ch\r
- ScrnOffs - Starting offset of page on whih to draw\r
- fgcolor - Color of the text foreground\r
- bgcolor - Color of the text background\r
-\r
- Parameters beyond bgolor conform to the standard printf parameters.\r
-\r
-\r
- x_get_char_width\r
- ----------------\r
-\r
- C Prototype: unsigned int x_get_char_width(char ch)\r
-\r
- ch - character to get width of\r
-\r
---------------------------------------------------------------------------\r
-MODULE XPBITMAP\r
---------------------------------------------------------------------------\r
-\r
- This module implements a set of functions to operate on planar bitmaps.\r
- Planar bitmaps as used by these functions have the following structure:\r
-\r
- BYTE 0 The bitmap width in bytes (4 pixel groups) range 1..255\r
- BYTE 1 The bitmap height in rows range 1..255\r
- BYTE 2..n1 The plane 0 pixels width*height bytes\r
- BYTE n1..n2 The plane 1 pixels width*height bytes\r
- BYTE n2..n3 The plane 2 pixels width*height bytes\r
- BYTE n3..n4 The plane 3 pixels width*height bytes\r
-\r
- These functions provide the fastest possible bitmap blts from system ram to\r
- to video and further, the single bitmap is applicable to all pixel\r
- allignments. The masked functions do not need separate masks since all non\r
- zero pixels are considered to be masking pixels, hence if a pixel is 0 the\r
- corresponding screen destination pixel is left unchanged.\r
-\r
-\r
- ASM SOURCES\r
-\r
- xpbitmap.asm xpbitmap.inc xlib.inc model.inc\r
-\r
- C HEADER FILE\r
-\r
- xpbitmap.h\r
-\r
- EXPORT FUNCTIONS\r
-\r
- x_put_masked_pbm\r
- ----------------\r
-\r
- C Prototype: extern void x_put_masked_pbm(WORD X,WORD Y,WORD ScrnOffs,\r
- BYTE far * Bitmap);\r
-\r
- Mask write a planar bitmap from system ram to video ram. All zero source\r
- bitmap bytes indicate destination byte to be left unchanged.\r
-\r
- Source Bitmap structure:\r
-\r
- Width:byte, Height:byte, Bitmap data (plane 0)...Bitmap data (plane 1)..,\r
- Bitmap data (plane 2)..,Bitmap data (plane 3)..\r
-\r
- NOTE: width is in bytes ie lots of 4 pixels\r
-\r
- LIMITATIONS: No clipping is supported\r
- Only supports bitmaps with widths which are a multiple of\r
- 4 pixels\r
-\r
- See Also: XBMTOOLS module for linear <-> planar bitmap conversion\r
- functions.\r
-\r
- x_put_pbm\r
- ---------\r
-\r
- C Prototype: extern void x_put_pbm(WORD X, WORD Y, WORD ScrnOffs,\r
- BYTE far * Bitmap);\r
-\r
- Write a planar bitmap from system ram to video ram.\r
-\r
- Source Bitmap structure:\r
-\r
- Width:byte, Height:byte, Bitmap data (plane 0)...Bitmap data (plane 1)..,\r
- Bitmap data (plane 2)..,Bitmap data (plane 3)..\r
-\r
- NOTE: width is in bytes ie lots of 4 pixels\r
-\r
- LIMITATIONS: No clipping is supported\r
- Only supports bitmaps with widths which are a multiple of\r
- 4 pixels\r
-\r
-\r
- See Also: XBMTOOLS module for linear <-> planar bitmap conversion\r
- functions.\r
-\r
- x_get_pbm\r
- ---------\r
-\r
- C Prototype: extern void x_get_pbm(WORD X, WORD Y,BYTE Bw,BYTE Bh,\r
- WORD ScrnOffs, BYTE far * Bitmap);\r
-\r
- Read a planar bitmap to system ram from video ram.\r
-\r
- Source Bitmap structure:\r
-\r
- Width:byte, Height:byte, Bitmap data (plane 0)...Bitmap data (plane 1)..,\r
- Bitmap data (plane 2)..,Bitmap data (plane 3)..\r
-\r
- NOTE: width is in bytes ie lots of 4 pixels\r
-\r
- LIMITATIONS: No clipping is supported\r
- Only supports bitmaps with widths which are a multiple of\r
- 4 pixels\r
-\r
-\r
- See Also: XBMTOOLS module for linear <-> planar bitmap conversion\r
- functions.\r
-\r
---------------------------------------------------------------------------\r
-MODULE XPBMCLIP\r
---------------------------------------------------------------------------\r
-\r
- This module implements a similar set of functions to operate on planar\r
- bitmaps as "XPBITMAP" but incorporates clipping to a user defined\r
- clipping rectangle (which is set by "x_set_cliprect" in module xmain).\r
-\r
- The planar bitmap format is identical to the above module\r
-\r
- There are three variations of the functions in XPBITMAP in this module\r
- identified by the three function name extensions: _clipx, _clipy _clipxy.\r
- Because speed is critical in games programming you do not want to be\r
- checking for clipping if not necessary thus for sprites that move only\r
- horizontally you would use the _clipx version of the put function,\r
- for sprites that move vertically you would use the _clipy version and for\r
- sprites that move both directions you would use the clipxy version.\r
- Keep in mind also that the clipping components of these functions assume\r
- that the clipping rectangle is equal to or larger than the size of the\r
- bitmap ie. if a bitmap is top clipped, it is assumed that the bitmap's\r
- bottom is not also clipped. Similarly with horizontal clipping.\r
-\r
- Note: performance in decreasing order is as follows.\r
- _clipy,_clipx,_clipxy with masked puts being slower than unmasked\r
- puts\r
-\r
- Horizontal clipping is performed to byte boundaries (4 pixels) rather than\r
- pixels. This allows for the fastest implementation of the functions. It is\r
- not such a handicap because for one, your screen width a multiple of 4\r
- pixels wide and for most purposes it is the screen edges that form the\r
- clipping rectangle.\r
-\r
- Following is an example of setting a clipping rectangle to the logical\r
- screen edges:\r
-\r
- x_set_cliprect(0,0,ScrnLogicalByteWidth,ScrnLogicalHeight)\r
-\r
- NOTE: the functions now return a value;\r
- 1 if clipped image is fully clipped (ie no portion of it\r
- appears on the screen) otherwise it returns 0\r
-\r
-\r
- ASM SOURCES\r
-\r
- xpbmclip.asm xpbmclip.inc xlib.inc model.inc\r
-\r
- C HEADER FILE\r
-\r
- xpbmclip.h\r
-\r
- EXPORT FUNCTIONS\r
-\r
- x_put_pbm_clipx\r
- ---------------\r
- x_put_pbm_clipy\r
- ---------------\r
- x_put_pbm_clipxy\r
- ----------------\r
- x_put_masked_pbm_clipx\r
- ----------------------\r
- x_put_masked_pbm_clipy\r
- ----------------------\r
- x_put_masked_pbm_clipxy\r
- -----------------------\r
-\r
- For a detailed description of parameters etc. see equivalent functions\r
- in module "XPBITMAP".\r
-\r
-\r
---------------------------------------------------------------------------\r
-MODULE XCBITMAP\r
---------------------------------------------------------------------------\r
-\r
- XCBITMAP:\r
- The Care and Feeding of Compiled Masked Blits\r
- by Matthew MacKenzie\r
-\r
-The XCBITMAP module of the Xlib library is made up of the files\r
-XCBITMAP.ASM, XCBITMAP.INC, and XCBITMAP.H.\r
-\r
-The XCBITMAP module is small, containing only three procedures:\r
- o x_compile_bitmap compiles your bitmap into native code which writes\r
- to the VGA screen in an X mode.\r
- o x_put_cbitmap converts X and Y coordinates into a location on the\r
- screen, sets up the necessary VGA registers, and executes the compiled\r
- bitmap as a subroutine.\r
- o x_sizeof_cbitmap takes a planar bitmap and returns an integer equal to\r
- the size of the compiled bitmap which the planar bitmap would produce.\r
- It is essentially a lobotomized version of x_compile_bitmap, with all\r
- the code generation replaced with a size counter.\r
-\r
- x_compile_bitmap scans through a source bitmap and generates 8086\r
-instructions to plot every nonzero pixel. It is designed to be used\r
-before the action begins rather than on-the-fly. The compiled bitmap\r
-contains no branches, and no reference to the zero (transparent) pixels.\r
-Where two pixels are exactly four columns apart they are plotted with a\r
-single 16-bit store, and the VGA MAP_MASK register will be set at most\r
-four times. As a result your bitmap may run several times faster than a\r
-traditional memory-to-VGA masked blit routine.\r
- There is no way to perform clipping on these bitmaps, or to plot a\r
-pixel of color zero.\r
- x_compile_bitmap works with bitmaps in the standard Xlib planar bitmap\r
-format. On a time scale of 60 frames per second, it is actually relatively\r
-slow. Since a compiled bitmap is relocatable you may just want to have it\r
-saved to disk, and not include the source bitmap in your program at all.\r
- The source bitmap format is an array of bytes, a little like this:\r
-\r
-char eye[] ={4, 7, /* four byte columns across, seven rows tall */\r
- 0, 0, 0, 0, 9, 1, 1, 1, 9, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 9, 9, 1, 1, 1, 4, 4, 9, 9, 0, 0, 0, 0, 0,\r
- 0, 9, 9, 1, 2, 0, 0, 4, 4, 1, 9, 9, 0, 0, 0, 0,\r
- 9, 9, 9, 1, 0, 0, 0, 0, 1, 1, 9, 9, 9, 0, 0, 0,\r
- 0, 9, 9, 1, 2, 0, 0, 2, 1, 1, 9, 9, 0, 0, 0, 0,\r
- 0, 0, 9, 9, 1, 1, 1, 1, 1, 9, 9, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 9, 1, 1, 1, 9, 0, 0, 0, 0, 0, 0, 0};\r
-\r
- This is actually a linear bitmap, which is the wrong format for\r
-compilation, but is easier on human eyes. Use the module XBMTOOLS to\r
-convert linear bitmaps into planar bitmaps, and vice-versa.\r
- To compile this image for a mode 360 pixels (90 byte columns) across:\r
-\r
-char planar_eye[4*7 + 2];\r
-char far * EyeSize;\r
-\r
-(void) x_bm_to_pbm((char far *) eye, (char far *) planar_eye);\r
-EyeSize = x_sizeof_cbitmap((far char *) planar_eye);\r
-CompiledEye = farmalloc(EyeSize);\r
-(void) x_compile_bitmap(90, (far char *) planar_eye, CompiledEye);\r
-\r
- Notice that both buffers must exist beforehand. Since x_compile_bitmap\r
-returns the size of the compiled code, in bytes, you can reallocate the\r
-bitmap immediately to the right size if using x_sizeof_xbitmap seems\r
-inconvenient (reallocation may even be faster, though using the function is\r
-cleaner). The pointers are 32-bit because compiled bitmaps take so much\r
-space: they are at one end of the speed-versus-memory spectrum. A good\r
-rule of thumb is to allocate (3.5 x buffer-height x buffer-width) + 25\r
-bytes (rounding up ;-), then pare your bitmap down when you find out how\r
-much space you've actually used.\r
- Since the compiled bitmap has to fit within one segment of memory, it\r
-cannot contain more than about 19,000 pixels. This will not be a\r
-limitation for most sane programmers. If you are not a sane programmer try\r
-splitting your huge, unwieldy image up into smaller parts -- you can use\r
-the same gigantic bitmap if you divide it into horizontal slices for\r
-compilation. For that matter, dividing the source up that way will let\r
-you use a source bitmap large than 64K, which is an even sicker idea...\r
- Back to business. A bitmap is compiled for only one width of screen.\r
-If you are using a logical screen larger than your physical screen, call\r
-the bitmap compiler with the logical width -- the important thing is the\r
-number of bytes per line. Notice that you do not have to be in a graphics\r
-mode to use this routine. This allows you to develop and compile bitmaps\r
-separately, with whatever utility programs you might cook up.\r
-\r
- The final function is x_put_cbitmap. To plot our eye at (99,4), on\r
-the page which starts at location 0:\r
-x_put_cbitmap(99, 4, 0, CompiledEye);\r
- This function depends on the global variable ScrnLogicalByteWidth from\r
-the module XMAIN, which should be the same number as the column parameter\r
-you used to compile your bitmap.\r
- The XCBITMAP module supports memory-to-VGA blits only. Xlib also\r
-includes non-masking routines which can quickly save and restore the\r
-background screen behind your bitmap, using fast string operations.\r
-\r
- This module is part of the Xlib package, and is in the public domain.\r
-If you write something which uses it, though, please send me a copy as a\r
-courtesy -- if for no other reason so I can tilt my chair back and reflect\r
-that it may have been worth the trouble after all.\r
-\r
-The included program DEMO2.C demonstrates the performance difference\r
-between planar bitmap masked blits and compiled bitmap blits.\r
-\r
---------------------------------------------------------------------------\r
-MODULE XCOMPPBM\r
---------------------------------------------------------------------------\r
-\r
-Identical to XCBITMAP except that the source bitmaps are the PBM form\r
-rather than LBM.\r
-\r
-FUNCTIONS\r
-\r
-x_compile_pbm\r
--------------\r
-x_sizeof_cpbm\r
--------------\r
-\r
-See XCBITMAP module\r
-\r
---------------------------------------------------------------------------\r
-MODULE XVBITMAP\r
---------------------------------------------------------------------------\r
-\r
-The XVBITMAP module implements yet another type of bitmap to complement\r
-planar and compiled bitmaps, VRAM based bitmaps. If a 4 cylinder car is\r
-analagous to planar bitmaps, that is thrifty on memory consumption but low\r
-performance and and a V8 is analagous to Compiled bitmaps, memory guzzlers\r
-that really fly, then VRAM based bitmaps are the 6 cylinder modest performers\r
-with acceptable memory consumption.\r
-\r
-To summarise their selling points, VBM's are moderately fast with fair memory\r
-consumption, and unlike compiled bitmaps, can be clipped. The disadvantages\r
-are that they are limited by the amount of free video ram and have a complex\r
-structure.\r
-\r
-The VRAM bitmap format is rather complex consisting of components stored in\r
-video ram and components in system ram working together. This complexity\r
-necessitates the existence of a creation function "x_make_vbm" which takes\r
-an input linear bitmap and generates the equivalent VBM (VRAM Bit Map).\r
-\r
-VBM structure:\r
-\r
- WORD 0 Size Total size of this VBM structure in bytes\r
- WORD 1 ImageWidth Width in bytes of the image (for all alignments)\r
- WORD 2 ImageHeight Height in scan lines of the image\r
-\r
- WORD 3 Alignment 0 ImagePtr Offset in VidRAM of this aligned image\r
- +--WORD 4 MaskPtr Offset (within this structure's DS) of\r
- | . alignment masks\r
- | .\r
- | .\r
- | WORD 9 Alignment 3 ImagePtr Offset in VidRAM of this aligned image\r
- +|--WORD 10 MaskPtr Offset (within this structure's DS) of\r
- || alignment masks\r
- ||\r
- |+->BYTE 21 (WORD 11) -------+-- Image masks for alignment 0\r
- | . |\r
- | . |\r
- | BYTE 21 + ImageWidth*ImageHeight -----+\r
- |\r
- | .\r
- | . (similaly for alignments 1 - 2 )\r
- | .\r
- |\r
- +-->BYTE 21 + 3*ImageWidth*ImageHeight + 1-+-- Image masks for alignment 3\r
- . |\r
- . |\r
- BYTE 21 + 4*(ImageWidth*ImageHeight) --+\r
-\r
- .\r
- .\r
- << Similarly for alignments 2 and 3 >>\r
- .\r
- .\r
- BYTE 21 + 4*(ImageWidth*ImageHeight)\r
- -------------\r
-\r
- (And dont forget the corresponding data in video ram)\r
-\r
-You can see for yourself the complexity of this bitmap format. The image\r
-is stored in video ram in its 4 different alignments with pointers to these\r
-alignments in the VBM. Similarly there are 4 alignments of the corresponding\r
-masks within the VBM itself (towards the end). The mask bytes contain the\r
-plane settings for the corresponding video bytes so that one memory move can\r
-move up to 4 pixels at a time (depending on the mask settings) using the\r
-VGA's latches, theoretically giving you a 4x speed improvement over\r
-conventional blits like the ones implemented in "XPBITMAP". In actual fact\r
-its anywhere between 2 and 3 due to incurred overheads.\r
-\r
-These bitmaps are more difficult to store in files than PBM'S and CBM's but\r
-still posible with a bit of work, so do not dismiss these as too difficult\r
-to use. Consider all the bitmap formats carefully before deciding on which\r
-to use. There may even be situations that a careful application of all three\r
-types would be most effective ie. compiled bitmaps for Background tiles and\r
-the main game character (which never need clipping), VRAM based bitmaps for\r
-the most frequently occuring (oponent, alien etc) characters which get\r
-clipped as they come into and leave your current location and planar bitmaps\r
-for smaller or less frequently encountered characters.\r
-\r
-ASM SOURCES\r
-\r
- xvbitmap.asm xvbitmap.inc xlib.inc model.inc\r
- xmakevbm.c - Additional C module implementing creation function\r
-\r
- C HEADER FILE\r
-\r
- xvbitmap.h\r
-\r
- EXPORTED FUNCTIONS\r
-\r
- x_make_vbm\r
- ----------\r
-\r
- C Prototype: extern char far * x_make_vbm(char far *lbm, WORD *VramStart);\r
-\r
- Create the VBM from the given linear bitmap and place the image alignments\r
- in video ram starting at the offset in the variable pointed to by\r
- "VramStart". "VramStart" is then updated to point to the next free VRAM byte\r
- (just after the last byte of the image alignments). Usually you will point\r
- "VramStart" to "NonVisual_Offs".\r
-\r
- lbm Pointer to the input linear bitmap\r
- VramStart Pointer to variable containing Offset of first free VRAM byte\r
-\r
- x_put_masked_vbm\r
- ----------------\r
-\r
- C Prototype: extern int x_put_masked_vbm(int X, int Y, WORD ScrnOffs,\r
- BYTE far * VBitmap);\r
-\r
- Draw a VRAM based bitmap at (X,Y) relative to the screen with starting\r
- offset "ScrnOffs".\r
-\r
- Returns 1 if clipped image is fully clipped (ie no portion of it\r
- appears on the screen) otherwise it returns 0\r
-\r
- x_put_masked_vbm_clipx\r
- ----------------------\r
- x_put_masked_vbm_clipy\r
- ----------------------\r
- x_put_masked_vbm_clipxy\r
- -----------------------\r
-\r
- Clipping versions of "x_put_masked_vbm".\r
-\r
- See XPBMCLIP for more details on the type of clipping used as it is\r
- identical to XVBITMAP.\r
-\r
---------------------------------------------------------------------------\r
-MODULE XMOUSE\r
---------------------------------------------------------------------------\r
-The XMOUSE module implements very basic mouse handling functions. The way\r
-in which it operates is by installing an event handler function during\r
-initialization which subsequently intercepts and processes mouse events and\r
-automatically updates status variables such as mouse position and button\r
-pressed status. It does not support the full functionality of:\r
-\r
- SPLIT SCREENS\r
- SCROLLED WINDOWS\r
- VIRTUAL WINDOWS\r
-\r
-This was done to primarily prevent unecessary impedences to performance,\r
-since the mouse handler function has the potential to degrade performance.\r
-It also saves me alot of coding which I was too lazy to do.\r
-\r
-Programs communicate with the mouse driver as with other devices, through\r
-an interrupt vector namely 33h. On generating an interrupt, the mouse driver\r
-expects a function number in AX and possibly other parameters in other\r
-registers and returns information via the registers. A brief description\r
-of the mouse functions follows:\r
-\r
- --------------------------------------\r
-\r
- MS Mouse Driver Functions\r
-\r
- Mouse Initialization 0\r
- Show Cursor 1\r
- Hide Cursor 2\r
- Get Mouse Position & Button Status 3\r
- Set Mouse Cursor Position 4\r
- Get Button Press Information 5\r
- Get Button Release Information 6\r
- Set Min/Max Horizontal Position 7\r
- Set Min/Max Vertical Position 8\r
- Define Graphics Cursor Block 9\r
- Define Text Cursor 10\r
- Read Mouse Motion Counters 11\r
- Define Event Handler 12\r
- Light Pen Emulation Mode ON 13\r
- Light Pen Emulation Mode OFF 14\r
- Set Mouse Mickey/Pixel Ratio 15\r
- Conditional Hide Cursor 16\r
- Set Double-Speed Threshold 19\r
- --------------------------------------\r
-\r
-In practice only afew of these functions are used and even fewer when the\r
-mouse status is monitored by an event handler function such as is used in\r
-this module.\r
-\r
-The most important thing to note when using the mouse module is that the\r
-mouse event handler must be removed before exiting the program. It is a good\r
-idea to have an exit function (see the C "atexit" function) and include the\r
-line "x_mouse_remove();" along with any other pre-exit cleanup code.\r
-\r
-\r
- ASM SOURCES\r
-\r
- xmouse.asm xlib.inc model.inc\r
-\r
- C HEADER FILE\r
-\r
- xmouse.h\r
-\r
- EXPORTED VARIABLES\r
-\r
- MouseInstalled - WORD - Indicates whether mouse handler installed\r
- MouseHidden - WORD - Indicates whether mouse cursor is hidden\r
- MouseButtonStatus - WORD - Holds the mouse button status\r
- MouseX - WORD - Current X position of mouse cursor\r
- MouseY - WORD - Current Y position of mouse cursor\r
- MouseFrozen - WORD - Disallows position updates if TRUE\r
- MouseColor - BYTE - The mouse cursors colour\r
-\r
- EXPORTED FUNCTIONS\r
-\r
- x_mouse_init\r
- ------------\r
-\r
- C Prototype: int x_mouse_init()\r
-\r
- Initialize the mouse driver functions and install the mouse event handler\r
- function. This is the first function you must call before using any of the\r
- mouse functions. This mouse code uses the fastest possible techniques to\r
- save and restore mouse backgrounds and to draw the mouse cursor.\r
-\r
- WARNING: This function uses and updates "NonVisual_Offset" to allocate\r
- video ram for the saved mouse background.\r
-\r
- LIMITATIONS: No clipping is supported horizontally for the mouse cursor\r
- No validity checking is performed for NonVisual_Offs\r
-\r
- **WARNING** You must Hide or at least Freeze the mouse cursor while drawing\r
- using any of the other XLIB modules since the mouse handler may\r
- modify vga register settings at any time. VGA register settings\r
- are not preserved which will result in unpredictable drawing\r
- behavior. If you know the drawing will occur away from the\r
- mouse cursor set MouseFrozen to TRUE (1), do your drawing\r
- then set it to FALSE (0). Alternatively call "x_hide_mouse",\r
- perform your drawing and then call "x_show_mouse". Another\r
- alternative is to disable interrupts while drawing but usually\r
- drawing takes up alot of time and having interrupts disabled\r
- for too long is not a good idea.\r
-\r
- x_define_mouse_cursor\r
- ---------------------\r
-\r
- C Prototype:\r
- void x_define_mouse_cursor(char far *MouseDef, unsigned char MouseColor)\r
-\r
- MouseDef - a pointer to 14 characters containing a bitmask for all the\r
- cursor's rows.\r
- MouseColor - The colour to use when drawing the mouse cursor.\r
-\r
- Define a mouse cursor shape for use in subsequent cursor redraws. XMouse\r
- has a hardwired mouse cursor size of 8 pixels across by 14 pixels down.\r
-\r
- WARNING: This function assumes MouseDef points to 14 bytes.\r
-\r
- Note: Bit order is in reverse. ie bit 7 represents pixel 0 ..\r
- bit 0 represents pixel 7 in each "MouseDef" byte.\r
-\r
- x_show_mouse\r
- ------------\r
-\r
- C Prototype: void x_show_mouse()\r
-\r
- Makes the cursor visible if it was previously hidden.\r
- See Also: "x_hide_mouse".\r
-\r
- x_hide_mouse\r
- ------------\r
-\r
- C Prototype: void x_hide_mouse()\r
-\r
- Makes the cursor hidden if it was previously visible.\r
- See Also: "x_show_mouse".\r
-\r
- x_mouse_remove\r
- --------------\r
-\r
- C Prototype: void x_mouse_remove()\r
-\r
- Stop mouse event handling and remove the mouse handler.\r
-\r
- NOTE: This function MUST be called before quitting the program if\r
- a mouse handler has been installed\r
-\r
- x_position_mouse\r
- ----------------\r
-\r
- C Prototype void x_position_mouse(int x, int y)\r
-\r
- Positions the mouse cursor at the specified location\r
-\r
- x_mouse_window\r
- ------------\r
-\r
- C Prototype: void x_mouse_window(int x0, int y0, int x1, int y1)\r
-\r
- Defines a mouse window.\r
-\r
- x_update_mouse\r
- --------------\r
-\r
- C Prototype: void x_update_mouse()\r
-\r
- Forces the mouse position to be updated and cursor to be redrawn.\r
- Note: this function is useful when you have set "MouseFrozen" to true.\r
- Allows the cursor position to be updated manually rather than\r
- automatically by the installed handler.\r
-\r
-\r
---------------------------------------------------------------------------\r
-MODULE XBMTOOLS\r
---------------------------------------------------------------------------\r
-\r
- This module implements a set of functions to convert between planar\r
- bitmaps and linear bitmaps.\r
-\r
- PLANAR BITMAPS\r
-\r
- Planar bitmaps as used by these functions have the following structure:\r
-\r
- BYTE 0 The bitmap width in bytes (4 pixel groups) range 1..255\r
- BYTE 1 The bitmap height in rows range 1..255\r
- BYTE 2..n1 The plane 0 pixels width*height bytes\r
- BYTE n1..n2 The plane 1 pixels width*height bytes\r
- BYTE n2..n3 The plane 2 pixels width*height bytes\r
- BYTE n3..n4 The plane 3 pixels width*height bytes\r
-\r
- as used by x_put_pbm, x_get_pbm, x_put_masked_pbm.\r
-\r
- LINEAR BITMAPS\r
-\r
- Linear bitmaps have the following structure:\r
-\r
- BYTE 0 The bitmap width in pixels range 1..255\r
- BYTE 1 The bitmap height in rows range 1..255\r
- BYTE 2..n The width*height bytes of the bitmap\r
-\r
- ASM SOURCES\r
-\r
- xbmtools.asm xpbmtools.inc model.inc\r
-\r
- C HEADER FILE\r
-\r
- xbmtools.h\r
-\r
- MACROS\r
-\r
- BM_WIDTH_ERROR\r
-\r
- LBMHeight(lbitmap) - Height of linear bitmap "lbitmap"\r
- LBMWidth(lbitmap) - Width of linear bitmap "lbitmap"\r
- PBMHeight(pbitmap) - Height of planar bitmap "pbitmap"\r
- PBMWidth(pbitmap) - Width of planar bitmap "pbitmap"\r
-\r
- LBMPutPix(x,y,lbitmap,color) - set pixel (x,y) colour in linear bitmap\r
- LBMGetPix(x,y,lbitmap) - colour of pixel (x,y) in linear bitmap\r
-\r
- EXPORT FUNCTIONS\r
-\r
- x_pbm_to_bm\r
- ------------\r
- C Prototype: extern int x_pbm_to_bm(char far * source_pbm,\r
- char far * dest_bm);\r
-\r
- This function converts a bitmap in the planar format to the linear format\r
- as used by x_compile_bitmap.\r
-\r
- WARNING: the source and destination bitmaps must be pre - allocated\r
-\r
- NOTE: This function can only convert planar bitmaps that are suitable.\r
- If the source planar bitmap's width (per plane) is >= 256/4\r
- it cannot be converted. In this situation an error code\r
- BM_WIDTH_ERROR. On successful conversion 0 is returned.\r
-\r
- x_bm_to_pbm\r
- ------------\r
- C Prototype: extern int x_bm_to_pbm(char far * source_pbm,\r
- char far * dest_bm);\r
-\r
- This function converts a bitmap in the linear format as used by\r
- x_compile_bitmap to the planar formap.\r
-\r
- WARNING: the source and destination bitmaps must be pre - allocated\r
-\r
- NOTE: This function can only convert linear bitmaps that are suitable.\r
- If the source linear bitmap's width is not a multiple of 4\r
- it cannot be converted. In this situation an error code\r
- BM_WIDTH_ERROR. On successful conversion 0 is returned.\r
-\r
+++ /dev/null
-PART 2 of 2\r
------------------------------------------------------------------------------\r
-\r
- ********* XLIB - Mode X graphics library ****************\r
- ********* ****************\r
- ********* Written By Themie Gouthas ****************\r
- ********* ****************\r
- ********* egg@dstos3.dsto.gov.au ****************\r
- ********* teg@bart.dsto.gov.au ****************\r
-\r
- Some of the code in this library has been contributed by :\r
-\r
- Matthew MacKenzie - matm@eng.umd.edu\r
-\r
- and others. See individual modules.\r
-\r
- I informally reserve all rights to the code in XLIB\r
- Rights to contributed code is also assumed to be reserved by\r
- the original authors.\r
------------------------------------------------------------------------------\r
-MODULE XCLIPPBM note: VERY SIMILAR to XPBMCLIP\r
-This module implements blits of clipped planar bitmaps. Blits are\r
-clipped to pixels, both horizontally. This makes the unmasked blit\r
-function here slightly slower than the equivalent functions in the\r
-XPBMCLIP module.\r
---------------------------------------------------------------------------\r
- XCLIPPBM:\r
- Blits and Pieces\r
- by Matthew MacKenzie\r
-\r
-The XCLIPPBM module contains clipping versions of two of the three routines\r
-in the XPBITMAP module:\r
- o x_clip_pbm transfers a planar bitmap to the screen, clipping off any\r
- part outside a bounding box.\r
- o x_clip_masked_pbm does the same thing, but transfers only nonzero\r
- pixels.\r
-\r
- The planar bitmap format is described elsewhere. Here we will look at\r
-the clipping itself, since it is the only distinguishing feature of this\r
-module.\r
- The bounding box is made up of four integers, TopBound, BottomBound,\r
-LeftBound, and RightBound. Unlike most global variables in Xlib, these are\r
-meant to be written to. In fact, they start out uninitialized. Be sure to\r
-set them before you try plotting any clipped bitmaps.\r
- Note that these are not the same variables which are used in the other\r
-clipping modules in Xlib. This is because the two systems are incompatible:\r
-the other modules clip horizontally to columns while this one clips to\r
-pixels. As you might have guessed, those functions and these were developed\r
-in different hemispheres of the planet...\r
- If it's any consolation, this does give you two independent\r
-bounding boxes to futz with, should the mood visit you.\r
- Bitmaps cannot go outside the perimeter of the bounding box, but they\r
-can overlap it. If TopBound equals BottomBound, for example, a horizontal\r
-slice of a bitmap may still be plotted. It is safe to turn the box "inside\r
-out" to make sure nothing will be plotted -- this is the first thing each\r
-routine checks for.\r
- To plot a bitmap, minus its zero pixels, minus anything outside the\r
-bounding box:\r
-\r
-x_clip_masked_pbm (int X, int Y, int ScreenOffs, char far * Bitmap);\r
-\r
- The arguments are in the same order as those for x_put_masked_pbm in\r
-the module XPBITMAP. The bounding box is relative to the given\r
-ScreenOffs(et). This lets you perform page flipping without worrying about\r
-what screen you are clipping to -- it's always the current screen. The\r
-bitmap itself, of course, is not affected; clipping is performed on-the-\r
-fly. Both functions return an integer which indicates whether any part\r
-of the bitmap was inside the bounding box. If the entire bitmap was\r
-outside, a 1 is returned; otherwise, a 0.\r
- The third function in XPBITMAP, for which this module has no\r
-equivalent, copies from video RAM to system RAM. The absence of such a\r
-routine may seem at first like a disadvantage -- but this, like so many\r
-things in this life, is an illusion. You can use the unclipped routine,\r
-and clip the bitmap when you want to plot it back onto the screen.\r
-\r
- ASM SOURCES\r
-\r
- xclippbm.asm xclippbm.inc xlib.inc model.inc\r
-\r
- C HEADER FILE\r
-\r
- xclippbm.h\r
-\r
- EXPORTED VARIABLES\r
-\r
- TopBound - int\r
- BottomBound - int\r
- LeftBound - int\r
- RightBound - int\r
-\r
- EXPORTED FUNCTIONS\r
-\r
- x_clip_pbm\r
- ----------\r
- C Prototype: extern int x_clip_pbm (int X, int Y, int ScreenOffs, char\r
- far * Bitmap);\r
-\r
- Copies a planar bitmap from SRAM to VRAM, with clipping. If the entire\r
- bitmap turns out to be outside the bounding box, this function returns\r
- a 1; otherwise it returns a 0.\r
-\r
- x_clip_masked_pbm\r
- -----------------\r
- C Prototype: extern int x_clip_masked_pbm (int X, int Y,\r
- int ScreenOffs, char far * Bitmap);\r
-\r
- Copies a planar bitmap from SRAM to VRAM, with clipping -- 0 bytes\r
- in the bitmap are not copied. If the entire bitmap turns out to be\r
- outside the bounding box, this function returns a 1; otherwise,\r
- it returns a 0.\r
-\r
-\r
---------------------------------------------------------------------------\r
-MODULE XMOUSE\r
---------------------------------------------------------------------------\r
-The XMOUSE module implements very basic mouse handling functions. The way\r
-in which it operates is by installing an event handler function during\r
-initialization which subsequently intercepts and processes mouse events and\r
-automatically updates status variables such as mouse position and button\r
-pressed status. It does not support the full functionality of:\r
-\r
- SPLIT SCREENS\r
- SCROLLED WINDOWS\r
- VIRTUAL WINDOWS\r
-\r
-This was done to primarily prevent unecessary impedences to performance,\r
-since the mouse handler function has the potential to degrade performance.\r
-It also saves me alot of coding which I was too lazy to do.\r
-\r
-Programs communicate with the mouse driver as with other devices, through\r
-an interrupt vector namely 33h. On generating an interrupt, the mouse driver\r
-expects a function number in AX and possibly other parameters in other\r
-registers and returns information via the registers. A brief description\r
-of the mouse functions follows:\r
-\r
- --------------------------------------\r
-\r
- MS Mouse Driver Functions\r
-\r
- Mouse Initialization 0\r
- Show Cursor 1\r
- Hide Cursor 2\r
- Get Mouse Position & Button Status 3\r
- Set Mouse Cursor Position 4\r
- Get Button Press Information 5\r
- Get Button Release Information 6\r
- Set Min/Max Horizontal Position 7\r
- Set Min/Max Vertical Position 8\r
- Define Graphics Cursor Block 9\r
- Define Text Cursor 10\r
- Read Mouse Motion Counters 11\r
- Define Event Handler 12\r
- Light Pen Emulation Mode ON 13\r
- Light Pen Emulation Mode OFF 14\r
- Set Mouse Mickey/Pixel Ratio 15\r
- Conditional Hide Cursor 16\r
- Set Double-Speed Threshold 19\r
- --------------------------------------\r
-\r
-In practice only afew of these functions are used and even fewer when the\r
-mouse status is monitored by an event handler function such as is used in\r
-this module.\r
-\r
-The most important thing to note when using the mouse module is that the\r
-mouse event handler must be removed before exiting the program. It is a good\r
-idea to have an exit function (see the C "atexit" function) and include the\r
-line "x_mouse_remove();" along with any other pre-exit cleanup code.\r
-\r
-See also: XDETECT for mouse detection.\r
-\r
- ASM SOURCES\r
-\r
- xmouse.asm xlib.inc model.inc\r
-\r
- C HEADER FILE\r
-\r
- xmouse.h\r
-\r
- EXPORTED VARIABLES\r
-\r
- MouseInstalled - WORD - Indicates whether mouse handler installed\r
- MouseHidden - WORD - Indicates whether mouse cursor is hidden\r
- MouseButtonStatus - WORD - Holds the mouse button status\r
- MouseX - WORD - Current X position of mouse cursor\r
- MouseY - WORD - Current Y position of mouse cursor\r
- MouseFrozen - WORD - Disallows position updates if TRUE\r
- MouseColor - BYTE - The mouse cursors colour\r
-\r
- EXPORTED FUNCTIONS\r
-\r
- x_mouse_init\r
- ------------\r
-\r
- C Prototype: int x_mouse_init()\r
-\r
- Initialize the mouse driver functions and install the mouse event handler\r
- function. This is the first function you must call before using any of the\r
- mouse functions. This mouse code uses the fastest possible techniques to\r
- save and restore mouse backgrounds and to draw the mouse cursor.\r
-\r
- WARNING: This function uses and updates "NonVisual_Offset" to allocate\r
- video ram for the saved mouse background.\r
-\r
- LIMITATIONS: No clipping is supported horizontally for the mouse cursor\r
- No validity checking is performed for NonVisual_Offs\r
-\r
- **WARNING** You must Hide or at least Freeze the mouse cursor while drawing\r
- using any of the other XLIB modules since the mouse handler may\r
- modify vga register settings at any time. VGA register settings\r
- are not preserved which will result in unpredictable drawing\r
- behavior. If you know the drawing will occur away from the\r
- mouse cursor set MouseFrozen to TRUE (1), do your drawing\r
- then set it to FALSE (0). Alternatively call "x_hide_mouse",\r
- perform your drawing and then call "x_show_mouse". Another\r
- alternative is to disable interrupts while drawing but usually\r
- drawing takes up alot of time and having interrupts disabled\r
- for too long is not a good idea.\r
-\r
- x_define_mouse_cursor\r
- ---------------------\r
-\r
- C Prototype:\r
- void x_define_mouse_cursor(char far *MouseDef, unsigned char MouseColor)\r
-\r
- MouseDef - a pointer to 14 characters containing a bitmask for all the\r
- cursor's rows.\r
- MouseColor - The colour to use when drawing the mouse cursor.\r
-\r
- Define a mouse cursor shape for use in subsequent cursor redraws. XMouse\r
- has a hardwired mouse cursor size of 8 pixels across by 14 pixels down.\r
-\r
- WARNING: This function assumes MouseDef points to 14 bytes.\r
-\r
- Note: Bit order is in reverse. ie bit 7 represents pixel 0 ..\r
- bit 0 represents pixel 7 in each "MouseDef" byte.\r
-\r
- x_show_mouse\r
- ------------\r
-\r
- C Prototype: void x_show_mouse()\r
-\r
- Makes the cursor visible if it was previously hidden.\r
- See Also: "x_hide_mouse".\r
-\r
- x_hide_mouse\r
- ------------\r
-\r
- C Prototype: void x_hide_mouse()\r
-\r
- Makes the cursor hidden if it was previously visible.\r
- See Also: "x_show_mouse".\r
-\r
- x_remove_mouse\r
- --------------\r
-\r
- C Prototype: void x_remove_mouse()\r
-\r
- Stop mouse event handling and remove the mouse handler.\r
-\r
- NOTE: This function MUST be called before quitting the program if\r
- a mouse handler has been installed\r
-\r
- x_position_mouse\r
- ----------------\r
-\r
- C Prototype void x_position_mouse(int x, int y)\r
-\r
- Positions the mouse cursor at the specified location\r
-\r
- x_update_mouse\r
- --------------\r
-\r
- C Prototype: void x_update_mouse()\r
-\r
- Forces the mouse position to be updated and cursor to be redrawn.\r
- Note: this function is useful when you have set "MouseFrozen" to true.\r
- Allows the cursor position to be updated manually rather than\r
- automatically by the installed handler.\r
-\r
---------------------------------------------------------------------------\r
-MODULE XCIRCLE\r
---------------------------------------------------------------------------\r
- XCIRCLE:\r
- Wheel Have to See About That\r
- by Matthew MacKenzie\r
-\r
-The XCIRCLE module contains two functions, neither of which should be\r
-a big mystery:\r
- o x_circle, oddly enough, draws a circle.\r
- o x_filled_circle does too, only the circle is filled (in some\r
- libraries this is called a disc).\r
-\r
- The word `circle' here refers to a round thing which is as many\r
-pixels tall as across. It only looks like a circle in 320x240 mode --\r
-the original mode X -- and in 376x282 mode.\r
- In both functions, the circle is specified by the coordinates of the\r
-upper-left-hand corner of the smallest box which holds it, and the\r
-diameter. Some circle functions have you specify a center point;\r
-this system is kind of odd because a circle with an even diameter does\r
-not have a particular pixel for a center. Every circle, on the other\r
-hand, has a box with an upper-left corner.\r
- No bounds are checked. A diameter of zero will draw nothing, and\r
-a negative diameter will blow your VGA board into hundreds of thousands\r
-of tiny little smoldering fragments. Neither function supports clipping.\r
- The calculation of the circle is based on an algorithm described\r
-by Michael P. Lindner in a letter to the editor on page 8 of Dr. Dobb's\r
-Journal #169 (October 1990). The algorithm has been rearranged to\r
-allow drawing and moving the plots in the eight octants to be performed\r
-in one step, so that each pixel does not have to be loaded into the CPU\r
-twice. x_filled_circle does not take advantage of this optimization\r
-because it handles different parts of each plot at different times.\r
-\r
- ASM SOURCES\r
-\r
- xcircle.asm xcircle.inc xlib.inc model.inc\r
-\r
- C HEADER FILE\r
-\r
- xcircle.h\r
-\r
- EXPORTED FUNCTIONS\r
-\r
- x_circle\r
- --------\r
- C Prototype: extern void x_circle (WORD Left, WORD Top, WORD Diameter,\r
- WORD Color, WORD ScreenOffs);\r
-\r
- Draws a circle with the given upper-left-hand corner and diameter,\r
- which are given in pixels.\r
-\r
-\r
- x_filled_circle\r
- ---------------\r
- C Prototype: extern void x_filled_circle (WORD Left, WORD Top,\r
- WORD Diameter, WORD Color, WORD ScreenOffs);\r
-\r
- Draws a filled circle with the given upper-left-hand corner and\r
- diameter.\r
-\r
-\r
---------------------------------------------------------------------------\r
-MODULE XDETECT\r
---------------------------------------------------------------------------\r
-\r
- This module implements a set of functions to detect the PC's hardware\r
- configuration.\r
-\r
- ASM SOURCES\r
-\r
- xdetect.asm xdetect.inc model.inc\r
-\r
- C HEADER FILE\r
-\r
- xdetect.h\r
-\r
- EXPORTED MACROS\r
-\r
- I8086 0\r
- I80186 1\r
- I80286 2\r
- I80386 3\r
-\r
- NoGraphics 0\r
- MDA 1\r
- CGA 2\r
- EGAMono 3\r
- EGAColor 4\r
- VGAMono 5\r
- VGAColor 6\r
- MCGAMono 7\r
- MCGAColor 8\r
-\r
- BUS_MOUSE 1\r
- SERIAL_MOUSE 2\r
- INPORT_MOUSE 3\r
- PS2_MOUSE 4\r
- HP_MOUSE 5\r
-\r
-\r
- EXPORT VARIABLES\r
-\r
- MouseButtonCount - WORD - The number of buttons on the detected mouse\r
- MouseVersion - WORD - Mouse driver version (High byte = Major version\r
- Low byte = minor version)\r
- MouseType - BYTE - The mouse type\r
- MouseIRQ - BYTE - The IRQ number used by the mouse driver\r
-\r
- EXPORT FUNCTIONS\r
-\r
-\r
- x_graphics_card\r
- ---------------\r
- C Prototype: extern int x_graphics_card();\r
-\r
- This function returns the type of graphics card installed. See defines\r
- above.\r
-\r
- x_processor\r
- -----------\r
- C Prototype: extern int x_processor();\r
-\r
- This function returns the type of processor installed. A 486 registers\r
- as a 386. See defines above.\r
-\r
- x_coprocessor\r
- -------------\r
- C Prototype: extern int x_coprocessor();\r
-\r
- This function returns 1 of a numeric co-processor is present, 0 if not.\r
- The type is not detected but it's mnot really necessary as the processor\r
- type usually determines the numeric coprocessor type\r
-\r
- x_mousedriver\r
- -------------\r
- C Prototype: extern int x_mousedriver();\r
-\r
- This function returns 1 of a mouse driver is installed, 0 otherwise.\r
- If a mouse driver is detected the mouse related variable (above) are\r
- set accordingly.\r
-\r
---------------------------------------------------------------------------\r
-MODULE XFILEIO\r
---------------------------------------------------------------------------\r
-\r
- Handle based file I/O functions.\r
-\r
- See any good DOS programming reference for more information on int 21h\r
- DOS services.\r
-\r
- ASM SOURCES\r
-\r
- xfileio.asm xfileio.inc model.inc\r
-\r
- C HEADER FILE\r
-\r
- xfileio.h\r
-\r
- EXPORTED MACROS\r
-\r
- file access modes\r
-\r
- F_RDONLY\r
- F_WRONLY\r
- F_RDWR\r
-\r
- seek codes\r
-\r
- SEEK_START\r
- SEEK_CURR\r
- SEEK_END\r
-\r
- file error value\r
-\r
- FILE_ERR\r
-\r
- EXPORT FUNCTIONS\r
-\r
- f_open\r
- ------\r
- C Prototype: extern int f_open(char * filename, char access);\r
-\r
- Opens a file according to the access char:\r
-\r
- F_RDONLY = read only - If doesnt exist return error\r
- F_WRONLY = write only - If doesnt exist create it otherwise clear it\r
- F_RDWR = read/write - If doesnt exist create it\r
-\r
- Returns the file handle on success, FILE_ERR on failure\r
-\r
-\r
- f_close\r
- -------\r
-\r
- C Prototype: extern int f_close(int handle);\r
-\r
- Closes the file associated with the specified handle\r
-\r
- Returns 0 on success, FILE_ERR on failure\r
-\r
-\r
- f_read\r
- ------\r
-\r
- C Prototype:\r
-\r
- extern int f_read(int handle,char near * buffer, int count);\r
-\r
- Reads a block of count bytes from the file specified by the handle\r
- into the near buffer\r
-\r
- Returns count on success, FILE_ERR on failure\r
-\r
- f_readfar\r
- ---------\r
-\r
- C Prototype:\r
-\r
- extern int f_readfar(int handle,char far * buffer, int count);\r
-\r
- Reads a block of count bytes from the file specified by the handle\r
- into the far buffer\r
-\r
- Returns count on success, FILE_ERR on failure\r
-\r
-\r
- f_write\r
- -------\r
-\r
- C Prototype: extern int f_write(int handle, char near * buffer, int count);\r
-\r
- Writes a block of count bytes to the file specified by the handle\r
- from the near buffer\r
-\r
- Returns count on success, FILE_ERR on failure\r
-\r
- f_writefar\r
- ----------\r
-\r
- C Prototype: extern int f_write(int handle, char far * buffer, int count);\r
-\r
- Writes a block of count bytes to the file specified by the handle\r
- from the far buffer\r
-\r
- Returns count on success, FILE_ERR on failure\r
-\r
-\r
- f_seek\r
- ------\r
-\r
- C Prototype: extern long int f_seek(int handle, long int position,\r
- char method_code)\r
-\r
- Moves the file pointer according to the position and method code\r
-\r
- Returns file pointer position on success, FILE_ERR on failure\r
-\r
-\r
- f_filelength\r
- ------------\r
-\r
- C Prototype:\r
-\r
- extern long int f_filelength(int handle)\r
-\r
- Returns the length of the file associated with the specified handle\r
-\r
- Returns file length on success, FILE_ERR on failure\r
-\r
-\r
- f_tell\r
- ------\r
-\r
- C Prototype:\r
-\r
- extern long int f_tell(int handle)\r
-\r
-\r
- Returns file pointer position on success, FILE_ERR on failure\r
-\r
---------------------------------------------------------------------------\r
-MODULE XRLETOOL\r
---------------------------------------------------------------------------\r
-\r
-This module implements a number of functions comprising an RLE encoding\r
-decoding system.\r
-\r
-RLE stands for RUN LENGTH ENCODING. It is a quick simple data compression\r
-scheme which is commonly used for image data compression or compression\r
-of any data. Although not the most efficient system, it is fast, which is\r
-why it is used in image storage systems like PCX. This implementation is\r
-more efficient than the one used in PCX files because it uses 1 bit to\r
-identify a Run Length byte as opposed to two in PCX files, but more on this\r
-later.\r
-\r
-This set of functions can be used to implement your own compressed image\r
-file format or for example compress game mapse for various levels etc.\r
-The uses are limited by your imagination.\r
-\r
-I opted for trading off PCX RLE compatibility for the improved compression\r
-efficiency.\r
-\r
-Here is how the data is un-compressed to give an idea of its structure.\r
-\r
-\r
-STEP 1 read a byte from the RLE compressed source buffer.\r
-\r
-STEP 2 if has its high bit is set then the lower 7 bits represent the number\r
- of times the next byte is to be repeated in the destination buffer.\r
- if the count (lower 7 bits) is zero then\r
- we have finished decoding goto STEP 5\r
- else goto STEP 4\r
-\r
-STEP 3 Read a data from the source buffer and copy it directly to the\r
- destination buffer.\r
- goto STEP 1\r
-\r
-STEP 4 Read a data byte from the source buffer and copy it to the destination\r
- buffer the number of times specified by step 2.\r
- goto STEP 1\r
-\r
-STEP 5 Stop, decoding done.\r
-\r
-If the byte does not have the high bit set then the byte itself is transfered\r
- to the destination buffer.\r
-\r
-Data bytes that have the high bit already set and are unique in the input\r
- stream are represented as a Run Length of 1 (ie 81 which includes high bit)\r
- followed by the data byte.\r
-\r
-If your original uncompressed data contains few consecutive bytes and most\r
-have high bit set (ie have values > 127) then your so called\r
-compressed data would require up to 2x the space of the uncompressed data,\r
-so be aware that the compression ratio is extremely variable depending on the\r
-type of data being compressed.\r
-\r
-Apologies for this poor attempt at a description, but you can look up\r
-RLE in any good text. Alternatively, any text that describes the PCX file\r
-structure in any depth should have a section on RLE compression.\r
-\r
-\r
-\r
- ASM SOURCES\r
-\r
- xrletool.asm xrletool.inc model.inc\r
-\r
- C HEADER FILE\r
-\r
- xrletool.h\r
-\r
- EXPORTED MACROS\r
-\r
-\r
- EXPORT FUNCTIONS\r
-\r
- x_buff_RLDecode\r
- ---------------\r
-\r
- Expands an RLE compresses source buffer to a destination buffer.\r
- returns the size of the resultant uncompressed data.\r
-\r
- C PROTOTYPE:\r
-\r
- extern unsigned int x_buff_RLDecode(char far * source_buff,\r
- char far * dest_buff);\r
-\r
- source_buff - The buffer to compress\r
- dest_buff - The destination buffer\r
-\r
- WARNING: buffers must be pre allocated.\r
-\r
-\r
- x_buff_RLEncode\r
- ---------------\r
-\r
- RLE Compresses a source buffer to a destination buffer and returns\r
- the size of the resultant compressed data.\r
-\r
- C PROTOTYPE:\r
-\r
- extern unsigned int x_buff_RLEncode(char far * source_buff,\r
- char far * dest_buff,unsigned int count);\r
-\r
- source_buff - The buffer to compress\r
- dest_buff - The destination buffer\r
- count - The size of the source data in bytes\r
-\r
- WARNING: buffers must be pre allocated.\r
-\r
- x_buff_RLE_size\r
- ---------------\r
-\r
- Returns the size the input data would compress to.\r
-\r
- C PROTOTYPE:\r
-\r
- extern unsigned int x_buff_RLE_size(char far * source_buff,\r
- unsigned int count);\r
-\r
- source_buff - The uncompressed data buffer\r
- count - The size of the source data in bytes\r
-\r
-\r
- x_file_RLEncode\r
- ---------------\r
-\r
- RLE Compresses a source buffer to an output file returning\r
- the size of the resultant compressed data or 0 if it fails.\r
-\r
- C PROTOTYPE:\r
-\r
- extern unsigned int x_file_RLEncode(int handle,\r
- char far * source_buff,unsigned int count);\r
-\r
- source_buff - The buffer to compress\r
- handle - The file handler\r
- count - The size of the source data in bytes\r
-\r
- x_file_RLDecode\r
- ---------------\r
-\r
- Expands an RLE compresses file to a destination RAM buffer.\r
- returns the size of the resultant uncompressed data.\r
-\r
- C PROTOTYPE:\r
-\r
- extern unsigned int x_buff_RLDecode(int handle,\r
- char far * dest_buff);\r
-\r
- handle - Input file handle\r
- dest_buff - The destination buffer\r
-\r
-\r
-\r
-\r
---------------------------------------------------------------------------\r
-MODULE XPOLYGON\r
---------------------------------------------------------------------------\r
-\r
- This module implements eneral filled convex polygon and triangle\r
- functions\r
-\r
- C HEADER FILE\r
-\r
- xpolygon.h\r
-\r
- TYPE DEFS\r
-\r
- typedef struct {\r
- int X;\r
- int Y;\r
- } far VERTEX;\r
-\r
-\r
-\r
- EXPORT FUNCTIONS\r
-\r
-\r
- x_triangle\r
- ------------\r
- C Prototype:\r
-\r
- void x_triangle(int x0, int y0, int x1, int y1, int x2, int y2,\r
- WORD color, WORD PageBase);\r
-\r
- This function draws a filled triangle which is clipped to the current\r
- clipping window defined by TopClip,BottomClip,LeftClip,RightClip.\r
- Remember: the X clipping variable are in BYTES not PIXELS so you\r
- can only clip to 4 pixel byte boundaries.\r
-\r
-\r
- x_polygon\r
- ---------\r
-\r
- C Prototype:\r
-\r
- void x_polygon(VERTEX *vertices, int num_vertices,\r
- WORD color, WORD PageBase);\r
-\r
- This function is similar to the triangle function but draws\r
- convex polygons. The vertices are supplied in the form of a FAR\r
- pointer.\r
-\r
- NOTE: a convex polygon is one such that if you draw a line from\r
- any two vertices, every point on that line will be within the\r
- polygon.\r
-\r
- This function works by splitting up a polygon into its component\r
- triangles and calling the triangle routine above to draw each one.\r
- Performance is respectable but a custom polygon routine might be\r
- faster.\r
-\r
-\r
---------------------------------------------------------------------------\r
-MODULE XFILL\r
---------------------------------------------------------------------------\r
-\r
- This module implements a couple of general purpose flood fill functions\r
- functions\r
-\r
- C HEADER FILE\r
-\r
- xfill.h\r
-\r
-\r
- EXPORT FUNCTIONS\r
-\r
-\r
- x_flood_fill\r
- ------------\r
- C Prototype:\r
-\r
- int x_flood_fill(int x, int y, unsigned ofs, int color);\r
-\r
- This function performs the familiar flood filling used by many\r
- paint programs and of course the Borland BGI's flood fill function.\r
- The pixel at x,y and all adjacent pixels of the same color are filled\r
- to the new color. Filling stops when there are no more adjacent pixels\r
- of the original pixel's color. The function returns the number of\r
- pixels that have been filled.\r
-\r
- x_boundary_fill\r
- ------------\r
- C Prototype:\r
-\r
-\r
- int x_boundary_fill(int x,int y,unsigned ofs,int boundary,int color);\r
-\r
- This function is a variant of the flood fill described above. This\r
- function, unlike the above function, can fill across color boundaries.\r
- Filling stops when the area being filled is fully enclosed by pixels\r
- of the color "boundary". Again, this function returns the number of\r
- pixels filled.\r
-\r
--------------------------------------------------------------------------------\r
-MODULE VSYNC\r
--------------------------------------------------------------------------------\r
-\r
- VSYNC\r
-\r
- Simulated Vertical Retrace Interrupt Module\r
-\r
- by Tore Jahn Bastiansen <toreba@ifi.uio.no>\r
-\r
- Inspired by REND386 v3.01 by Dave Stampe and Bernie Roehl\r
-\r
-The xvsync module uses timer 0 to simulate a vertical retrace interrupt.\r
-It's designed to significantly reduce the idle waiting time in Xlib.\r
-Why simulate the VRT interrupt ? Simply because a true VRT interrupt is\r
-not implemented on many VGA cards. Using a VRT interrupt as opposed to\r
-polling, can result in huge performance improvements for your code and\r
-help make animation much smoother than it would be using polling.\r
-\r
-Normally xlib waits for vsync when x_page_flip, x_set_start_address or\r
-x_put_pal_??? is called. This waiting period could be better utilized to do\r
-housekeeping calculations or whatever. The x_put_pal_??? functions also\r
-doesn't work very smoothly in conjunction with other functions that wait for\r
-the vertical retrace since each function introduces its own VRT delay.\r
-\r
-When using the vsync handler, the VRT delay is reduced to the absolute\r
-minumum which can result in a huge performance boost for your programs.\r
-\r
-When using double buffering, you may still have to wait before drawing,\r
-but you could do as much other work as possible, like this:\r
-\r
- x_page_flip(...)\r
- ...\r
- <animate the palette>\r
- <do some collision detection and 3D calculations>\r
- <read the joystick>\r
- ...\r
- x_wait_start_address(); (Not needed with triple buffering)\r
- ...\r
- <draw next frame>\r
- ...\r
-\r
-ASM SOURCES\r
-\r
- xvsync.asm xmain.asm xvsync.inc xmain.inc\r
-\r
-C HEADER FILE\r
-\r
- xvsync.h\r
-\r
-EXPORTED VARIABLES\r
-\r
-VsyncPeriod - WORD -time in 1.193 us between two vsyncs\r
-\r
-TicksPerSecond - WORD - number of vsyncs per second\r
-\r
-VsyncTimerInt - long - number of vsyncs since x_install_vsync_handler was\r
- called. Nice for game timing.\r
-\r
-EXPORTED FUNCTIONS\r
-\r
-x_install_vsync_handler\r
------------------------\r
-\r
-C Prototype: void x_install_vsync_handler(int VrtsToSkip);\r
-\r
-This function installs the vsync handler using timer 0. It's called\r
-about 100 microseconds before every vertical retrace.\r
-\r
-The VrtsToSkip value (>=1) defines the delay in VRT's between consecutive\r
-physical screen start address changes, thus allowing you to limit the\r
-maximum frame rate for page flips in animation systems. The frame rate\r
-is calculated as Vertical refresh rate / VrtsToSkip, eg for\r
-320x240 mode which refreshes at 60Hz a VrtsToSkip value of 3 will result\r
-in a maximum page flipping rate of 20Hz (frames per second)\r
-\r
-WARNING: Be sure to remove it before exiting.\r
- When used with a debugger, the system clock may speed up.\r
-\r
-x_remove_vsync_handler\r
-----------------------\r
-\r
-C Prototype: void x_remove_vsync_handler\r
-\r
-This routine _MUST_ be called before exiting (or aborting) the program,\r
-or your system will crash.\r
-\r
-x_set_user_vsync_handler\r
-------------------------\r
-\r
-C Prototype: void x_set_user_vsync_handler(void far (*f)());\r
-\r
-Installs a user routine to be called once each vertical retrace. The user\r
-handler have its own stack of 256 bytes , so be careful with the stack\r
-checking option in BC.\r
-WARNING: This installs an interrupt driven handler, beware of the following:\r
- Only 8086 registers are preserved. If you're using 386 code, save\r
- all the 386 regs.\r
- Don't do any drawing.\r
- Don't call any DOS functions.\r
-\r
-So why use it?\r
-Well, you can update global variables if you're careful. And it's nice for\r
-palette animation. You can even do fades while loading from disk. You\r
-should use this instead of installing your own int08h routine and chain\r
-to the original.\r
-\r
-x_wait_start_addr\r
------------------\r
-\r
-C Prototype: void x_wait_start_addr(void)\r
-\r
-You must call this function before drawing after a call to x_set_start_addr\r
-or x_page_flip when you are using the vsync handler and not using\r
-triple buffering.\r
-\r
-MODULE XMAIN additions\r
-\r
-EXPORTED VARIABLES\r
-\r
-Page2_Offs - WORD - Offset in video ram of third virtual screen. Set by\r
- x_triple_buffer.\r
-\r
-WaitingPageOffs - WORD - Offset of page waiting to be invisible. Initially\r
- set by x_set_triple_buffer but is updated by x_page_flip. This\r
- variable is only used while triple buffering is on.\r
-\r
-VsyncHandlerActive - WORD - Indicates whether the vsync handler is installed.\r
-\r
-TripleBufferActive - WORD - Indicates whether triple-buffering is on.\r
- Set by x_triple_buffer.\r
-\r
-StartAddressFlag - WORD - This flag is set if there is a new start\r
- address waiting to be set by the vsync handler.\r
-\r
-WaitingStartLow - WORD - Needed by vsync handler. Keep off.\r
-WaitingStartHigh - WORD - Needed by vsync handler. Keep off.\r
-WaitingPelPan - WORD - Needed by vsync handler. Keep off.\r
-\r
-VsyncPaletteStart - WORD - Start index of video DAC register to be\r
- updated next vsync. Set by palette functions.\r
-\r
-VsyncPaletteCount - WORD - Number of palette entries to be outed next\r
- vsync. Set by palette functions.\r
-\r
-VsyncPaletteBuffer - BYTE[768] - Buffer containing values for the next\r
- update of the DAC.\r
-\r
-EXPORTED FUNCTIONS\r
-\r
-x_triple_buffer\r
-----------------\r
-\r
-C Prototype: void x_triple_buffer(WORD PageHeight);\r
-\r
-This function behaves like x_double_buffer, but when used with\r
-x_install_vsync_handler you can draw immediately after a page flip.\r
-When x_page_flip is called, VisiblePageOffs is set to the page that\r
-will be display next vsync. Until then, WaitingPageOffs will be displayed.\r
-You can draw to HiddenPageOffs .\r
-\r
-\r
-\r
-\r
---------------------------------------------------------------------\r
-REFERENCE SECTION\r
---------------------------------------------------------------------\r
-\r
-\r
-REFERENCES\r
-----------\r
-\r
-In my opinion Doctor Dobbs Journal is the best reference text for\r
-VGA Mode X graphics:\r
-\r
-Issue 178 Jul 1991 : First reference to Mode X\r
-Article Abstract : VGA's undocumented Mode X supports page flipping,\r
- makes off screen memory available, has square pixels,\r
- and increases performance by as muck as 4 times.\r
-\r
-Issue 179 Aug 1991 : Continuation\r
-Article Abstract : Michael discusses latches and VGA's undoccumented\r
- Mode X.\r
-\r
-Issue 181 Sep 1991 : Continuation\r
-Article Abstract : Michael puts the moves on animation using VGA's 256\r
- colors.\r
-\r
-Issue 184 Oct 1991 : First of a continuing series covering 3-D animation\r
- using VGA's Mode X. This series is still ongoing\r
- (October 1992)\r
-Article Abstract : Michael moves into 3-D animation, starting with basic\r
- polygon fills and page flips.\r
-\r
-\r
-WHAT IS MODE X ?\r
-----------------\r
-\r
-Mode X is a derrivative of the VGA's standard mode 13h (320x200 256 color).\r
-It is a (family) of undocumented video modes that are created by tweaking\r
-the VGA's registers. The beauty of mode X is that it offers several\r
-benefits to the programmer:\r
- - Multiple graphice pages where mode 13h doesn't allowing for page flipping\r
- (also known as double buffering) and storage of images and data in\r
- offscreen video memory\r
- - A planar video ram organization which although more difficult to program,\r
- allows the VGA's plane-oriented hardware to be used to process pixels in\r
- parallel, improving performance by up to 4 times over mode 13h\r
-\r
- See issue 178-179 of D.D.J. for a full description of VGA's Mode X.\r
-\r
-WHAT IS A SPLIT SCREEN ?\r
-------------------------\r
-\r
-A split screen is a neat hardware feature offered by the EGA and VGA video\r
-cards. A split screen is a mode of graphics operationin which the Hardware\r
-splits the visual graphics screen horizontally and treats both halves as\r
-individual screens each starting at different locations in video RAM.\r
-\r
-The bottom half (which is usually referred to as the split screen) always\r
-starts at address A000:0000 but the top half's starting address is user\r
-definable.\r
-\r
-The most common application of split screens in games is the status display\r
-in scrolling games. Split screens make this sort of game simpler to program\r
-because when the top half window is scrolled the programmer does not have to\r
-worry about redrawing the bottom half.\r
-\r
-WHAT IS DOUBLE BUFFERING ?\r
---------------------------\r
-\r
-Double buffering (also known as page flipping) is the technique most often\r
-used to do animation. it requires hardware that is capable of displaying\r
-multiple graphics pages (or at least 2). Animation is achieved by drawing\r
-an image in the non visible screen and then displaying the non visible\r
-screen. Once the page has been flipped the process starts again. The next\r
-frame of the animation is drawn on the non visible screen, the page is\r
-flipped again etc.\r
-\r
-\r
-WHAT IS TRIPPLE BUFFERING ?\r
---------------------------\r
-\r
-Triple buffering is similar to double buffering in many ways, but it\r
-relies on 3 pages being defined for animation. The main selling point\r
-of triple buffering is that it eliminates the need to wait for the\r
-vertical retrace to flip pages before drawing on the new page thus\r
-alowing the programmer to start building the next animation frame\r
-immediately after completing the current one. Heres how it works:\r
-\r
-With double buffering, once you complete drawing the hidden page and\r
-youre ready to flip pages, you have to wait for the VGA hardware to\r
-actually flip the page (during the vertical retrace) before you start\r
-drawing the next page otherwise you will be drawing on the visible page.\r
-\r
-With triple buffering you cycle between three pages, thus the page you\r
-draw on is guaranteed not to be visible. I know this is a poor\r
-description but it really is quite simple\r
-\r
-Triple buffering can acheive the fastest possible animation under the\r
-right conditions but the draw back is that more video RAM is required. If\r
-you wish to store bitmaps in video ram such as background tiles, double\r
-buffering would be the better alternative.\r
-\r
-\r
-WHAT IS MODE X ?\r
-----------------\r
-\r
-Mode X is a derrivative of the VGA's standard mode 13h (320x200 256 color).\r
-It is a (family) of undocumented video modes that are created by tweaking\r
-the VGA's registers. The beauty of mode X is that it offers several\r
-benefits to the programmer:\r
- - Multiple graphice pages where mode 13h doesn't allowing for page flipping\r
- (also known as double buffering) and storage of images and data in\r
- offscreen video memory\r
- - A planar video ram organization which although more difficult to program,\r
- allows the VGA's plane-oriented hardware to be used to process pixels in\r
- parallel, improving performance by up to 4 times over mode 13h\r
-\r
- Again see D.D.J. for an in depth discussion of animation using Mode X.\r
-\r
- -----------------------------------------------------------------------\r
-\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XLINE\r
-;\r
-; Line drawing functions.\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-include xlib.inc\r
-include xline.inc\r
-\r
- .code\r
-\r
-\r
-ModeXAddr macro\r
- mov cl,bl\r
- push dx\r
- mov dx,[_ScrnLogicalByteWidth]\r
- mul dx\r
- pop dx\r
- shr bx,2\r
- add bx,ax\r
- add bx,[PgOffs]\r
- and cl,3\r
- endm\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; _x_line\r
-;\r
-; Line drawing function for all MODE X 256 Color resolutions\r
-; Based on code from "PC and PS/2 Video Systems" by Richard Wilton.\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-\r
-_x_line proc\r
-ARG x1:word,y1:word,x2:word,y2:word,Color:word,PgOffs:word\r
-LOCAL vertincr:word,incr1:word,incr2:word,routine:word=LocalStk\r
- push bp ; Set up stack frame\r
- mov bp,sp\r
- sub sp,LocalStk\r
- push si\r
- push di\r
-\r
- mov ax,0a000h\r
- mov es,ax\r
-\r
- mov dx,SC_INDEX ; setup for plane mask access\r
-\r
-; check for vertical line\r
-\r
- mov si,[_ScrnLogicalByteWidth]\r
- mov cx,[x2]\r
- sub cx,[x1]\r
- jz VertLine\r
-\r
-; force x1 < x2\r
-\r
- jns L01\r
-\r
- neg cx\r
-\r
- mov bx,[x2]\r
- xchg bx,[x1]\r
- mov [x2],bx\r
-\r
- mov bx,[y2]\r
- xchg bx,[y1]\r
- mov [y2],bx\r
-\r
-; calc dy = abs(y2 - y1)\r
-\r
-L01:\r
- mov bx,[y2]\r
- sub bx,[y1]\r
- jnz short skip\r
- jmp HorizLine\r
-skip: jns L03\r
-\r
- neg bx\r
- neg si\r
-\r
-; select appropriate routine for slope of line\r
-\r
-L03:\r
- mov [vertincr],si\r
- mov [routine],offset LoSlopeLine\r
- cmp bx,cx\r
- jle L04\r
- mov [routine],offset HiSlopeLine\r
- xchg bx,cx\r
-\r
-; calc initial decision variable and increments\r
-\r
-L04:\r
- shl bx,1\r
- mov [incr1],bx\r
- sub bx,cx\r
- mov si,bx\r
- sub bx,cx\r
- mov [incr2],bx\r
-\r
-; calc first pixel address\r
-\r
- push cx\r
- mov ax,[y1]\r
- mov bx,[x1]\r
- ModeXAddr\r
- mov di,bx\r
- mov al,1\r
- shl al,cl\r
- mov ah,al ; duplicate nybble\r
- shl al,4\r
- add ah,al\r
- mov bl,ah\r
- pop cx\r
- inc cx\r
- jmp [routine]\r
-\r
-; routine for verticle lines\r
-\r
-VertLine:\r
- mov ax,[y1]\r
- mov bx,[y2]\r
- mov cx,bx\r
- sub cx,ax\r
- jge L31\r
- neg cx\r
- mov ax,bx\r
-\r
-L31:\r
- inc cx\r
- mov bx,[x1]\r
- push cx\r
- ModeXAddr\r
-\r
- mov ah,1\r
- shl ah,cl\r
- mov al,MAP_MASK\r
- out dx,ax\r
- pop cx\r
- mov ax, word ptr [Color]\r
-\r
-; draw the line\r
-\r
-L32:\r
- mov es:[bx],al\r
- add bx,si\r
- loop L32\r
- jmp Lexit\r
-\r
-; routine for horizontal line\r
-\r
-HorizLine:\r
- push ds\r
-\r
- mov ax,[y1]\r
- mov bx,[x1]\r
- ModeXAddr\r
-\r
- mov di,bx ; set dl = first byte mask\r
- mov dl,00fh\r
- shl dl,cl\r
-\r
- mov cx,[x2] ; set dh = last byte mask\r
- and cl,3\r
- mov dh,00eh\r
- shl dh,cl\r
- not dh\r
-\r
-; determine byte offset of first and last pixel in line\r
-\r
- mov ax,[x2]\r
- mov bx,[x1]\r
-\r
- shr ax,2 ; set ax = last byte column\r
- shr bx,2 ; set bx = first byte column\r
- mov cx,ax ; cx = ax - bx\r
- sub cx,bx\r
-\r
- mov ax,dx ; mov end byte masks to ax\r
- mov dx,SC_INDEX ; setup dx for VGA outs\r
- mov bx, [Color]\r
-\r
-; set pixels in leftmost byte of line\r
-\r
- or cx,cx ; is start and end pt in same byte\r
- jnz L42 ; no !\r
- and ah,al ; combine start and end masks\r
- jmp short L44\r
-\r
-L42: push ax\r
- mov ah,al\r
- mov al,MAP_MASK\r
- out dx,ax\r
- mov al,bl\r
- stosb\r
- dec cx\r
-\r
-; draw remainder of the line\r
-\r
-L43:\r
- mov ah,0Fh\r
- mov al,MAP_MASK\r
- out dx,ax\r
- mov al,bl\r
- rep stosb\r
- pop ax\r
-\r
-; set pixels in rightmost byte of line\r
-\r
-L44:\r
- mov al,MAP_MASK\r
- out dx, ax\r
- mov byte ptr es:[di],bl\r
- pop ds\r
- jmp short Lexit\r
-\r
-\r
-; routine for dy >= dx (slope <= 1)\r
-\r
-LoSlopeLine:\r
- mov al,MAP_MASK\r
- mov bh,byte ptr [Color]\r
-L10:\r
- mov ah,bl\r
-\r
-L11:\r
- or ah,bl\r
- rol bl,1\r
- jc L14\r
-\r
-; bit mask not shifted out\r
-\r
- or si,si\r
- jns L12\r
- add si,[incr1]\r
- loop L11\r
-\r
- out dx,ax\r
- mov es:[di],bh\r
- jmp short Lexit\r
-\r
-L12:\r
- add si,[incr2]\r
- out dx,ax\r
- mov es:[di],bh\r
- add di,[vertincr]\r
- loop L10\r
- jmp short Lexit\r
-\r
-; bit mask shifted out\r
-\r
-L14: out dx,ax\r
- mov es:[di],bh\r
- inc di\r
- or si,si\r
- jns L15\r
- add si,[incr1]\r
- loop L10\r
- jmp short Lexit\r
-\r
-L15:\r
- add si,[incr2]\r
- add di,[vertincr]\r
- loop L10\r
- jmp short Lexit\r
-\r
-; routine for dy > dx (slope > 1)\r
-\r
-HiSlopeLine:\r
- mov bx,[vertincr]\r
- mov al,MAP_MASK\r
-L21: out dx,ax\r
- push ax\r
- mov ax,[Color]\r
- mov es:[di],al\r
- pop ax\r
- add di,bx\r
-\r
-L22:\r
- or si,si\r
- jns L23\r
-\r
- add si,[incr1]\r
- loop L21\r
- jmp short Lexit\r
-\r
-L23:\r
- add si,[incr2]\r
- rol ah,1\r
- adc di,0\r
-lx21: loop L21\r
-\r
-; return to caller\r
-\r
-Lexit:\r
- pop di\r
- pop si\r
- mov sp,bp\r
- pop bp\r
- ret\r
-\r
-_x_line endp\r
-\r
-end\r
-\1a
\ No newline at end of file
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XLINE - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;----------------------------------------------------------------------*/\r
-\r
-#ifndef _XLINE_H_\r
-#define _XLINE_H_\r
-\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-extern void x_line( /* Draw a line, what else */\r
- WORD x0,\r
- WORD y0,\r
- WORD x1,\r
- WORD y1,\r
- WORD color,\r
- WORD PageBase);\r
-\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif\r
-\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XLINE - Include file\r
-;\r
-; XLINE.ASM export functions\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
- global _x_line :proc\r
-\1a
\ No newline at end of file
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XMAIN\r
-;\r
-; Initialization, panning and split screen functions for all MODE X 256\r
-; Color resolutions\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; MODIFICATIONS:\r
-; 26-9-92: Pel panning code added\r
-; Dates forgotten: Numerous ;^)\r
-; 05-10-93: Timer synchronized vsync handling extensions\r
-; and tripple buffering - Tore Jahn Bastiansen\r
-; (toreba@ifi.uio.no) for the\r
-;-----------------------------------------------------------------------\r
-\r
-\r
-include xlib.inc\r
-include xmain.inc\r
-\r
-\r
- .data\r
-\r
-\r
-; Mode X CRTC register tweaks for various resolutions\r
-\r
-\r
-LABEL X256Y200 word\r
- db 0e3h ; dot clock\r
- db 8 ; Number of CRTC Registers to update\r
- dw 05f00h ; horz total\r
- dw 03f01h ; horz displayed\r
- dw 04202h ; start horz blanking\r
- dw 09f03h ; end horz blanking\r
- dw 04c04h ; start h sync\r
- dw 00005h ; end h sync\r
- dw 00014h ; turn off dword mode\r
- dw 0e317h ; turn on byte mode\r
- dw 256\r
- dw 200\r
-\r
-\r
-LABEL X256Y240 word\r
- db 0e3h ; dot clock\r
- db 16 ; Number of CRTC Registers to update\r
- dw 05f00h ; horz total\r
- dw 03f01h ; horz displayed\r
- dw 04202h ; start horz blanking\r
- dw 09f03h ; end horz blanking\r
- dw 04c04h ; start h sync\r
- dw 00005h ; end h sync\r
- dw 00d06h ; vertical total\r
- dw 03e07h ; overflow (bit 8 of vertical counts)\r
- dw 04109h ; cell height (2 to double-scan)\r
- dw 0ea10h ; v sync start\r
- dw 0ac11h ; v sync end and protect cr0-cr7\r
- dw 0df12h ; vertical displayed\r
- dw 00014h ; turn off dword mode\r
- dw 0e715h ; v blank start\r
- dw 00616h ; v blank end\r
- dw 0e317h ; turn on byte mode\r
- dw 256\r
- dw 240\r
-\r
-\r
-X320Y200 label word\r
- db 00 ; 0e3h ; dot clock\r
- db 02 ; Number of CRTC Registers to update\r
- dw 00014h ; turn off dword mode\r
- dw 0e317h ; turn on byte mode\r
- dw 320 ; width\r
- dw 200 ; height\r
-\r
-X320Y240 label word\r
- db 0e3h ; dot clock\r
- db 10 ; Number of CRTC Registers to update\r
- dw 00d06h ; vertical total\r
- dw 03e07h ; overflow (bit 8 of vertical counts)\r
- dw 04109h ; cell height (2 to double-scan)\r
- dw 0ea10h ; v sync start\r
- dw 0ac11h ; v sync end and protect cr0-cr7\r
- dw 0df12h ; vertical displayed\r
- dw 00014h ; turn off dword mode\r
- dw 0e715h ; v blank start\r
- dw 00616h ; v blank end\r
- dw 0e317h ; turn on byte mode\r
- dw 320 ; width\r
- dw 240 ; height\r
-\r
-X360Y200 label word\r
- db 0e7h ; dot clock\r
- db 08 ; Number of CRTC Registers to update\r
- dw 06b00h ; horz total\r
- dw 05901h ; horz displayed\r
- dw 05a02h ; start horz blanking\r
- dw 08e03h ; end horz blanking\r
- dw 05e04h ; start h sync\r
- dw 08a05h ; end h sync\r
- dw 00014h ; turn off dword mode\r
- dw 0e317h ; turn on byte mode\r
- dw 360 ; width\r
- dw 200 ; height\r
-\r
-X360Y240 label word\r
- db 0e7h ; dot clock\r
- db 17 ; Number of CRTC Registers to update\r
- dw 06b00h ; horz total\r
- dw 05901h ; horz displayed\r
- dw 05a02h ; start horz blanking\r
- dw 08e03h ; end horz blanking\r
- dw 05e04h ; start h sync\r
- dw 08a05h ; end h sync\r
- dw 00d06h ; vertical total\r
- dw 03e07h ; overflow (bit 8 of vertical counts)\r
- dw 04109h ; cell height (2 to double-scan)\r
- dw 0ea10h ; v sync start\r
- dw 0ac11h ; v sync end and protect cr0-cr7\r
- dw 0df12h ; vertical displayed\r
- dw 02d13h ; offset;\r
- dw 00014h ; turn off dword mode\r
- dw 0e715h ; v blank start\r
- dw 00616h ; v blank end\r
- dw 0e317h ; turn on byte mode\r
- dw 360\r
- dw 240\r
-\r
-X376Y282 label word\r
- db 0e7h\r
- db 18\r
- dw 06e00h ; horz total\r
- dw 05d01h ; horz displayed\r
- dw 05e02h ; start horz blanking\r
- dw 09103h ; end horz blanking\r
- dw 06204h ; start h sync\r
- dw 08f05h ; end h sync\r
- dw 06206h ; vertical total\r
- dw 0f007h ; overflow\r
- dw 06109h ; cell height\r
- dw 0310fh ;\r
- dw 03710h ; v sync start\r
- dw 08911h ; v sync end and protect cr0-cr7\r
- dw 03312h ; vertical displayed\r
- dw 02f13h ; offset\r
- dw 00014h ; turn off dword mode\r
- dw 03c15h ; v blank start\r
- dw 05c16h ; v blank end\r
- dw 0e317h ; turn on byte mode\r
- dw 376\r
- dw 282\r
-\r
-LABEL X256Y400 word\r
- db 0e3h ; dot clock\r
- db 8 ; Number of CRTC Registers to update\r
- dw 05f00h ; horz total\r
- dw 03f01h ; horz displayed\r
- dw 04202h ; start horz blanking\r
- dw 09f03h ; end horz blanking\r
- dw 04c04h ; start h sync\r
- dw 00005h ; end h sync\r
- dw 04009h ; cell height\r
- dw 00014h ; turn off dword mode\r
- dw 0e317h ; turn on byte mode\r
- dw 256\r
- dw 400\r
-\r
-\r
-LABEL X256Y480 word\r
- db 0e3h ; dot clock\r
- db 16 ; Number of CRTC Registers to update\r
- dw 05f00h ; horz total\r
- dw 03f01h ; horz displayed\r
- dw 04202h ; start horz blanking\r
- dw 09f03h ; end horz blanking\r
- dw 04c04h ; start h sync\r
- dw 00005h ; end h sync\r
- dw 00d06h ; vertical total\r
- dw 03e07h ; overflow (bit 8 of vertical counts)\r
- dw 04009h ; cell height (2 to double-scan)\r
- dw 0ea10h ; v sync start\r
- dw 0ac11h ; v sync end and protect cr0-cr7\r
- dw 0df12h ; vertical displayed\r
- dw 00014h ; turn off dword mode\r
- dw 0e715h ; v blank start\r
- dw 00616h ; v blank end\r
- dw 0e317h ; turn on byte mode\r
- dw 256\r
- dw 480\r
-\r
-\r
-\r
-X320Y400 label word\r
- db 0e3h ; dot clock\r
- db 03 ; Number of CRTC Registers to update\r
- dw 04009h ; cell height\r
- dw 00014h ; turn off dword mode\r
- dw 0e317h ; turn on byte mode\r
- dw 320 ; width\r
- dw 400 ; height\r
-\r
-X320Y480 label word\r
- db 0e3h ; dotclock\r
- db 10 ; Number of CRTC Registers to update\r
- dw 00d06h ; vertical total\r
- dw 03e07h ; overflow (bit 8 of vertical counts)\r
- dw 04009h ; cell height (2 to double-scan)\r
- dw 0ea10h ; v sync start\r
- dw 0ac11h ; v sync end and protect cr0-cr7\r
- dw 0df12h ; vertical displayed\r
- dw 00014h ; turn off dword mode\r
- dw 0e715h ; v blank start\r
- dw 00616h ; v blank end\r
- dw 0e317h ; turn on byte mode\r
- dw 320 ; width\r
- dw 480 ; height\r
-\r
-X360Y400 label word\r
- db 0e7h ; dot clock\r
- db 09 ; Number of CRTC Registers to update\r
- dw 06b00h ; horz total\r
- dw 05901h ; horz displayed\r
- dw 05a02h ; start horz blanking\r
- dw 08e03h ; end horz blanking\r
- dw 05e04h ; start h sync\r
- dw 08a05h ; end h sync\r
- dw 04009h ; cell height\r
- dw 00014h ; turn off dword mode\r
- dw 0e317h ; turn on byte mode\r
- dw 360 ; width\r
- dw 400 ; height\r
-\r
-\r
-\r
-X360Y480 label word\r
- db 0e7h\r
- db 17\r
- dw 06b00h ; horz total\r
- dw 05901h ; horz displayed\r
- dw 05a02h ; start horz blanking\r
- dw 08e03h ; end horz blanking\r
- dw 05e04h ; start h sync\r
- dw 08a05h ; end h sync\r
- dw 00d06h ; vertical total\r
- dw 03e07h ; overflow\r
- dw 04009h ; cell height\r
- dw 0ea10h ; v sync start\r
- dw 0ac11h ; v sync end and protect cr0-cr7\r
- dw 0df12h ; vertical displayed\r
- dw 02d13h ; offset\r
- dw 00014h ; turn off dword mode\r
- dw 0e715h ; v blank start\r
- dw 00616h ; v blank end\r
- dw 0e317h ; turn on byte mode\r
- dw 360\r
- dw 480\r
-\r
-X360Y360 label word\r
- db 0e7h\r
- db 15\r
- dw 06b00h ; horz total\r
- dw 05901h ; horz displayed\r
- dw 05a02h ; start horz blanking\r
- dw 08e03h ; end horz blanking\r
- dw 05e04h ; start h sync\r
- dw 08a05h ; end h sync\r
- dw 04009h ; cell height\r
- dw 08810h ; v sync start\r
- dw 08511h ; v sync end and protect cr0-cr7\r
- dw 06712h ; vertical displayed\r
- dw 02d13h ; offset\r
- dw 00014h ; turn off dword mode\r
- dw 06d15h ; v blank start\r
- dw 0ba16h ; v blank end\r
- dw 0e317h ; turn on byte mode\r
- dw 360\r
- dw 360\r
-\r
-\r
-X376Y308 label word\r
- db 0e7h\r
- db 18\r
- dw 06e00h ; horz total\r
- dw 05d01h ; horz displayed\r
- dw 05e02h ; start horz blanking\r
- dw 09103h ; end horz blanking\r
- dw 06204h ; start h sync\r
- dw 08f05h ; end h sync\r
- dw 06206h ; vertical total\r
- dw 00f07h ; overflow\r
- dw 04009h ;\r
- dw 0310fh ;\r
- dw 03710h ; v sync start\r
- dw 08911h ; v sync end and protect cr0-cr7\r
- dw 03312h ; vertical displayed\r
- dw 02f13h ; offset\r
- dw 00014h ; turn off dword mode\r
- dw 03c15h ; v blank start\r
- dw 05c16h ; v blank end\r
- dw 0e317h ; turn on byte mode\r
- dw 376\r
- dw 308\r
-\r
-X376Y564 label word\r
- db 0e7h\r
- db 18\r
- dw 06e00h ; horz total\r
- dw 05d01h ; horz displayed\r
- dw 05e02h ; start horz blanking\r
- dw 09103h ; end horz blanking\r
- dw 06204h ; start h sync\r
- dw 08f05h ; end h sync\r
- dw 06206h ; vertical total\r
- dw 0f007h ; overflow\r
- dw 06009h ;\r
- dw 0310fh ;\r
- dw 03710h ; v sync start\r
- dw 08911h ; v sync end and protect cr0-cr7\r
- dw 03312h ; vertical displayed\r
- dw 02f13h ; offset\r
- dw 00014h ; turn off dword mode\r
- dw 03c15h ; v blank start\r
- dw 05c16h ; v blank end\r
- dw 0e317h ; turn on byte mode\r
- dw 376\r
- dw 564\r
-\r
-LAST_X_MODE equ 13\r
-ModeTable label word ; Mode X tweak table\r
- dw offset X320Y200\r
- dw offset X320Y240\r
- dw offset X360Y200\r
- dw offset X360Y240\r
- dw offset X376Y282\r
- dw offset X320Y400\r
- dw offset X320Y480\r
- dw offset X360Y400\r
- dw offset X360Y480\r
- dw offset X360Y360\r
- dw offset X376Y308\r
- dw offset X376Y564\r
- dw offset X256Y200\r
- dw offset X256Y240\r
-\r
-\r
-PARAMS label byte\r
-\r
- _CurrXMode dw 0 ; Current graphics mode index\r
- _InGraphics db 0 ; Flag indicating graphics activity\r
- _ScrnPhysicalByteWidth dw 0 ; Physical width in bytes of screen\r
- _ScrnPhysicalPixelWidth dw 0 ; Physical width in pixels of screen\r
- _ScrnPhysicalHeight dw 0 ; Physical Height of screen\r
- _ErrorValue db 0 ; Set after function calls\r
-\r
-\r
- _SplitScrnActive db 0 ; Flag indicating Split scrn activity\r
- _DoubleBufferActive dw 0 ; Flag indicating double buffering\r
- _TrippleBufferActive dw 0 ; Flag indicating tripple buffering\r
-\r
- _SplitScrnScanLine dw 0 ; Split Screen's starting scan line\r
- _SplitScrnVisibleHeight dw 0 ; Split Screen's height on screen\r
-\r
- _SplitScrnOffs dw 0 ; Offset in video ram of Split Screen\r
- ; always = 0\r
- _Page0_Offs dw 0 ; Ofset in video ram of Main virtual\r
- ; screen ( = 0 if no split screen\r
- ; otherwise = offset of first byte\r
- ; after split screen\r
- _Page1_Offs dw 0 ; Ofset in video ram of Second virtual\r
- ; screen ( = 0 if no split screen\r
- ; otherwise = offset of first byte\r
- ; after split screen\r
- ; = Page0_Offs if Doubble buffering\r
- ; not enabled\r
- _Page2_Offs dw 0\r
-\r
- _NonVisual_Offs dw 0 ; Ofset in video ram of first byte\r
- ; of non visible ram\r
- _ScrnLogicalByteWidth dw 0 ; Logical width in bytes of screen\r
- _ScrnLogicalPixelWidth dw 0 ; Logical width in pixels of screen\r
- _ScrnLogicalHeight dw 0 ; Logical Height of screen\r
-\r
- _MaxScrollX dw 0 ; Max X start position of Physical\r
- ; screen within virtual screen (in\r
- ; bytes)\r
- _MaxScrollY dw 0 ; Max Y start position of Physical\r
- ; screen within virtual screen\r
-\r
- _VisiblePageIdx dw 0 ; Index of currently visible D.B.\r
- ; page\r
-\r
- PageAddrTable label word\r
- _VisiblePageOffs dw 0 ; Table containing starting offsets\r
- _HiddenPageOffs dw 0 ; of the double buffer pages\r
- _WaitingPageOffs dw 0\r
-\r
- _TopClip dw 0 ; Clipping Rectangle\r
- _BottomClip dw 0 ;\r
- _LeftClip dw 0 ; Left/Right coordinates in bytes\r
- _RightClip dw 0 ;\r
- _PhysicalStartByteX dw 0 ; X byte coord of physical screen\r
- ; relative to virtual virtual screen\r
- _PhysicalStartPixelX dw 0 ; X pixel coord of physical screen\r
- ; relative to virtual screen\r
- _PhysicalStartY dw 0 ; Y pixel coord of physical screen\r
- ; relative to virtual screen\r
-\r
-; NEW\r
- _VsyncHandlerActive dw 0\r
- _MouseRefreshFlag dw 0\r
- _MouseVsyncHandler dd 0\r
- _StartAddressFlag dw 0\r
- _WaitingStartLow dw 0\r
- _WaitingStartHigh dw 0\r
- _WaitingPelPan dw 0\r
- _VsyncPaletteStart dw 0\r
- _VsyncPaletteCount dw 0\r
- _VsyncPaletteBuffer label byte\r
- db 768 dup(?)\r
-\r
-\r
-PARAMS_END label byte\r
-\r
-PARAM_COUNT equ ($-PARAMS)\r
-\r
-\r
-; Index/data pairs for CRT Controller registers that differ between\r
-; mode 13h and mode X.\r
-\r
- ;Pelpan values for 0,1,2,3 pixel panning to the left, respectively\r
- PelPanMask db 000h,002h,004h,006h\r
-\r
-DoubleScanFlag db ? ; Flag to indicate double scanned mode\r
-\r
- .code\r
-\r
-;-------------------------------------------------------------------------\r
-; Local Logical Screen Width setting function\r
-; cx = Requitrd Logical Width\r
-;\r
-; WARNING: no registers are preserved\r
-\r
-SetLogicalScrWidth proc\r
- mov dx,CRTC_INDEX\r
- mov al,CRTC_OFFSET\r
- out dx,al\r
- inc dx\r
-\r
- mov ax,cx\r
- cmp ax,[_ScrnPhysicalPixelWidth]; Is logical width >= physical width\r
- jge @@ValidLogicalWidth ; yes - continue\r
- mov ax,bx ; no - set logical width = physical\r
-\r
-@@ValidLogicalWidth:\r
- shr ax,3\r
- out dx,al\r
-\r
- ; The EXACT logical pixel width may not have been possible since\r
- ; it should be divisible by 8. Round down to the closest possible\r
- ; width and update the status variables\r
-\r
- shl ax,1\r
- mov bx,ax\r
- mov [_ScrnLogicalByteWidth],ax ; Store the byte width of virtual\r
- mov [_RightClip],ax ; Set default Right clip column\r
- ; screen\r
- sub ax,[_ScrnPhysicalByteWidth] ; Calculate and store Max X position\r
- shl ax,2 ; of physical screen in virtual\r
- mov [_MaxScrollX],ax ; screen in pixels\r
- mov ax,bx ; set ax to byte width of virt scrn\r
- shl ax,2 ; convert to pixels\r
- mov [_ScrnLogicalPixelWidth],ax ; store virt scrn pixel width\r
- mov cx,ax ; save ax (return value)\r
-\r
- ; calculate no. non split screen rows in video ram\r
-\r
- mov ax,0ffffh ; cx = Maximum video ram offset\r
- sub dx,dx ; DX:AX is divide operand, set DX = 0\r
- div bx ; divide ax by ScrnLogicalByteWidth\r
- mov [_ScrnLogicalHeight],ax ; Save Screen Logical Height\r
- mov [_BottomClip],ax ; Set default bottom clip row\r
- sub ax,[_ScrnPhysicalHeight] ; Update the maximum Y position of\r
- mov [_MaxScrollY],ax ; Physical screen in logical screen\r
- mov ax,cx ; restore ax (return value)\r
-\r
- ; calculate initial NonVisual\r
- mov ax,[_ScrnLogicalByteWidth]\r
- mul [_ScrnPhysicalHeight]\r
- mov [_NonVisual_Offs],ax\r
-\r
-@@Done: ret\r
-SetLogicalScrWidth endp\r
-\r
-clear_vram proc\r
- push di\r
- mov dx,SC_INDEX\r
- mov ax,0f02h\r
- out dx,ax ; enable writes to all four planes\r
- mov ax,SCREEN_SEG ; now clear all display memory, 8 pixels\r
- mov es,ax ; at a time\r
- sub di,di ; point ES:DI to display memory\r
-\r
- WaitVsyncEnd\r
-\r
- sub ax,ax ; clear to zero-value pixels\r
- mov cx,0FFFFh ; # of words in display memory\r
- rep stosw ; clear all of display memory\r
- pop di\r
- ret\r
-clear_vram endp\r
-\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; Mode X graphics mode set with a virtual screen\r
-; logical screen width.\r
-; C near-callable as:\r
-;\r
-; int x_set_mode(unsigned int mode,unsigned int WidthInPixels);\r
-;\r
-; returns the actual width of the allocated virtual screen in pixels\r
-; if a valid mode was selected otherwise returns -1\r
-;\r
-; Saves virtual screen pixel width in _ScrnLogicalPixelWidth.\r
-; Saves virtual screen byte width in _ScrnLogicalByteWidth.\r
-; Physical screen dimensions are set in _ScrnPhysicalPixelWidth,\r
-; _ScrnPhysicalByteWidth and _ScrnPhysicalHeight\r
-;\r
-;\r
-; Modes: 0 = 320 x 200 (256 color) NOTE: Some of these modes require\r
-; 1 = 320 x 240 (256 color) vertical size adjustment.\r
-; 2 = 360 x 200 (256 color)\r
-; 3 = 360 x 240 (256 color)\r
-; 4 = 320 x 400 (256 color)\r
-; 5 = 320 x 480 (256 color)\r
-; 6 = 360 x 200 (256 color)\r
-; 7 = 360 x 480 (256 color)\r
-; 8 = 360 x 360 (256 color)\r
-; 9 = 376 x 308 (256 color)\r
-; 10 = 376 x 564 (256 color)\r
-;\r
-; Written by Themie Gouthas,\r
-; parts adapted from M. Abrash code.\r
-;------------------------------------------------------------------------\r
-_x_set_mode proc\r
- ARG mode:word,logicalscrwidth:word\r
- push bp ;preserve caller's stack frame\r
- mov bp,sp\r
-\r
- push si ;preserve C register vars\r
- push di ; (don't count on BIOS preserving anything)\r
-\r
- cld\r
- mov ax,ds\r
- mov es,ax\r
- mov di,offset PARAMS\r
- xor ax,ax\r
- mov cx,PARAM_COUNT\r
- rep stosb\r
-\r
- mov cx,[mode]\r
- cmp cx,LAST_X_MODE ; have we selected a valid mode\r
- jle @@ValidMode ; Yes !\r
-\r
- mov [_InGraphics],FALSE ; No return -1\r
- mov ax,-1\r
- pop di\r
- pop si\r
- pop bp\r
- ret\r
-\r
-@@ValidMode:\r
-\r
- mov [_CurrXMode],cx\r
- mov [_InGraphics],TRUE\r
-\r
- xor al,al\r
- cmp cx,3\r
- jg @@SetDoubleScanFlag\r
- mov al,TRUE\r
-@@SetDoubleScanFlag:\r
- mov [DoubleScanFlag],al\r
- push cx ; some bios's dont preserve cx\r
-\r
- call clear_vram\r
-\r
- mov ax,13h ; let the BIOS set standard 256-color\r
- int 10h ; mode (320x200 linear)\r
-\r
-\r
- pop cx\r
-\r
- mov dx,SC_INDEX\r
- mov ax,0604h\r
- out dx,ax ; disable chain4 mode\r
- mov ax,0100h\r
- out dx,ax ; synchronous reset while setting Misc\r
- ; Output for safety, even though clock\r
- ; unchanged\r
-\r
- mov bx,offset ModeTable\r
- shl cx,1\r
- add bx,cx\r
- mov si, word ptr [bx]\r
- lodsb\r
-\r
- or al,al\r
- jz @@DontSetDot\r
- mov dx,MISC_OUTPUT\r
- out dx,al ; select the dot clock and Horiz\r
- ; scanning rate\r
-@@DontSetDot:\r
- mov dx,SC_INDEX\r
- mov ax,0300h\r
- out dx,ax ; undo reset (restart sequencer)\r
-\r
-\r
- mov dx,CRTC_INDEX ; reprogram the CRT Controller\r
- mov al,11h ; VSync End reg contains register write\r
- out dx,al ; protect bit\r
- inc dx ; CRT Controller Data register\r
- in al,dx ; get current VSync End register setting\r
- and al,07fh ; remove write protect on various\r
- out dx,al ; CRTC registers\r
- dec dx ; CRT Controller Index\r
- cld\r
- xor cx,cx\r
- lodsb\r
- mov cl,al\r
-\r
-@@SetCRTParmsLoop:\r
- lodsw ; get the next CRT Index/Data pair\r
- out dx,ax ; set the next CRT Index/Data pair\r
- loop @@SetCRTParmsLoop\r
-\r
- mov dx,SC_INDEX\r
- mov ax,0f02h\r
- out dx,ax ; enable writes to all four planes\r
- mov ax,SCREEN_SEG ; now clear all display memory, 8 pixels\r
- mov es,ax ; at a time\r
- sub di,di ; point ES:DI to display memory\r
- sub ax,ax ; clear to zero-value pixels\r
- mov cx,8000h ; # of words in display memory\r
- rep stosw ; clear all of display memory\r
-\r
- ; Set pysical screen dimensions\r
-\r
- lodsw ; Load scrn pixel width\r
- mov [_ScrnPhysicalPixelWidth],ax ; from tweak table and store\r
- mov [_SplitScrnScanLine],ax ; No splitscrn ==\r
- ; splitscrn=PhysicalscrnHeight\r
- mov bx,ax ; Copy width for later use\r
- shr ax,2 ; Convert to byte width\r
- mov [_ScrnPhysicalByteWidth],ax ; Store for later use\r
- lodsw ; Load Screen Phys. Height\r
- mov [_ScrnPhysicalHeight],ax ; Store for later use\r
-\r
-\r
- ; Mode X is set, now set the required logical page width.\r
-\r
- mov cx,[logicalscrwidth]\r
-\r
- call SetLogicalScrWidth\r
-\r
- pop di ;restore C register vars\r
- pop si\r
- pop bp ;restore caller's stack frame\r
- ret\r
-_x_set_mode endp\r
-\r
-;----------------------------------------------------------------------\r
-; Mode X (256 color mode) set default access video plane\r
-;\r
-; C near-callable as:\r
-; void x_select_default_plane(unsigned char plane);\r
-;\r
-; Enables Read/Write access to a plane using general memory access\r
-; methods\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_select_default_plane proc\r
-ARG Plane:byte\r
- push bp\r
- mov bp,sp ; set up stack frame\r
- mov cl,byte ptr [Plane]\r
-\r
- ; SELECT WRITE PLANE\r
- and cl,011b ;CL = plane\r
- mov ax,0100h + MAP_MASK ;AL = index in SC of Map Mask reg\r
- shl ah,cl ;set only the bit for the required\r
- ; plane to 1\r
- mov dx,SC_INDEX ;set the Map Mask to enable only the\r
- out dx,ax ; pixel's plane\r
-\r
- ; SELECT READ PLANE\r
- mov ah,cl ;AH = plane\r
- mov al,READ_MAP ;AL = index in GC of the Read Map reg\r
- mov dx,GC_INDEX ;set the Read Map to read the pixel's\r
- out dx,ax ; plane\r
-\r
- pop bp\r
- ret\r
-_x_select_default_plane endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; Mode X (256 color mode) Set Mode X split screen starting row\r
-; The split screen resides on the bottom half of the screen and has a\r
-; starting address of A000:0000\r
-;\r
-; C near-callable as:\r
-; void x_set_splitscreen(unsigned int line);\r
-;\r
-; Updates _Page0_Offs to reflect the existence of the split screen region\r
-; ie _MainScrnOffset is set to the offset of the first pixel beyond the split\r
-; screen region\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-\r
-_x_set_splitscreen proc\r
- ARG Line:word\r
- push bp\r
- mov bp,sp ; set up stack frame\r
- push si\r
-\r
- xor si,si ; si=0 -> x virtual page start coord\r
-\r
- cmp [_DoubleBufferActive],0\r
- jne @@error\r
-\r
- cmp [_SplitScrnActive],0\r
- je @@NotPreviouslyCalled\r
-\r
-@@error:\r
- mov [_ErrorValue],ERROR\r
- pop si\r
- pop bp ; Return if previously called\r
- ret\r
-\r
-@@NotPreviouslyCalled:\r
-\r
- ; Turn on split screen pal pen suppression, so the split screen\r
- ; wo'nt be subject to pel panning as is the non split screen portion.\r
-\r
- mov dx,INPUT_STATUS_0\r
- in al,dx ; Reset the AC Index/Data toggle to\r
- ; index state\r
- mov al,AC_MODE_CONTROL+20h ; Bit 5 set to prevent screen blanking\r
- mov dx,AC_INDEX ; Point AC to Index/Data register\r
- out dx,al\r
- inc dx ; Point to AC Data reg (for reads only)\r
- in al,dx ; Get the current AC Mode Control reg\r
- or al,20h ; Enable split scrn Pel panning suppress.\r
- dec dx ; Point to AC Index/Data reg (for writes only)\r
- out dx,al ; Write the new AC Mode Control setting\r
- ; with split screen pel panning\r
- ; suppression turned on\r
-\r
- mov [_PhysicalStartByteX],ax ; Set the Phisical screen start\r
- mov [_PhysicalStartPixelX],ax ; offset within virtual screen\r
- mov [_PhysicalStartY],ax\r
- mov [_SplitScrnActive],TRUE\r
- mov ax,[Line]\r
- jns @@NotNeg ; Check that Split Scrn start scan line is +ve\r
-\r
- mov ax,0 ; Since -ve set to 0\r
-\r
-@@NotNeg:\r
- mov [_SplitScrnScanLine],ax ; save the scanline\r
-\r
-\r
-\r
- or [DoubleScanFlag],0\r
- jz @@NotDoubleScanned\r
- shl ax,1\r
- dec ax\r
-@@NotDoubleScanned:\r
- ;mov cl,[DoubleScanFlag]\r
- ;shl ax,cl ; Mode X 200 and 240 line modes are actually\r
- ; 400 and 480 lines that are double scanned\r
- ; so for start scanline multiply required ModeX\r
- ; scan line by 2 if its a double scanned mode\r
-\r
-\r
- mov bx,ax ; save the scanline\r
-\r
-\r
- WaitVsyncStart ; wait for vertical retrace\r
-\r
- cli ; Dont allow register setting to be interrupted\r
- mov dx,CRTC_INDEX\r
- mov ah,bl\r
- mov al,LINE_COMPARE\r
- out dx,ax ; Bits 7-0 of the split screen scan line\r
-\r
- mov ah,bh\r
- and ah,1\r
- shl ah,4\r
- mov al,OVERFLOW ; Bit 4 of overflow register = Bit 8 of split\r
- out dx,al ; screen scan line,\r
- inc dx ; So using readability of VGA registers\r
- in al,dx ; Read the OVERFLOW register, and set the\r
- and al, not 10h ; bit corresponding to Bit 8 (above)\r
- or al,ah\r
- out dx,al\r
-\r
- dec dx\r
- mov ah,bh\r
- and ah,2\r
- ror ah,3\r
- mov al,MAX_SCAN_LINE ; Bit 6 of max scan line register =\r
- out dx,al ; Bit 9 of split screen scan line\r
- inc dx ; As we did before, update the apropriate\r
- in al,dx ; bit without disturbing the rest\r
- and al, not 40h\r
- or al,ah\r
- out dx,al\r
- sti ; Registers are set, so interrupts are safe\r
-\r
- mov ax,[_ScrnPhysicalHeight] ; Determine where the first byte\r
- sub ax,[_SplitScrnScanLine] ; of the non split screen video ram\r
- mov [_SplitScrnVisibleHeight],ax ; starts and store it for reference\r
-\r
- mov bx,[_ScrnLogicalByteWidth]\r
- mul bx\r
- mov [_Page0_Offs],ax\r
- mov [_Page1_Offs],ax\r
- mov [_Page2_Offs],ax\r
-\r
- ; calculate no. non split screen rows in video ram\r
- mov cx,0ffffh ; cx = Maximum video ram offset\r
- sub cx,ax ; cx = cx - _Page0_Offs\r
- xchg cx,ax ; swap cx and ax\r
- sub dx,dx ; DX:AX is divide operand, set DX = 0\r
- div bx ; divide ax (prev cx) by\r
- ; ScrnLogicalByteWidth\r
-\r
- mov [_ScrnLogicalHeight],ax ; Save Screen Logical Height\r
- cmp ax,[_BottomClip]\r
- jle @@BottomClipOK ; Adjust Clip Rectangle if necessary\r
- mov [_BottomClip],ax\r
-@@BottomClipOK:\r
- sub ax,[_SplitScrnScanLine] ; Update the maximum Y position of\r
- mov [_MaxScrollY],ax ; Physical screen in logical screen\r
-\r
- xchg cx,ax ; restore original ax (MainScrnOfs)\r
- mov bh,al ; Set the visible screen start address\r
- mov ch,ah ; to the top left corner of the virtual\r
- jmp StartAddrEntry ; screen\r
-_x_set_splitscreen endp\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; Mode X (256 color mode) Page flip primer\r
-; No clipping is performed.\r
-; C near-callable as:\r
-;\r
-; void x_page_flip(unsigned int x, unsigned int y);\r
-;\r
-; Swaps visible and hidden page offsets and then executes the SetStartAddr\r
-; to achieve a page flip.\r
-;\r
-; SEE x_set_start_addr below\r
-;\r
-; Written by Themie Gouthas\r
-;------------------------------------------------------------------------\r
-\r
-_x_page_flip proc\r
- ARG x:word,y:word\r
- push bp ;preserve caller's stack frame\r
- mov bp,sp ;point to local stack frame\r
- push si\r
-\r
- mov si,[x]\r
- mov ax,[_ScrnLogicalByteWidth] ; Calculate Offset increment\r
- mov cx,[y]\r
- mul cx ; for Y\r
- cmp [_DoubleBufferActive],TRUE ; Do we have double buffering ?\r
- je @@DoubleBuffer\r
- cmp [_TrippleBufferActive],TRUE\r
- jne PageFlipEntry1\r
-\r
-; TrippleBuffer\r
- mov bx,[_HiddenPageOffs]\r
- xchg bx,[_VisiblePageOffs]\r
- xchg bx,[_WaitingPageOffs]\r
- mov [_HiddenPageOffs],bx\r
- mov bx,[_VisiblePageIdx]\r
- inc bx\r
- cmp bx,3\r
- jne @@IdxOk\r
- xor bx,bx\r
-@@IdxOk:\r
- mov [_VisiblePageIdx],bx\r
- jmp short PageFlipEntry2\r
-@@DoubleBuffer:\r
- mov bx,[_HiddenPageOffs]\r
- xchg bx,[_VisiblePageOffs] ; Swap the Page Offsete\r
- xchg [_HiddenPageOffs],bx\r
- xor [_VisiblePageIdx],01h ; Set the Visible page index\r
- jmp short PageFlipEntry2\r
-_x_page_flip endp\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; Mode X (256 color mode) Set Mode X non split screen start address\r
-; of logical screen.\r
-; C near-callable as:\r
-;\r
-; void x_set_start_addr(unsigned int x, unsigned int y);\r
-;\r
-; Params: StartOffset is offset of first byte of logical screen ram\r
-; (Useful if you want to double buffer by splitting your non\r
-; split screen video ram into 2 pages)\r
-; X,Y coordinates of the top left hand corner of the physical screen\r
-; within the logical screen\r
-; X must not exceed (Logical screen width - Physical screen width)\r
-; Y must not exceed (Logical screen height - Physical screen height)\r
-;\r
-;\r
-; Written by Themie Gouthas,\r
-; Parts addapted from M. Abrash code published in DDJ Mag.\r
-;------------------------------------------------------------------------\r
-_x_set_start_addr proc\r
- ARG x:word,y:word\r
- push bp\r
- mov bp,sp\r
- push si\r
-\r
- mov si,[x]\r
- mov ax,[_ScrnLogicalByteWidth] ; Calculate Offset increment\r
- mov cx,[y] ; for Y\r
- mul cx\r
- cmp [_DoubleBufferActive],TRUE ; Do we have double buffering ?\r
- je @@PageResolution\r
- cmp [_TrippleBufferActive],TRUE\r
- je @@PageResolution\r
-PageFlipEntry1:\r
- add ax,[_Page0_Offs] ; no - add page 0 offset\r
- jmp short @@AddColumn\r
-\r
-PageFlipEntry2:\r
-\r
- mov [_PhysicalStartPixelX],si\r
- mov [_PhysicalStartY],cx\r
-\r
-@@PageResolution:\r
- add ax,[_VisiblePageOffs] ; Add visible page offset\r
-\r
-@@AddColumn:\r
- mov cx,si\r
- shr cx,2\r
- mov [_PhysicalStartByteX],cx\r
- add ax,cx ; add the column offset for X\r
- mov bh,al ; setup CRTC start addr regs and\r
- ; values in word registers for\r
- mov ch,ah ; fast word outs\r
-\r
-StartAddrEntry:\r
- mov bl,ADDR_LOW\r
- mov cl,ADDR_HIGH\r
- and si,0003h ; select pel pan register value for the\r
- mov ah,PelPanMask[si] ; required x coordinate\r
- mov al,PEL_PANNING+20h\r
- mov si,ax\r
-\r
- cmp [_VsyncHandlerActive],TRUE\r
- jne @@NoVsyncHandler\r
-; NEW STUFF\r
-@@WaitLast:\r
- cmp [_StartAddressFlag],0\r
- jne @@WaitLast\r
- cli\r
- mov [_WaitingStartLow],bx\r
- mov [_WaitingStartHigh],cx\r
- mov [_WaitingPelPan],si\r
- mov [_StartAddressFlag],1\r
- sti\r
- jmp short @@Return\r
-\r
-@@NoVsyncHandler:\r
- mov dx,INPUT_STATUS_0 ;Wait for trailing edge of Vsync pulse\r
-@@WaitDE:\r
- in al,dx\r
- test al,01h\r
- jnz @@WaitDE ;display enable is active low (0 = active)\r
-\r
- mov dx,CRTC_INDEX\r
- mov ax,bx\r
- cli\r
- out dx,ax ;start address low\r
- mov ax,cx\r
- out dx,ax ;start address high\r
- sti\r
-\r
-; Now wait for vertical sync, so the other page will be invisible when\r
-; we start drawing to it.\r
- mov dx,INPUT_STATUS_0 ;Wait for trailing edge of Vsync pulse\r
-@@WaitVS:\r
- in al,dx\r
- test al,08h\r
- jz @@WaitVS ;display enable is active low (0 = active)\r
-\r
-\r
- mov dx,AC_INDEX\r
- mov ax,si ; Point the attribute controller to pel pan\r
- cli\r
- out dx,al ; reg. Bit 5 also set to prevent blanking\r
- mov al,ah\r
- out dx,al ; load new Pel Pan setting.\r
- sti\r
-\r
-@@Return:\r
- mov [_ErrorValue],OK\r
- pop si\r
- pop bp\r
- ret\r
-_x_set_start_addr endp\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; Mode X (256 color mode) Mode X split screen hide\r
-; C near-callable as:\r
-;\r
-; void x_hide_splitscreen()\r
-;\r
-; Hides an existing split screen by setting its starting scan line to\r
-; the last physical screen scan line\r
-;\r
-; WARNING: Only to be used if SplitScrnLine has been previously called\r
-; WARNING: DO NOT USE with mode 5-11 (320x400-376x564). The memory for\r
-; the initial split screen is reserved and the size limitations\r
-; of these modes means any change in the split screen scan line\r
-; will encroach on the split screen ram\r
-;\r
-; Written by Themie Gouthas\r
-;------------------------------------------------------------------------\r
-\r
-_x_hide_splitscreen proc\r
- push bp\r
- mov bp,sp\r
-\r
- cmp [_SplitScrnActive],TRUE\r
- je @@SplitScreenEnabled\r
-\r
-@@error:\r
- mov [_ErrorValue],ERROR\r
- pop bp\r
- ret\r
-\r
-@@SplitScreenEnabled:\r
- cmp [_CurrXMode],4 ; Do nothing for Modes > 2\r
- jg @@error\r
- mov bx,[_ScrnPhysicalHeight]\r
-\r
- mov ax,[_ScrnLogicalHeight]\r
- sub ax,bx\r
- mov [_MaxScrollY],ax\r
- xor ax,ax\r
- mov [_SplitScrnVisibleHeight],ax\r
-\r
- or [DoubleScanFlag],0\r
- jz @@NotDoubleScanned\r
- shl bx,1\r
- dec bx\r
-@@NotDoubleScanned:\r
- ;mov cl,[DoubleScanFlag] ; Compensate for double scanned modes\r
- ;shl bx,cl\r
-\r
- WaitVsyncStart ; wait for vertical retrace\r
-\r
- cli ; Dont allow register setting to be interrupted\r
- mov dx,CRTC_INDEX\r
- mov ah,bl\r
- mov al,LINE_COMPARE\r
- out dx,ax ; Bits 7-0 of the split screen scan line\r
-\r
- mov ah,bh\r
- and ah,1\r
- shl ah,4\r
- mov al,OVERFLOW ; Bit 4 of overflow register = Bit 8 of split\r
- out dx,al ; screen scan line,\r
- inc dx ; So using readability of VGA registers\r
- in al,dx ; Read the OVERFLOW register, and set the\r
- and al, not 10h ; bit corresponding to Bit 8 (above)\r
- or al,ah\r
- out dx,al\r
-\r
- dec dx\r
- mov ah,bh\r
- and ah,2\r
- ror ah,3\r
- mov al,MAX_SCAN_LINE ; Bit 6 of max scan line register =\r
- out dx,al ; Bit 9 of split screen scan line\r
- inc dx ; As we did before, update the apropriate\r
- in al,dx ; bit without disturbing the rest\r
- and al, not 40h\r
- or al,ah\r
- out dx,al\r
- sti ; Registers are set, so interrupts are safe\r
-\r
-@@done:\r
-\r
- mov [_ErrorValue],OK\r
- pop bp\r
- ret\r
-_x_hide_splitscreen endp\r
-\r
-;-----------------------------------------------------------------------\r
-; Mode X (256 color mode) Mode X split screen show\r
-; C near-callable as:\r
-;\r
-; void x_show_splitscreen()\r
-;\r
-; Restores split screen start scan line to the initial split screen\r
-; starting scan line as set by SplitScrnLine.\r
-;\r
-; WARNING: Only to be used if SplitScrnLine has been previously called\r
-; WARNING: DO NOT USE with mode 5-11 (320x400-376x564). The memory for\r
-; the initial split screen is reserved and the size limitations\r
-; of these modes means any change in the split screen scan line\r
-; will encroach on the split screen ram\r
-; Update: Now disabled for these modes\r
-;\r
-; Written by Themie Gouthas\r
-;------------------------------------------------------------------------\r
-\r
-\r
-_x_show_splitscreen proc\r
- push bp\r
- mov bp,sp\r
-\r
- cmp [_SplitScrnActive],TRUE\r
- je @@SplitScreenEnabled\r
-\r
-@@error:\r
- mov [_ErrorValue],ERROR\r
- pop bp\r
- ret\r
-\r
-@@SplitScreenEnabled:\r
- cmp [_CurrXMode],4 ; Do nothing for Modes > 2\r
- jg @@error\r
-\r
- mov bx,[_SplitScrnScanLine]\r
- mov ax,[_ScrnLogicalHeight] ; Update Max Scroll Y\r
- sub ax,bx\r
- mov [_MaxScrollY],ax\r
-\r
- mov ax,[_ScrnPhysicalHeight]\r
- sub ax,bx\r
- mov [_SplitScrnVisibleHeight],ax\r
-\r
- or [DoubleScanFlag],0\r
- jz @@NotDoubleScanned\r
- shl bx,1\r
- dec bx\r
-@@NotDoubleScanned:\r
- ;mov cl,[DoubleScanFlag] ; Compensate for double scanned modes\r
- ;shl bx,cl\r
- WaitVsyncStart ; wait for vertical retrace\r
-\r
- cli ; Dont allow register setting to be interrupted\r
- mov dx,CRTC_INDEX\r
- mov ah,bl\r
- mov al,LINE_COMPARE\r
- out dx,ax ; Bits 7-0 of the split screen scan line\r
-\r
- mov ah,bh\r
- and ah,1\r
- shl ah,4\r
- mov al,OVERFLOW ; Bit 4 of overflow register = Bit 8 of split\r
- out dx,al ; screen scan line,\r
- inc dx ; So using readability of VGA registers\r
- in al,dx ; Read the OVERFLOW register, and set the\r
- and al, not 10h ; bit corresponding to Bit 8 (above)\r
- or al,ah\r
- out dx,al\r
-\r
- dec dx\r
- mov ah,bh\r
- and ah,2\r
- ror ah,3\r
- mov al,MAX_SCAN_LINE ; Bit 6 of max scan line register =\r
- out dx,al ; Bit 9 of split screen scan line\r
- inc dx ; As we did before, update the apropriate\r
- in al,dx ; bit without disturbing the rest\r
- and al, not 40h\r
- or al,ah\r
- out dx,al\r
- sti ; Registers are set, so interrupts are safe\r
-\r
-@@Done:\r
- mov [_ErrorValue],0\r
- pop bp\r
- ret\r
-_x_show_splitscreen endp\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; Mode X (256 color mode) Modify Mode X split screen starting scan line\r
-; C near-callable as:\r
-;\r
-; void x_adjust_splitscreen(unsigned int ScanLine)\r
-;\r
-; Sets the split screen start scan line to a new scan line. Valid scan lines\r
-; are between the initial split screen starting scan line and the last\r
-; physical screen scan line.\r
-;\r
-; WARNING: Only to be used if SplitScrnLine has been previously called\r
-; WARNING: DO NOT USE with mode 5-11 (320x400-376x564). The memory for\r
-; the initial split screen is reserved and the size limitations\r
-; of these modes means any change in the split screen scan line\r
-; will encroach on the split screen ram\r
-; Update: Now disabled for these modes\r
-;\r
-;\r
-; Written by Themie Gouthas\r
-;------------------------------------------------------------------------\r
-\r
-\r
-_x_adjust_splitscreen proc\r
- ARG ScanLine\r
- push bp\r
- mov bp,sp\r
-\r
- cmp [_SplitScrnActive],TRUE\r
- je @@SplitScreenEnabled\r
-\r
-@@error:\r
- mov [_ErrorValue],ERROR\r
- pop bp\r
- ret\r
-\r
-@@SplitScreenEnabled:\r
- cmp [_CurrXMode],4 ; Do nothing for Modes > 2\r
- jg @@error\r
- mov bx,[ScanLine] ; Is the required starting scan line\r
- cmp bx,[_SplitScrnScanLine] ; valid ?\r
- js @@Done ; No - Then do nothing\r
-\r
-@@ValidScanLine:\r
-\r
- mov ax,[_ScrnLogicalHeight] ; Update Max Scroll Y\r
- sub ax,bx\r
- mov [_MaxScrollY],ax\r
-\r
- mov ax,[_ScrnPhysicalHeight]\r
- sub ax,bx\r
- mov [_SplitScrnVisibleHeight],ax\r
-\r
- or [DoubleScanFlag],0\r
- jz @@NotDoubleScanned\r
- shl bx,1\r
- dec bx\r
-@@NotDoubleScanned:\r
- ;mov cl,[DoubleScanFlag] ; Compensate for double scanned modes\r
- ;shl bx,cl\r
-\r
- WaitVsyncStart ; wait for vertical retrace\r
-\r
- cli ; Dont allow register setting to be interrupted\r
-\r
- mov dx,CRTC_INDEX\r
- mov ah,bl\r
- mov al,LINE_COMPARE\r
- out dx,ax ; Bits 7-0 of the split screen scan line\r
-\r
- mov ah,bh\r
- and ah,1\r
- shl ah,4\r
- mov al,OVERFLOW ; Bit 4 of overflow register = Bit 8 of split\r
- out dx,al ; screen scan line,\r
- inc dx ; So using readability of VGA registers\r
- in al,dx ; Read the OVERFLOW register, and set the\r
- and al, not 10h ; bit corresponding to Bit 8 (above)\r
- or al,ah\r
- out dx,al\r
-\r
- dec dx\r
- mov ah,bh\r
- and ah,2\r
- ror ah,3\r
- mov al,MAX_SCAN_LINE ; Bit 6 of max scan line register =\r
- out dx,al ; Bit 9 of split screen scan line\r
- inc dx ; As we did before, update the apropriate\r
- in al,dx ; bit without disturbing the rest\r
- and al, not 40h\r
- or al,ah\r
- out dx,al\r
- sti ; Registers are set, so interrupts are safe\r
-@@Done:\r
- mov [_ErrorValue],OK\r
- pop bp\r
- ret\r
-_x_adjust_splitscreen endp\r
-\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; Mode X (256 color mode) Enable DoubleBuffering on non split screen area\r
-; C near-callable as:\r
-;\r
-; int x_set_doublebuffer(unsigned int PageHeight);\r
-;\r
-; Params: PageHeight is the height of the virtual screen to double buffer\r
-; Returns the closest possible height to the specified.\r
-;\r
-; Sets up two double buffering virtual pages\r
-; GLOBAL variables set:\r
-;\r
-; _Page1_Offs Offset of second virtual page\r
-; _NonVisual_Offs Offset of first non visible video ram byte\r
-; _DoubleBufferActive Flag\r
-; _PageAddrTable Table of Double buffering pages start offsets\r
-; _ScrnLogicalHeight Logical height of the double buffering pages\r
-;\r
-;\r
-; Written by Themie Gouthas\r
-;------------------------------------------------------------------------\r
-\r
-\r
-_x_set_doublebuffer proc\r
- ARG PageHeight:word\r
- push bp\r
- mov bp,sp\r
-\r
- cmp [_DoubleBufferActive],0\r
- je @@OkToContinue\r
-@error:\r
- mov [_ErrorValue],ERROR\r
- pop bp\r
- ret\r
-\r
-@@OkToContinue:\r
- mov [_VisiblePageIdx],0 ; Set visible Page to 0\r
- mov ax,[_ScrnLogicalHeight] ; Set Maximum D.B. Page height to\r
- shr ax,1 ; _ScrnLogicalHeight / 2\r
-\r
- mov bx,[PageHeight] ; Is the require D.B. Page Height\r
- cmp ax,bx ; > the Maximum D.B. Page Height ?\r
-\r
- js @@InvalidHeight ; no - jump\r
- mov ax,bx ; yes - Set the D.B. Page height to\r
- ; to the maximum allowed.\r
-\r
-@@InvalidHeight:\r
- mov [_ScrnLogicalHeight],ax ; Update logical screen height to\r
- ; reflect the height of a D.B. page\r
- cmp ax,[_BottomClip]\r
- jle @@BottomClipOK ; Adjust Clip Rectangle if necessary\r
- mov [_BottomClip],ax\r
-@@BottomClipOK:\r
- push ax\r
- mul [_ScrnLogicalByteWidth] ; Calculate the offset of the second\r
- mov cx,ax ; D.B. Page in video ram\r
- mov bx,[_Page0_Offs]\r
- mov [_VisiblePageOffs],bx\r
-\r
- add ax,bx\r
- mov [_Page1_Offs],ax ; Save it\r
- mov [_HiddenPageOffs],ax\r
-\r
- add ax,cx ; Calculate the offset of first byte\r
- mov [_NonVisual_Offs],ax ; beyond the D.B. pages and save it\r
- mov [_DoubleBufferActive],TRUE ; Set flag indicating D.B'ing mode on\r
-\r
- pop ax\r
- sub ax,[_ScrnPhysicalHeight]\r
- add ax,[_SplitScrnVisibleHeight]\r
- mov [_MaxScrollY],ax\r
-\r
- mov ax,dx ; return the D.B. pages' height\r
- mov [_ErrorValue],OK\r
- pop bp\r
- ret\r
-_x_set_doublebuffer endp\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; Mode X (256 color mode) Enable TrippleBuffering on non split screen area\r
-; C near-callable as:\r
-;\r
-; int x_set_tripplebuffer(unsigned int PageHeight);\r
-;\r
-; Params: PageHeight is the height of the virtual screen to tripple buffer\r
-; Returns the closest possible height to the specified.\r
-;\r
-; Sets up two tripple buffering virtual pages\r
-; GLOBAL variables set:\r
-;\r
-; _Page1_Offs Offset of second virtual page\r
-; _Page2_Offs Offset of third virtual page\r
-; _NonVisual_Offs Offset of first non visible video ram byte\r
-; _DoubleBufferActive Flag\r
-; _PageAddrTable Table of Double buffering pages start offsets\r
-; _ScrnLogicalHeight Logical height of the double buffering pages\r
-;\r
-;\r
-; Almost written by Tore Bastiansen (cut & paste from _x_set_doublebuffer)\r
-;------------------------------------------------------------------------\r
-\r
-_x_set_tripplebuffer proc\r
- ARG PageHeight:word\r
- push bp\r
- mov bp,sp\r
-\r
- cmp [_DoubleBufferActive],0\r
- jne @@Error\r
- cmp [_TrippleBufferActive],0\r
- je @@OkToContinue\r
-@@Error:\r
- mov [_ErrorValue],ERROR\r
- pop bp\r
- ret\r
-\r
-@@OkToContinue:\r
- mov [_VisiblePageIdx],0 ; Set visible Page to 0\r
- mov ax,[_ScrnLogicalHeight] ; Set Maximum T.B. Page height to\r
- mov bx,3\r
- xor dx,dx\r
- idiv bx ; _ScrnLogicalHeight / 3\r
-\r
- mov bx,[PageHeight] ; Is the require T.B. Page Height\r
- cmp ax,bx ; > the Maximum T.B. Page Height ?\r
-\r
- js @@InvalidHeight ; no - jump\r
- mov ax,bx ; yes - Set the T.B. Page height to\r
- ; to the maximum allowed.\r
-\r
-@@InvalidHeight:\r
- mov [_ScrnLogicalHeight],ax ; Update logical screen height to\r
- ; reflect the height of a T.B. page\r
- cmp ax,[_BottomClip]\r
- jle @@BottomClipOK ; Adjust Clip Rectangle if necessary\r
- mov [_BottomClip],ax\r
-@@BottomClipOK:\r
- push ax\r
- mul [_ScrnLogicalByteWidth] ; Calculate the offset of the second\r
- mov cx,ax ; D.B. Page in video ram\r
- mov bx,[_Page0_Offs]\r
- mov [_VisiblePageOffs],bx\r
-\r
- add ax,bx\r
- mov [_Page1_Offs],ax ; Save it\r
- mov [_HiddenPageOffs],ax\r
-\r
- add ax,cx\r
- mov [_Page2_Offs],ax ; Save the other it ?\r
- mov [_WaitingPageOffs],ax\r
-\r
- add ax,cx ; Calculate the offset of first byte\r
- mov [_NonVisual_Offs],ax ; beyond the D.B. pages and save it\r
- mov [_TrippleBufferActive],TRUE ; Set flag indicating T.B'ing mode on\r
-\r
- pop ax\r
- sub ax,[_ScrnPhysicalHeight]\r
- add ax,[_SplitScrnVisibleHeight]\r
- mov [_MaxScrollY],ax\r
-\r
- mov ax,dx ; return the D.B. pages' height\r
- mov [_ErrorValue],OK\r
- pop bp\r
- ret\r
-_x_set_tripplebuffer endp\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; Set Clipping rectangle\r
-; C callable as:\r
-;\r
-;\r
-; int x_set_cliprect(WORD left,WORD top, WORD right, WORD bottom);\r
-;\r
-;\r
-; NOTE clipping is byte oriented. "left" and "right" are in bytes not pixels.\r
-; Only selected functions perform any clipping at all.\r
-;\r
-; Written by Themie Gouthas\r
-;------------------------------------------------------------------------\r
-\r
-_x_set_cliprect proc\r
-ARG left:word,top:word,right:word,bottom:word\r
- push bp\r
- mov bp,sp\r
- mov ax,[left]\r
- mov bx,[right]\r
- cmp bx,ax\r
- jns @@CorrectXOrder\r
- xchg bx,ax\r
-@@CorrectXOrder:\r
- mov [_LeftClip],ax\r
- mov [_RightClip],bx\r
- mov ax,[top]\r
- mov bx,[bottom]\r
- cmp bx,ax\r
- jns @@CorrectYOrder\r
- xchg bx,ax\r
-@@CorrectYOrder:\r
- mov [_TopClip],ax\r
- mov [_BottomClip],bx\r
- pop bp\r
- ret\r
-_x_set_cliprect endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; Return to text mode\r
-;\r
-_x_text_mode proc\r
- push bp\r
- call clear_vram\r
- mov ax,03h ; Restore Text Mode\r
- int 10h\r
-\r
- pop bp\r
- ret\r
-_x_text_mode endp\r
-\r
-;-----------------------------------------------------------------------\r
-; Wait for Vertical sync\r
-_x_wait_vsync proc\r
- push bp\r
- WaitVsyncStart\r
- pop bp\r
- ret\r
-_x_wait_vsync endp\r
-\r
-\r
- end\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XMAIN - Include file\r
-;\r
-; XMAIN.ASM export functions\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
- global _x_set_mode :proc\r
- global _x_page_flip :proc\r
- global _x_set_start_addr :proc\r
- global _x_set_splitscreen :proc\r
- global _x_text_mode :proc\r
- global _x_set_mode :proc\r
- global _x_select_default_plane :proc\r
- global _x_hide_splitscreen :proc\r
- global _x_show_splitscreen :proc\r
- global _x_adjust_splitscreen :proc\r
- global _x_set_doublebuffer :proc\r
- global _x_set_tripplebuffer :proc\r
- global _x_set_cliprect :proc\r
- global _x_wait_vsync :proc
\ No newline at end of file
+++ /dev/null
-/*----------------------------------------------------------------------\r
-; MODULE XMAKEVBM\r
-;\r
-; Implements function to generate a Video bitmap (VBM) from a linear bitmap\r
-; (LBM)\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; Based on "CreateMaskedAlignedImage" published in Dr Dobbs Journal\r
-; by Michael Abrash (Jul - Aug 1991)\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-; ****** Aeronautical Research Laboratory ****************\r
-; ****** Defence Science and Technology Organisation ****************\r
-; ****** Australia ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------*/\r
-/*\r
- Here is an outline of the XLIB image formats\r
-\r
-\r
- PLANAR BITMAPS\r
- --------------\r
-\r
- Planar bitmaps as used by these functions have the following structure:\r
-\r
- BYTE 0 The bitmap width in bytes (4 pixel groups) range 1..255\r
- BYTE 1 The bitmap height in rows range 1..255\r
- BYTE 2..n1 The plane 0 pixels width*height bytes\r
- BYTE n1..n2 The plane 1 pixels width*height bytes\r
- BYTE n2..n3 The plane 2 pixels width*height bytes\r
- BYTE n3..n4 The plane 3 pixels width*height bytes\r
-\r
- LINEAR BITMAPS\r
- --------------\r
-\r
- Linear bitmaps have the following structure:\r
-\r
- BYTE 0 The bitmap width in pixels range 1..255\r
- BYTE 1 The bitmap height in rows range 1..255\r
- BYTE 2..n The width*height bytes of the bitmap\r
-\r
-\r
- VIDEO BITMAPS\r
- -------------\r
-\r
- WORD 0 Size Total size of this VBM structure in bytes\r
- WORD 1 ImageWidth Width in bytes of the image (for all alignments)\r
- WORD 2 ImageHeight Height in scan lines of the image\r
-\r
- WORD 3 Alignment 0 ImagePtr Offset in VidRAM of this aligned image\r
- +--WORD 4 MaskPtr Offset (within this structure's DS) of\r
- | . alignment masks\r
- | .\r
- | .\r
- | WORD 9 Alignment 3 ImagePtr Offset in VidRAM of this aligned image\r
- +|--WORD 10 MaskPtr Offset (within this structure's DS) of\r
- || alignment masks\r
- ||\r
- |+->BYTE 21 (WORD 11) -------+-- Image masks for alignment 0\r
- | . |\r
- | . |\r
- | BYTE 21 + ImageWidth*ImageHeight -----+\r
- |\r
- | .\r
- | . (similaly for alignments 1 - 2 )\r
- | .\r
- |\r
- +-->BYTE 21 + 3*ImageWidth*ImageHeight + 1-+-- Image masks for alignment 3\r
- . |\r
- . |\r
- BYTE 21 + 4*(ImageWidth*ImageHeight) --+\r
-\r
- .\r
- .\r
- << Similarly for alignments 2 and 3 >>\r
- .\r
- .\r
- BYTE 21 + 4*(ImageWidth*ImageHeight)\r
- -------------\r
-\r
- (And dont forget the corresponding data in video ram)\r
-\r
-\r
-*/\r
-\r
-\r
-\r
-#include <alloc.h>\r
-#include <dos.h>\r
-\r
-/* function to store the linear bitmap in the required video RAM offset */\r
-/* and in the required alignment */\r
-\r
-extern unsigned int x_store_vbm_image(unsigned int, int, char far *);\r
-\r
-\r
-/* Alignment structures, 4 of which make up the header section of the */\r
-/* video bitmap */\r
-\r
-typedef struct {\r
- unsigned int size;\r
- unsigned int ImageWidth;\r
- unsigned int ImageHeight;\r
- struct {\r
- unsigned int ImagePtr;\r
- unsigned int MaskPtr;\r
- } alignments[4];\r
-} alignment_header;\r
-\r
-/* Structure to extract width/height frol LBM (linear bit map) */\r
-\r
-typedef struct {\r
- unsigned char width;\r
- unsigned char height;\r
-} lbm_header;\r
-\r
-\r
-/*************************************************************************/\r
-/* */\r
-/* Generates all four possible mode X image/mask alignments, stores */\r
-/* image alignments in display memory, allocates memory for and generates*/\r
-/* mask alignments, and fills out a VBM aligned masked image structure. */\r
-/* Each non-zero byte in source bitmap corresponds to image pixel to be */\r
-/* drawn. */\r
-/* On success returns a far pointer to the new VBM structure otherwise */\r
-/* it returns NULL */\r
-/* */\r
-/* Source Language: C */\r
-/* */\r
-/* Parameters: */\r
-/* lbm pointer to linear bitmap */\r
-/* vramStart contains the next available video offset which is */\r
-/* also updated after calling this function */\r
-/* */\r
-/*************************************************************************/\r
-\r
-char far *x_make_vbm(char far *lbm, unsigned int *VramStart)\r
-{\r
-\r
- lbm_header far *lbm_headr;\r
- alignment_header far *vbm_headr;\r
- char far *vbm_mask_ptr,*p;\r
- char far *lbm_pixel_ptr;\r
- int align,BitNum,TempImageWidth;\r
- unsigned int TempWidth,TempHeight,TempSize,MaskSize,VramOffs,MaskSpace=0;\r
- int scanline;\r
- unsigned char MaskTemp;\r
-\r
- VramOffs = *VramStart;\r
- lbm_headr = (lbm_header far *) lbm;\r
-\r
- TempWidth = (lbm_headr->width+3)/4+1;\r
- TempHeight = lbm_headr->height;\r
- TempSize = TempWidth*TempHeight;\r
-\r
- vbm_headr = (alignment_header far *) farmalloc(22+TempSize*4);\r
- if (!vbm_headr) return NULL;\r
-\r
- MaskSpace=22;\r
-\r
- vbm_headr->ImageWidth = TempWidth;\r
- vbm_headr->ImageHeight = TempHeight;\r
- vbm_headr->size = 22+TempSize*4;\r
- for (align=0;align<4;align++){\r
- vbm_headr->alignments[align].ImagePtr = VramOffs;\r
- x_store_vbm_image(VramOffs,align,lbm);\r
- MaskSpace+=TempSize;\r
- VramOffs+=TempSize;\r
- }\r
-\r
-\r
- vbm_mask_ptr = (char far *)vbm_headr+22;\r
-\r
- for (align=0;align<4;align++){\r
- lbm_pixel_ptr = lbm + 2;\r
- vbm_headr->alignments[align].MaskPtr = FP_OFF(vbm_mask_ptr);\r
- for (scanline=0;scanline<TempHeight;scanline++){\r
- BitNum=align;\r
- MaskTemp=0;\r
- TempImageWidth=lbm_headr->width;\r
- do {\r
- MaskTemp |= (*lbm_pixel_ptr++ !=0) << BitNum;\r
- if (++BitNum > 3) {\r
- *vbm_mask_ptr++=MaskTemp;\r
- MaskTemp=BitNum=0;\r
- }\r
- } while (--TempImageWidth);\r
- *vbm_mask_ptr++=(BitNum != 0)?MaskTemp:0;\r
- }\r
-\r
- }\r
-\r
- *VramStart=VramOffs;\r
- return (char far *) vbm_headr;\r
-}\r
-\r
-\r
-\1a
\ No newline at end of file
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XMOUSE\r
-;\r
-; Mouse functions functions for all MODE X 256 Color resolutions\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; This module is based on Shane Hyde's module of the same name,\r
-; posted to Rec.Games.Programmer, October 92.\r
-;\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; mouse cursor shape by Tiaan A Geldenhuys\r
-;\r
-;-----------------------------------------------------------------------\r
-\r
-COMMENT $\r
-\r
-\r
-This is a module implementing very basic mouse functions.\r
-\r
-It does not support the full functionality of:\r
-\r
- SPLIT SCREENS\r
- SCROLLED WINDOWS\r
- VIRTUAL WINDOWS\r
-\r
- --------------------------------------\r
-\r
- MS Mouse Driver Functions\r
-\r
- Mouse Initialization 0\r
- Show Cursor 1\r
- Hide Cursor 2\r
- Get Mouse Position & Button Status 3\r
- Set Mouse Cursor Position 4\r
- Get Button Press Information 5\r
- Get Button Release Information 6\r
- Set Min/Max Horizontal Position 7\r
- Set Min/Max Vertical Position 8\r
- Define Graphics Cursor Block 9\r
- Define Text Cursor 10\r
- Read Mouse Motion Counters 11\r
- Define Event Handler 12\r
- Light Pen Emulation Mode ON 13\r
- Light Pen Emulation Mode OFF 14\r
- Set Mouse Mickey/Pixel Ratio 15\r
- Conditional Hide Cursor 16\r
- Set Double-Speed Threshold 19\r
- --------------------------------------\r
-$\r
-\r
-include xlib.inc\r
-include xdetect.inc\r
-\r
-.data\r
-\r
-global _MouseInstalled :word\r
-global _MouseHidden :word\r
-global _MouseButtonStatus :word\r
-global _MouseX :word\r
-global _MouseY :word\r
-global _MouseFrozen :byte\r
-global _MouseColor :byte\r
-\r
-global _x_define_mouse_cursor :proc\r
-global _x_show_mouse :proc\r
-global _x_hide_mouse :proc\r
-global _x_mouse_remove :proc\r
-global _x_position_mouse :proc\r
-global _x_put_cursor :proc\r
-global _x_update_mouse :proc\r
-global _x_mouse_init :proc\r
-global _x_mouse_window :proc\r
-\r
-\r
-ALIGN 2\r
-\r
-\r
-\r
- InitMouseDef db 00000001b ; Default mouse mask, note the reverse order\r
- db 00000011b\r
- db 00000111b\r
- db 00001111b\r
- db 00011111b\r
- db 00111111b\r
- db 01111111b\r
- db 11111111b\r
- db 00011111b\r
- db 00011011b\r
- db 00110001b\r
- db 00110000b\r
- db 01100000b\r
- db 01100000b\r
-\r
-\r
-\r
-COMMENT $\r
-\r
- Old mouse definition\r
-\r
- InitMouseDef db 00000001b ; Default mouse mask, note the reverse order\r
- db 00000011b\r
- db 00000111b\r
- db 00001111b\r
- db 00011111b\r
- db 00111111b\r
- db 01111111b\r
- db 11111111b\r
- db 00011100b\r
- db 00111100b\r
- db 01111100b\r
- db 00000000b\r
- db 00000000b\r
- db 00000000b\r
-\r
-$\r
-\r
- MouseMask db 168 dup(?)\r
- OldHandlerSeg dw ?\r
- OldHandlerOffs dw ?\r
- OldHandlerMask dw ?\r
- OldX dw ?\r
- OldY dw ?\r
- OldScrnOffs dw ?\r
-\r
- BGSaveOffs dw 0\r
-\r
- _MouseInstalled dw 0 ; Flag indicating whether mouse is installed\r
- _MouseHidden dw 0 ; Flag indicating whether mouse is hidden\r
- _MouseButtonStatus dw 0 ; Holds current button press information\r
- _MouseX dw 0 ; Coords of cursor hot spot\r
- _MouseY dw 0\r
- _MouseFrozen db 0 ; Mouse motion enable/disable control\r
- _MouseColor db 0 ; Mouse cursor colour\r
-\r
- inhandler db 0\r
-.code\r
-\r
-;----------------------------------------------------------------------\r
-; Local function that updates the cursor position\r
-;\r
-; Destroys SI,DI,AX,BX\r
-;\r
-;----------------------------------------------------------------------\r
-proc update_cursor near\r
- WaitVsyncStart\r
-\r
- mov di,[OldScrnOffs] ; Delete cursor (restore old background)\r
- mov ax,[OldY]\r
- mov bx,[OldX]\r
-\r
- call restorebg\r
-\r
- mov si,[_VisiblePageOffs] ; Save cursor background\r
- mov ax,[_MouseY]\r
- mov bx,[_MouseX]\r
- mov [OldScrnOffs],si\r
- mov [OldY],ax\r
- mov [OldX],bx\r
- call getbg\r
-\r
- push [_VisiblePageOffs] ; Draw the cursor\r
- mov ax,[_ScrnPhysicalHeight]\r
- push ax\r
- mov ax,0\r
- push ax\r
- push [OldY]\r
- push [OldX]\r
- call _x_put_cursor\r
- add sp,10\r
- ret\r
-update_cursor endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_mouse_init - Initialise Mode X mouse handler\r
-;\r
-; C Prototype\r
-;\r
-; int x_mouse_init()\r
-;\r
-; This is the first function you must call before using any of the mouse\r
-; functions\r
-;\r
-; WARNING: This function uses and updates "NonVisual_Offset" to allocate\r
-; video ram for the saved mouse background.\r
-;\r
-; This mouse code uses the fastest possible techniques to save and restore\r
-; mouse backgrounds and to draw the mouse cursor.\r
-;\r
-; LIMITATIONS: No clipping is supported horizontally for the mouse cursor\r
-; No validity checking is performed for NonVisual_Offs\r
-;\r
-;\r
-; **WARNING** Hide or freeze mouse while drawing using any of the other\r
-; Modules. VGA register settings are not preserved which will\r
-; result in unpredictable drawing behavior.\r
-; If you know the drawing will occur away from the mouse cursor\r
-; set MouseFrozen to TRUE (1), do your drawing then set it to\r
-; FALSE (0). Alternatively call "x_hide_mouse", perform your\r
-; drawing and then call "x_show_mouse"\r
-;\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_mouse_init proc\r
- push bp\r
- mov bp,sp\r
-\r
- cmp [_MouseButtonCount],0 ; Dont initialize if mouse detection\r
- jne @@DontInitialize ; or initialization function previously\r
- ; called\r
- xor ax,ax ; FUNC 0: Mouse Initialization\r
- int 33h ;\r
- or ax,ax ; Is there a mouse installed ?\r
- jz @@Done\r
- mov [_MouseButtonCount],bx ; Set the button count\r
-\r
-@@DontInitialize:\r
-\r
- mov [_MouseInstalled],ax\r
- or ax,ax ; Do we have an installed mouse driver ?\r
- jz @@Done ; Nop!\r
-\r
- mov ax,[_NonVisual_Offs]; ; Allocate VRAM for saved background\r
- mov BGSaveOffs,ax\r
-\r
- add ax,14*3\r
- mov [_NonVisual_Offs],ax ; Update NonVisualOffset\r
-\r
- mov ax,02 ; FUNC 2: Hide Cursor\r
- int 33h ; (hide the mouse driver's default cursor)\r
- mov _MouseInstalled,TRUE ; Indicate user mouse driver present\r
-\r
- mov ax,07h ; FUNC 7:Set min/max horizontal position\r
- mov cx,0\r
- mov dx,[_ScrnPhysicalPixelWidth]\r
- shl dx,1 ; Mult X by 2 as cursor steps by 2 pixels\r
- int 33h ; 0 < X < _ScrnPhysicalPixelWidth\r
-\r
- mov ax,08h ; FUNC 8:Set min/max vertical position\r
- mov cx,0\r
- mov dx,_ScrnPhysicalHeight\r
- int 33h ; 0 < Y < _ScrnPhysicalHeight\r
-\r
- mov ax,0fh ; FUNC 15: Mouse Hor/Vert resolution\r
- mov cx,4 ; Horiz speed >> Value => << Speed\r
- mov dx,8 ; Vert Speed\r
- int 33h\r
-\r
- mov ax,3 ; FUNC 3: Get mouse pos & button status\r
- int 33h\r
- mov [_MouseY],dx\r
- shr cx,1\r
- mov [_MouseX],cx\r
-\r
- mov ax,12 ; FUNC 12: Define Event Handler\r
- mov bx,seg mouse_handler ; ES:DX -> Event handler\r
- mov es,bx\r
- mov dx,offset mouse_handler\r
- mov cx,1fh ; Set handler for all events\r
- int 33h\r
-\r
-\r
-\r
- mov [_MouseHidden],TRUE ; Mouse initially hidden\r
-\r
- push ds ; Set the default cursor shape\r
- mov ax,offset InitMouseDef\r
- push ax\r
- call _x_define_mouse_cursor\r
- add sp,04h\r
-\r
- mov ax,[_MouseInstalled] ; Return MouseInstalled flag\r
-@@Done:\r
- pop bp\r
- ret\r
-_x_mouse_init endp\r
-\r
-;----------------------------------------------------------------------\r
-; x_mouse_window - Define a mouse window\r
-;\r
-; C Prototype\r
-;\r
-; void x_mouse_window(int x0, int y0, int x1, int y1);\r
-;\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_mouse_window proc\r
-ARG x0:word,y0:word,x1:word,y1:word\r
- push bp\r
- mov bp,sp\r
-\r
- mov ax,7 ; FUNC 7: Set X range\r
- mov cx,x0\r
- shl cx,1\r
- mov dx,x1\r
- shl dx,1\r
- int 33h\r
-\r
- mov ax,8 ; FUNC 8: Set Y range\r
- mov cx,y0\r
- mov dx,y1\r
- int 33h\r
- pop bp\r
- ret\r
-_x_mouse_window endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_define_mouse_cursor - Define a mouse cursor from an input bitmask\r
-;\r
-; C Prototype\r
-;\r
-; void x_define_mouse_cursor(char far *MouseDef, unsigned char MouseColor)\r
-;\r
-; WARNING: This function assumes MouseDef points to 14 bytes.\r
-;\r
-; Note: Bit order is in reverse. ie bit 7 represents pixel 0 ..\r
-; bit 0 represents pixel 7 in each "MouseDef" byte.\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_define_mouse_cursor proc\r
-ARG MouseDef:dword,MouseColor:byte\r
- push bp\r
- mov bp,sp\r
-\r
- cmp [_MouseInstalled],FALSE ; Check whether we have installed\r
- je @@Done ; our mouse handler and leave if not\r
-\r
- mov al,[MouseColor] ; Set the mouse pointers color\r
- mov [_MouseColor],al\r
-\r
- push si\r
- push di\r
- push ds\r
- mov ax,ds ; ES:DI -> Stored plane mask for all\r
- mov es,ax ; pixel alignments of mouse cursor\r
- mov di,offset MouseMask\r
- lds si,MouseDef\r
- xor cl,cl ; CL = current alignment (initially zero)\r
-@@AlignmentLoop:\r
- push si ; save MouseDef ptr for next alignment\r
- mov dh,14 ; Init Row counter to Cursor Height\r
-@@RowLoop:\r
- lodsb ; Load first cursor def byte each bit\r
- ; representing pixel in the row\r
- xor ah,ah ; AH is the shift overflow byte\r
- shl ax,cl ; Shift mask for current alignment\r
-\r
- mov bl,al ; store first three nibbles of ax into\r
- and bl,0fh ; consecutive bytes in the destination\r
- mov es:[di],bl ; buffer\r
- inc di\r
- shr al,4\r
- stosw\r
-\r
- dec dh ; Next row for this alignment if there\r
- jnz @@RowLoop ; are more to do\r
-\r
- pop si ; point to the start of the cursor def.\r
- inc cl ; Select next pixel alignment\r
- cmp cl,4 ; If there are more alignments to do\r
- jne @@AlignmentLoop ; then jump\r
-\r
- pop ds\r
- pop di\r
- pop si\r
-@@Done:\r
- pop bp\r
- ret\r
-_x_define_mouse_cursor endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_show_mouse - Shows a previously hidden mouse cursor\r
-;\r
-; C Prototype\r
-;\r
-; void x_show_mouse()\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_show_mouse proc\r
- push bp\r
- mov bp,sp\r
- cmp [_MouseInstalled],FALSE ; Make sure our handler is installed\r
- je @@Done\r
- cmp [_MouseHidden],FALSE ; If not hidden then exit\r
- je @@Done\r
- push si\r
- push di\r
-\r
-\r
-@@WaitEndOfHandler: ; Make sure handler not currently active\r
- mov cl,[inhandler]\r
- or cl,cl\r
- jnz @@WaitEndOfHandler\r
-\r
-\r
- mov si,[_VisiblePageOffs] ; Save mouse background and pos details\r
- mov ax,[_MouseY]\r
- mov bx,[_MouseX]\r
- mov [OldScrnOffs],si\r
- mov [OldY],ax\r
- mov [OldX],bx\r
- call getbg\r
-\r
- push [_VisiblePageOffs] ; Draw cursor\r
- push [_ScrnLogicalHeight]\r
- xor ax,ax\r
- push ax\r
- push [OldY]\r
- push [OldX]\r
- call _x_put_cursor\r
- add sp,10\r
-\r
- mov [_MouseHidden],FALSE ; Indicate mouse cursor no longer hidden\r
-\r
- pop di\r
- pop si\r
-@@Done:\r
- pop bp\r
- ret\r
-_x_show_mouse endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_hide_mouse - Hides a previously visible mouse cursor\r
-;\r
-; C Prototype\r
-;\r
-; void x_hide_mouse()\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_hide_mouse proc\r
- push bp\r
- mov bp,sp\r
-\r
- cmp [_MouseInstalled],FALSE ; Make sure our handler is installed\r
- je @@Done\r
- cmp [_MouseHidden],FALSE ; If cursor is already hidden exit\r
- jne @@Done\r
- push si\r
- push di\r
-\r
-@@WaitEndOfHandler: ; Make sure handler not currently active\r
- mov cl,[inhandler]\r
- or cl,cl\r
- jnz @@WaitEndOfHandler\r
-\r
- mov [_MouseHidden],TRUE ; Delete mouse cursor\r
- mov di,[OldScrnOffs]\r
- mov ax,[OldY]\r
- mov bx,[OldX]\r
- call restorebg\r
- pop di\r
- pop si\r
-@@Done:\r
- pop bp\r
- ret\r
-_x_hide_mouse endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_remove_mouse - removes mouse handler\r
-;\r
-; C Prototype\r
-;\r
-; void x_remove_mouse()\r
-;\r
-; NOTE: This function MUST be called before quitting the program if\r
-; a mouse handler has been installed\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_mouse_remove proc\r
- push bp\r
- mov bp,sp\r
- cmp [_MouseInstalled],FALSE ; Check whether we have installed\r
- je @@Done ; our mouse handler\r
- call _x_hide_mouse\r
- mov ax,12 ; FUNC 12: Install event handler\r
- xor cx,cx ; Disable all events\r
- int 33h\r
- mov [_MouseInstalled],FALSE\r
-@@Done:\r
- pop bp\r
- ret\r
-_x_mouse_remove endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_position_mouse - Positions the mouse cursor at the specified location\r
-;\r
-; C Prototype\r
-;\r
-; void x_position_mouse(int x, int y)\r
-;\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_position_mouse proc\r
-ARG X:word,Y:word\r
- push bp\r
- mov bp,sp\r
-\r
-@@WaitEndOfHandler: ; Make sure handler not currently active\r
- mov bl,[inhandler]\r
-\r
- or bl,bl\r
- jnz @@WaitEndOfHandler\r
-\r
- mov ax,4\r
- mov cx,X\r
- mov dx,Y\r
- mov [_MouseX],cx\r
- mov [_MouseY],dx\r
- shl cx,1\r
-\r
- mov [inhandler],1\r
- int 33h\r
-\r
- ; The handler doesnt get called so need\r
- ; to update manually;\r
-\r
- cmp [_MouseHidden],FALSE\r
- jne @@NotVisible\r
- push di si\r
- call update_cursor\r
- pop si di\r
-\r
-@@NotVisible:\r
- mov [inhandler],0\r
- pop bp\r
- ret\r
-_x_position_mouse endp\r
-\r
-;----------------------------------------------------------------------\r
-; x_update_mouse - Forces the mouse position to be updated and cursor\r
-; to be redrawn.\r
-;\r
-; C Prototype\r
-;\r
-; void x_update_mouse()\r
-;\r
-; Note this function is useful when you have set "MouseFrozen" to true.\r
-; Allows the cursor position to be updated manually rather than\r
-; automatically by the installed handler.\r
-;\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_update_mouse proc\r
- push bp\r
- mov bp,sp\r
- cmp [_MouseInstalled],FALSE ; Make sure our handler is installed\r
- je @@Done\r
- cmp [_MouseHidden],FALSE ; If cursor is already hidden exit\r
- jne @@Done\r
- push si\r
- push di\r
- mov ax,03h ; FUNC 3: get cursor pos / button status\r
- int 33h ; Update position variables first\r
- shr cx,1\r
- mov [_MouseX],cx\r
- mov [_MouseY],dx\r
- mov [_MouseButtonStatus],bx ; Update button status\r
- call update_cursor\r
- pop di\r
- pop si\r
-@@Done:\r
- pop bp\r
- ret\r
-_x_update_mouse endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_put_cursor - Draws the mouse cursor\r
-;\r
-; C Prototype\r
-;\r
-; void x_put_cursor(int X, int Y, int TopClip, int BottomClip, WORD ScrnOffs)\r
-;\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-ALIGN 2\r
-_x_put_cursor proc\r
-ARG X:word,Y:word,TopClip,BottomClip,ScrnOffs\r
-LOCAL Height,TopRow,NextLineIncr:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- mov ax,@data\r
- mov ds,ax\r
- cld\r
-\r
- mov ax,14 ; Get image height and save in AX\r
- mov bx,Y\r
- ; cx = top Row\r
-\r
- ;;;;; CLIP PROCESSING FOR TOP CLIP BORDER ;;;;;;;;;;;;;;;;;;;;;\r
-\r
- mov dx,[TopClip] ; Compare u.l. Y coord with Top\r
- sub dx,bx ; clipping border\r
- jle @@NotTopClip ; jump if not clipped from above\r
- cmp dx,ax\r
- jnl @@NotVisible ; jump if is completely obscured\r
- mov cx,dx\r
- sub ax,dx\r
- add bx,dx\r
- jmp short @@VertClipDone\r
-\r
- ;;;; EXIT FOR COMPLETELY OBSCURED ;;;;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotVisible:\r
- pop ds\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-\r
- ;;;;; CLIP PROCESSING FOR BOTTOM CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotTopClip:\r
- mov dx,[BottomClip]\r
- sub dx,bx\r
- js @@NotVisible\r
- mov cx,0\r
- cmp dx,ax\r
- jg @@VertClipDone\r
- inc dx\r
- mov ax,dx\r
-\r
-@@VertClipDone:\r
-\r
- mov [Height],ax\r
- mov [TopRow],cx\r
-\r
- mov ax,SCREEN_SEG ; Point es to VGA segment\r
- mov es,ax\r
-\r
- mov ax,bx\r
- mov cx,[_ScrnLogicalByteWidth] ; Find required screen address\r
- mul cx\r
- mov di,ax\r
-\r
- sub cx,3 ; Distance to next screen row\r
- mov [NextLineIncr],cx\r
-\r
-\r
- mov cx,[X]\r
- mov bx,cx\r
- shr cx,2\r
- add di,cx\r
- and bx,3\r
- add di,[ScrnOffs]\r
-\r
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-\r
-\r
- mov ax,42\r
- mul bx\r
- mov si,offset MouseMask\r
- add si,ax\r
-\r
- mov ax,3 ; Increment DS:BX and DS:SI to\r
- mul [TopRow] ; been clipped by the top border\r
- add si,ax ; by the L.H.S border\r
-\r
- mov dx,SC_INDEX ; Point SC register to map mask\r
- mov al,MAP_MASK ; in preperation for masking data\r
- out dx,al\r
- inc dx ; Point dx to SC data register\r
- mov ah,byte ptr [Height] ; AH = Scanline loop counter\r
- mov bl,[_MouseColor]\r
-@@RowLoop:\r
- mov cx,3 ; Width in bytes across\r
-@@ColLoop:\r
- lodsb ; load plane mask and set MAP MASK\r
- out dx,al\r
- mov es:[di],bl ; store color to specified planes\r
- inc di\r
- loop @@ColLoop\r
-\r
- add di,[NextLineIncr]\r
- dec ah\r
- jnz @@RowLoop\r
-\r
- pop ds\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_put_cursor endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; getbg - saves cursor background\r
-;\r
-; C Prototype\r
-;\r
-; local function using register parameters\r
-;\r
-; si = screen offset\r
-; ax = y\r
-; bx = x\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-ALIGN 2\r
-getbg proc near\r
-\r
- push bp\r
- mov bp,sp\r
- push ds\r
- cld\r
-\r
- mov cx,[_ScrnLogicalByteWidth] ; by mult. dest Y coord by Screen\r
- mul cx ; width then adding screen offset\r
- add si,ax ; Add Dest Screen Row to di\r
- sub cx,3\r
- shr bx,2\r
- add si,bx\r
- mov bx,cx\r
-\r
- mov di,BGSaveOffs\r
- mov ax,SCREEN_SEG ; Point es to VGA segment\r
- mov es,ax\r
- mov ds,ax\r
-\r
- mov dx,GC_INDEX ; Set bit mask for all bits from\r
- mov ax,BIT_MASK ; VGA latches and none from CPU\r
- out dx,ax\r
-\r
- mov dx,SC_INDEX ; Point SC register to map mask\r
- mov al,MAP_MASK ; in preperation for masking data\r
- out dx,al\r
- inc dx\r
- mov al,0fh\r
- out dx,al\r
-\r
- mov cx,14\r
-@@Loop:\r
- movsb\r
- movsb\r
- movsb\r
- add si,bx\r
- loop @@Loop\r
-\r
-mov dx,GC_INDEX+1 ;restore the bit mask to its default,\r
- mov al,0ffh ; which selects all bits from the CPU\r
- out dx,al ; and none from the latches (the GC\r
- ; Index still points to Bit Mask)\r
-\r
- pop ds\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-getbg endp\r
-\r
-;----------------------------------------------------------------------\r
-; restorebg - restores cursor background\r
-;\r
-; C Prototype\r
-;\r
-; local function using register parameters\r
-;\r
-; di = screen offset\r
-; ax = y\r
-; bx = x\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-ALIGN 2\r
-restorebg proc near\r
-;di = scrn offs\r
-;ax = y\r
-;bx = x\r
- push bp\r
- mov bp,sp\r
- push ds\r
- cld\r
-\r
- mov cx,[_ScrnLogicalByteWidth] ; by mult. dest Y coord by Screen\r
- mul cx ; width then adding screen offset\r
- add di,ax ; Add Dest Screen Row to di\r
- sub cx,3\r
- shr bx,2\r
- add di,bx\r
- mov si,BGSaveOffs\r
- mov ax,SCREEN_SEG ; Point es to VGA segment\r
- mov es,ax\r
- mov ds,ax\r
-\r
- mov dx,GC_INDEX ; Set bit mask for all bits from\r
- mov ax,BIT_MASK ; VGA latches and none from CPU\r
- out dx,ax\r
-\r
- mov dx,SC_INDEX ; Point SC register to map mask\r
- mov al,MAP_MASK ; in preperation for masking data\r
- out dx,al\r
- inc dx\r
- mov al,0fh\r
- out dx,al\r
-\r
- mov bx,cx\r
- mov cx,14\r
-@@Loop:\r
- movsb\r
- movsb\r
- movsb\r
- add di,bx\r
- loop @@Loop\r
- mov dx,GC_INDEX+1 ;restore the bit mask to its default,\r
- mov al,0ffh ; which selects all bits from the CPU\r
- out dx,al ; and none from the latches (the GC\r
- ; Index still points to Bit Mask)\r
- pop ds\r
- pop bp\r
- ret\r
-restorebg endp\r
-\r
-\r
-\r
-;********************** The Mouse event handler *************************\r
-\r
-ALIGN 2\r
-mouse_handler proc far\r
- push bp\r
- mov bp,sp\r
- push ds\r
-\r
- mov di,@data ; Make sure DS points to data segment\r
- mov ds,di\r
- cmp [inhandler],1\r
- jne @@NotActive\r
- pop ds\r
- pop bp\r
- ret\r
-\r
-@@NotActive:\r
- mov [inhandler],1\r
- mov [_MouseButtonStatus],bx ; Update button status\r
- test ax,1 ; Is this a motion event ?\r
- jz @@Done ; No Jump\r
-\r
- shr cx,1 ; convert X coord to pixel coords\r
- mov [_MouseX],cx ; save mouse position\r
- mov [_MouseY],dx\r
-\r
- cmp [_MouseHidden],TRUE ; If mouse hidden dont bother drawing\r
- je @@Done\r
-\r
- cmp [_MouseFrozen],TRUE ; If mouse hidden dont bother drawing\r
- je @@Done\r
-\r
- call update_cursor\r
-@@Done:\r
- mov [inhandler],0\r
- pop ds\r
- pop bp\r
- ret\r
-mouse_handler endp\r
-\r
-\r
-end\r
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XMOUSE - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;-----------------------------------------------------------------------*/\r
-\r
-#ifndef _XMOUSE_H_\r
-#define _XMOUSE_H_\r
-\r
-#define LEFT_PRESSED 1\r
-#define RIGHT_PRESSED 2\r
-\r
-/* GLOBAL VARS ========================================================= */\r
-\r
-extern WORD MouseInstalled; /* Indicates whether mouse handler installed */\r
-extern WORD MouseHidden; /* Indicates whether mouse cursor is hidden */\r
-extern WORD MouseButtonStatus;/* Holds the mouse button status */\r
-extern WORD MouseX; /* Current X position of mouse cursor */\r
-extern WORD MouseY; /* Current Y position of mouse cursor */\r
-extern BYTE MouseFrozen; /* Disallows position updates if TRUE */\r
-extern BYTE MouseColor; /* The mouse cursors colour */\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-\r
-\r
-void x_mouse_init(void); /* Initialize mouse cursor */\r
-\r
-void x_define_mouse_cursor( /* Define and set a cursor shape */\r
- char far MouseDef,\r
- int color);\r
-\r
-void x_update_mouse(void); /* Force mouse cursor position update */\r
-\r
-void x_show_mouse(void); /* Show mouse cursor if hidden */\r
-\r
-void x_hide_mouse(void); /* Hide mouse cursor if visible */\r
-\r
-void x_mouse_remove(void); /* Remove installed mouse handler */\r
-\r
-void x_position_mouse( /* Set the mouse position */\r
- int x,\r
- int y);\r
-\r
-void x_put_cursor( /* Draw the mouse cursor (NOT FOR */\r
- int x, /* general use) */\r
- int y,\r
- int topclip,\r
- int botclip,\r
- WORD ScrnOff);\r
-\r
-\r
-void x_mouse_window(int x0, /* Define a mouse window */\r
- int y0,\r
- int x1,\r
- int y1);\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif\1a\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XPAL\r
-;\r
-; Palette functions all MODE X 256 Color resolutions\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
-COMMENT $\r
-\r
-\r
-\r
- All the functions in this module operate on two variations of the\r
- pallete buffer, the raw and annotated buffers.\r
-\r
- All those functions ending in buff operate on the following palette\r
- structure:\r
-\r
- BYTE:r0,g0,b0,r1,g1,b1,...rn,gn,bn\r
-\r
- No reference to the starting colour index or number of colours stored\r
- is contained in the structure.\r
-\r
- All those functions ending in struc operate on the following palette\r
- structure:\r
-\r
- BYTE:c,BYTE:n,BYTE:r0,g0,b0,r1,g1,b1,...rn,gn,bn\r
-\r
- where c is the starting colour and n is the number of colours stored\r
-\r
-\r
- NOTE: previously interrupts were disabled for DAC reads/writes but\r
- they have been left enabled in this version to allow the mouse\r
- interrupt to be invoked.\r
-\r
-$\r
-\r
-\r
-\r
-\r
-include xlib.inc\r
-include xpal.inc\r
-\r
-.code\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; Read DAC palette into annotated type buffer with interrupts disabled\r
-; ie BYTE colours to skip, BYTE colours to set, r1,g1,b1,r1,g2,b2...rn,gn,bn\r
-;\r
-; x_get_pal_struc(char far * pal, int num_colrs, int start_color)\r
-;\r
-; WARNING: memory for the palette buffers must all be pre-allocated\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_get_pal_struc proc\r
-ARG PalBuff:dword,NumColors:word,StartColor:word\r
- push bp ; Set up stack frame\r
- mov bp,sp\r
- push di\r
- push si\r
- cld\r
-\r
- les di,dword ptr [PalBuff] ; Point es:di to palette buffer\r
- mov si,[StartColor] ; Store the Start Colour\r
- mov ax,si\r
- stosb\r
- mov dx,[NumColors] ; Store the Number of Colours\r
- mov al,dl\r
- stosb\r
-\r
- mov cx,dx ; setup regs and jump\r
- jmp short ReadPalEntry\r
-\r
-_x_get_pal_struc endp\r
-\r
-\r
-\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; Read DAC palette into raw buffer with interrupts disabled\r
-; ie BYTE r1,g1,b1,r1,g2,b2...rn,gn,bn\r
-;\r
-; x_get_pal_raw(char far * pal, int num_colrs, int start_index)\r
-;\r
-; WARNING: memory for the palette buffers must all be pre-allocated\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_get_pal_raw proc\r
-ARG PalBuff:dword,NumColors:word,StartColor:word\r
- push bp ; Set up stack frame\r
- mov bp,sp\r
- push di\r
- push si\r
-\r
- les di,dword ptr [PalBuff] ; Point es:di to palette buffer\r
-\r
- mov si,[StartColor]\r
- mov cx,[NumColors]\r
-\r
-ReadPalEntry:\r
- cld\r
- WaitVsyncStart\r
- mov ax,si\r
- mov dx,DAC_READ_INDEX\r
- ;cli\r
- out dx,al ; Tell DAC what colour to start reading\r
- mov dx,DAC_DATA\r
-\r
- mov bx,cx ; set cx to Num Colors * 3 ( size of\r
- shl bx,1 ; palette buffer)\r
- add cx,bx\r
-\r
- rep insb ; read the palette enntries\r
-\r
- ;sti\r
- pop si\r
- pop di\r
- pop bp\r
- ret\r
-_x_get_pal_raw endp\r
-\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; Write DAC palette from annotated type buffer with interrupts disabled\r
-; ie BYTE colours to skip, BYTE colours to set, r1,g1,b1,r1,g2,b2...rn,gn,bn\r
-;\r
-; x_put_pal_struc(char far * pal)\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-\r
-_x_put_pal_struc proc\r
-ARG CompPalBuff:dword\r
- push bp ;preserve caller's stack frame\r
- mov bp,sp ;point to local stack frame\r
- push ds\r
- push si\r
- cld\r
- lds si,[CompPalBuff] ; load the source compressed colour data\r
- lodsb ; get the colours to skip\r
- mov ah,0\r
- mov bx,ax ; skip colours\r
-\r
- lodsb ; get the count of colours to set\r
- mov ah,0\r
- mov cx,ax ; use it as a loop counter\r
- jmp short WritePalEntry\r
-\r
-_x_put_pal_struc endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; Write DAC palette from annotated type buffer with interrupts disabled\r
-; starting at a new palette index\r
-;\r
-; ie BYTE colours to skip, BYTE colours to set, r1,g1,b1,r1,g2,b2...rn,gn,bn\r
-;\r
-; x_transpose_pal_struc(char far * pal, int StartColor)\r
-;\r
-; WARNING: memory for the palette buffers must all be pre-allocated\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-\r
-_x_transpose_pal_struc proc\r
-ARG CompPalBuff:dword,StartColor:word\r
- push bp ;preserve caller's stack frame\r
- mov bp,sp ;point to local stack frame\r
- push ds\r
- push si\r
- cld\r
- lds si,[CompPalBuff] ; load the source compressed colour data\r
- mov bx,[StartColor]\r
- mov [si],bl\r
- inc si\r
- lodsb ; get the count of colours to set\r
- mov ah,0\r
- mov cx,ax ; use it as a loop counter\r
- jmp short WritePalEntry\r
-_x_transpose_pal_struc endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; Write DAC palette from raw buffer with interrupts disabled\r
-; ie BYTE r1,g1,b1,r1,g2,b2...rn,gn,bn\r
-;\r
-; _x_put_pal_raw(char far * pal, int num_colrs, int start_index)\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_put_pal_raw proc\r
-ARG PalBuff:dword,NumColors:word,StartColor:word\r
- push bp ; Set up stack frame\r
- mov bp,sp\r
- push ds\r
- push si\r
-\r
- mov cx,[NumColors] ; Number of colours to set\r
- mov bx,[StartColor]\r
- lds si,[PalBuff] ; ds:si -> palette buffer\r
-\r
-\r
-WritePalEntry:\r
- mov ax,@data\r
- mov es,ax\r
- cmp es:[_VsyncHandlerActive],TRUE\r
- jne @@NoVsyncHandler\r
-@@WaitForLast:\r
- cmp es:[_VsyncPaletteCount],0\r
- jne @@WaitForLast\r
- push cx\r
- push es\r
- mov di, offset _VsyncPaletteBuffer\r
- mov ax,3\r
- mul cx\r
- mov cx,ax\r
- rep movsb\r
- pop ds\r
- pop cx\r
- mov [_VsyncPaletteStart],bx\r
- mov [_VsyncPaletteCount],cx\r
- jmp short @@Done\r
-@@NoVsyncHandler:\r
-\r
-\r
- or cx,cx\r
- jz @@Done\r
- ;cli\r
- cld ; Make sure we're going the right way\r
- WaitVsyncStart ; Wait for vert sync to start\r
- mov ax,bx\r
- mov bx,60 ; set the vsync check timer (Vsync\r
- ; is tested for at each bx'th entry to\r
- ; prevent snow 60 is otimum for 10\r
- ; MHz 286 or greater\r
-\r
-@@SetLoop:\r
- mov dx,DAC_WRITE_INDEX ; Tell DAC what colour index to start\r
- out dx,al ; writing from\r
- mov dx,DAC_DATA\r
-\r
- outsb ; Set the red component\r
- outsb ; Set the green component\r
- outsb ; Set the blue component\r
- inc al ; increment the colour index\r
- dec bx ; decrement vsync test counter\r
- js @@test_vsync ; ready to test for vsync again ?\r
- loop @@SetLoop ; No! - continue loop\r
- jmp short @@Done ; All colours done\r
-\r
-@@test_vsync:\r
- mov dx,INPUT_STATUS_0\r
- push ax ; save current colour index\r
-@@Wait:\r
- in al,dx ; wait for vsync leading edge pulse\r
- test al,08h\r
- jz @@Wait\r
-\r
- pop ax ; restore current colour index\r
- mov bx,60 ; reset vsync test counter\r
- loop @@SetLoop ; loop for next colour index\r
-\r
-@@Done:\r
- ;sti\r
- pop si\r
- pop ds\r
- pop bp\r
- ret\r
-_x_put_pal_raw endp\r
-\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; Set the RGB setting of a vga color\r
-;\r
-; _x_set_rgb(unsigned char color, unsigned char R,unsigned char G,\r
-; unsigned char B)\r
-;\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_set_rgb proc\r
-ARG ColorIndex:byte,R:byte,G:byte,B:byte\r
- push bp ; Set up stack frame\r
- mov bp,sp\r
-\r
- mov al,[ColorIndex]\r
- mov dx,DAC_WRITE_INDEX ; Tell DAC what colour index to\r
- out dx,al ; write to\r
- mov dx,DAC_DATA\r
-\r
- mov al,[R] ; Set the red component\r
- out dx,al\r
- mov al,[G] ; Set the green component\r
- out dx,al\r
- mov al,[B] ; Set the blue component\r
- out dx,al\r
- pop bp\r
- ret\r
-_x_set_rgb endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; Rotate annotated palette buffer entries\r
-;\r
-; x_rot_pal_struc(char far * pal, int direction)\r
-;\r
-; Direction : 0 = backward 1 = forward\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_rot_pal_struc proc\r
-ARG PalBuff:dword,Direction:word\r
- push bp ; Set up stack frame\r
- mov bp,sp\r
- push ds\r
- push si\r
- push di\r
-\r
- cld\r
- lds si,dword ptr [PalBuff] ; point ds:si to Palette buffer\r
- lodsw ; al = colorst ot skip, ah = num colors\r
-\r
- xor ch,ch ; Set the number of palette entries to cycle in cx\r
- mov cl,ah ;\r
-\r
- jmp short RotatePalEntry\r
-\r
-_x_rot_pal_struc endp\r
-\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; Rotate raw palette buffer\r
-;\r
-; x_rot_pal_raw(char far * pal, int direction, int num_colrs)\r
-;\r
-; Direcction : 0 = backward 1 = forward\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_rot_pal_raw proc\r
-ARG PalBuff:dword,Direction:word,NumColors:word\r
- push bp ; Set up stack frame\r
- mov bp,sp\r
- push ds\r
- push si\r
- push di\r
-\r
- cld\r
- mov cx,[NumColors] ; Set the number of palette entries to cycle\r
- lds si,dword ptr [PalBuff] ; point ds:si to Palette buffer\r
-\r
-RotatePalEntry:\r
-\r
-\r
- mov ax,ds ; copy ds to es\r
- mov es,ax\r
-\r
- dec cx\r
- mov bx,cx ; Multiply cx by 3\r
- shl bx,1\r
- add cx,bx\r
-\r
- cmp [Direction],0 ; are we going forward ?\r
- jne @@forward ; yes - jump (colors move one position back)\r
-\r
- std ; no - set reverse direction\r
- add si,cx ; set si to last byte in palette\r
- add si,2\r
-\r
-@@forward:\r
- mov ax,si ; copy si to di\r
- mov di,ax\r
-\r
- lodsb ; load first color triplet into regs\r
- mov dl,al\r
- lodsb\r
- mov dh,al\r
- lodsb\r
- mov bl,al\r
-\r
- rep movsb ; move remaining triplets direction indicated\r
- ; by direction flag\r
-\r
- mov al,dl ; write color triplet from regs to last position\r
- stosb\r
- mov al,dh\r
- stosb\r
- mov al,bl\r
- stosb\r
-\r
- pop di\r
- pop si\r
- pop ds\r
- pop bp\r
- ret\r
-_x_rot_pal_raw endp\r
-\r
-;----------------------------------------------------------------------\r
-; Copy palette making intensity adjustment\r
-; x_cpcontrast_pal_struc(char far *src_pal, char far *dest_pal, unsigned char Intensity)\r
-;\r
-; WARNING: memory for the palette buffers must all be pre-allocated\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_cpcontrast_pal_struc proc\r
-ARG PalSrcBuff:dword,PalDestBuff:dword,Intensity:byte\r
- push bp ; Set up stack frame\r
- mov bp,sp\r
- push ds\r
- push si\r
- push di\r
-\r
- cld\r
- mov bh,0ffh\r
- sub bh,[Intensity]\r
- and bh,07fh ; Palettes are 7 bit\r
- lds si,dword ptr [PalSrcBuff] ; point ds:si to Source Palette buffer\r
- les di,dword ptr [PalDestBuff] ; point ds:si to Source Palette buffer\r
- lodsw ; al = colorst ot skip, ah = num color\r
- stosw\r
-\r
- xor ch,ch ; Set the number of palette entries to adjust\r
- mov cl,ah ;\r
-\r
- mov dx,0 ; flag set to 0 if all output palette entries zero\r
-@@MainLoop:\r
- lodsw\r
- sub al,bh ; adjust intensity and copy RED\r
- jns @@DecrementOK_R\r
- xor al,al\r
-@@DecrementOK_R:\r
- sub ah,bh ; adjust intensity and copy GREEN\r
- jns @@DecrementOK_G\r
- xor ah,ah\r
-@@DecrementOK_G:\r
- or dx,ax\r
- or dl,ah\r
- stosw\r
- lodsb\r
- sub al,bh ; adjust intensity and copy BLUE\r
- jns @@DecrementOK_B\r
- xor al,al\r
-@@DecrementOK_B:\r
- or dl,al\r
- stosb\r
- loop @@MainLoop\r
-\r
- mov ax,dx\r
- pop di\r
- pop si\r
- pop ds\r
- pop bp\r
- ret\r
-_x_cpcontrast_pal_struc endp\r
-\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; Write DAC palette from annotated type buffer with specified intensity\r
-; ie BYTE colours to skip, BYTE colours to set, r1,g1,b1,r1,g2,b2...rn,gn,bn\r
-;\r
-; x_put_contrast_pal_struc(char far * pal, unsigned char intensity)\r
-;\r
-; Designed for fading in or out a palette without using an intermediate\r
-; working palette buffer ! (Slow but memory efficient ... OK for small\r
-; pal strucs}\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-\r
-_x_put_contrast_pal_struc proc\r
-ARG CompPalBuff:dword,Intensity:byte\r
- push bp ;preserve caller's stack frame\r
- mov bp,sp ;point to local stack frame\r
- push ds\r
- push si\r
- push di\r
- cld\r
-\r
- mov bh,0ffh\r
- sub bh,[Intensity]\r
- and bh,07fh ; Palettes are 7 bit\r
- mov di,40 ; set the vsync check timer (Vsync\r
- ; is tested for at each di'th entry to\r
- ; prevent snow 40 is otimum for 10\r
- ; MHz 286 or greater)\r
- lds si,[CompPalBuff] ; load the source compressed colour data\r
- lodsb ; get the colours to skip\r
- mov bl,al\r
-\r
- lodsb ; get the count of colours to set\r
- mov ah,0\r
- mov cx,ax ; use it as a loop counter\r
- or cx,cx\r
- jz @@Done\r
-\r
- WaitVsyncStart ; Wait for vert sync to start\r
-\r
-@@MainLoop:\r
- mov al,bl\r
- mov dx,DAC_WRITE_INDEX ; Tell DAC what colour index to start\r
- out dx,al ; writing from\r
- inc dx ; == mov dx,DAC_DATA\r
-\r
- lodsb ; Load each colour component, modify for\r
- sub al,bh ; intensity and write to DAC H/Ware\r
- jns @@DecrementOK_R\r
- xor al,al\r
-@@DecrementOK_R:\r
- out dx,al\r
-\r
- lodsb\r
- sub al,bh\r
- jns @@DecrementOK_G\r
- xor al,al\r
-@@DecrementOK_G:\r
- out dx,al\r
-\r
- lodsb\r
- sub al,bh\r
- jns @@DecrementOK_B\r
- xor al,al\r
-@@DecrementOK_B:\r
- out dx,al\r
-\r
- inc bl ; increment color index\r
- dec di ; decrement vsync test flag\r
- js @@test_vsync\r
- loop @@MainLoop\r
- jmp short @@Done\r
-\r
-\r
-@@test_vsync:\r
- mov dx,INPUT_STATUS_0\r
- push ax ; save current colour index\r
-@@Wait:\r
- in al,dx ; wait for vsync leading edge pulse\r
- test al,08h\r
- jz @@Wait\r
-\r
- pop ax ; restore current colour index\r
- mov di,40 ; reset vsync test counter\r
- loop @@MainLoop ; loop for next colour index\r
-\r
-@@Done:\r
- ;sti\r
- pop di\r
- pop si\r
- pop ds\r
- pop bp\r
- ret\r
-\r
-_x_put_contrast_pal_struc endp\r
-\r
-\r
- end\r
-\r
-\r
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XPAL - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;----------------------------------------------------------------------*/\r
-\r
-#ifndef _XPAL_H_\r
-#define _XPAL_H_\r
-\r
-#define PAL_ROTATE_DOWN 0\r
-#define PAL_ROTATE_UP 1\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-\r
- void x_get_pal_raw( /* Read DAC palette into raw buffer */\r
- BYTE far * pal,\r
- WORD num_colrs,\r
- WORD start_index);\r
-\r
- void x_get_pal_struc( /* Read DAC palette into annotated buffer */\r
- BYTE far * pal,\r
- WORD num_colrs,\r
- WORD start_index);\r
-\r
- void x_put_pal_raw( /* Write DAC palette from raw buffer */\r
- BYTE far * pal,\r
- WORD num_colrs,\r
- WORD start_index);\r
-\r
- void x_put_pal_struc( /* Write DAC palette from annotated buffer*/\r
- BYTE far * pal);\r
-\r
- x_set_rgb( /* Set the RGB components of a color index*/\r
- BYTE color,\r
- BYTE red_c,\r
- BYTE green_c,\r
- BYTE blue_c);\r
-\r
- x_rot_pal_raw( /* Rotate a raw palette buffer */\r
- BYTE far * pal,\r
- WORD direction,\r
- WORD num_colrs);\r
-\r
- void x_rot_pal_struc( /* Rotate an anottated palette buffer */\r
- BYTE far * pal,\r
- WORD direction);\r
-\r
- WORD x_cpcontrast_pal_struc( /* Copy and contrast adjust annotated */\r
- BYTE far *src_pal, /* palette buffer */\r
- BYTE far *dest_pal,\r
- BYTE Intensity);\r
-\r
- void x_transpose_pal_struc( /* Write DAC palette from annotated type*/\r
- BYTE far * pal, /* buffer with a new offset */\r
- WORD StartColor);\r
-\r
- void x_put_contrast_pal_struc( /* Write DAC palette from annotated */\r
- BYTE far * pal, /* type buffer with specified intensity */\r
- BYTE intensity);\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-\r
-#endif\r
-\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XPAL - Include file\r
-;\r
-; XPAL.ASM export functions\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
- global _x_get_pal_struc :proc\r
- global _x_get_pal_raw :proc\r
-\r
- global _x_put_pal_struc :proc\r
- global _x_put_pal_raw :proc\r
- global _x_set_rgb :proc\r
-\r
- global _x_rot_pal_struc :proc\r
- global _x_rot_pal_raw :proc\r
-\r
-\r
- global _x_put_contrast_pal_struc:proc\r
-\r
- global _x_transpose_pal_struc :proc\r
-\r
- global _x_cpcontrast_pal_struc :proc\1a
\ No newline at end of file
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XPBITMAP\r
-;\r
-; Planar Bitmap functions - System Ram <-> Video Ram\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
-COMMENT $\r
-\r
- This module implements a set of functions to operate on planar bitmaps.\r
- Planar bitmaps as used by these functions have the following structure:\r
-\r
- BYTE 0 The bitmap width in bytes (4 pixel groups) range 1..255\r
- BYTE 1 The bitmap height in rows range 1..255\r
- BYTE 2..n1 The plane 0 pixels width*height bytes\r
- BYTE n1..n2 The plane 1 pixels width*height bytes\r
- BYTE n2..n3 The plane 2 pixels width*height bytes\r
- BYTE n3..n4 The plane 3 pixels width*height bytes\r
-\r
- These functions provide the fastest possible bitmap blts from system ram to\r
- to video and further, the single bitmap is applicable to all pixel\r
- allignments. The masked functions do not need separate masks since all non\r
- zero pixels are considered to be masking pixels, hence if a pixel is 0 the\r
- corresponding screen destination pixel is left unchanged.\r
-\r
-\r
-$\r
-\r
-include xlib.inc\r
-include xpbitmap.inc\r
-LOCALS\r
- .code\r
-\r
-;----------------------------------------------------------------------\r
-; x_flip_masked_pbm - mask write a planar bitmap from system ram to video ram\r
-; all zero source bitmap bytes indicate destination byte to be left unchanged\r
-; If "Orientation" is set then the bitmap is flipped from left to right as\r
-; it is drawn\r
-;\r
-; Source Bitmap structure:\r
-;\r
-; Width:byte, Height:byte, Bitmap data (plane 0)...Bitmap data (plane 1)..,\r
-; Bitmap data (plane 2)..,Bitmap data (plane 3)..\r
-;\r
-; note width is in bytes ie lots of 4 pixels\r
-;\r
-; x_flip_masked_pbm(X,Y,ScrnOffs,char far * Bitmap, Orientation)\r
-;\r
-;\r
-; LIMITATIONS: No clipping is supported\r
-; Only supports bitmaps with widths which are a multiple of\r
-; 4 pixels\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_flip_masked_pbm proc\r
- ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword,Orientation:word\r
- LOCAL Plane:byte,BMHeight:byte,LineInc:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
- mov ax,SCREEN_SEG\r
- mov es,ax\r
- mov ax,[Y] ; Calculate dest screen row\r
- mov bx,[_ScrnLogicalByteWidth] ; by mult. dest Y coord by Screen\r
- mul bx ; width then adding screen offset\r
- mov di,[ScrnOffs] ; store result in DI\r
- add di,ax\r
- mov cx,[X] ; Load X coord into CX and make a\r
- mov dx,cx ; copy in DX\r
- shr dx,2 ; Find starting byte in dest row\r
- add di,dx ; add to DI giving screen offset of\r
- ; first pixel's byte\r
- lds si,[Bitmap] ; DS:SI -> Bitmap data\r
- lodsw ; Al = B.M. width (bytes) AH = B.M.\r
- ; height\r
- cmp Orientation,0\r
- jz UnFlippedMasked\r
-\r
- mov [BMHeight],ah ; Save source bitmap dimensions\r
- xor ah,ah ; LineInc = bytes to the begin.\r
- add bx,ax ; of bitmaps next row on screen\r
- mov [LineInc],bx\r
- mov bh,al ; Use bh as column loop count\r
- and cx,0003h ; mask X coord giving plane of 1st\r
- ; bitmap pixel(zero CH coincidentally)\r
- mov ah,11h ; Init. mask for VGA plane selection\r
- shl ah,cl ; Shift for starting pixel plane\r
- mov dx,SC_INDEX ; Prepare VGA for cpu to video writes\r
- mov al,MAP_MASK\r
- out dx,al\r
- inc dx\r
- mov [Plane],4 ; Set plane counter to 4\r
-@@PlaneLoop:\r
- push di ; Save bitmap's start dest. offset\r
- mov bl,[BMHeight] ; Reset row counter (BL)\r
- mov al,ah\r
- out dx,al ; set vga write plane\r
-@@RowLoop:\r
- mov cl,bh ; Reset Column counter cl\r
-@@ColLoop:\r
- lodsb ; Get next source bitmap byte\r
- or al,al ; If not zero then write to dest.\r
- jz @@NoPixel ; otherwise skip to next byte\r
- mov es:[di],al\r
-@@NoPixel:\r
- dec di\r
- loop @@ColLoop ; loop if more columns left\r
- add di,[LineInc] ; Move to next row\r
- dec bl ; decrement row counter\r
- jnz @@RowLoop ; Jump if more rows left\r
- pop di ; Restore bitmaps start dest byte\r
- ror ah,1 ; Shift mask for next plane\r
- sbb di,0 ; If wrapped increment dest address\r
- dec [Plane] ; Decrement plane counter\r
- jnz @@PlaneLoop ; Jump if more planes left\r
-\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_flip_masked_pbm endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_put_masked_pbm - mask write a planar bitmap from system ram to video ram\r
-; all zero source bitmap bytes indicate destination byte to be left unchanged\r
-;\r
-; Source Bitmap structure:\r
-;\r
-; Width:byte, Height:byte, Bitmap data (plane 0)...Bitmap data (plane 1)..,\r
-; Bitmap data (plane 2)..,Bitmap data (plane 3)..\r
-;\r
-; note width is in bytes ie lots of 4 pixels\r
-;\r
-; x_put_masked_pbm(X,Y,ScrnOffs,char far * Bitmap)\r
-;\r
-;\r
-; LIMITATIONS: No clipping is supported\r
-; Only supports bitmaps with widths which are a multiple of\r
-; 4 pixels\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_put_masked_pbm proc\r
- ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword\r
- LOCAL Plane:byte,BMHeight:byte,LineInc:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
- mov ax,SCREEN_SEG\r
- mov es,ax\r
- mov ax,[Y] ; Calculate dest screen row\r
- mov bx,[_ScrnLogicalByteWidth] ; by mult. dest Y coord by Screen\r
- mul bx ; width then adding screen offset\r
- mov di,[ScrnOffs] ; store result in DI\r
- add di,ax\r
- mov cx,[X] ; Load X coord into CX and make a\r
- mov dx,cx ; copy in DX\r
- shr dx,2 ; Find starting byte in dest row\r
- add di,dx ; add to DI giving screen offset of\r
- ; first pixel's byte\r
- lds si,[Bitmap] ; DS:SI -> Bitmap data\r
- lodsw ; Al = B.M. width (bytes) AH = B.M.\r
- ; height\r
-UnFlippedMasked:\r
- mov [BMHeight],ah ; Save source bitmap dimensions\r
- xor ah,ah ; LineInc = bytes to the begin.\r
- sub bx,ax ; of bitmaps next row on screen\r
- mov [LineInc],bx\r
- mov bh,al ; Use bh as column loop count\r
- and cx,0003h ; mask X coord giving plane of 1st\r
- ; bitmap pixel(zero CH coincidentally)\r
- mov ah,11h ; Init. mask for VGA plane selection\r
- shl ah,cl ; Shift for starting pixel plane\r
- mov dx,SC_INDEX ; Prepare VGA for cpu to video writes\r
- mov al,MAP_MASK\r
- out dx,al\r
- inc dx\r
- mov [Plane],4 ; Set plane counter to 4\r
-@@PlaneLoop:\r
- push di ; Save bitmap's start dest. offset\r
- mov bl,[BMHeight] ; Reset row counter (BL)\r
- mov al,ah\r
- out dx,al ; set vga write plane\r
-@@RowLoop:\r
- mov cl,bh ; Reset Column counter cl\r
-@@ColLoop:\r
- lodsb ; Get next source bitmap byte\r
- or al,al ; If not zero then write to dest.\r
- jz @@NoPixel ; otherwise skip to next byte\r
- mov es:[di],al\r
-@@NoPixel:\r
- inc di\r
- loop @@ColLoop ; loop if more columns left\r
- add di,[LineInc] ; Move to next row\r
- dec bl ; decrement row counter\r
- jnz @@RowLoop ; Jump if more rows left\r
- pop di ; Restore bitmaps start dest byte\r
- rol ah,1 ; Shift mask for next plane\r
- adc di,0 ; If wrapped increment dest address\r
- dec [Plane] ; Decrement plane counter\r
- jnz @@PlaneLoop ; Jump if more planes left\r
-\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_put_masked_pbm endp\r
-\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_put_pbm - Write a planar bitmap from system ram to video ram\r
-;\r
-; Source Bitmap structure:\r
-;\r
-; Width:byte, Height:byte, Bitmap data (plane 0)...Bitmap data (plane 1)..,\r
-; Bitmap data (plane 2)..,Bitmap data (plane 3)..\r
-;\r
-; note width is in bytes ie lots of 4 pixels\r
-;\r
-; x_put_pbm(X,Y,ScrnOffs,char far * Bitmap)\r
-;\r
-;\r
-; LIMITATIONS: No clipping is supported\r
-; Only supports bitmaps with widths which are a multiple of\r
-; 4 pixels\r
-; FEATURES : Automatically selects REP MOVSB or REP MOVSW depending on\r
-; source bitmap width, by modifying opcode ;-).\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-\r
-\r
-_x_put_pbm proc\r
- ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword\r
- LOCAL Plane:byte,BMHeight:byte,LineInc:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
- mov ax,SCREEN_SEG\r
- mov es,ax\r
- mov ax,[Y] ; Calculate dest screen row\r
- mov bx,[_ScrnLogicalByteWidth] ; by mult. dest Y coord by Screen\r
- mul bx ; width then adding screen offset\r
- mov di,[ScrnOffs] ; store result in DI\r
- add di,ax\r
- mov cx,[X] ; Load X coord into CX and make a\r
- mov dx,cx ; copy in DX\r
- shr dx,2 ; Find starting byte in dest row\r
- add di,dx ; add to DI giving screen offset of\r
- ; first pixel's byte\r
- lds si,[Bitmap] ; DS:SI -> Bitmap data\r
- lodsw ; Al = B.M. width (bytes) AH = B.M.\r
- ; height\r
-UnFlipped:\r
- mov [BMHeight],ah ; Save source bitmap dimensions\r
- xor ah,ah ; LineInc = bytes to the begin.\r
- sub bx,ax ; of bitmaps next row on screen\r
- mov [LineInc],bx\r
- mov bh,al\r
- ; Self Modifying, Shame, shame shame..\r
- and cx,0003h ; mask X coord giving plane of 1st\r
- ; bitmap pixel(zero CH coincidentally)\r
- mov ah,11h ; Init. mask for VGA plane selection\r
- shl ah,cl ; Shift for starting pixel plane\r
- mov dx,SC_INDEX ; Prepare VGA for cpu to video writes\r
- mov al,MAP_MASK\r
- out dx,al\r
- inc dx\r
- mov [Plane],4 ; Set plane counter to 4\r
-@@PlaneLoop:\r
- push di\r
- mov bl,[BMHeight]\r
- mov al,ah\r
- out dx,al\r
-@@RowLoop:\r
- mov cl,bh\r
- shr cl,1\r
- rep movsw ; Copy a complete row for curr plane\r
- adc cl,0\r
- rep movsb\r
- add di,[LineInc] ; Move to next row\r
- dec bl ; decrement row counter\r
- jnz @@RowLoop ; Jump if more rows left\r
- pop di ; Restore bitmaps start dest byte\r
- rol ah,1 ; Shift mask for next plane\r
- adc di,0 ; If wrapped increment dest address\r
- dec [Plane] ; Decrement plane counter\r
- jnz @@PlaneLoop ; Jump if more planes left\r
-\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_put_pbm endp\r
-\r
-;----------------------------------------------------------------------\r
-; x_flip_pbm - Write a planar bitmap from system ram to video ram\r
-; If "Orientation" is set then the bitmap is flipped from left to right as\r
-; it is drawn\r
-\r
-;\r
-; Source Bitmap structure:\r
-;\r
-; Width:byte, Height:byte, Bitmap data (plane 0)...Bitmap data (plane 1)..,\r
-; Bitmap data (plane 2)..,Bitmap data (plane 3)..\r
-;\r
-; note width is in bytes ie lots of 4 pixels\r
-;\r
-; x_flip_pbm(X,Y,ScrnOffs,char far * Bitmap, WORD orientation)\r
-;\r
-;\r
-; LIMITATIONS: No clipping is supported\r
-; Only supports bitmaps with widths which are a multiple of\r
-; 4 pixels\r
-;\r
-; NOTES: The flipped put function is slower than the standard put function\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_flip_pbm proc\r
- ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword,Orientation:word\r
- LOCAL Plane:byte,BMHeight:byte,LineInc:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
- mov ax,SCREEN_SEG\r
- mov es,ax\r
- mov ax,[Y] ; Calculate dest screen row\r
- mov bx,[_ScrnLogicalByteWidth] ; by mult. dest Y coord by Screen\r
- mul bx ; width then adding screen offset\r
- mov di,[ScrnOffs] ; store result in DI\r
- add di,ax\r
- mov cx,[X] ; Load X coord into CX and make a\r
- mov dx,cx ; copy in DX\r
- shr dx,2 ; Find starting byte in dest row\r
- add di,dx ; add to DI giving screen offset of\r
- ; first pixel's byte\r
- lds si,[Bitmap] ; DS:SI -> Bitmap data\r
- lodsw ; Al = B.M. width (bytes) AH = B.M.\r
- ; height\r
- cmp Orientation,0\r
- jz UnFlipped\r
-\r
- mov [BMHeight],ah ; Save source bitmap dimensions\r
- xor ah,ah ; LineInc = bytes to the begin.\r
- add bx,ax ; of bitmaps next row on screen\r
- mov [LineInc],bx\r
- mov bh,al ; Use bh as column loop count\r
- and cx,0003h ; mask X coord giving plane of 1st\r
- ; bitmap pixel(zero CH coincidentally)\r
- mov ah,11h ; Init. mask for VGA plane selection\r
- shl ah,cl ; Shift for starting pixel plane\r
- mov dx,SC_INDEX ; Prepare VGA for cpu to video writes\r
- mov al,MAP_MASK\r
- out dx,al\r
- inc dx\r
- mov [Plane],4 ; Set plane counter to 4\r
-@@PlaneLoop:\r
- push di ; Save bitmap's start dest. offset\r
- mov bl,[BMHeight] ; Reset row counter (BL)\r
- mov al,ah\r
- out dx,al ; set vga write plane\r
-@@RowLoop:\r
- mov cl,bh ; Reset Column counter cl\r
-@@ColLoop:\r
- lodsb\r
- mov es:[di],al\r
- dec di\r
- sub di,2\r
- loop @@ColLoop ; loop if more columns left\r
-@@DoneCol:\r
- add di,[LineInc] ; Move to next row\r
- dec bl ; decrement row counter\r
- jnz @@RowLoop ; Jump if more rows left\r
- pop di ; Restore bitmaps start dest byte\r
- ror ah,1 ; Shift mask for next plane\r
- sbb di,0 ; If wrapped increment dest address\r
- dec [Plane] ; Decrement plane counter\r
- jnz @@PlaneLoop ; Jump if more planes left\r
-\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_flip_pbm endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_get_pbm - Read a planar bitmap to system ram from video ram\r
-;\r
-; Source Bitmap structure:\r
-;\r
-; Width:byte, Height:byte, Bitmap data (plane 0)...Bitmap data (plane 1)..,\r
-; Bitmap data (plane 2)..,Bitmap data (plane 3)..\r
-;\r
-; note width is in bytes ie lots of 4 pixels\r
-;\r
-; x_get_pbm(X,Y,BMwidth,BMheight,ScrnOffs,char far * Bitmap)\r
-;\r
-;\r
-; LIMITATIONS: No clipping is supported\r
-; Only supports bitmaps with widths which are a multiple of\r
-; 4 pixels\r
-; FEATURES : Automatically selects REP MOVSB or REP MOVSW depending on\r
-; source bitmap width, by modifying opcode ;-).\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_get_pbm proc\r
- ARG X:word,Y:word,SrcWidth:byte,SrcHeight:byte,ScrnOffs:word,Bitmap:dword\r
- LOCAL Plane:byte,LineInc:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
-\r
- mov ax,[Y] ; Calculate screen row\r
- mov bx,[_ScrnLogicalByteWidth] ; by mult. Y coord by Screen\r
- mul bx ; width then adding screen offset\r
- mov si,[ScrnOffs] ; store result in SI\r
- add si,ax\r
- mov cx,[X] ; Load X coord into CX and make a\r
- mov dx,cx ; copy in DX\r
- shr dx,2 ; Find starting byte in screen row\r
- add si,dx ; add to SI giving screen offset of\r
- ; first pixel's byte\r
- mov ax,SCREEN_SEG\r
- mov ds,ax\r
- les di,[Bitmap] ; ES:DI -> Bitmap data\r
- mov al,[SrcWidth]\r
- mov ah,[SrcHeight]\r
- stosw ; Al = B.M. width (bytes) AH = B.M.\r
- ; height\r
- xor ah,ah ; LineInc = bytes to the begin.\r
- sub bx,ax ; of bitmaps next row on screen\r
- mov [LineInc],bx\r
- mov bh,al\r
- ; Self Modifying, Shame, shame shame..\r
- and cx,0003h ; mask X coord giving plane of 1st\r
- ; bitmap pixel(zero CH coincidentally)\r
- mov ah,11h ; Init. mask for VGA plane selection\r
- shl ah,cl ; Shift for starting pixel plane\r
- mov dx,GC_INDEX ; Prepare VGA for cpu to video reads\r
- mov al,READ_MAP\r
- out dx,al\r
- inc dx\r
- mov [Plane],4 ; Set plane counter (BH) to 4\r
- mov al,cl\r
-@@PlaneLoop:\r
- push si\r
- mov bl,[SrcHeight]\r
- out dx,al\r
-@@RowLoop:\r
- mov cl,bh\r
- shr cl,1\r
- rep movsw ; Copy a complete row for curr plane\r
- adc cl,0\r
- rep movsb\r
- add si,[LineInc] ; Move to next row\r
- dec bl ; decrement row counter\r
- jnz @@RowLoop ; Jump if more rows left\r
- pop si ; Restore bitmaps start dest byte\r
-\r
- inc al ; Select next plane to read from\r
- and al,3 ;\r
-\r
- rol ah,1 ; Shift mask for next plane\r
- adc si,0 ; If wrapped increment dest address\r
- dec [Plane] ; Decrement plane counter\r
- jnz @@PlaneLoop ; Jump if more planes left\r
-\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_get_pbm endp\r
-\r
-\r
-\r
-\r
- end\r
-\r
-\r
-\r
- ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword,Orientation:word\r
- LOCAL Plane:byte,BMHeight:byte,LineInc:word,Columns:byte=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
- mov ax,SCREEN_SEG\r
- mov es,ax\r
- mov ax,[Y] ; Calculate dest screen row\r
- mov bx,[_ScrnLogicalByteWidth] ; by mult. dest Y coord by Screen\r
- mul bx ; width then adding screen offset\r
- mov di,[ScrnOffs] ; store result in DI\r
- add di,ax\r
- mov cx,[X] ; Load X coord into CX and make a\r
- mov dx,cx ; copy in DX\r
- shr dx,2 ; Find starting byte in dest row\r
- add di,dx ; add to DI giving screen offset of\r
- ; first pixel's byte\r
- lds si,[Bitmap] ; DS:SI -> Bitmap data\r
- lodsw ; Al = B.M. width (bytes) AH = B.M.\r
- ; height\r
- cmp Orientation,0\r
- jz UnFlipped\r
-\r
- mov [BMHeight],ah ; Save source bitmap dimensions\r
- xor ah,ah ; LineInc = bytes to the begin.\r
- add bx,ax ; of bitmaps next row on screen\r
- mov [LineInc],bx\r
- mov [Columns],al ; Use bh as column loop count\r
- and cx,0003h ; mask X coord giving plane of 1st\r
- ; bitmap pixel(zero CH coincidentally)\r
- mov ah,11h ; Init. mask for VGA plane selection\r
- shl ah,cl ; Shift for starting pixel plane\r
- mov bh,ah\r
- mov dx,SC_INDEX ; Prepare VGA for cpu to video writes\r
- mov al,MAP_MASK\r
- out dx,al\r
- inc dx\r
- mov [Plane],4 ; Set plane counter to 4\r
-@@PlaneLoop:\r
- push di ; Save bitmap's start dest. offset\r
- mov bl,[BMHeight] ; Reset row counter (BL)\r
- mov al,bh\r
- out dx,al ; set vga write plane\r
-@@RowLoop:\r
- mov cl,[Columns] ; Reset Column counter cl\r
- shr cx,1\r
- jnc @@ColLoop\r
- lodsb\r
- mov es:[di],al\r
- dec di\r
-@@ColLoop:\r
- lodsw ; Get next source bitmap byte\r
- xchg al,ah\r
- mov es:[di],ax\r
- sub di,2\r
- loop @@ColLoop ; loop if more columns left\r
-\r
- add di,[LineInc] ; Move to next row\r
- dec bl ; decrement row counter\r
- jnz @@RowLoop ; Jump if more rows left\r
- pop di ; Restore bitmaps start dest byte\r
- ror bh,1 ; Shift mask for next plane\r
- sbb di,0 ; If wrapped increment dest address\r
- dec [Plane] ; Decrement plane counter\r
- jnz @@PlaneLoop ; Jump if more planes left\r
-\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret
\ No newline at end of file
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XPBITMAP - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-; ****** Aeronautical Research Laboratory ****************\r
-; ****** Defence Science and Technology Organisation ****************\r
-; ****** Australia ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;-----------------------------------------------------------------------*/\r
-\r
-#ifndef _XPBITMAP_H_\r
-#define _XPBITMAP_H_\r
-\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-\r
- void x_put_masked_pbm( /* Copy a planar bitmap from SRAM masking */\r
- WORD X, /* only non zero pixels to VRAM */\r
- WORD Y,\r
- WORD ScrnOffs,\r
- BYTE far * Bitmap);\r
-\r
- void x_flip_masked_pbm( /* Copy a planar bitmap from SRAM masking */\r
- WORD X, /* only non zero pixels to VRAM. Bitmap */\r
- WORD Y, /* is mirrored. */\r
- WORD ScrnOffs,\r
- BYTE far * Bitmap,\r
- WORD orientation);\r
-\r
- void x_put_pbm( /* Copy a planar bitmap from SRAM to VRAM */\r
- WORD X,\r
- WORD Y,\r
- WORD ScrnOffs,\r
- BYTE far * Bitmap);\r
-\r
- void x_flip_pbm( /* Copy a planar bitmap from SRAM to VRAM */\r
- WORD X,\r
- WORD Y,\r
- WORD ScrnOffs,\r
- BYTE far * Bitmap,\r
- WORD orientation);\r
-\r
- void x_get_pbm( /* Copy a planar bitmap from VRAM to SRAM */\r
- WORD X,\r
- WORD Y,\r
- BYTE Bw,\r
- BYTE Bh,\r
- WORD ScrnOffs,\r
- BYTE far * Bitmap);\r
-\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-\r
-#endif\r
-\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XPBITMAP - Include file\r
-;\r
-; XPBITMAP.ASM export functions\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
- global _x_put_masked_pbm :proc\r
- global _x_flip_masked_pbm :proc\r
- global _x_put_pbm :proc\r
- global _x_flip_pbm :proc\r
- global _x_get_pbm :proc\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XPBMCLIP\r
-;\r
-; Clipped Planar Bitmap functions - System Ram <-> Video Ram\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
-COMMENT $\r
-\r
- This module implements a set of functions to operate on planar bitmaps.\r
- Planar bitmaps as used by these functions have the following structure:\r
-\r
- BYTE 0 The bitmap width in bytes (4 pixel groups) range 1..255\r
- BYTE 1 The bitmap height in rows range 1..255\r
- BYTE 2..n1 The plane 0 pixels width*height bytes\r
- BYTE n1..n2 The plane 1 pixels width*height bytes\r
- BYTE n2..n3 The plane 2 pixels width*height bytes\r
- BYTE n3..n4 The plane 3 pixels width*height bytes\r
-\r
- These functions provide the fastest possible bitmap blts from system ram to\r
- to video and further, the single bitmap is applicable to all pixel\r
- allignments. The masked functions do not need separate masks since all non\r
- zero pixels are considered to be masking pixels, hence if a pixel is 0 the\r
- corresponding screen destination pixel is left unchanged.\r
-\r
-\r
-$\r
-LOCALS\r
-include xlib.inc\r
-include xpbmclip.inc\r
-\r
- .code\r
-\r
-;----------------------------------------------------------------------\r
-; x_put_masked_pbm_clipx - mask write a planar bitmap from system ram to video\r
-; ram all zero source bitmap bytes indicate destination\r
-; byte to be left unchanged.\r
-; Performs clipping in x directions. similar to\r
-; "x_put_masked_pbm".\r
-;\r
-; See Also: x_put_masked_pbm, x_put_masked_pbm_clipxy\r
-;\r
-; Clipping region variables: LeftClip,RightClip\r
-;\r
-; Written by Themie Gouthas\r
-;\r
-; This code is a SLOW hack, any better ideas are welcome\r
-;----------------------------------------------------------------------\r
-_x_put_masked_pbm_clipx proc\r
-ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword\r
-LOCAL Plane:byte,CType,LeftSkip,DataInc,Width,Height,TopRow,LineInc:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
-\r
- les si,[Bitmap] ; Point ES:SI to start of bitmap\r
-\r
- xor ax,ax ; Clear AX\r
- mov [CType],ax ; Clear Clip type descision var\r
- mov al,byte ptr es:[si] ; AX=width (byte coverted to word)\r
-\r
-\r
- mov di,[X] ; DI = X coordinate of dest\r
- mov cx,di ; copy to CX\r
- sar di,2 ; convert to offset in row\r
-\r
-\r
- ;;;;; CLIP PROCESSING FOR LEFT CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
- mov dx,[_LeftClip] ; Is X Coord to the right of\r
- sub dx,di ; LeftClip ?\r
- jle @@NotLeftClip ; Yes! => no left clipping\r
- cmp dx,ax ; Is dist of X Coord from\r
- jnl @@NotVisible ; ClipLeft > Width ? yes => the\r
- ; bitmap is not visible\r
- add di,dx\r
- mov [LeftSkip],dx\r
- mov [DataInc],dx\r
- sub ax,dx\r
- mov [CType],1\r
- jmp short @@HorizClipDone\r
-\r
- ;;;; EXIT FOR COMPLETELY OBSCURED P.B.M's ;;;;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotVisible:\r
- mov ax,1\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-\r
- ;;;;; CLIP PROCESSING FOR RIGHT CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotLeftClip:\r
- mov dx,[_RightClip]\r
- sub dx,di\r
- js @@NotVisible\r
- mov [LeftSkip],0\r
- mov [DataInc],0\r
- cmp dx,ax\r
- jge @@HorizClipDone ; was jg\r
- inc dx\r
- sub ax,dx\r
- mov [DataInc],ax\r
- mov ax,dx\r
- mov [CType],-1\r
-\r
-@@HorizClipDone:\r
-\r
- xor bh,bh\r
- mov bl,byte ptr es:[si+1] ; BX = height\r
-\r
- mov [Width],ax ; Save width and height of clipped\r
- mov [Height],bx ; image\r
-\r
-\r
- add si,2 ; Skip dimension bytes in source\r
- add si,[LeftSkip] ; Skip pixels in front of row that\r
- ; are clipped\r
-\r
-\r
- mov bx,[_ScrnLogicalByteWidth] ; Set BX to Logical Screen Width\r
- mov dx,bx ; BX - Width of image = No. bytes\r
- sub dx,ax ; to first byte of next screen\r
- mov [LineInc],dx ; row.\r
-\r
- mov ax,[Y] ; Calculate screen start row\r
- mul bx ; then adding screen offset\r
- add di,ax\r
- add di,[ScrnOffs]\r
- mov ax,es ; copy ES to DS\r
- mov ds,ax\r
- mov ax,SCREEN_SEG ; Point ES to VGA segment\r
- mov es,ax\r
-\r
- and cx,3\r
- mov ah,11h ; Set up initial plane mask\r
- shl ah,cl\r
-\r
- mov dx,SC_INDEX ; Prepare VGA for cpu to video writes\r
- mov al,MAP_MASK\r
- out dx,al\r
- inc dx\r
- mov [Plane],4 ; Set plane counter to 4\r
- mov bh,byte ptr [Width] ; set bh to width for fast looping\r
-@@PlaneLoop:\r
- push di ; Save bitmap's start dest. offset\r
- mov bl,byte ptr [Height] ; Reset row counter (BL)\r
- mov al,ah\r
- out dx,al ; set vga write plane\r
-@@RowLoop:\r
- mov cl,bh ; Reset Column counter cl\r
- jcxz @@NoWidth\r
-@@ColLoop:\r
- lodsb ; Get next source bitmap byte\r
- or al,al ; If not zero then write to dest.\r
- jz @@NoPixel ; otherwise skip to next byte\r
- mov es:[di],al\r
-@@NoPixel:\r
- inc di\r
- loop @@ColLoop\r
-@@NoWidth:\r
- add si,[DataInc] ; Move to next source row\r
- add di,[LineInc] ; Move to next screen row\r
- dec bl ; decrement row counter\r
- jnz @@RowLoop ; Jump if more rows left\r
- pop di ; Restore bitmaps start dest byte\r
- rol ah,1 ; Shift mask for next plane\r
-\r
- ; Plane Transition (A HACK but it works!)\r
-\r
- jnb @@Nocarry ; Jump if not plane transition\r
- mov bl,ah ; Save Plane Mask\r
- mov ax,[CType] ; set AX to clip type inc variable\r
- add bh,al ; Update advancing variables\r
- sub [DataInc],ax ;\r
- sub [LineInc],ax ;\r
- cmp al,0 ; What type of clip do we have\r
- mov ah,bl ; restore Plane mask\r
- jg @@RightAdvance ; jump on a right clip!\r
- inc di ; otherwise increment DI\r
- jmp @@Nocarry\r
-@@RightAdvance:\r
- dec si\r
-@@Nocarry:\r
- dec [Plane] ; Decrement plane counter\r
- jnz @@PlaneLoop ; Jump if more planes left\r
-\r
- xor ax,ax\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_put_masked_pbm_clipx endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_put_masked_pbm_clipy - mask write a planar bitmap from system ram to video\r
-; ram all zero source bitmap bytes indicate destination\r
-; byte to be left unchanged.\r
-; Performs clipping in y direction. similar to\r
-; "x_put_masked_pbm".\r
-;\r
-; See Also: x_put_masked_pbm, x_put_masked_pbm_clipx, x_put_masked_pbm_clipy\r
-;\r
-; Clipping region variables: TopClip,BottomClip\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_put_masked_pbm_clipy proc\r
-ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword\r
-LOCAL Width,Height,TopRow,LineInc,PlaneInc:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
-\r
- les si,[Bitmap]\r
-\r
- xor bh,bh\r
- mov bl,byte ptr es:[si+1] ; BX = height\r
-\r
- xor ah,ah\r
- mov al,byte ptr es:[si] ; AX = width\r
-\r
- mov cx,ax ; Save AX\r
- mul bx ; AX = AX*BX = bytes/plane\r
- mov [PlaneInc],ax ; save as PlaneInc\r
- mov ax,cx ; Restore AX\r
-\r
- mov di,[X]\r
- mov cx,di\r
- shr di,2\r
-\r
- ;;;;; CLIP PROCESSING FOR TOP CLIP BORDER ;;;;;;;;;;;;;;;;;;;;;\r
-\r
- mov dx,[_TopClip] ; Compare u.l. Y coord with Top\r
- sub dx,[Y] ; clipping border\r
- jle @@NotTopClip ; jump if VBM not clipped from above\r
- cmp dx,bx\r
- jnl @@NotVisible ; jump if VBM is completely obscured\r
- mov [TopRow],dx\r
- sub bx,dx\r
- add [Y],dx\r
- jmp short @@VertClipDone\r
-\r
- ;;;; EXIT FOR COMPLETELY OBSCURED P.B.M's ;;;;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotVisible:\r
- mov ax,1\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-\r
- ;;;;; CLIP PROCESSING FOR BOTTOM CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotTopClip:\r
- mov dx,[_BottomClip]\r
- sub dx,[Y]\r
- js @@NotVisible\r
- mov [TopRow],0\r
- cmp dx,bx\r
- jg @@VertClipDone\r
- inc dx\r
- mov bx,dx\r
-\r
-@@VertClipDone:\r
-\r
- mov [Width],ax\r
- mov [Height],bx ; Calculate relative offset in data\r
- mul [TopRow] ; of first visible scanline\r
- add ax,2 ; Skip dimension bytes in source\r
- add si,ax ; Skip top rows that arent visible\r
-\r
-\r
- mov ax,[Y] ; Calculate screen row\r
- mov bx,[_ScrnLogicalByteWidth] ; by mult. Y coord by Screen\r
- mul bx ; width then adding screen offset\r
- add di,ax\r
- add di,[ScrnOffs]\r
- sub bx,[Width] ; calculate difference from end of\r
- mov [LineInc],bx ; b.m. in curr line to beginning of\r
- ; b.m. on next scan line\r
- mov ax,es ; copy ES to DS\r
- mov ds,ax\r
- mov ax,SCREEN_SEG ; Point ES to VGA segment\r
- mov es,ax\r
-\r
- mov ah,11h ; Set up initial plane mask\r
- and cx,3\r
- shl ah,cl\r
-\r
- mov dx,SC_INDEX ; Prepare VGA for cpu to video writes\r
- mov al,MAP_MASK\r
- out dx,al\r
- inc dx\r
- mov bh,4 ; Set plane counter to 4\r
-@@PlaneLoop:\r
- push di ; Save bitmap's start dest. offset\r
- push si ; Save Bitmaps data offset\r
- mov bl,byte ptr [Height] ; Reset row counter (BL)\r
- mov al,ah\r
- out dx,al ; set vga write plane\r
-@@RowLoop:\r
- mov cl,byte ptr [Width] ; Reset Column counter cl\r
-@@ColLoop:\r
- lodsb ; Get next source bitmap byte\r
- or al,al ; If not zero then write to dest.\r
- jz @@NoPixel ; otherwise skip to next byte\r
- mov es:[di],al\r
-@@NoPixel:\r
- inc di\r
- loop @@ColLoop ; loop if more columns left\r
- add di,[LineInc] ; Move to next row\r
- dec bl ; decrement row counter\r
- jnz @@RowLoop ; Jump if more rows left\r
- pop si ; Restore SI and set to offset of\r
- add si,[PlaneInc] ; first vis pixel in next plane data\r
- pop di ; Restore bitmaps start dest byte\r
- rol ah,1 ; Shift mask for next plane\r
- adc di,0 ; if carry increment screen offset\r
- dec bh ; Decrement plane counter\r
- jnz @@PlaneLoop ; Jump if more planes left\r
-\r
- xor ax,ax\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_put_masked_pbm_clipy endp\r
-\r
-;----------------------------------------------------------------------\r
-; x_put_masked_pbm_clipxy - Write a planar bitmap from system ram to video\r
-; RAM with clipping in x and y directions. similar to\r
-; "x_put_masked_pbm".\r
-;\r
-; See Also: x_put_masked_pbm, x_put_masked_pbm_clipx, x_put_masked_pbm_clipxy\r
-;\r
-; Clipping region variables: LeftClip,RightClip,TopClip,BottomClip\r
-;\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_put_masked_pbm_clipxy proc\r
-ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword\r
-LOCAL Plane:byte,CType,LeftSkip,DataInc,Width,Height,TopRow,LineInc,PlaneInc:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
-\r
- les si,[Bitmap]\r
-\r
- xor ax,ax\r
- mov [CType],ax\r
- mov al,byte ptr es:[si] ; AX = width\r
- xor bh,bh\r
- mov bl,byte ptr es:[si+1] ; BX = height\r
-\r
- mov cx,ax ; Save AX\r
- mul bx ; AX = AX*BX = bytes/plane\r
- mov [PlaneInc],ax ; save as PlaneInc\r
- mov ax,cx ; Restore AX\r
-\r
-\r
- mov di,[X] ; DI = X coordinate of dest.\r
- mov cx,di ; save in CX\r
- sar di,2 ; convert to address byte\r
-\r
-\r
- ;;;;; CLIP PROCESSING FOR TOP CLIP BORDER ;;;;;;;;;;;;;;;;;;;;;\r
-\r
- mov dx,[_TopClip] ; Compare u.l. Y coord with Top\r
- sub dx,[Y] ; clipping border\r
- jle @@NotTopClip ; jump if VBM not clipped from above\r
- cmp dx,bx\r
- jnl @@NotVisible ; jump if VBM is completely obscured\r
- mov [TopRow],dx\r
- sub bx,dx\r
- add [Y],dx\r
- jmp short @@VertClipDone\r
-\r
- ;;;; EXIT FOR COMPLETELY OBSCURED P.B.M's ;;;;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotVisible:\r
- mov ax,1\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-\r
- ;;;;; CLIP PROCESSING FOR BOTTOM CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotTopClip:\r
- mov dx,[_BottomClip]\r
- sub dx,[Y]\r
- js @@NotVisible\r
- mov [TopRow],0\r
- cmp dx,bx\r
- jg @@VertClipDone\r
- inc dx\r
- mov bx,dx\r
-\r
-@@VertClipDone:\r
-\r
- ;;;;; CLIP PROCESSING FOR LEFT CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
- mov dx,[_LeftClip]\r
- sub dx,di\r
- jle @@NotLeftClip\r
- cmp dx,ax\r
- jnl @@NotVisible\r
-\r
- add di,dx\r
- mov [LeftSkip],dx\r
- mov [DataInc],dx\r
- sub ax,dx\r
- mov [CType],1\r
- jmp short @@HorizClipDone\r
-\r
- ;;;;; CLIP PROCESSING FOR RIGHT CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotLeftClip:\r
- mov dx,[_RightClip]\r
- sub dx,di\r
- js @@NotVisible\r
- mov [LeftSkip],0\r
- mov [DataInc],0\r
- cmp dx,ax\r
- jge @@HorizClipDone ; was jg\r
- inc dx\r
- sub ax,dx\r
- mov [DataInc],ax\r
- mov ax,dx\r
-\r
-\r
- mov [CType],-1\r
-\r
-@@HorizClipDone:\r
-\r
-\r
-\r
- mov [Width],ax ; Save width and height of clipped\r
- mov [Height],bx ; image\r
-\r
- add ax,[DataInc] ; AX = original width of image\r
- mul [TopRow] ; Calculate bytes in clipped top\r
- add si,ax ; rows\r
- add si,2 ; Skip dimension bytes in source\r
- add si,[LeftSkip] ; Skip pixels in front of row that\r
- ; are clipped\r
-\r
- mov bx,[_ScrnLogicalByteWidth] ; Set BX to Logical Screen Width\r
- mov dx,bx ; BX - Width of image = No. bytes\r
- sub dx,[Width] ; to first byte of next screen\r
- mov [LineInc],dx ; row.\r
-\r
- mov ax,[Y] ; Calculate screen start row\r
- mul bx ; then adding screen offset\r
- add di,ax\r
- add di,[ScrnOffs]\r
- mov ax,es ; copy ES to DS\r
- mov ds,ax\r
- mov ax,SCREEN_SEG ; Point ES to VGA segment\r
- mov es,ax\r
-\r
-\r
-\r
- and cx,3\r
- mov ah,11h ; Set up initial plane mask\r
- shl ah,cl\r
-\r
- mov dx,SC_INDEX ; Prepare VGA for cpu to video writes\r
- mov al,MAP_MASK\r
- out dx,al\r
- inc dx\r
- mov [Plane],4 ; Set plane counter to 4\r
- mov bh,byte ptr [Width] ; set bh to width for fast looping\r
-@@PlaneLoop:\r
- push di ; Save bitmap's start dest. offset\r
- push si\r
- mov bl,byte ptr [Height] ; Reset row counter (BL)\r
- mov al,ah\r
- out dx,al ; set vga write plane\r
-@@RowLoop:\r
- mov cl,bh ; Reset Column counter cl\r
- jcxz @@NoWidth\r
-@@ColLoop:\r
- lodsb ; Get next source bitmap byte\r
- or al,al ; If not zero then write to dest.\r
- jz @@NoPixel ; otherwise skip to next byte\r
- mov es:[di],al\r
-@@NoPixel:\r
- inc di\r
- loop @@ColLoop\r
-@@NoWidth:\r
- add si,[DataInc] ; Move to next source row\r
- add di,[LineInc] ; Move to next screen row\r
- dec bl ; decrement row counter\r
- jnz @@RowLoop ; Jump if more rows left\r
- pop si ; Restore SI and set to offset of\r
- add si,[PlaneInc] ; first vis pixel in next plane data\r
- pop di ; Restore bitmaps start dest byte\r
- rol ah,1 ; Shift mask for next plane\r
-\r
- ; Plane Transition (A HACK but it works!)\r
-\r
- jnb @@Nocarry ; Jump if not plane transition\r
- mov bl,ah ; Save Plane Mask\r
- mov ax,[CType] ; set AX to clip type inc variable\r
- add bh,al ; Update advancing variables\r
- sub [DataInc],ax ;\r
- sub [LineInc],ax ;\r
- cmp al,0 ; What type of clip do we have\r
- mov ah,bl ; restore Plane mask\r
- jg @@RightAdvance ; jump on a right clip!\r
- inc di ; otherwise increment DI\r
- jmp @@Nocarry\r
-@@RightAdvance:\r
- dec si\r
-@@Nocarry:\r
- dec [Plane] ; Decrement plane counter\r
- jnz @@PlaneLoop ; Jump if more planes left\r
-\r
- xor ax,ax\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_put_masked_pbm_clipxy endp\r
-\r
-\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_put_pbm_clipx - Write a planar bitmap from system ram to video ram\r
-; with clipping in x and y directions. similar to\r
-; "x_put_pbm".\r
-;\r
-; See Also: x_put_pbm_clip\r
-;\r
-;\r
-; See Also: x_put_pbm,x_put_pbm_clipy,x_put_pbm_clipxy\r
-;\r
-; Clipping region variables: LeftClip,RightClip\r
-;\r
-; Written by Themie Gouthas\r
-;\r
-; This code is a SLOW hack, any better ideas are welcome\r
-;----------------------------------------------------------------------\r
-_x_put_pbm_clipx proc\r
-ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword\r
-LOCAL Plane:byte,CType,LeftSkip,DataInc,Width,Height,TopRow,LineInc:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
-\r
- les si,[Bitmap]\r
-\r
- xor ax,ax\r
- mov [CType],ax\r
- mov al,byte ptr es:[si] ; AX = width\r
-\r
-\r
- mov di,[X] ; DI = X coordinate of dest.\r
- mov cx,di ; save in CX\r
- sar di,2 ; convert to address byte\r
-\r
-\r
-\r
- ;;;;; CLIP PROCESSING FOR LEFT CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
- mov dx,[_LeftClip]\r
- sub dx,di\r
- jle @@NotLeftClip\r
- cmp dx,ax\r
- jnl @@NotVisible\r
-\r
- add di,dx\r
- mov [LeftSkip],dx\r
- mov [DataInc],dx\r
- sub ax,dx\r
- mov [CType],1\r
- jmp short @@HorizClipDone\r
-\r
- ;;;; EXIT FOR COMPLETELY OBSCURED P.B.M's ;;;;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotVisible:\r
- mov ax,1\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-\r
- ;;;;; CLIP PROCESSING FOR RIGHT CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotLeftClip:\r
- mov dx,[_RightClip]\r
- sub dx,di\r
- js @@NotVisible\r
- mov [LeftSkip],0\r
- mov [DataInc],0\r
- cmp dx,ax\r
- jge @@HorizClipDone ; was jg\r
- inc dx\r
- sub ax,dx\r
- mov [DataInc],ax\r
- mov ax,dx\r
- mov [CType],-1\r
-\r
-@@HorizClipDone:\r
-\r
- xor bh,bh\r
- mov bl,byte ptr es:[si+1] ; BX = height\r
-\r
- mov [Width],ax ; Save width and height of clipped\r
- mov [Height],bx ; image\r
-\r
-\r
- add si,2 ; Skip dimension bytes in source\r
- add si,[LeftSkip] ; Skip pixels in front of row that\r
- ; are clipped\r
-\r
-\r
- mov bx,[_ScrnLogicalByteWidth] ; Set BX to Logical Screen Width\r
- mov dx,bx ; BX - Width of image = No. bytes\r
- sub dx,ax ; to first byte of next screen\r
- mov [LineInc],dx ; row.\r
-\r
- mov ax,[Y] ; Calculate screen start row\r
- mul bx ; then adding screen offset\r
- add di,ax\r
- add di,[ScrnOffs]\r
- mov ax,es ; copy ES to DS\r
- mov ds,ax\r
- mov ax,SCREEN_SEG ; Point ES to VGA segment\r
- mov es,ax\r
-\r
- and cx,3\r
- mov ah,11h ; Set up initial plane mask\r
- shl ah,cl\r
-\r
- mov dx,SC_INDEX ; Prepare VGA for cpu to video writes\r
- mov al,MAP_MASK\r
- out dx,al\r
- inc dx\r
- mov [Plane],4 ; Set plane counter to 4\r
- mov bh,byte ptr [Width] ; set bh to width for fast looping\r
-@@PlaneLoop:\r
- push di ; Save bitmap's start dest. offset\r
- mov bl,byte ptr [Height] ; Reset row counter (BL)\r
- mov al,ah\r
- out dx,al ; set vga write plane\r
-@@RowLoop:\r
- mov cl,bh ; Reset Column counter cl\r
- shr cl,1\r
- rep movsw ; Copy a complete row\r
- adc cl,0\r
- rep movsb\r
- add si,[DataInc] ; Move to next source row\r
- add di,[LineInc] ; Move to next screen row\r
- dec bl ; decrement row counter\r
- jnz @@RowLoop ; Jump if more rows left\r
- pop di ; Restore bitmaps start dest byte\r
- rol ah,1 ; Shift mask for next plane\r
-\r
- ; Plane Transition (A HACK but it works!)\r
-\r
- jnb @@Nocarry ; Jump if not plane transition\r
- mov bl,ah ; Save Plane Mask\r
- mov ax,[CType] ; set AX to clip type inc variable\r
- add bh,al ; Update advancing variables\r
- sub [DataInc],ax ;\r
- sub [LineInc],ax ;\r
- cmp al,0 ; What type of clip do we have\r
- mov ah,bl ; restore Plane mask\r
- jg @@RightAdvance ; jump on a right clip!\r
- inc di ; otherwise increment DI\r
- jmp @@Nocarry\r
-@@RightAdvance:\r
- dec si\r
-@@Nocarry:\r
- dec [Plane] ; Decrement plane counter\r
- jnz @@PlaneLoop ; Jump if more planes left\r
-\r
- xor ax,ax\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_put_pbm_clipx endp\r
-\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_put_pbm_clipy - Write a planar bitmap from system ram to video ram\r
-; with clipping in y direction only. similar to\r
-; "x_put_pbm".\r
-;\r
-; See Also: x_put_pbm,x_put_pbm_clipx,x_put_pbm_clipxy\r
-;\r
-; Clipping region variables: TopClip,BottomClip\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_put_pbm_clipy proc\r
-ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword\r
-LOCAL Width,Height,TopRow,LineInc,PlaneInc:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
-\r
- les si,[Bitmap]\r
-\r
- xor bh,bh\r
- mov bl,byte ptr es:[si+1] ; BX = height\r
- ;mov [Height],bx\r
-\r
- xor ah,ah\r
- mov al,byte ptr es:[si] ; AX = width\r
- mov [Width],ax\r
-\r
- mov cx,ax ; Save AX\r
- mul bx ; AX = AX*BX = bytes/plane\r
- mov [PlaneInc],ax ; save as PlaneInc\r
- mov ax,cx ; Restore AX\r
-\r
- mov di,[X]\r
- mov cx,di\r
- and cx,3\r
- shr di,2\r
-\r
- ;;;;; CLIP PROCESSING FOR TOP CLIP BORDER ;;;;;;;;;;;;;;;;;;;;;\r
-\r
- mov dx,[_TopClip] ; Compare u.l. Y coord with Top\r
- sub dx,[Y] ; clipping border\r
- jle @@NotTopClip ; jump if VBM not clipped from above\r
- cmp dx,bx\r
- jnl @@NotVisible ; jump if VBM is completely obscured\r
- mov [TopRow],dx\r
- sub bx,dx\r
- add [Y],dx\r
- jmp short @@VertClipDone\r
-\r
- ;;;; EXIT FOR COMPLETELY OBSCURED P.B.M's ;;;;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotVisible:\r
- mov ax,1\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-\r
- ;;;;; CLIP PROCESSING FOR BOTTOM CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotTopClip:\r
- mov dx,[_BottomClip]\r
- sub dx,[Y]\r
- js @@NotVisible\r
- mov [TopRow],0\r
- cmp dx,bx\r
- jg @@VertClipDone\r
- inc dx\r
- mov bx,dx\r
-\r
-@@VertClipDone:\r
-\r
- mov [Height],bx ; Calculate relative offset in data\r
- mul [TopRow] ; of first visible scanline\r
- add ax,2 ; Skip dimension bytes in source\r
- add si,ax ; Skip top rows that arent visible\r
-\r
-\r
- mov ax,[Y] ; Calculate screen row\r
- mov bx,[_ScrnLogicalByteWidth] ; by mult. Y coord by Screen\r
- mul bx ; width then adding screen offset\r
- add di,ax\r
- add di,[ScrnOffs]\r
- sub bx,[Width] ; calculate difference from end of\r
- mov [LineInc],bx ; b.m. in curr line to beginning of\r
- ; b.m. on next scan line\r
- mov ax,es ; copy ES to DS\r
- mov ds,ax\r
- mov ax,SCREEN_SEG ; Point ES to VGA segment\r
- mov es,ax\r
-\r
- mov ah,11h ; Set up initial plane mask\r
- shl ah,cl\r
-\r
- mov dx,SC_INDEX ; Prepare VGA for cpu to video writes\r
- mov al,MAP_MASK\r
- out dx,al\r
- inc dx\r
- mov bh,4 ; Set plane counter to 4\r
-@@PlaneLoop:\r
- push di ; Save bitmap's start dest. offset\r
- push si ; Save Bitmaps data offset\r
- mov bl,byte ptr [Height] ; Reset row counter (BL)\r
- mov al,ah\r
- out dx,al ; set vga write plane\r
-@@RowLoop:\r
- mov cl,byte ptr [Width] ; Reset Column counter cl\r
- shr cl,1\r
- rep movsw ; Copy a complete row\r
- adc cl,0\r
- rep movsb\r
-\r
- add di,[LineInc] ; Move to next row\r
- dec bl ; decrement row counter\r
- jnz @@RowLoop ; Jump if more rows left\r
- pop si ; Restore SI and set to offset of\r
- add si,[PlaneInc] ; first vis pixel in next plane data\r
- pop di ; Restore bitmaps start dest byte\r
- rol ah,1 ; Shift mask for next plane\r
- adc di,0 ; if carry increment screen offset\r
- dec bh ; Decrement plane counter\r
- jnz @@PlaneLoop ; Jump if more planes left\r
-\r
- xor ax,ax\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_put_pbm_clipy endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_put_pbm_clipxy - Write a planar bitmap from system ram to video ram\r
-; with clipping in x and y directions. similar to\r
-; "x_put_pbm".\r
-;\r
-; See Also: x_put_pbm,x_put_pbm_clipy,x_put_pbm_clipx\r
-;\r
-; Clipping region variables: LeftClip,RightClip,TopClip,BottomClip\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_put_pbm_clipxy proc\r
-ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword\r
-LOCAL Plane:byte,CType,LeftSkip,DataInc,Width,Height,TopRow,LineInc,PlaneInc:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
-\r
- les si,[Bitmap]\r
-\r
- xor ax,ax\r
- mov [CType],ax\r
- mov al,byte ptr es:[si] ; AX = width\r
- xor bh,bh\r
- mov bl,byte ptr es:[si+1] ; BX = height\r
-\r
- mov cx,ax ; Save AX\r
- mul bx ; AX = AX*BX = bytes/plane\r
- mov [PlaneInc],ax ; save as PlaneInc\r
- mov ax,cx ; Restore AX\r
-\r
-\r
- mov di,[X] ; DI = X coordinate of dest.\r
- mov cx,di ; save in CX\r
- sar di,2 ; convert to address byte\r
-\r
-\r
- ;;;;; CLIP PROCESSING FOR TOP CLIP BORDER ;;;;;;;;;;;;;;;;;;;;;\r
-\r
- mov dx,[_TopClip] ; Compare u.l. Y coord with Top\r
- sub dx,[Y] ; clipping border\r
- jle @@NotTopClip ; jump if VBM not clipped from above\r
- cmp dx,bx\r
- jnl @@NotVisible ; jump if VBM is completely obscured\r
- mov [TopRow],dx\r
- sub bx,dx\r
- add [Y],dx\r
- jmp short @@VertClipDone\r
-\r
- ;;;; EXIT FOR COMPLETELY OBSCURED P.B.M's ;;;;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotVisible:\r
- mov ax,1\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-\r
- ;;;;; CLIP PROCESSING FOR BOTTOM CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotTopClip:\r
- mov dx,[_BottomClip]\r
- sub dx,[Y]\r
- js @@NotVisible\r
- mov [TopRow],0\r
- cmp dx,bx\r
- jg @@VertClipDone\r
- inc dx\r
- mov bx,dx\r
-\r
-@@VertClipDone:\r
-\r
- ;;;;; CLIP PROCESSING FOR LEFT CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
- mov dx,[_LeftClip]\r
- sub dx,di\r
- jle @@NotLeftClip\r
- cmp dx,ax\r
- jnl @@NotVisible\r
-\r
- add di,dx\r
- mov [LeftSkip],dx\r
- mov [DataInc],dx\r
- sub ax,dx\r
- mov [CType],1\r
- jmp short @@HorizClipDone\r
-\r
- ;;;;; CLIP PROCESSING FOR RIGHT CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotLeftClip:\r
- mov dx,[_RightClip]\r
- sub dx,di\r
- js @@NotVisible\r
- mov [LeftSkip],0\r
- mov [DataInc],0\r
- cmp dx,ax\r
- jge @@HorizClipDone ; was jg\r
- inc dx\r
- sub ax,dx\r
- mov [DataInc],ax\r
- mov ax,dx\r
- mov [CType],-1\r
-\r
-@@HorizClipDone:\r
-\r
-\r
-\r
- mov [Width],ax ; Save width and height of clipped\r
- mov [Height],bx ; image\r
-\r
- add ax,[DataInc] ; AX = original width of image\r
- mul [TopRow] ; Calculate bytes in clipped top\r
- add si,ax ; rows\r
- add si,2 ; Skip dimension bytes in source\r
- add si,[LeftSkip] ; Skip pixels in front of row that\r
- ; are clipped\r
-\r
- mov bx,[_ScrnLogicalByteWidth] ; Set BX to Logical Screen Width\r
- mov dx,bx ; BX - Width of image = No. bytes\r
- sub dx,[Width] ; to first byte of next screen\r
- mov [LineInc],dx ; row.\r
-\r
- mov ax,[Y] ; Calculate screen start row\r
- mul bx ; then adding screen offset\r
- add di,ax\r
- add di,[ScrnOffs]\r
- mov ax,es ; copy ES to DS\r
- mov ds,ax\r
- mov ax,SCREEN_SEG ; Point ES to VGA segment\r
- mov es,ax\r
-\r
-\r
-\r
- and cx,3\r
- mov ah,11h ; Set up initial plane mask\r
- shl ah,cl\r
-\r
- mov dx,SC_INDEX ; Prepare VGA for cpu to video writes\r
- mov al,MAP_MASK\r
- out dx,al\r
- inc dx\r
- mov [Plane],4 ; Set plane counter to 4\r
- mov bh,byte ptr [Width] ; set bh to width for fast looping\r
-@@PlaneLoop:\r
- push di ; Save bitmap's start dest. offset\r
- push si\r
- mov bl,byte ptr [Height] ; Reset row counter (BL)\r
- mov al,ah\r
- out dx,al ; set vga write plane\r
-@@RowLoop:\r
- mov cl,bh ; Reset Column counter cl\r
- shr cl,1\r
- rep movsw ; Copy a complete row\r
- adc cl,0\r
- rep movsb\r
- add si,[DataInc] ; Move to next source row\r
- add di,[LineInc] ; Move to next screen row\r
- dec bl ; decrement row counter\r
- jnz @@RowLoop ; Jump if more rows left\r
- pop si ; Restore SI and set to offset of\r
- add si,[PlaneInc] ; first vis pixel in next plane data\r
- pop di ; Restore bitmaps start dest byte\r
- rol ah,1 ; Shift mask for next plane\r
-\r
- ; Plane Transition (A HACK but it works!)\r
-\r
- jnb @@Nocarry ; Jump if not plane transition\r
- mov bl,ah ; Save Plane Mask\r
- mov ax,[CType] ; set AX to clip type inc variable\r
- add bh,al ; Update advancing variables\r
- sub [DataInc],ax ;\r
- sub [LineInc],ax ;\r
- cmp al,0 ; What type of clip do we have\r
- mov ah,bl ; restore Plane mask\r
- jg @@RightAdvance ; jump on a right clip!\r
- inc di ; otherwise increment DI\r
- jmp @@Nocarry\r
-@@RightAdvance:\r
- dec si\r
-@@Nocarry:\r
- dec [Plane] ; Decrement plane counter\r
- jnz @@PlaneLoop ; Jump if more planes left\r
-\r
- xor ax,ax\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_put_pbm_clipxy endp\r
-\r
- end\r
-\r
-\r
-\r
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XPBMCLIP - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;-----------------------------------------------------------------------*/\r
-\r
-#ifndef _XPBMCLIP_H_\r
-#define _XPBMCLIP_H_\r
-\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-\r
- int x_put_masked_pbm_clipx( /* Copy a planar bitmap from SRAM masking */\r
- int X, /* only non zero pixels to VRAM */\r
- int Y, /* Supports clipping in the X direction */\r
- WORD ScrnOffs,\r
- BYTE far * Bitmap);\r
-\r
-\r
- int x_put_masked_pbm_clipy( /* Copy a planar bitmap from SRAM masking */\r
- int X, /* only non zero pixels to VRAM */\r
- int Y, /* Supports clipping in the Y direction */\r
- WORD ScrnOffs,\r
- BYTE far * Bitmap);\r
-\r
- int x_put_masked_pbm_clipxy( /* Copy a planar bitmap from SRAM masking */\r
- int X, /* only non zero pixels to VRAM */\r
- int Y, /* Supports clipping in the Y direction */\r
- WORD ScrnOffs,\r
- BYTE far * Bitmap);\r
-\r
- int x_put_pbm_clipx( /* Copy a planar bitmap from SRAM masking */\r
- int X, /* Supports clipping in the x direction */\r
- int Y,\r
- WORD ScrnOffs,\r
- BYTE far * Bitmap);\r
-\r
- int x_put_pbm_clipy( /* Copy a planar bitmap from SRAM masking */\r
- int X, /* Supports clipping in the Y direction */\r
- int Y,\r
- WORD ScrnOffs,\r
- BYTE far * Bitmap);\r
-\r
- int x_put_pbm_clipx( /* Copy a planar bitmap from SRAM masking */\r
- int X, /* Supports clipping in the X direction */\r
- int Y,\r
- WORD ScrnOffs,\r
- BYTE far * Bitmap);\r
-\r
- int x_put_pbm_clipxy( /* Copy a planar bitmap from SRAM masking */\r
- int X, /* Supports clipping in the X&Y directions */\r
- int Y,\r
- WORD ScrnOffs,\r
- BYTE far * Bitmap);\r
-\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-\r
-#endif\r
-\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XPBMCLIP - Include file\r
-;\r
-; XPBMCLIP.ASM export functions\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
- global _x_put_masked_pbm_clipx :proc\r
- global _x_put_masked_pbm_clipy :proc\r
- global _x_put_masked_pbm_clipxy :proc\r
-\r
- global _x_put_pbm_clipx :proc\r
- global _x_put_pbm_clipy :proc\r
- global _x_put_pbm_clipxy :proc\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XPOINT\r
-;\r
-; Point functions all MODE X 256 Color resolutions\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
-include xlib.inc\r
-include xpoint.inc\r
-\r
- .code\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; Mode X (256 color mode) write pixel routine.\r
-; No clipping is performed.\r
-;\r
-; Based on code originally published in DDJ Mag by M. Abrash\r
-;\r
-; C near-callable as:\r
-; void x_put_pix(int X, int Y, int PageOffset, int Color);\r
-;\r
-;\r
-\r
-_x_put_pix proc \r
- ARG X:word,Y:word,PgOfs:word,Color:word\r
- push bp ;preserve caller's stack frame\r
- mov bp,sp ;point to local stack frame\r
-\r
- mov ax,[_ScrnLogicalByteWidth]\r
- mul [Y] ;offset of pixel's scan line in page\r
- mov bx,[X]\r
- shr bx,2 ;X/4 = offset of pixel in scan line\r
- add bx,ax ;offset of pixel in page\r
- add bx,[PgOfs] ;offset of pixel in display memory\r
- mov ax,SCREEN_SEG\r
- mov es,ax ;point ES:BX to the pixel's address\r
-\r
- mov cl,byte ptr [X]\r
- and cl,011b ;CL = pixel's plane\r
- mov ax,0100h + MAP_MASK ;AL = index in SC of Map Mask reg\r
- shl ah,cl ;set only the bit for the pixel's\r
- ; plane to 1\r
- mov dx,SC_INDEX ;set the Map Mask to enable only the\r
- out dx,ax ; pixel's plane\r
-\r
- mov al,byte ptr [Color]\r
- mov es:[bx],al ;draw the pixel in the desired color\r
-\r
- pop bp ;restore caller's stack frame\r
- ret\r
-_x_put_pix endp\r
-\r
-;-------------------------------------------------------------------------\r
-; Mode X (320x240, 256 colors) read pixel routine. Works on all VGAs.\r
-; No clipping is performed.\r
-;\r
-; Based on code originally published in DDJ Mag by M. Abrash\r
-;\r
-; C near-callable as:\r
-; unsigned int x_get_pix(int X, int Y, unsigned int PageBase);\r
-\r
-\r
-_x_get_pix proc\r
- ARG x:word,y:word,PageBase:word\r
- push bp ;preserve caller's stack frame\r
- mov bp,sp ;point to local stack frame\r
-\r
- mov ax,[_ScrnLogicalByteWidth]\r
- mul [Y] ;offset of pixel's scan line in page\r
- mov bx,[X]\r
- shr bx,1\r
- shr bx,1 ;X/4 = offset of pixel in scan line\r
- add bx,ax ;offset of pixel in page\r
- add bx,[PageBase] ;offset of pixel in display memory\r
- mov ax,SCREEN_SEG\r
- mov es,ax ;point ES:BX to the pixel's address\r
-\r
- mov ah,byte ptr [X]\r
- and ah,011b ;AH = pixel's plane\r
- mov al,READ_MAP ;AL = index in GC of the Read Map reg\r
- mov dx,GC_INDEX ;set the Read Map to read the pixel's\r
- out dx,ax ; plane\r
-\r
- mov al,es:[bx] ;read the pixel's color\r
- sub ah,ah ;convert it to an unsigned int\r
-\r
- pop bp ;restore caller's stack frame\r
- ret\r
-_x_get_pix endp\r
- end\r
-\r
-\r
- end\r
-\r
-\1a
\ No newline at end of file
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XPOINT - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;-----------------------------------------------------------------------*/\r
-\r
-#ifndef _XPOINT_H_\r
-#define _XPOINT_H_\r
-\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-\r
- void x_put_pix( /* Draw a pixel on the screen */\r
- WORD X,\r
- WORD Y,\r
- WORD PageOffset,\r
- WORD Color);\r
-\r
- WORD x_get_pix( /* Read a pixel from the screen */\r
- WORD X,\r
- WORD Y,\r
- WORD PageBase);\r
-\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-\r
-#endif\r
-\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XPOINT - Include file\r
-;\r
-; XPOINT.ASM export functions\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
- global _x_put_pix :proc\r
- global _x_get_pix :proc\r
-\1a
\ No newline at end of file
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XPOLYGON\r
-;\r
-; Filled Triangle function for all MODE X 256 Color resolutions\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; This module is based on code developed by Steve Dollind for his\r
-; XSPACE game.\r
-; Copyright (C) 1992 Steven Dollins -- sdollins@uiuc.edu\r
-;\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-include xlib.inc\r
-include xpolygon.inc\r
-\r
-.data\r
-; Plane masks for clipping left and right edges of rectangle.\r
- LeftClipPlaneMask db 00fh,00eh,00ch,008h\r
- RightClipPlaneMask db 00fh,001h,003h,007h\r
-\r
-.code\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; void HLineClipR\r
-;\r
-; Draws a horizontal line from (X1, Y) to (X2, Y).\r
-; Uses Watcom Parameter passing convention in registers\r
-;\r
-; X1 in AX\r
-; X2 in DX\r
-; Y in CX\r
-; Color in BX\r
-; PageOffset in DI\r
-;\r
-; By Themie Gouthas - Adapted from x_fill_rect.\r
-;-----------------------------------------------------------------------\r
-proc _HLineClipR near\r
- push di\r
- cmp dx,ax ; if (X2 < X1) then assume no line\r
- jl @@Invisible ; is visible\r
-\r
- cmp cx,[_TopClip] ; if (Y < TopClip) then no line\r
- jl @@Invisible\r
-\r
- cmp cx,[_BottomClip] ;if (Y > BottomClip) then no line\r
- jg @@Invisible\r
-\r
- mov di,[_RightClip] ;convert RightClip to pixel coords\r
- sal di,2\r
- cmp ax,di ; if (X1 > RightClip) then no line\r
- jg @@Invisible\r
-\r
- cmp dx,di ; if (X2 > RightClip) then\r
- jle @@ClipLeft ; X2:=RightClip\r
- mov dx,di\r
-\r
-@@ClipLeft:\r
- mov di,[_LeftClip] ;convert LeftClip to pixel coords\r
- sal di,2\r
- cmp dx,di ; if (X2 < LeftClip) then no line\r
- jl @@Invisible\r
-\r
- cmp ax,di ;if (X1 > LeftClip) then were ready to plot\r
- jge @@DoLine\r
-\r
- mov ax,di ; X1:=LeftClip\r
- jmp short @@DoLine\r
-\r
-@@Invisible:\r
- pop di\r
- ret\r
-\r
-@@DoLine:\r
- pop di ; di = PageOffset\r
- xchg cx,ax ; AX = Y, CX = X1\r
- mov si,dx ; SI = DX = X2\r
- mul [_ScrnLogicalByteWidth]\r
- mov dx,si ; Reset DX to X1 since mul erases DX\r
- add ax,di\r
- mov di,cx\r
- sar di,2 ; Convert to bytes\r
- add di,ax ; DI->First byte\r
-\r
- and si,03h ; look up right edge plane mask\r
- mov ah,RightClipPlaneMask[si]\r
- mov si,cx ; look up left edge plane mask\r
- and si,03h\r
- mov al,LeftClipPlaneMask[si]\r
-\r
- cmp dx,cx ; No harm in being paranoid..\r
- jle @@Invisible2\r
-\r
- xchg cx,dx ;CX=X2, DX=X1\r
- dec cx\r
- and dx,not 03h\r
- sub cx,dx\r
- js @@Invisible2\r
- shr cx,2\r
- jnz @@MasksSet\r
- and al,ah\r
-@@MasksSet:\r
- mov dl,bl ; set BX=Plane Masks, AH=Color\r
- mov bx,ax\r
- mov ah,dl\r
- mov dx,SC_INDEX+1 ;set the Sequence Controller Index to\r
- mov al,bl\r
- out dx,al\r
- mov al,ah\r
- stosb ; Plot left byte\r
- dec cx\r
- js @@Invisible2\r
- jz @@RightEnd\r
-\r
-\r
- mov al,0fh ; plot middle bytes\r
- out dx,al\r
- mov al,ah\r
- shr cx,1\r
- rep stosw\r
- adc cx,cx\r
- rep stosb\r
-\r
-\r
-\r
-@@RightEnd:\r
- mov al,bh ; Plot right byte\r
- out dx,al\r
- mov al,ah\r
- stosb\r
-@@Invisible2:\r
- ret\r
-_HLineClipR endp\r
-\r
-\r
-;-----------------------------------------------------------------------\r
-; void x_triangle( int X0, int Y0, int X1, int Y1,\r
-; int X2, int Y2, unsigned Color, unsigned PageOffset );\r
-;\r
-;\r
-; Written by S. Dollins\r
-\r
-_x_triangle proc\r
-ARG X0:word,Y0:word,X1:word,Y1:word,X2:word,Y2:word,Color:word,PageOffset:word\r
-LOCAL DX01:word, DY01:word, DX02:word, DY02:word, DX12:word, DY12:word, \\r
- DP01:word, DP02:word, DP12:word, XA01:word, XA02:word, XA12:word=STK\r
-\r
- push bp\r
- mov bp,sp\r
- sub sp,STK\r
- push ds es si di ; Save es for polygon routine\r
-\r
- mov ax,X0\r
- mov bx,Y0\r
- mov cx,X1\r
- mov dx,Y1\r
-\r
- cmp bx,dx ; Y0,Y1\r
- jl tri_Y0lY1\r
- je tri_Y0eY1\r
- xchg ax,cx ; X0,X1\r
- xchg bx,dx ; Y0,Y1\r
-tri_Y0lY1:\r
- cmp dx,Y2 ; Y1,Y2\r
- jg tri_a\r
- jmp tri_sorted\r
-tri_a: xchg cx,X2 ; X1,X2\r
- xchg dx,Y2 ; Y1,Y2\r
- cmp bx,dx ; Y0,Y1\r
- jge tri_b\r
- jmp tri_sorted\r
-tri_b: je tri_bot\r
- xchg ax,cx ; X0,X1\r
- xchg bx,dx ; Y0,Y1\r
- jmp tri_sorted\r
-tri_Y0eY1:\r
- cmp bx,Y2 ; Y0,Y2\r
- jl tri_bot\r
- jg tri_c\r
- jmp tri_done\r
-tri_c: xchg ax,X2 ; X0,X2\r
- xchg bx,Y2 ; Y0,Y2\r
- jmp tri_sorted\r
-\r
-tri_bot:\r
- cmp ax,cx ; X0,X1\r
- jl tri_bot_sorted\r
- jg tri_bot_a\r
- jmp tri_done\r
-tri_bot_a:\r
- xchg ax,cx ; X0,X1\r
-tri_bot_sorted:\r
- cmp bx,[_BottomClip]\r
- jle tri_bot_y0ok\r
- jmp tri_done\r
-tri_bot_y0ok:\r
- mov si,Y2\r
- cmp si,[_TopClip]\r
- jge tri_bot_y2ok\r
- jmp tri_done\r
-tri_bot_y2ok:\r
- mov X0,ax\r
- mov Y0,bx\r
- mov X1,cx\r
- mov Y1,dx\r
-\r
- mov bx,Y2 ; bx <- Y2\r
- sub bx,Y0 ; bx <- Y2 - Y0\r
- mov DY02,bx ; DY02 <- Y2 - Y0\r
- mov ax,X2 ; ax <- X2\r
- sub ax,X0 ; ax <- X2 - X0\r
- mov DX02,ax ; DX02 <- X2 - X0\r
- mov cx,ax ; cx <- DX02\r
- cwd ; dx:ax <- DX02\r
- idiv bx ; ax <- DX02 / DY02\r
- cmp cx,0\r
- jge short tri_bot02\r
- dec ax ; ax <- DX02 / DY02 - 1\r
-tri_bot02:\r
- mov XA02,ax ; XA02 <- DX02 / DY02\r
- imul bx ; ax <- XA02 * DY02\r
- sub cx,ax ; cx <- DX02 - XA02 * DY02\r
- mov DP02,cx ; DP02 <- DX02 - XA02 * DY02\r
-\r
- mov bx,Y2 ; bx <- Y2\r
- sub bx,Y1 ; bx <- Y2 - Y1\r
- mov DY12,bx ; DY02 <- Y2 - Y1\r
- mov ax,X2 ; ax <- X2\r
- sub ax,X1 ; ax <- X2 - X1\r
- mov DX12,ax ; DX12 <- X2 - X1\r
- mov cx,ax ; cx <- DX12\r
- cwd ; dx:ax <- DX12\r
- idiv bx ; ax <- DX12 / DY12\r
- cmp cx,0\r
- jge short tri_bot12\r
- dec ax ; ax <- DX12 / DY12 - 1\r
-tri_bot12:\r
- mov XA12,ax ; XA12 <- DX12 / DY12\r
- imul bx ; ax <- XA12 * DY12\r
- sub cx,ax ; cx <- DX12 - XA12 * DY12\r
- mov DP12,cx ; DP12 <- DX12 - XA12 * DY12\r
-\r
- mov ax,0 ; PL <- 0\r
- mov bx,0 ; PS <- 0\r
- mov cx,Y0 ; Y <- Y0\r
- mov si,X0\r
- mov di,X1\r
- dec di\r
-tri_bot_loop:\r
- inc cx ; Y\r
-\r
- add ax,DP02 ; PL,DP02\r
- jle short tri_bot_shortl\r
- sub ax,DY02 ; PL,DY02\r
- inc si ; XL\r
-tri_bot_shortl:\r
- add si,XA02 ; XL,XA02\r
-\r
- add bx,DP12 ; PS,DP12\r
- jle short tri_bot_shortr\r
- sub bx,DY12 ; PS,DY12\r
- inc di ; XS\r
-tri_bot_shortr:\r
- add di,XA12 ; XS,XA12\r
-\r
- push di ; XS\r
- push si ; XL\r
- cmp cx,Y2 ; Y,Y2\r
- jl short tri_bot_loop\r
-\r
- jmp tri_draw_lines\r
-\r
-\r
-tri_sorted:\r
- cmp bx,[_BottomClip]\r
- jle tri_y0ok\r
- jmp tri_done\r
-tri_y0ok:\r
- mov si,Y2\r
- cmp si,[_TopClip]\r
- jge tri_y2ok\r
- jmp tri_done\r
-tri_y2ok:\r
- mov X0,ax\r
- mov Y0,bx\r
- mov X1,cx\r
- mov Y1,dx\r
-\r
- mov bx,dx ; bx <- Y1\r
- sub bx,Y0 ; bx <- Y1 - Y0\r
- mov DY01,bx ; DY01 <- Y1 - Y0\r
- mov ax,X1 ; ax <- X1\r
- sub ax,X0 ; ax <- X1 - X0\r
- mov DX01,ax ; DX01 <- X1 - X0\r
- mov cx,ax ; cx <- DX01\r
- cwd ; dx:ax <- DX01\r
- idiv bx ; ax <- DX01 / DY01\r
- cmp cx,0 ; DX01 ? 0\r
- jge short tri_psl01\r
- dec ax ; ax <- DX01 / DY01 - 1\r
-tri_psl01:\r
- mov XA01,ax ; XA01 <- DX01 / DY01\r
- imul bx ; ax <- XA01 * DY01\r
- sub cx,ax ; cx <- DX01 - XA01 * DY01\r
- mov DP01,cx ; DP01 <- DX01 - XA01 * DY01\r
-\r
- mov bx,Y2 ; bx <- Y2\r
- sub bx,Y0 ; bx <- Y2 - Y0\r
- mov DY02,bx ; DY02 <- Y2 - Y0\r
- mov ax,X2 ; ax <- X2\r
- sub ax,X0 ; ax <- X2 - X0\r
- mov DX02,ax ; DX02 <- X2 - X0\r
- mov cx,ax ; cx <- DX02\r
- cwd ; dx:ax <- DX02\r
- idiv bx ; ax <- DX02 / DY02\r
- cmp cx,0\r
- jge short tri_psl02\r
- dec ax ; ax <- DX02 / DY02 - 1\r
-tri_psl02:\r
- mov XA02,ax ; XA02 <- DX02 / DY02\r
- imul bx ; ax <- XA02 * DY02\r
- sub cx,ax ; cx <- DX02 - XA02 * DY02\r
- mov DP02,cx ; DP02 <- DX02 - XA02 * DY02\r
-\r
- mov bx,Y2 ; bx <- Y2\r
- sub bx,Y1 ; bx <- Y2 - Y1\r
- jle short tri_const_computed\r
- mov DY12,bx ; DY12 <- Y2 - Y1\r
- mov ax,X2 ; ax <- X2\r
- sub ax,X1 ; ax <- X2 - X1\r
- mov DX12,ax ; DX12 <- X2 - X1\r
- mov cx,ax ; cx <- DX12\r
- cwd ; dx:ax <- DX12\r
- idiv bx ; ax <- DX12 / DY12\r
- cmp cx,0\r
- jge short tri_psl12\r
- dec ax ; ax <- DX12 / DY12 - 1\r
-tri_psl12:\r
- mov XA12,ax ; XA12 <- DX12 / DY12\r
- imul bx ; ax <- XA12 * DY12\r
- sub cx,ax ; cx <- DX12 - XA12 * DY12\r
- mov DP12,cx ; DP12 <- DX12 - XA12 * DY12\r
-\r
-tri_const_computed:\r
- mov ax,DX01\r
- imul word ptr DY02\r
- mov bx,ax\r
- mov cx,dx ; DX01 * DY02 in cx:bx\r
-\r
- mov ax,DX02\r
- imul word ptr DY01 ; DX02 * DY01 in dx:ax\r
- cmp cx,dx\r
- jg tri_pt1rt\r
- jl tri_pt1lt\r
- cmp bx,ax\r
- ja tri_pt1rt\r
- jb tri_pt1lt\r
- jmp tri_done\r
-\r
-;------------------------------------\r
-; Short sides are on the left\r
-;\r
-tri_pt1lt:\r
- mov ax,0 ; PL <- 0\r
- mov bx,0 ; PS <- 0\r
- mov cx,Y0 ; Y <- Y0\r
- mov si,X0\r
- mov di,si\r
- dec si\r
-tri_lt_loop:\r
- inc cx ; Y\r
-\r
- add ax,DP02 ; PL,DP02\r
- jle short tri_lt_shortl\r
- sub ax,DY02 ; PL,DY02\r
- inc si ; XL\r
-tri_lt_shortl:\r
- add si,XA02 ; XL,XA02\r
-\r
- add bx,DP01 ; PS,DP01\r
- jle short tri_lt_shortr\r
- sub bx,DY01 ; PS,DY01\r
- inc di ; XS\r
-tri_lt_shortr:\r
- add di,XA01 ; XS,XA01\r
-\r
- push si ; XL\r
- push di ; XS\r
- cmp cx,Y1 ; Y,Y1\r
- jl short tri_lt_loop\r
-\r
- jmp short tri_lb_start\r
-tri_lb_loop:\r
- inc cx ; Y\r
-\r
- add ax,DP02 ; PL,DP02\r
- jle short tri_lb_shortl\r
- sub ax,DY02 ; PL,DY02\r
- inc si ; XL\r
-tri_lb_shortl:\r
- add si,XA02 ; XL,XA02\r
-\r
- add bx,DP12 ; PS,DP12\r
- jle short tri_lb_shortr\r
- sub bx,DY12 ; PS,DY12\r
- inc di ; XS\r
-tri_lb_shortr:\r
- add di,XA12 ; XS,XA12\r
-\r
- push si ; XL\r
- push di ; XS\r
-tri_lb_start:\r
- cmp cx,Y2 ; Y,Y2\r
- jl tri_lb_loop\r
- jmp short tri_draw_lines\r
-\r
-;------------------------------------\r
-; short sides are on the right\r
-;\r
-tri_pt1rt:\r
- mov ax,0 ; PL <- 0\r
- mov bx,0 ; PS <- 0\r
- mov cx,Y0 ; Y <- Y0\r
- mov si,X0\r
- mov di,si\r
- dec di\r
-tri_rt_loop:\r
- inc cx ; Y\r
-\r
- add ax,DP02 ; PL,DP02\r
- jle short tri_rt_shortl\r
- sub ax,DY02 ; PL,DY02\r
- inc si ; XL\r
-tri_rt_shortl:\r
- add si,XA02 ; XL,XA02\r
-\r
- add bx,DP01 ; PS,DP01\r
- jle short tri_rt_shortr\r
- sub bx,DY01 ; PS,DY01\r
- inc di ; XS\r
-tri_rt_shortr:\r
- add di,XA01 ; XS,XA01\r
-\r
- push di ; XS\r
- push si ; XL\r
- cmp cx,Y1 ; Y,Y1\r
- jl short tri_rt_loop\r
-\r
- jmp short tri_rb_start\r
-tri_rb_loop:\r
- inc cx ; Y\r
-\r
- add ax,DP02 ; PL,DP02\r
- jle short tri_rb_shortl\r
- sub ax,DY02 ; PL,DY02\r
- inc si ; XL\r
-tri_rb_shortl:\r
- add si,XA02 ; XL,XA02\r
-\r
- add bx,DP12 ; PS,DP12\r
- jle short tri_rb_shorts\r
- sub bx,DY12 ; PS,DY12\r
- inc di ; XS\r
-tri_rb_shorts:\r
- add di,XA12 ; XS,XA12\r
-\r
- push di ; XS\r
- push si ; XL\r
-tri_rb_start:\r
- cmp cx,Y2 ; Y,Y2\r
- jl short tri_rb_loop\r
-\r
-;------------------------------------\r
-; Draw the horizontal lines\r
-;\r
-\r
-\r
-tri_draw_lines:\r
-\r
- mov cx,SCREEN_SEG ;point ES to video segment\r
- mov es,cx\r
- mov dx,SC_INDEX ;set the Sequence Controller Index to\r
- mov al,MAP_MASK ; point to the Map Mask register\r
- out dx,al\r
-\r
-\r
-line_loop:\r
- pop ax\r
- pop dx\r
- cmp ax,dx\r
- jg tri_draw_next\r
- mov bx,Color\r
- mov cx,Y2\r
- add dx,2\r
- mov di,PageOffset\r
- call _HLineClipR\r
-tri_draw_next:\r
- dec word ptr Y2\r
- dec word ptr DY02\r
- jnz line_loop\r
-\r
-tri_done:\r
- pop di si es ds\r
- mov sp,bp\r
- pop bp\r
- ret\r
-_x_triangle endp\r
-\r
-;-----------------------------------------------------------------------\r
-; void x_polygon( VERTEX vertices[], int num_vertices,unsigned Color,\r
-; unsigned PageOffset );\r
-;\r
-; Where VERTEX is defined as:\r
-;\r
-; typedef struct {\r
-; int X;\r
-; int Y;\r
-; } far VERTEX;\r
-;\r
-;\r
-; Written by T. Gouthas\r
-;\r
-;\r
-;\r
-; Note: This is just a quick hack of a generalized polygon routine.\r
-; The way it works is by splitting up polygons into triangles and\r
-; drawing each individual triangle.\r
-;\r
-; Obviously this is not as fast as it could be, but for polygons of\r
-; 4 vertices it should perform quite respectably.\r
-;\r
-; Warning: Only works for convex polygons (convex polygons are such\r
-; that if you draw a line from any two vertices, every point on that\r
-; line will be within the polygon)\r
-;\r
-;\r
-\r
-_x_polygon proc\r
- ARG vertices:dword,numvertices:word,Color:word,PageOffset:word\r
- LOCAL x0:word,y0:word,tri_count:word=STK\r
- push bp\r
- mov bp,sp\r
- sub sp,STK\r
- push di si\r
-\r
- mov cx,numvertices\r
- cmp cx,3\r
- jl @@Done\r
-\r
- sub cx,3\r
- mov tri_count,cx ; Number of triangles to draw\r
- les di,vertices ; ES:DI -> Vertices\r
-\r
- mov ax,es:[di] ; Save first vertex\r
- mov x0,ax\r
- mov ax,es:[di+2]\r
- mov y0,ax\r
-\r
- ; Set up permanent parameter stack frame for\r
- ; triangle parameters\r
-\r
- mov ax,PageOffset\r
- push ax\r
- mov ax,Color\r
- push ax\r
-\r
- sub sp,12\r
- mov si,sp\r
-\r
-@@NextTriangle:\r
-\r
- add di,4\r
- mov ax,es:[di] ; Vertex 2\r
- mov ss:[si],ax\r
- mov ax,es:[di+2]\r
- mov ss:[si+2],ax\r
-\r
- mov ax,es:[di+4] ; Vertex 1\r
- mov ss:[si+4],ax\r
- mov ax,es:[di+6]\r
- mov ss:[si+6],ax\r
-\r
- mov ax,x0 ; Vertex 0: The first vertex is\r
- mov ss:[si+8],ax ; part of every triangle\r
- mov ax,y0\r
- mov ss:[si+10],ax\r
-\r
- call _x_triangle\r
- dec tri_count\r
- jns @@NextTriangle\r
-\r
- add sp,16 ; Remove triangle stack frame\r
-\r
-@@Done:\r
- pop si di\r
- mov sp,bp\r
- pop bp\r
- ret\r
-_x_polygon endp\r
- end
\ No newline at end of file
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XPOLYGON - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;----------------------------------------------------------------------*/\r
-\r
-#ifndef _XPOLYGON_H_\r
-#define _XPOLYGON_H_\r
-\r
-\r
-typedef struct {\r
- int X;\r
- int Y;\r
-} far VERTEX;\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-void x_triangle( /* Draw a triangle */\r
- int x0,\r
- int y0,\r
- int x1,\r
- int y1,\r
- int x2,\r
- int y2,\r
- WORD color,\r
- WORD PageBase);\r
-\r
-void x_polygon( /* Draw a convex polygon */\r
- VERTEX *vertices,\r
- int num_vertices,\r
- WORD color,\r
- WORD PageBase);\r
-\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif\r
-\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XPOLYGON - Include file\r
-;\r
-; XPOLYGON.ASM export functions\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
- global _x_triangle :proc\r
- global _x_polygon :proc\r
+++ /dev/null
-#include <stdarg.h>\r
-#include <string.h>\r
-#include "xlib.h"\r
-#include "xrect.h"\r
-#include "xtext.h"\r
-\r
-\r
-extern unsigned char CharWidth;\r
-extern unsigned char CharHeight;\r
-\r
-void x_printf(WORD x, WORD y,WORD ScrnOffs,WORD color,char *ln,...){\r
- char dlin[100],*dl=dlin;\r
- char ch;\r
- va_list ap;\r
-\r
- va_start(ap,ln);\r
- vsprintf(dlin,ln,ap);\r
- va_end(ap);\r
-\r
- while(*dl){\r
- x+=x_char_put(*dl++,x,y,ScrnOffs,color);\r
- }\r
-\r
-}\r
-\r
-void x_bgprintf(WORD x, WORD y,WORD ScrnOffs,WORD fgcolor,\r
- WORD bgcolor, char *ln,...){\r
- char dlin[100],*dl=dlin;\r
- char ch;\r
- va_list ap;\r
-\r
- va_start(ap,ln);\r
- vsprintf(dlin,ln,ap);\r
- va_end(ap);\r
-\r
- while(*dl){\r
- x_rect_fill(x,y,x+x_get_char_width(*dl),y+CharHeight,ScrnOffs,bgcolor);\r
- x+=x_char_put(*dl++,x,y,ScrnOffs,fgcolor);\r
- }\r
-\r
-}\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XRECT\r
-;\r
-; Rectangle functions all MODE X 256 Color resolutions\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
-include xlib.inc\r
-include xrect.inc\r
-\r
-\r
- .data\r
-; Plane masks for clipping left and right edges of rectangle.\r
- LeftClipPlaneMask db 00fh,00eh,00ch,008h\r
- RightClipPlaneMask db 00fh,001h,003h,007h\r
- .code\r
-\r
-;---------------------------------------------------------------------------\r
-; Mode X (320x240, 256 colors) rectangle solid colour fill routine.\r
-;\r
-; Based on code originally published in DDJ Mag by M. Abrash\r
-;\r
-; with TASM 2. C near-callable as:\r
-;\r
-; void x_rect_fill_clipped(int StartX, int StartY, int EndX, int EndY,\r
-; unsigned int PageBase, unsigne int color);\r
-;\r
-;\r
-\r
-\r
-_x_rect_fill_clipped proc\r
-ARG StartX:word,StartY:word,EndX:word,EndY:word,PageBase:word,Color:word\r
- push bp ;preserve caller's stack frame\r
- mov bp,sp ;point to local stack frame\r
- push si ;preserve caller's register variables\r
- push di\r
-\r
- mov dx,[_TopClip] ; Compare u.l. Y coord with Top\r
- mov cx,[_BottomClip]\r
- mov ax,[StartY]\r
- mov bx,[EndY]\r
- cmp dx,ax\r
- jle @@CheckBottomClip\r
- cmp dx,bx\r
- jg @@NotVisible\r
- mov [StartY],dx\r
-\r
-@@CheckBottomClip:\r
- cmp cx,bx\r
- jg @@CheckLeftClip\r
- cmp cx,ax\r
- jl @@NotVisible\r
- mov [EndY],cx\r
-\r
-@@CheckLeftClip:\r
- mov dx,[_LeftClip] ; Compare u.l. Y coord with Top\r
- mov cx,[_RightClip]\r
- mov ax,[StartX]\r
- mov bx,[EndX]\r
- sal dx,2\r
- sal cx,2\r
- cmp dx,ax\r
- jle @@CheckRightClip\r
- cmp dx,bx\r
- jg @@NotVisible\r
- mov [StartX],dx\r
-\r
-@@CheckRightClip:\r
- cmp cx,bx\r
- jg RFClipDone\r
- cmp cx,ax\r
- jl @@NotVisible\r
- mov [EndX],cx\r
- jmp RFClipDone\r
-\r
-@@NotVisible:\r
- mov ax,1\r
- pop di ; restore registers\r
- pop si\r
- pop bp\r
- ret\r
-_x_rect_fill_clipped endp\r
-\r
-\r
-\r
-;---------------------------------------------------------------------------\r
-; Mode X (320x240, 256 colors) rectangle solid colour fill routine.\r
-;\r
-; Based on code originally published in DDJ Mag by M. Abrash\r
-;\r
-; with TASM 2. C near-callable as:\r
-;\r
-; void x_rect_fill(int StartX, int StartY, int EndX, int EndY,\r
-; unsigned int PageBase, unsigne int color);\r
-;\r
-;\r
-\r
-\r
-_x_rect_fill proc\r
-ARG StartX:word,StartY:word,EndX:word,EndY:word,PageBase:word,Color:word\r
- push bp ;preserve caller's stack frame\r
- mov bp,sp ;point to local stack frame\r
- push si ;preserve caller's register variables\r
- push di\r
-\r
-RFClipDone:\r
- cld\r
- mov ax,[_ScrnLogicalByteWidth]\r
- mul [StartY] ;offset in page of top rectangle scan line\r
- mov di,[StartX]\r
- sar di,2 ;X/4 = offset of first rectangle pixel in scan\r
- add di,ax ;offset of first rectangle pixel in page\r
- add di,[PageBase] ;offset of first rectangle pixel in\r
- ; display memory\r
- mov ax,SCREEN_SEG ;point ES:DI to the first rectangle\r
- mov es,ax ; pixel's address\r
- mov dx,SC_INDEX ;set the Sequence Controller Index to\r
- mov al,MAP_MASK ; point to the Map Mask register\r
- out dx,al\r
- inc dx ;point DX to the SC Data register\r
- mov si,[StartX]\r
- and si,0003h ;look up left edge plane mask\r
- mov bh,LeftClipPlaneMask[si] ; to clip & put in BH\r
- mov si,[EndX]\r
- and si,0003h ;look up right edge plane\r
- mov bl,RightClipPlaneMask[si] ; mask to clip & put in BL\r
-\r
- mov cx,[EndX] ;calculate # of addresses across rect\r
- mov si,[StartX]\r
- cmp cx,si\r
- jle @@FillDone ;skip if 0 or negative width\r
- dec cx\r
- and si,not 011b\r
- sub cx,si\r
- sar cx,2 ;# of addresses across rectangle to fill - 1\r
- jnz @@MasksSet ;there's more than one byte to draw\r
- and bh,bl ;there's only one byte, so combine the left\r
- ; and right edge clip masks\r
-@@MasksSet:\r
- mov si,[EndY]\r
- sub si,[StartY] ;BX = height of rectangle\r
- jle @@FillDone ;skip if 0 or negative height\r
- mov ah,byte ptr [Color] ;color with which to fill\r
- mov bp,[_ScrnLogicalByteWidth] ;stack frame isn't needed any more\r
- sub bp,cx ;distance from end of one scan line to start\r
- dec bp ; of next\r
-@@FillRowsLoop:\r
- push cx ;remember width in addresses - 1\r
- mov al,bh ;put left-edge clip mask in AL\r
- out dx,al ;set the left-edge plane (clip) mask\r
- mov al,ah ;put color in AL\r
- stosb ;draw the left edge\r
- dec cx ;count off left edge byte\r
- js @@FillLoopBottom ;that's the only byte\r
- jz @@DoRightEdge ;there are only two bytes\r
- mov al,00fh ;middle addresses drawn 4 pixels at a pop\r
- out dx,al ;set the middle pixel mask to no clip\r
- mov al,ah ;put color in AL\r
- rep stosb ;draw middle addresses four pixels apiece\r
-@@DoRightEdge:\r
- mov al,bl ;put right-edge clip mask in AL\r
- out dx,al ;set the right-edge plane (clip) mask\r
- mov al,ah ;put color in AL\r
- stosb ;draw the right edge\r
-@@FillLoopBottom:\r
- add di,bp ;point to start of the next scan line of\r
- ; the rectangle\r
- pop cx ;retrieve width in addresses - 1\r
- dec si ;count down scan lines\r
- jnz @@FillRowsLoop\r
-@@FillDone:\r
- pop di ;restore caller's register variables\r
- pop si\r
- pop bp ;restore caller's stack frame\r
- ret\r
-_x_rect_fill endp\r
-\r
-\r
-\r
-;---------------------------------------------------------------------------\r
-; Mode X (320x240, 256 colors) rectangle 4x4 pattern fill routine.\r
-; Upper left corner of pattern is always aligned to a multiple-of-4\r
-; row and column. Works on all VGAs. Uses approach of copying the\r
-; pattern to off-screen display memory, then loading the latches with\r
-; the pattern for each scan line and filling each scan line four\r
-; pixels at a time. Fills up to but not including the column at EndX\r
-; and the row at EndY. No clipping is performed. All ASM code tested\r
-;\r
-;\r
-; Based on code originally published in DDJ Mag by M. Abrash\r
-;\r
-;\r
-; C near-callable as:\r
-;\r
-; void x_rect_pattern_clipped(int StartX, int StartY, int EndX, int EndY,\r
-; unsigned int PageBase, char far * Pattern);\r
-;\r
-;\r
-\r
-_x_rect_pattern_clipped proc\r
-ARG StartX:word,StartY:word,EndX:word,EndY:word,PageBase:word,Pattern:dword\r
-LOCAL NextScanOffset:word,RectAddrWidth:word,Height:word=LocalStk\r
- push bp ;preserve caller's stack frame\r
- mov bp,sp ;point to local stack frame\r
- sub sp,LocalStk ;allocate space for local vars\r
- push si ;preserve caller's register variables\r
- push di\r
- push ds\r
-\r
- mov dx,[_TopClip] ; Compare u.l. Y coord with Top\r
- mov cx,[_BottomClip]\r
- mov ax,[StartY]\r
- mov bx,[EndY]\r
- cmp dx,ax\r
- jle @@CheckBottomClip\r
- cmp dx,bx\r
- jg @@NotVisible\r
- mov [StartY],dx\r
-\r
-@@CheckBottomClip:\r
- cmp cx,bx\r
- jg @@CheckLeftClip\r
- cmp cx,ax\r
- jl @@NotVisible\r
- mov [EndY],cx\r
-\r
-@@CheckLeftClip:\r
- mov dx,[_LeftClip] ; Compare u.l. Y coord with Top\r
- mov cx,[_RightClip]\r
- mov ax,[StartX]\r
- mov bx,[EndX]\r
- sal dx,2\r
- sal cx,2\r
- cmp dx,ax\r
- jle @@CheckRightClip\r
- cmp dx,bx\r
- jg @@NotVisible\r
- mov [StartX],dx\r
-\r
-@@CheckRightClip:\r
- cmp cx,bx\r
- jg RPClipDone\r
- cmp cx,ax\r
- jl @@NotVisible\r
- mov [EndX],cx\r
- jmp RPClipDone\r
-\r
-@@NotVisible:\r
- mov ax,1\r
- pop ds\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp\r
- pop bp\r
- ret\r
-\r
-_x_rect_pattern_clipped endp\r
-\r
-;---------------------------------------------------------------------------\r
-; Mode X (320x240, 256 colors) rectangle 4x4 pattern fill routine.\r
-; Upper left corner of pattern is always aligned to a multiple-of-4\r
-; row and column. Works on all VGAs. Uses approach of copying the\r
-; pattern to off-screen display memory, then loading the latches with\r
-; the pattern for each scan line and filling each scan line four\r
-; pixels at a time. Fills up to but not including the column at EndX\r
-; and the row at EndY. No clipping is performed. All ASM code tested\r
-;\r
-;\r
-; Based on code originally published in DDJ Mag by M. Abrash\r
-;\r
-;\r
-; C near-callable as:\r
-;\r
-; void x_rect_pattern(int StartX, int StartY, int EndX, int EndY,\r
-; unsigned int PageBase, char far * Pattern);\r
-\r
-\r
-\r
-_x_rect_pattern proc\r
-ARG StartX:word,StartY:word,EndX:word,EndY:word,PageBase:word,Pattern:dword\r
-LOCAL NextScanOffset:word,RectAddrWidth:word,Height:word=LocalStk\r
- push bp ;preserve caller's stack frame\r
- mov bp,sp ;point to local stack frame\r
- sub sp,LocalStk ;allocate space for local vars\r
- push si ;preserve caller's register variables\r
- push di\r
- push ds\r
-\r
-RPClipDone:\r
- cld\r
- mov ax,SCREEN_SEG ;point ES to display memory\r
- mov es,ax\r
- ;copy pattern to display memory buffer\r
- lds si,dword ptr [Pattern] ;point to pattern to fill with\r
- mov di,PATTERN_BUFFER ;point ES:DI to pattern buffer\r
- mov dx,SC_INDEX ;point Sequence Controller Index to\r
- mov al,MAP_MASK ; Map Mask\r
- out dx,al\r
- inc dx ;point to SC Data register\r
- mov cx,4 ;4 pixel quadruplets in pattern\r
-@@DownloadPatternLoop:\r
- mov al,1 ;\r
- out dx,al ;select plane 0 for writes\r
- movsb ;copy over next plane 0 pattern pixel\r
- dec di ;stay at same address for next plane\r
- mov al,2 ;\r
- out dx,al ;select plane 1 for writes\r
- movsb ;copy over next plane 1 pattern pixel\r
- dec di ;stay at same address for next plane\r
- mov al,4 ;\r
- out dx,al ;select plane 2 for writes\r
- movsb ;copy over next plane 2 pattern pixel\r
- dec di ;stay at same address for next plane\r
- mov al,8 ;\r
- out dx,al ;select plane 3 for writes\r
- movsb ;copy over next plane 3 pattern pixel\r
- ; and advance address\r
- loop @@DownloadPatternLoop\r
- pop ds\r
-\r
- mov dx,GC_INDEX ;set the bit mask to select all bits\r
- mov ax,00000h+BIT_MASK ; from the latches and none from\r
- out dx,ax ; the CPU, so that we can write the\r
- ; latch contents directly to memory\r
- mov ax,[StartY] ;top rectangle scan line\r
- mov si,ax\r
- and si,011b ;top rect scan line modulo 4\r
- add si,PATTERN_BUFFER ;point to pattern scan line that\r
- ; maps to top line of rect to draw\r
- mov dx,[_ScrnLogicalByteWidth]\r
- mul dx ;offset in page of top rect scan line\r
- mov di,[StartX]\r
- mov bx,di\r
- sar di,2 ;X/4 = offset of first rectangle pixel in scan\r
- add di,ax ;offset of first rectangle pixel in page\r
- add di,[PageBase] ;offset of first rectangle pixel in\r
- ; display memory\r
- and bx,0003h ;look up left edge plane mask\r
- mov ah,LeftClipPlaneMask[bx] ; to clip\r
- mov bx,[EndX]\r
- and bx,0003h ;look up right edge plane\r
- mov al,RightClipPlaneMask[bx] ; mask to clip\r
- mov bx,ax ;put the masks in BX\r
-\r
- mov cx,[EndX] ;calculate # of addresses across rect\r
- mov ax,[StartX]\r
- cmp cx,ax\r
- jle @@FillDone ;skip if 0 or negative width\r
- dec cx\r
- and ax,not 011b\r
- sub cx,ax\r
- sar cx,2 ;# of addresses across rectangle to fill - 1\r
- jnz @@MasksSet ;there's more than one pixel to draw\r
- and bh,bl ;there's only one pixel, so combine the left\r
- ; and right edge clip masks\r
-@@MasksSet:\r
- mov ax,[EndY]\r
- sub ax,[StartY] ;AX = height of rectangle\r
- jle @@FillDone ;skip if 0 or negative height\r
- mov [Height],ax\r
- mov ax,[_ScrnLogicalByteWidth]\r
- sub ax,cx ;distance from end of one scan line to start\r
- dec ax ; of next\r
- mov [NextScanOffset],ax\r
- mov [RectAddrWidth],cx ;remember width in addresses - 1\r
- mov dx,SC_INDEX+1 ;point to Sequence Controller Data reg\r
- ; (SC Index still points to Map Mask)\r
-@@FillRowsLoop:\r
- mov cx,[RectAddrWidth] ;width across - 1\r
- mov al,es:[si] ;read display memory to latch this scan\r
- ; line's pattern\r
- inc si ;point to the next pattern scan line, wrapping\r
- jnz short @@NoWrap ; back to the start of the pattern if\r
- sub si,4 ; we've run off the end\r
-@@NoWrap:\r
- mov al,bh ;put left-edge clip mask in AL\r
- out dx,al ;set the left-edge plane (clip) mask\r
- stosb ;draw the left edge (pixels come from latches;\r
- ; value written by CPU doesn't matter)\r
- dec cx ;count off left edge address\r
- js @@FillLoopBottom ;that's the only address\r
- jz @@DoRightEdge ;there are only two addresses\r
- mov al,00fh ;middle addresses drawn 4 pixels at a pop\r
- out dx,al ;set middle pixel mask to no clip\r
- rep stosb ;draw middle addresses four pixels apiece\r
- ; (from latches; value written doesn't matter)\r
-@@DoRightEdge:\r
- mov al,bl ;put right-edge clip mask in AL\r
- out dx,al ;set the right-edge plane (clip) mask\r
- stosb ;draw the right edge (from latches; value\r
- ; written doesn't matter)\r
-@@FillLoopBottom:\r
- add di,[NextScanOffset] ;point to the start of the next scan\r
- ; line of the rectangle\r
- dec word ptr [Height] ;count down scan lines\r
- jnz @@FillRowsLoop\r
-@@FillDone:\r
- mov dx,GC_INDEX+1 ;restore the bit mask to its default,\r
- mov al,0ffh ; which selects all bits from the CPU\r
- out dx,al ; and none from the latches (the GC\r
- ; Index still points to Bit Mask)\r
-\r
- pop di ;restore caller's register variables\r
- pop si\r
- mov sp,bp ;discard storage for local variables\r
- pop bp ;restore caller's stack frame\r
- ret\r
-_x_rect_pattern endp\r
-\r
-;-----------------------------------------------------------------------\r
-; Mode X (320x240, 256 colors) display memory to display memory copy\r
-; routine. Left edge of source rectangle modulo 4 must equal left edge\r
-; of destination rectangle modulo 4. Works on all VGAs. Uses approach\r
-; of reading 4 pixels at a time from the source into the latches, then\r
-; writing the latches to the destination. Copies up to but not\r
-; including the column at SrcEndX and the row at SrcEndY. No\r
-; clipping is performed. Results are not guaranteed if the source and\r
-; destination overlap.\r
-;\r
-;\r
-; Based on code originally published in DDJ Mag by M. Abrash\r
-;\r
-;C near-callable as:\r
-; void x_cp_vid_rect(int SrcStartX, int SrcStartY,\r
-; int SrcEndX, int SrcEndY, int DestStartX,\r
-; int DestStartY, unsigned int SrcPageBase,\r
-; unsigned int DestPageBase, int SrcBitmapWidth,\r
-; int DestBitmapWidth);\r
-\r
-_x_cp_vid_rect proc\r
- ARG SrcStartX:word,SrcStartY:word,SrcEndX:word,SrcEndY:word,DestStartX:word,DestStartY:word,SrcPageBase:word,DestPageBase:word,SrcBitmapW:word,DestBitmapW:word\r
- LOCAL SrcNextOffs:word,DestNextOffs:word,RectAddrW:word,Height:word=LocalStk\r
- push bp ;preserve caller's stack frame\r
- mov bp,sp ;point to local stack frame\r
- sub sp,LocalStk ;allocate space for local vars\r
- push si ;preserve caller's register variables\r
- push di\r
- push ds\r
-\r
- cld\r
- mov dx,GC_INDEX ;set the bit mask to select all bits\r
- mov ax,00000h+BIT_MASK ; from the latches and none from\r
- out dx,ax ; the CPU, so that we can write the\r
- ; latch contents directly to memory\r
- mov ax,SCREEN_SEG ;point ES to display memory\r
- mov es,ax\r
- mov ax,[DestBitmapW]\r
- shr ax,2 ;convert to width in addresses\r
- mul [DestStartY] ;top dest rect scan line\r
- mov di,[DestStartX]\r
- sar di,2 ;X/4 = offset of first dest rect pixel in\r
- ; scan line\r
- add di,ax ;offset of first dest rect pixel in page\r
- add di,[DestPageBase] ;offset of first dest rect pixel\r
- ; in display memory\r
- mov ax,[SrcBitmapW]\r
- sar ax,2 ;convert to width in addresses\r
- mul [SrcStartY] ;top source rect scan line\r
- mov si,[SrcStartX]\r
- mov bx,si\r
- sar si,2 ;X/4 = offset of first source rect pixel in\r
- ; scan line\r
- add si,ax ;offset of first source rect pixel in page\r
- add si,[SrcPageBase] ;offset of first source rect\r
- ; pixel in display memory\r
- and bx,0003h ;look up left edge plane mask\r
- mov ah,LeftClipPlaneMask[bx] ; to clip\r
- mov bx,[SrcEndX]\r
- and bx,0003h ;look up right edge plane\r
- mov al,RightClipPlaneMask[bx] ; mask to clip\r
- mov bx,ax ;put the masks in BX\r
-\r
- mov cx,[SrcEndX] ;calculate # of addresses across\r
- mov ax,[SrcStartX] ; rect\r
- cmp cx,ax\r
- jle @@CopyDone ;skip if 0 or negative width\r
- dec cx\r
- and ax,not 011b\r
- sub cx,ax\r
- sar cx,2 ;# of addresses across rectangle to copy - 1\r
- jnz @@MasksSet ;there's more than one address to draw\r
- and bh,bl ;there's only one address, so combine the left\r
- ; and right edge clip masks\r
-@@MasksSet:\r
- mov ax,[SrcEndY]\r
- sub ax,[SrcStartY] ;AX = height of rectangle\r
- jle @@CopyDone ;skip if 0 or negative height\r
- mov [Height],ax\r
- mov ax,[DestBitmapW]\r
- sar ax,2 ;convert to width in addresses\r
- sub ax,cx ;distance from end of one dest scan line\r
- dec ax ; to start of next\r
- mov [DestNextOffs],ax\r
- mov ax,[SrcBitmapW]\r
- sar ax,2 ;convert to width in addresses\r
- sub ax,cx ;distance from end of one source scan line\r
- dec ax ; to start of next\r
- mov [SrcNextOffs],ax\r
- mov [RectAddrW],cx ;remember width in addresses - 1\r
- mov dx,SC_INDEX+1 ;point to Sequence Controller Data reg\r
- ; (SC Index still points to Map Mask)\r
- mov ax,es ;DS=ES=screen segment for MOVS\r
- mov ds,ax\r
-@@CopyRowsLoop:\r
- mov cx,[RectAddrW] ;width across - 1\r
- mov al,bh ;put left-edge clip mask in AL\r
- out dx,al ;set the left-edge plane (clip) mask\r
- movsb ;copy the left edge (pixels go through\r
- ; latches)\r
- dec cx ;count off left edge address\r
- js @@CopyLoopBottom ;that's the only address\r
- jz @@DoRightEdge ;there are only two addresses\r
- mov al,00fh ;middle addresses are drawn 4 pix per go\r
- out dx,al ;set the middle pixel mask to no clip\r
- rep movsb ;draw the middle addresses four pix per go\r
- ; (pixels copied through latches)\r
-@@DoRightEdge:\r
- mov al,bl ;put right-edge clip mask in AL\r
- out dx,al ;set the right-edge plane (clip) mask\r
- movsb ;draw the right edge (pixels copied through\r
- ; latches)\r
-@@CopyLoopBottom:\r
- add si,[SrcNextOffs] ;point to the start of\r
- add di,[DestNextOffs] ; next source & dest lines\r
- dec word ptr [Height] ;count down scan lines\r
- jnz @@CopyRowsLoop\r
-@@CopyDone:\r
- mov dx,GC_INDEX+1 ;restore the bit mask to its default,\r
- mov al,0ffh ; which selects all bits from the CPU\r
- out dx,al ; and none from the latches (the GC\r
- ; Index still points to Bit Mask)\r
- pop ds\r
- pop di ;restore caller's register variables\r
- pop si\r
- mov sp,bp ;discard storage for local variables\r
- pop bp ;restore caller's stack frame\r
- ret\r
-_x_cp_vid_rect endp\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-; Copy a rectangular region of a VGA screen, with x coordinates\r
-; rounded to the nearest byte -- source and destination may overlap.\r
-;\r
-; C near-callable as:\r
-;\r
-; void x_shift_rect (WORD SrcLeft, WORD SrcTop,\r
-; WORD SrcRight, WORD SrcBottom,\r
-; WORD DestLeft, WORD DestTop, WORD ScreenOffs);\r
-;\r
-; SrcRight is rounded up, and the left edges are rounded down, to ensure\r
-; that the pixels pointed to by the arguments are inside the rectangle.\r
-;\r
-; The width of the rectangle in bytes (width in pixels / 4)\r
-; cannot exceed 255.\r
-;\r
-; ax, bx, cx, dx, and es eat hot lead.\r
-;\r
-; This function was written by Matthew MacKenzie\r
-; matm@eng.umd.edu\r
-\r
- align 2\r
-_x_shift_rect proc\r
-ARG SrcLeft,SrcTop,SrcRight,SrcBottom,DestLeft,DestTop,ScreenOffs:word\r
-LOCAL width_temp:word=LocalStk\r
-\r
- push bp\r
- mov bp, sp\r
- sub sp, LocalStk\r
- push si\r
- push di\r
- push ds\r
-\r
- ; find values for width & x motion\r
- mov si, SrcLeft ; source x in bytes\r
- sar si, 2\r
-\r
- mov di, DestLeft ; destination x in bytes\r
- sar di, 2\r
-\r
- mov bx, SrcRight ; right edge of source in bytes, rounded up\r
- add bx, 3\r
- sar bx, 2\r
- sub bx, si\r
- mov ax, bx ; width - 1\r
- inc bx ; we'll use this as an offset for moving up or down\r
- mov width_temp, bx\r
-\r
- cld ; by default, strings increment\r
-\r
- cmp si, di\r
- jge @@MovingLeft\r
-\r
-; we're moving our rectangle right, so we copy it from right to left\r
- add si, ax ; source & destination will start on the right edge\r
- add di, ax\r
- neg bx\r
- std ; strings decrement\r
-\r
-@@MovingLeft:\r
-\r
-; find values for height & y motion\r
- mov cx, _ScrnLogicalByteWidth ; bytes to move to advance one line\r
- mov ax, SrcTop\r
- mov dx, DestTop ; default destination y\r
- cmp ax, dx\r
- jge @@MovingUp\r
-\r
-; we're moving our rectangle down, so we copy it from bottom to top\r
- mov ax, SrcBottom ; source starts at bottom\r
- add dx, ax ; add (height - 1) to destination y\r
- sub dx, SrcTop\r
- neg cx ; advance up screen rather than down\r
-\r
-@@MovingUp:\r
- push dx ; save destination y during multiply\r
- mul _ScrnLogicalByteWidth\r
- add si, ax ; add y in bytes to source\r
- pop ax ; restore destination y\r
- mul _ScrnLogicalByteWidth\r
- add di, ax ; add y in bytes to destination\r
-\r
- sub cx, bx ; final value for moving up or down\r
-\r
- add si, ScreenOffs ; source & destination are on the same screen\r
- add di, ScreenOffs\r
-\r
- mov dx, SC_INDEX ; set map mask to all four planes\r
- mov ax, 00f02h\r
- out dx, ax\r
-\r
- mov dx, GC_INDEX ; set bit mask to take data from latches\r
- mov ax, BIT_MASK ; rather than CPU\r
- out dx, ax\r
-\r
- mov ax, SCREEN_SEG ; source and destination are VGA memory\r
- mov es, ax\r
- mov ds, ax\r
-\r
- mov ah, byte ptr width_temp ; width in bytes should fit in 8 bits\r
-\r
- mov bx, SrcBottom ; height - 1\r
- sub bx, SrcTop\r
-\r
- mov dx, cx ; bytes to add to advance one line\r
-\r
- xor ch, ch ; ready to rock\r
-\r
-@@LineLoop:\r
- mov cl, ah ; load width in bytes\r
- rep movsb ; move 4 pixels at a time using latches (YOW!)\r
-\r
- add si, dx ; advance source by one line\r
- add di, dx ; advance destination by one line\r
-\r
- dec bx ; line counter\r
- jge @@LineLoop ; 0 still means one more to go\r
-\r
- mov dx, GC_INDEX + 1; set bit mask to take data from CPU (normal setting)\r
- mov al, 0ffh\r
- out dx, al\r
-\r
-; kick\r
- pop ds\r
- pop di\r
- pop si\r
- mov sp, bp\r
- pop bp\r
-\r
- ret\r
-_x_shift_rect endp\r
-\r
- end\r
-\r
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XRECT - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;-----------------------------------------------------------------------*/\r
-\r
-#ifndef _XRECT_H_\r
-#define _XRECT_H_\r
-\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
- void x_rect_pattern( /* draw a pattern filled rectangle */\r
- WORD StartX,\r
- WORD StartY,\r
- WORD EndX,\r
- WORD EndY,\r
- WORD PageBase,\r
- BYTE far * Pattern);\r
-\r
- void x_rect_pattern_clipped( /* draw a pattern filled clipped */\r
- WORD StartX, /* rectangle */\r
- WORD StartY,\r
- WORD EndX,\r
- WORD EndY,\r
- WORD PageBase,\r
- BYTE far * Pattern);\r
-\r
- void x_rect_fill( /* draw a single colour filled rectangle */\r
- WORD StartX,\r
- WORD StartY,\r
- WORD EndX,\r
- WORD EndY,\r
- WORD PageBase,\r
- WORD color);\r
-\r
- void x_rect_fill_clipped( /* draw a single colour filled */\r
- WORD StartX, /* and clipped rectangle */\r
- WORD StartY,\r
- WORD EndX,\r
- WORD EndY,\r
- WORD PageBase,\r
- WORD color);\r
-\r
- void x_cp_vid_rect( /* Copy rect region within VRAM */\r
- WORD SourceStartX,\r
- WORD SourceStartY,\r
- WORD SourceEndX,\r
- WORD SourceEndY,\r
- WORD DestStartX,\r
- WORD DestStartY,\r
- WORD SourcePageBase,\r
- WORD DestPageBase,\r
- WORD SourceBitmapWidth,\r
- WORD DestBitmapWidth);\r
-\r
-/* Copy a rectangular region of a VGA screen, with x coordinates\r
- rounded to the nearest byte -- source and destination may overlap. */\r
-\r
- void x_shift_rect (WORD SrcLeft, WORD SrcTop,\r
- WORD SrcRight, WORD SrcBottom,\r
- WORD DestLeft, WORD DestTop, WORD ScreenOffs);\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-\r
-#endif\r
-\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XRECT - Include file\r
-;\r
-; XRECT.ASM export functions\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
- global _x_rect_fill :proc\r
- global _x_rect_fill_clipped :proc\r
- global _x_rect_pattern :proc\r
- global _x_rect_pattern_clipped :proc\r
- global _x_cp_vid_rect :proc\r
- global _x_shift_rect :proc\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XRLETOOL\r
-;\r
-; Hardware detection module\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-COMMENT $\r
-\r
-Firstly, please note that this module has been built from the ground up\r
-in a rush so although I'm confident all the functions work, I have'nt\r
-extensively checked them. If any should surface please let me know.\r
-\r
-\r
-This module implements a number of functions comprising an RLE encoding\r
-decoding system.\r
-\r
-RLE stands for RUN LENGTH ENCODING. It is a quick simple data compression\r
-scheme which is commonly used for image data compression or compression\r
-of any data. Although not the most efficient system, it is fast, which is\r
-why it is used in image storage systems like PCX. This implementation is\r
-more efficient than the one used in PCX files because it uses 1 bit to\r
-identify a Run Length byte as opposed to two in PCX files, but more on this\r
-later.\r
-\r
-This set of functions can be used to implement your own compressed image\r
-file format or for example compress game mapse for various levels etc.\r
-The uses are limited by your imagination.\r
-\r
-I opted for trading off PCX RLE compatibility for the improved compression\r
-efficiency.\r
-\r
-Here is how the data is un-compressed to give an idea of its structure.\r
-\r
-\r
-STEP 1 read a byte from the RLE compressed source buffer.\r
-\r
-STEP 2 if has its high bit then the lower 7 bits represent the number of\r
- times the next byte is to be repeated in the destination buffer.\r
- if the count (lower 7 bits) is zero then\r
- we have finished decoding goto STEP 5\r
- else goto STEP 4\r
-\r
-STEP 3 Read a data from the source buffer and copy it directly to the\r
- destination buffer.\r
- goto STEP 1\r
-\r
-STEP 4 Read a data from the source buffer and copy it to the destination\r
- buffer the number of times specified by step 2.\r
- goto STEP 1\r
-\r
-STEP 5 Stop, decoding done.\r
-\r
-If the byte does not have the high bit set then the byte itself is transfered\r
- to the destination buffer.\r
-\r
-Data bytes that have the high bit already set and are unique in the input\r
- stream are represented as a Run Length of 1 (ie 81 which includes high bit)\r
- followed by the data byte.\r
-\r
-If your original uncompressed data contains few consecutive bytes and most\r
-have high bit set (ie have values > 127) then your so called\r
-compressed data would require up to 2x the space of the uncompressed data,\r
-so be aware that the compression ratio is extremely variable depending on the\r
-type of data being compressed.\r
-\r
-Apologies for this poor attempt at a description, but you can look up\r
-RLE in any good text. Alternatively, any text that describes the PCX file\r
-structure in any depth should have a section on RLE compression.\r
-\r
-\r
-\r
-$\r
-\r
-LOCALS\r
-.286\r
-\r
-include model.inc\r
-include xrletool.inc\r
-\r
- .data\r
-\r
-_RLE_last_buff_offs dw (0)\r
-RLEbuff db 2 dup (?)\r
-\r
- .code\r
-\r
-;****************************************************************\r
-;*\r
-;* NAME: x_buff_RLEncode\r
-;*\r
-;*\r
-;* RLE Compresses a source buffer to a destination buffer and returns\r
-;* the size of the resultant compressed data.\r
-;*\r
-;* C PROTOTYPE:\r
-;*\r
-;* extern unsigned int x_buff_RLEncode(char far * source_buff,\r
-;* char far * dest_buff,unsigned int count);\r
-;*\r
-;* source_buff - The buffer to compress\r
-;* dest_buff - The destination buffer\r
-;* count - The size of the source data in bytes\r
-;*\r
-;* WARNING: buffers must be pre allocated.\r
-;*\r
-proc _x_buff_RLEncode\r
-ARG src:dword,dest:dword,count:word\r
- push bp\r
- mov bp,sp\r
- push ds\r
- push si\r
- push di\r
-\r
- lds si,[src]\r
- les di,[dest]\r
- mov dx,[count]\r
-\r
- push di\r
-\r
- lodsb ; Load first byte into BL\r
- mov bl,al\r
- xor cx,cx ; Set number characters packed to zero\r
- cld ; All moves are forward\r
-\r
-@@RepeatByte:\r
- lodsb ; Get byte into AL\r
- inc cx ; Increment compressed byte count\r
- sub dx,1 ; Decrement bytes left\r
- je @@LastByte ; Finished when dx = 1\r
- cmp cx,7fh ; Filled block yet\r
- jne @@NotFilled ; Nope!\r
-\r
- or cl,80h ; Set bit to indicate value is repeat count\r
- mov es:[di],cl ; store it\r
- inc di\r
- xor cx,cx ; clear compressed byte count\r
- mov es:[di],bl ; store byte to be repeated\r
- inc di\r
-\r
-@@NotFilled:\r
- cmp al,bl ; hase there been a byte transition ?\r
- je @@RepeatByte ; No!\r
-\r
- cmp cl,1 ; do we have a unique byte ?\r
- jne @@NotUnique ; No\r
-\r
- test bl,80h ; Can this byte be mistaken for repeat count\r
- jz @@Unambiguous ; No ! Dont bother with repeat count\r
-\r
-@@NotUnique:\r
- or cl,80h ; Set bit to indicate value is repeat count\r
- mov es:[di],cl ; store it\r
- inc di\r
-@@Unambiguous:\r
- xor cx,cx ; clear compressed byte count\r
- mov es:[di],bl ; store byte to be repeated\r
- inc di\r
- mov bl,al ; move latest byte into bl\r
- jmp short @@RepeatByte\r
-\r
-@@LastByte:\r
- cmp cl,1 ; Is this a unique byte\r
- jne @@FinalCount ; No\r
-\r
- test bl,80h ; Can this byte be mistaken for repeat count\r
- jz @@FinalByte ; No, so dont bother with the repeat count\r
-\r
-@@FinalCount: ; Output the repeat count\r
- or cl,80h\r
- mov al,cl\r
- stosb\r
-\r
-@@FinalByte:\r
- mov al,bl\r
- stosb\r
-\r
- mov al,80h ; store terminating null length\r
- stosb\r
-\r
- ; Calculate encoded length of buffer\r
-\r
- mov ax,di\r
- pop di\r
- sub ax,di\r
-\r
- pop di\r
- pop si\r
- pop ds\r
- pop bp\r
- ret\r
-_x_buff_RLEncode endp\r
-\r
-\r
-\r
-;****************************************************************\r
-;*\r
-;* NAME: x_buff_RLE_size\r
-;*\r
-;*\r
-;* Returns the size the input data would compress to.\r
-;*\r
-;* C PROTOTYPE:\r
-;*\r
-;* extern unsigned int x_buff_RLE_size(char far * source_buff,\r
-;* unsigned int count);\r
-;*\r
-;* source_buff - The uncompressed data buffer\r
-;* count - The size of the source data in bytes\r
-;*\r
-;*\r
-proc _x_buff_RLE_size\r
-ARG src:dword,count:word\r
- push bp\r
- mov bp,sp\r
- push ds\r
- push si\r
- push di\r
-\r
- lds si,[src]\r
- mov dx,[count]\r
-\r
- xor di,di\r
-\r
- lodsb ; Load first byte into BL\r
- mov bl,al\r
- xor cx,cx ; Set number characters packed to zero\r
- cld ; All moves are forward\r
-\r
-@@RepeatByte:\r
- lodsb ; Get byte into AL\r
- inc cx ; Increment compressed byte count\r
- sub dx,1 ; Decrement bytes left\r
- je @@LastByte ; Finished when dx = 1\r
- cmp cx,7fh ; Filled block yet\r
- jne @@NotFilled ; Nope!\r
-\r
- add di,2 ; RL/BYTE pair stub\r
-\r
-@@NotFilled:\r
- cmp al,bl ; hase there been a byte transition ?\r
- je @@RepeatByte ; No!\r
-\r
- cmp cl,1 ; do we have a unique byte ?\r
- jne @@NotUnique ; No\r
-\r
- test bl,80h ; Can this byte be mistaken for repeat count\r
- jz @@Unambiguous ; No ! Dont bother with repeat count\r
-\r
-@@NotUnique:\r
- inc di ; RL stub\r
-\r
-@@Unambiguous:\r
- xor cx,cx ; clear compressed byte count\r
- inc di ; BYTE stub\r
- mov bl,al ; move latest byte into bl\r
- jmp short @@RepeatByte\r
-\r
-@@LastByte:\r
- cmp cl,1 ; Is this a unique byte\r
- jne @@FinalCount ; No\r
-\r
- test bl,80h ; Can this byte be mistaken for repeat count\r
- jz @@FinalByte ; No, so dont bother with the repeat count\r
-\r
-@@FinalCount: ; Output the repeat count\r
- inc di ; RL stub\r
-\r
-@@FinalByte:\r
- inc di ; BYTE stub\r
- inc di ; RL stub - Account for termiating null\r
- mov ax,di\r
-\r
- pop di\r
- pop si\r
- pop ds\r
- pop bp\r
- ret\r
-_x_buff_RLE_size endp\r
-\r
-;****************************************************************\r
-;*\r
-;* NAME: x_buff_RLDecode\r
-;*\r
-;*\r
-;* Expands an RLE compresses source buffer to a destination buffer.\r
-;* returns the size of the resultant uncompressed data.\r
-;*\r
-;* C PROTOTYPE:\r
-;*\r
-;* extern unsigned int x_buff_RLDecode(char far * source_buff,\r
-;* char far * dest_buff);\r
-;*\r
-;* source_buff - The buffer to compress\r
-;* dest_buff - The destination buffer\r
-;*\r
-;* WARNING: buffers must be pre allocated.\r
-;*\r
-proc _x_buff_RLDecode\r
-ARG src:dword,dest:dword\r
-LOCAL si_ini:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk\r
- push ds\r
- push si\r
- push di\r
-\r
- mov dx,-1 ; zero output data buffer size - 1 (compensate for\r
- ; terminating null RL)\r
- xor cx,cx ; clear CX\r
- cld ; Move forward\r
-\r
- lds si,[src] ; point ds:si -> RLE source\r
- les di,[dest] ; point es:di -> uncompressed buffer\r
- mov [si_ini],si\r
-\r
-@@UnpackLoop:\r
- lodsb ; load a byte into AL\r
- cmp al,80h ; is it terminating null RL code\r
- je @@done ; if so jump\r
-\r
- test al,80h ; is AL a RL code (is high bit set ?)\r
- jz @@NoRepeats ; if not the no RL encoding for this byte, jump\r
-\r
- mov cl,al ; set CL to RL (run length) taking care\r
- xor cl,80h ; to remove the bit identifying it as a RL\r
- add dx,cx ; increment buffer size\r
-\r
- lodsb ; get the next byte which should be a data byte\r
-\r
- shr cx,1 ; divide RL by 2 to use word stos\r
- jcxz @@NoRepeats ; result is zero, jump\r
-\r
- mov ah,al ; copy data byte to AH since going to use stosw\r
- rep stosw ; copy AX to outbut buffer RL times\r
- jnb @@UnpackLoop ; when we shifted the RL if we had a carry =>\r
- ; we had an odd number of repeats so store the\r
- ; last BYTE if carry was set otherwise jump\r
- stosb ; store AL in destination buffer\r
- jmp short @@UnpackLoop\r
-\r
-@@NoRepeats:\r
- inc dx ; increment buffer size\r
- stosb ; store AL in destination buffer\r
- jmp short @@UnpackLoop\r
-\r
-@@done:\r
-\r
- mov bx,si\r
- sub bx,[si_ini]\r
- mov ax,dx\r
- pop di\r
- pop si\r
- pop ds\r
- mov [_RLE_last_buff_offs],bx\r
- mov sp,bp\r
- pop bp\r
- ret\r
-_x_buff_RLDecode endp\r
-\r
-;==========================================================================\r
-;==========================================================================\r
-; RLEncode to file / RLDecode from file\r
-; WARNING the following functions are *MUCH* slower than the above\r
-; Its best to use the above functions with intermediate buffers where\r
-; disk i/o is concearned... See demo 4\r
-;==========================================================================\r
-;==========================================================================\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-;\r
-; put_cx\r
-;\r
-; Local utility proc for x_file_RLEncode - write cx to file\r
-;\r
-; Entry:\r
-; es:dx -> output buffer\r
-; cx = word to write\r
-;\r
-;\r
-put_cx proc near\r
- push ds ; preserve critical registers\r
- push ax\r
- push bx\r
- mov ax,ds ; set up DS to output buffers segment\r
- mov ds,ax\r
- mov word ptr [RLEbuff],cx ; copy CX to output buffer\r
- mov ah,40h ; select "write to file or device" DOS service\r
- mov bx,[handle] ; select handle of file to write\r
- mov cx,2 ; sending 2 bytes\r
- int 21h ; call DOS service\r
- pop bx ; recover registers\r
- pop ax\r
- pop ds\r
- ret\r
-put_cx endp\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-;\r
-; put_cx\r
-;\r
-; Local utility proc for x_file_RLEncode - write cx to file\r
-;\r
-; Entry:\r
-; es:dx -> output buffer\r
-; cx = word to write\r
-;\r
-;\r
-put_cl proc near\r
- push ds ; preserve critical registers\r
- push ax\r
- push bx\r
- mov ax,ds ; set up DS to output buffers segment\r
- mov ds,ax\r
- mov byte ptr [RLEbuff],cl\r
- mov ah,40h ; select "write to file or device" DOS service\r
- mov bx,[handle] ; select handle of file to write\r
- mov cx,1 ; sending 1 byte\r
- int 21h ; call DOS service\r
- pop bx ; recover registers\r
- pop ax\r
- pop ds\r
- ret\r
-put_cl endp\r
-\r
-\r
-;****************************************************************\r
-;*\r
-;* NAME: x_file_RLEncode\r
-;*\r
-;*\r
-;* RLE Compresses a source buffer to an output file returning\r
-;* the size of the resultant compressed data or 0 if it fails.\r
-;*\r
-;* C PROTOTYPE:\r
-;*\r
-;* extern unsigned int x_file_RLEncode(int handle,\r
-;* char far * source_buff,unsigned int count);\r
-;*\r
-;* source_buff - The buffer to compress\r
-;* handle - The file handler\r
-;* count - The size of the source data in bytes\r
-;*\r
-;*\r
-proc _x_file_RLEncode\r
-ARG handle:word,src:dword,count:word\r
-LOCAL filesize:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk\r
- push ds\r
- push si\r
- push di\r
-\r
- mov [filesize],0\r
- mov dx,offset [RLEbuff]\r
- mov ax,ds\r
- mov es,ax\r
- lds si,[src]\r
- mov di,[count]\r
-\r
- lodsb ; Load first byte into BL\r
- mov bl,al\r
- xor cx,cx ; Set number characters packed to zero\r
- cld ; All moves are forward\r
-\r
-@@RepeatByte:\r
- lodsb ; Get byte into AL\r
- inc cx ; Increment compressed byte count\r
- sub di,1 ; Decrement bytes left\r
- je @@LastByte ; Finished when di = 1\r
- cmp cx,7fh ; Filled block yet\r
- jne @@NotFilled ; Nope!\r
-\r
- or cl,80h ; Set bit to indicate value is repeat count\r
- mov ch,bl\r
- add [filesize],2\r
- call put_cx\r
- jb @@FileError ; if carry set then file I/O error\r
- xor cx,cx ; clear compressed byte count\r
-\r
-@@NotFilled:\r
- cmp al,bl ; hase there been a byte transition ?\r
- je @@RepeatByte ; No!\r
-\r
- cmp cl,1 ; do we have a unique byte ?\r
- jne @@NotUnique ; No\r
-\r
- test bl,80h ; Can this byte be mistaken for repeat count\r
- jz @@Unambiguous ; No ! Dont bother with repeat count\r
-\r
-@@NotUnique:\r
- or cl,80h ; Set bit to indicate value is repeat count\r
- inc [filesize]\r
- call put_cl ; store it\r
- jb @@FileError ; if carry set then file I/O error\r
-@@Unambiguous:\r
-\r
- mov cl,bl ; store byte to be repeated\r
- inc [filesize]\r
- call put_cl\r
- jb @@FileError ; if carry set then file I/O error\r
- mov bl,al ; move latest byte into bl\r
- xor cx,cx ; clear compressed byte count\r
- jmp short @@RepeatByte\r
-\r
-@@FileError:\r
- mov ax,0\r
- jmp short @@exit\r
-\r
-@@LastByte:\r
- cmp cl,1 ; Is this a unique byte\r
- jne @@FinalCount ; No\r
-\r
- test bl,80h ; Can this byte be mistaken for repeat count\r
- jz @@FinalByte ; No, so dont bother with the repeat count\r
-\r
-@@FinalCount: ; Output the repeat count\r
- or cl,80h\r
- inc [filesize]\r
- call put_cl\r
- jb @@FileError ; if carry set then file I/O error\r
-\r
-@@FinalByte:\r
- mov cl,bl\r
- mov ch,80h\r
- add [filesize],2\r
- call put_cx ; store terminating null length\r
- jb @@FileError ; if carry set then file I/O error\r
-\r
- mov ax,[filesize]\r
- jmp short @@exit\r
-\r
-@@exit:\r
- pop di\r
- pop si\r
- pop ds\r
- mov sp,bp\r
- pop bp\r
- ret\r
-_x_file_RLEncode endp\r
-\r
-\r
-\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-;\r
-; GET_BYTE\r
-;\r
-; macro to read a byte from the input file into al\r
-;\r
-GET_BYTE macro\r
- push bx\r
- mov ah,3fh ; select "read from file or device" DOS service\r
- mov bx,[handle] ; Select handle of file to close\r
- mov cx,1 ; Want to read 1 byte\r
- int 21h ; call DOS service\r
- pop bx\r
- jb @@FileError ; failed if carry flag set\r
- mov al,[RLEbuff]\r
- endm\r
-\r
-\r
-;****************************************************************\r
-;*\r
-;* NAME: x_file_RLDecode\r
-;*\r
-;*\r
-;* Expands an RLE compresses file to a destination RAM buffer.\r
-;* returns the size of the resultant uncompressed data.\r
-;*\r
-;* C PROTOTYPE:\r
-;*\r
-;* extern unsigned int x_buff_RLDecode(int handle,\r
-;* char far * dest_buff);\r
-;*\r
-;* handle - Input file handle\r
-;* dest_buff - The destination buffer\r
-;*\r
-;*\r
-proc _x_file_RLDecode\r
-ARG handle:word,dest:dword\r
- push bp\r
- mov bp,sp\r
- push si\r
- push di\r
-\r
-\r
- mov bx,-1 ; zero output data buffer size - 1 (compensate for\r
- ; terminating null RL)\r
- mov dx,offset [RLEbuff] ; setup DS:DX -> RLEBuffer\r
- xor cx,cx ; clear CX\r
- cld ; Move forward\r
-\r
- les di,[dest] ; point es:di -> uncompressed buffer\r
-\r
-@@UnpackLoop:\r
-\r
- GET_BYTE ; Load a byte from file into AL\r
-\r
- cmp al,80h ; is it terminating null RL code\r
- je @@done ; if so jump\r
-\r
- test al,80h ; is AL a RL code (is high bit set ?)\r
- jz @@NoRepeats ; if not the no RL encoding for this byte, jump\r
-\r
- mov cl,al ; set CL to RL (run length) taking care\r
- xor cl,80h ; to remove the bit identifying it as a RL\r
- add bx,cx ; increment buffer size\r
- mov si,cx ; save the CX value\r
- GET_BYTE ; Load a byte from file into AL\r
- mov cx,si ; restore CX value\r
- shr cx,1 ; divide RL by 2 to use word stos\r
- jcxz @@NoRepeats ; result is zero, jump\r
-\r
- mov ah,al ; copy data byte to AH since going to use stosw\r
- rep stosw ; copy AX to outbut buffer RL times\r
- jnb @@UnpackLoop ; when we shifted the RL if we had a carry =>\r
- ; we had an odd number of repeats so store the\r
- ; last BYTE if carry was set otherwise jump\r
- stosb ; store AL in destination buffer\r
- jmp short @@UnpackLoop\r
-\r
-@@NoRepeats:\r
- inc bx\r
- stosb ; store AL in destination buffer\r
- jmp short @@UnpackLoop\r
-\r
-@@FileError:\r
- mov ax,0\r
- jmp short @@exit\r
-\r
-@@done:\r
- mov ax,bx\r
-@@exit:\r
- pop di\r
- pop si\r
- pop bp\r
- ret\r
-_x_file_RLDecode endp\r
-\r
- end\r
-\r
-\1a
\ No newline at end of file
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XRLETOOL - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-;-----------------------------------------------------------------------*/\r
-\r
-#ifndef _XRLETOOL_H_\r
-#define _XRLETOOL_H_\r
-\r
-extern unsigned int RLE_last_buff_offs;\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-extern unsigned int x_buff_RLEncode( /* Compress data buffer */\r
- char far * source_buff,\r
- char far * dest_buff,\r
- unsigned int count);\r
-\r
-extern unsigned int x_buff_RLE_size( /* Calculate buffer's compressed size */\r
- char far * source_buff,\r
- unsigned int count);\r
-\r
-\r
-extern unsigned int x_buff_RLDecode( /* Uncompress data buffer */\r
- char far * source_buff,\r
- char far * dest_buff);\r
-\r
-extern int x_file_RLEncode( /* Compress data buffer to file */\r
- int handle,\r
- char far * src_buff,\r
- unsigned int count);\r
-\r
-extern int x_file_RLDecode( /* Uncompress data file */\r
- int file_handle,\r
- char far * dest_buff);\r
-\r
-\r
-#endif\r
-\r
-\r
-\1a
\ No newline at end of file
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XRLETOOL - Include file\r
-;\r
-; XRLETOOL.ASM export functions\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
- global _x_buff_RLEncode :proc\r
- global _x_buff_RLE_size :proc\r
- global _x_buff_RLDecode :proc\r
- global _x_file_RLEncode :proc\r
- global _x_file_RLDecode :proc\r
-\r
- global _RLE_last_buff_offs :word\r
- \r
-\1a
\ No newline at end of file
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XTEXT\r
-;\r
-; Point functions all MODE X 256 Color resolutions\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
-include xlib.inc\r
-include xtext.inc\r
-\r
-.data\r
-\r
-_FontDriverActive db 0\r
-\r
-\r
-_CharHeight db 0\r
-_CharWidth db 0\r
-_FontPtr dw 2 dup (0)\r
-_FirstChar db 0\r
-\r
-_UserFontPtr dw 2 dup (0)\r
-_UserChHeight db 0\r
-_UserChWidth db 0\r
-_UserFirstCh db 0\r
-\r
-\r
-F8x8Ptr dw 2 dup (0)\r
-F8x14Ptr dw 2 dup (0)\r
-\r
-; This is a look up table for the mirror image of a byte eg\r
-; a byte with the value 11001010 has a corresponding byte in the table\r
-; 01010011. This is necessary as the VGA rom font bits are the reverse\r
-; order of what we need for the Mode X. If you know a better-faster way\r
-; TELL ME!\r
-\r
-MirrorTable label byte\r
- db 0,128, 64,192, 32,160, 96,224, 16,144, 80,208, 48,176,112,240\r
- db 8,136, 72,200, 40,168,104,232, 24,152, 88,216, 56,184,120,248\r
- db 4,132, 68,196, 36,164,100,228, 20,148, 84,212, 52,180,116,244\r
- db 12,140, 76,204, 44,172,108,236, 28,156, 92,220, 60,188,124,252\r
- db 2,130, 66,194, 34,162, 98,226, 18,146, 82,210, 50,178,114,242\r
- db 10,138, 74,202, 42,170,106,234, 26,154, 90,218, 58,186,122,250\r
- db 6,134, 70,198, 38,166,102,230, 22,150, 86,214, 54,182,118,246\r
- db 14,142, 78,206, 46,174,110,238, 30,158, 94,222, 62,190,126,254\r
- db 1,129, 65,193, 33,161, 97,225, 17,145, 81,209, 49,177,113,241\r
- db 9,137, 73,201, 41,169,105,233, 25,153, 89,217, 57,185,121,249\r
- db 5,133, 69,197, 37,165,101,229, 21,149, 85,213, 53,181,117,245\r
- db 13,141, 77,205, 45,173,109,237, 29,157, 93,221, 61,189,125,253\r
- db 3,131, 67,195, 35,163, 99,227, 19,147, 83,211, 51,179,115,243\r
- db 11,139, 75,203, 43,171,107,235, 27,155, 91,219, 59,187,123,251\r
- db 7,135, 71,199, 39,167,103,231, 23,151, 87,215, 55,183,119,247\r
- db 15,143, 79,207, 47,175,111,239, 31,159, 95,223, 63,191,127,255\r
-\r
-MirrorTableOffs dw ?\r
-.code\r
-\r
-;----------------------------------------------------------------------\r
-; x_text_init - Initializes the Mode X text driver and sets the\r
-; default font (VGA ROM 8x8)\r
-;\r
-; C caller:\r
-;\r
-; x_text_init()\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_text_init proc\r
- push bp\r
-\r
- mov [_FontDriverActive],TRUE\r
- mov ax,1130h ; AH = BIOS generator function\r
- ; AL = BIOS get font pointer subfunction\r
- push ax ; Save Video interrupt function parameters\r
- mov bh,3 ; Select 8x8 VGA ROM font\r
- int 10h ; Call BIOS video interrupt\r
- mov word ptr [F8x8Ptr],bp ; Save 8x8 Font address in FontPtr table\r
- mov word ptr [F8x8Ptr+2],es\r
-\r
- mov word ptr [_FontPtr],bp ; Default font = 8x8 ROM font\r
- mov word ptr [_FontPtr+2],es\r
-\r
- pop ax ; Recall Video interrupt function parameters\r
- mov bh,2 ; Select 8x14 VGA ROM font\r
- int 10h ; Call BIOS video interrupt\r
- mov word ptr [F8x14Ptr],bp ; Save 8x14 Font address in FontPtr table\r
- mov word ptr [F8x14Ptr+2],es\r
-\r
-\r
- mov al,8\r
- mov [_CharHeight],al ; Set the font character heights\r
- mov [_CharWidth] ,al ; Set the font character widths\r
-\r
- mov dx,offset MirrorTable ; Initialize mirror table offset\r
- mov [MirrorTableOffs],dx\r
-\r
- pop bp\r
- ret\r
-_x_text_init endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_set_font - Mode X Set current font for text drawing\r
-;\r
-; C caller:\r
-;\r
-; x_set_font(int FontID)\r
-;\r
-; PARAMETERS FontID 0 = VGA ROM 8x8\r
-; 1 = VGA ROM 8x14\r
-; 2 = User defined bitmapped font\r
-;\r
-;\r
-; WARNING: A user font must be registered before setting FontID 2\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-\r
-_x_set_font proc\r
- ARG FontID:word\r
- push bp\r
- mov bp,sp\r
-\r
- xor dx,dx ; Clear DX - Mirror table offset (0 for non ROM fonts)\r
- mov cx,FontID\r
- cmp cx,2\r
-\r
- jne @@not_userfont ; Do we have a user font\r
- mov ax,[_UserFontPtr] ; Yes - Activate it\r
- mov [_FontPtr],ax\r
-\r
- mov ax,[_UserFontPtr+2]\r
- mov [_FontPtr+2],ax\r
-\r
- mov al,[_UserChHeight]\r
- mov [_CharHeight],al ; Set the font character heights\r
-\r
- mov al,[_UserChWidth]\r
- mov [_CharWidth],al ; Set the font character heights\r
-\r
- mov al,[_UserFirstCh]\r
- mov [_FirstChar],al\r
- jmp short @@done\r
-\r
-@@not_userfont: ; We have a ROM font\r
-\r
- mov dx,offset MirrorTable\r
- mov [_CharWidth],8 ; Set the font character widths\r
- mov [_FirstChar],0 ; Character sets start at ascii 0\r
- cmp cx,1 ; Do we have an 8x14 ROM font\r
- jne @@not_8x14font ; No, we have 8x8 - jump\r
-\r
- mov ax,[F8x14Ptr] ; Yes Activate it\r
- mov [_FontPtr],ax\r
-\r
- mov ax,[F8x14Ptr+2]\r
- mov [_FontPtr+2],ax\r
-\r
- mov [_CharHeight],14 ; Set the font character heights\r
- jmp short @@done\r
-\r
-@@not_8x14font:\r
- mov ax,[F8x8Ptr] ; Activate the 8x8 ROM Font\r
- mov [_FontPtr],ax\r
-\r
- mov ax,[F8x8Ptr+2]\r
- mov [_FontPtr+2],ax\r
-\r
- mov [_CharHeight],8 ; Set the font character heights\r
-\r
-@@done:\r
- mov [MirrorTableOffs],dx\r
-\r
- pop bp\r
- ret\r
-_x_set_font endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_register_userfont - Mode X register user font\r
-;\r
-; C caller:\r
-;\r
-; x_register_userfont(void far *user_font)\r
-;\r
-;\r
-; NOTES registering a user font deregisters the previous user font\r
-; User fonts may be at most 8 pixels wide\r
-;\r
-;\r
-; USER FONT STRUCTURE\r
-;\r
-; Word: ascii code of first char in font\r
-; Byte: Height of chars in font\r
-; Byte: Width of chars in font\r
-; n*h*Byte: the font data where n = number of chars and h = height\r
-; of chars\r
-;\r
-; WARNING: The onus is on the program to ensure that all characters\r
-; drawn whilst this font is active, are within the range of\r
-; characters defined.\r
-;\r
-;\r
-; UPDATE: Variable width fonts are now available (up to 8 pixels max)\r
-; If the Width byte in the font header is 0 then it is assumed that\r
-; the font is variable width. For variable width fonts each characters\r
-; data is followed by one byte representing the characters pixel width.\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_register_userfont proc\r
- ARG FontToRegister:dword\r
- push bp\r
- mov bp,sp\r
- push si\r
-\r
- mov ax,word ptr [FontToRegister]\r
- mov bx,word ptr [FontToRegister+2]\r
- add ax,4\r
- mov [_UserFontPtr],ax\r
- mov [_UserFontPtr+2],bx\r
-\r
- push ds\r
- lds si,[FontToRegister]\r
- lodsw\r
- mov bx,ax\r
- lodsw\r
- pop ds\r
-\r
- mov [_UserChHeight],al\r
- mov [_UserChWidth],ah\r
- mov [_UserFirstCh],bl\r
- pop si\r
- pop bp\r
- ret\r
-_x_register_userfont endp\r
-\r
-\r
-_x_get_char_width proc\r
- ARG Chr:byte\r
- push bp\r
- mov bp,sp\r
-\r
- xor ah,ah\r
- mov al,[_CharWidth]\r
- or al,al\r
- jz @@NotFixed\r
- pop bp\r
- ret\r
-\r
-@@NotFixed:\r
- push si\r
- mov al,[_CharHeight]\r
- mov bx,ax\r
- inc al\r
- mov dl,[Chr] ; User fonts may have incomplete charsets\r
- sub dl,[_FirstChar] ; this compensates for fonts not starting at\r
- ; ascii value 0\r
- mul dl ; Mult AX by character to draw giving offset\r
- ; of first character byte in font table\r
- add ax,bx\r
- les si,dword ptr [_FontPtr]\r
- add si,ax\r
- xor ah,ah\r
- mov al,es:[si]\r
- pop si\r
- pop bp\r
- ret\r
-_x_get_char_width endp\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_char_put - Mode X Draw a text character at the specified location\r
-;\r
-;\r
-; C caller:\r
-;\r
-; x_char_put(char ch, int x, int y, unsigned ScrnOffs, unsigned Color)\r
-;\r
-; PARAMETERS ch char to draw\r
-; x,y screen coords at which to draw ch\r
-; ScrnOffs Starting offset of page on whih to draw\r
-; Color Color of the text\r
-;\r
-; NOTES: Uses the current font settings. See SetFont, InitTextDriver,\r
-; RegisterUserFont\r
-;\r
-; WARNING: InitTextDriver must be called before using this function\r
-;\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_char_put proc\r
- ARG Chr:byte,X:word,Y:word,ScrnOffs:word,Color:word\r
- LOCAL ScreenInc:word,Hold:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk\r
- push si\r
- push di\r
- push ds\r
-\r
- cld\r
- mov ax,[_ScrnLogicalByteWidth] ; AX = Virtual screen width\r
- mov bx,ax ; copy Virt screen width and decrement\r
- sub bx,3 ; by the max number of bytes (whole or part)\r
- ; that a character row may occupy on the screen\r
- mov [ScreenInc],bx ; Save it to the local stack var. SceenInc\r
- mul [Y] ; Find the starting dest. screen address of\r
- mov di,[X] ; the character to draw\r
- mov cx,di\r
- shr di,2\r
- add di,ax\r
- add di,[ScrnOffs] ; Dont forget to compensate for page\r
-\r
- mov ax,SCREEN_SEG ; ES:DI -> first screen dest. byte of char\r
- mov es,ax\r
-\r
- and cx,3 ; CH = 0, CL = Plane of first pixel\r
-\r
- mov bx,[MirrorTableOffs] ; set BX to offset of mirror table for XLAT\r
- mov al,[_CharHeight] ; AL = Character height, AH = 0\r
- xor ah,ah\r
- mov ch,al ; CH = Character height\r
-\r
- cmp [_CharWidth],0\r
- jne @@NoWidthByte\r
- inc al\r
-@@NoWidthByte:\r
-\r
- mov dl,[Chr] ; User fonts may have incomplete charsets\r
- sub dl,[_FirstChar] ; this compensates for fonts not starting at\r
- ; ascii value 0\r
- mul dl ; Mult AX by character to draw giving offset\r
- ; of first character byte in font table\r
-\r
- lds si,dword ptr [_FontPtr] ; DS:SI -> beggining of required font\r
- add si,ax ; DS:SI -> first byte of req. char\r
-\r
- mov dx,SC_INDEX ; Prepare for VGA out's\r
-\r
-@@MainLoop:\r
-\r
- lodsb ; load character byte into AL\r
- or al,al\r
- jz @@NoCharPixels ; Dont bother if no pixels to draw\r
-\r
- or bx,bx ; if BX=0 -> User font, so no need to mirror data\r
- jz @@DontMirror\r
- push ds\r
- mov dx,@data ; Set DS to the Mirror lookup table's segment\r
- mov ds,dx ; - BX should already contain the offset addr of table\r
- xlatb ; AL is now replaced by the corresponding table entry\r
- pop ds ; Restore previous data segment\r
- mov dx,SC_INDEX ; Restore DX\r
-\r
-@@DontMirror:\r
- xor ah,ah ; shift the byte for the dest plane and save it\r
- shl ax,cl\r
- mov [Hold],ax\r
-\r
- mov ah,al ; output high nibble of first byte of shifted char\r
- and ah,0fh ; 4 pixels at a time !\r
- jnz @@p1 ; if nibble has pixels, draw them\r
- inc di ; otherwise go to next nibble\r
- jmp @@SecondNibble\r
-\r
-@@p1:\r
- mov al,MAP_MASK\r
- out dx,ax\r
- mov al,byte ptr [Color]\r
- stosb\r
-\r
-@@SecondNibble:\r
- ; output low nibble of first byte of shifted char\r
- mov ax,[Hold]\r
- shl ax,4\r
- and ah,0fh\r
- jnz @@p2\r
- inc di\r
- jmp @@ThirdNibble\r
-\r
-@@p2:\r
- mov al,MAP_MASK\r
- out dx,ax\r
- mov al,byte ptr [Color]\r
- stosb\r
-\r
-@@ThirdNibble:\r
- mov ax,[Hold] ; output high nibble of last byte of shifted char\r
- and ah,0fh\r
- jnz @@p3\r
- inc di\r
- jmp short @@NextCharRow\r
-\r
-@@p3:\r
- mov al,MAP_MASK ; completing the drawing of one character row\r
- out dx,ax\r
- mov al,byte ptr [Color]\r
- stosb\r
-\r
-@@NextCharRow:\r
- add di,[ScreenInc] ; Now move to the next screen row and do the same\r
- dec ch ; any remaining character bytes\r
- jnz @@MainLoop\r
-\r
-@@done:\r
- pop es\r
- mov ah,0\r
- mov al,es:[_CharWidth] ; return the character width (for string fuctions\r
- or al,al\r
- jnz @@FixedSpacing ; using this character drawing function).\r
- lodsb\r
-@@FixedSpacing:\r
-\r
- mov bx,es\r
- mov ds,bx\r
-\r
- pop di\r
- pop si\r
- mov sp,bp\r
- pop bp\r
- ret\r
-\r
-@@NoCharPixels:\r
- add di,3\r
- add di,[ScreenInc] ; Now move to the next screen row and do the same\r
- dec ch ; any remaining character bytes\r
- jnz @@MainLoop\r
- jmp short @@done\r
-\r
-_x_char_put endp\r
-\r
-\r
-end\r
-\r
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XTEXT - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;-----------------------------------------------------------------------*/\r
-\r
-#ifndef _XTEXT_H_\r
-#define _XTEXT_H_\r
-\r
-\r
-#define FONT_8x8 0\r
-#define FONT_8x15 1\r
-#define FONT_USER 2\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-WORD x_text_init(void); /* Initialize text functionns */\r
-\r
-void x_set_font(\r
- WORD FontId); /* Set the font style */\r
-\r
-void x_register_userfont( /* register a user defined font */\r
- char far *UserFontPtr);\r
-\r
-unsigned int x_char_put( /* Draw a text character using */\r
- char ch, /* the currently active font */\r
- WORD X,\r
- WORD Y,\r
- WORD PgOffs,\r
- WORD Color);\r
-\r
-\r
-unsigned int x_get_char_width( /* Get the character width */\r
- char ch);\r
-\r
-\r
-/* the folowing function is from xprintf.c but is included due to its */\r
-/* close relationship with this module */\r
-\r
-void x_printf( /* formatted text output */\r
- WORD x,\r
- WORD y,\r
- WORD ScrnOffs,\r
- WORD color,\r
- char *ln,...);\r
-\r
-void x_bgprintf( /* formatted text output */\r
- WORD x,\r
- WORD y,\r
- WORD ScrnOffs,\r
- WORD fgcolor,\r
- WORD bgcolor,\r
- char *ln,...);\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-\r
-/* VARIABLES =========================================================== */\r
-\r
-extern BYTE CharHeight; /* Char height of currently active font */\r
-extern BYTE CharWidth; /* Char width of currently active font */\r
-extern BYTE FirstChar; /* First char in the curr. active font */\r
-\r
-extern BYTE UserCharHeight; /* Char height of currentle regist'd user font */\r
-extern BYTE UserCharWidth; /* Char height of currentle regist'd user font */\r
-extern BYTE UserFirstChar; /* First char of the curr. regist'd usera font */\r
-\r
-\r
-#endif\r
-\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XPOINT - Include file\r
-;\r
-; XPOINT.ASM export functions\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
- global _x_text_init :proc\r
- global _x_set_font :proc\r
- global _x_char_put :proc\r
- global _x_register_userfont :proc\r
- global _x_get_char_width :proc\r
-\r
- global _CharHeight :byte\r
- global _CharWidth :byte\r
- global _FontPtr :word:2\r
- global _FirstChar :byte\r
- global _UserFontPtr :word:2\r
- global _UserChHeight :byte\r
- global _UserChWidth :byte\r
- global _UserFirstCh :byte\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-; MODULE XVBITMAP\r
-;\r
-; Video Bitmap functions - Video Ram <-> Video Ram\r
-;\r
-; Compile with Tasm.\r
-; C callable.\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-COMMENT $\r
-\r
-The XVBITMAP module implements yet another type of bitmap to complement\r
-planar and compiled bitmaps, VRAM based bitmaps. If a 4 cylinder car is\r
-analagous to planar bitmaps, that is thrifty on memory consumption but low\r
-performance and and a V8 is analagous to Compiled bitmaps, memory guzzlers\r
-that really fly, then VRAM based bitmaps are the 6 cylinder modest performers\r
-with acceptable memory consumption.\r
-\r
-To summarise their selling points, VBM's are moderately fast with fair memory\r
-consumption, and unlike compiled bitmaps, can be clipped. The disadvantages\r
-are that they are limited by the amount of free video ram and have a complex\r
-structure.\r
-\r
-The VRAM bitmap format is rather complex consisting of components stored in\r
-video ram and components in system ram working together. This complexity\r
-necessitates the existence of a creation function "x_make_vbm" which takes\r
-an input linear bitmap and generates the equivalent VBM (VRAM Bit Map).\r
-\r
-VBM structure:\r
-\r
- WORD 0 Size Total size of this VBM structure in bytes\r
- WORD 1 ImageWidth Width in bytes of the image (for all alignments)\r
- WORD 2 ImageHeight Height in scan lines of the image\r
-\r
- WORD 3 Alignment 0 ImagePtr Offset in VidRAM of this aligned image\r
- +--WORD 4 MaskPtr Offset (within this structure's DS) of\r
- | . alignment masks\r
- | .\r
- | .\r
- | WORD 9 Alignment 3 ImagePtr Offset in VidRAM of this aligned image\r
- +|--WORD 10 MaskPtr Offset (within this structure's DS) of\r
- || alignment masks\r
- ||\r
- |+->BYTE 21 (WORD 11) -------+-- Image masks for alignment 0\r
- | . |\r
- | . |\r
- | BYTE 21 + ImageWidth*ImageHeight -----+\r
- |\r
- | .\r
- | . (similaly for alignments 1 - 2 )\r
- | .\r
- |\r
- +-->BYTE 21 + 3*ImageWidth*ImageHeight + 1-+-- Image masks for alignment 3\r
- . |\r
- . |\r
- BYTE 21 + 4*(ImageWidth*ImageHeight) --+\r
-\r
- .\r
- .\r
- << Similarly for alignments 2 and 3 >>\r
- .\r
- .\r
- BYTE 21 + 4*(ImageWidth*ImageHeight)\r
- -------------\r
-\r
- (And dont forget the corresponding data in video ram)\r
-\r
-$\r
-\r
-\r
-include xlib.inc\r
-include xvbitmap.inc\r
-\r
-VBM_info_struc struc\r
- Size dw ?\r
- ImageWidth dw ?\r
- ImageHeight dw ?\r
-; AlignData dw ?\r
-VBM_info_struc ends\r
-\r
-AlignData equ 6\r
-\r
-VBM_alignment_struc struc\r
- ImagePtr dw ?\r
- MaskPtr dw ?\r
-VBM_alignment_struc ends\r
-\r
-\r
- .code\r
-\r
-\r
-;----------------------------------------------------------------------\r
-; x_store_vbm_image\r
-;\r
-; Store the linear bitmap in video RAM using the specified alignment and\r
-; start address. Returns number video ram bytes used.\r
-;\r
-; THIS FUNCTION IS FOR USE BY x_make_masked_vbm\r
-;\r
-; Prototype:\r
-;\r
-; x_store_vbm_image(unsigned int vramoffs, unsigned int Align,\r
-; char far *lbm);\r
-;\r
-;\r
-; Written by Themie Gouthas\r
-;----------------------------------------------------------------------\r
-_x_store_vbm_image proc\r
- ARG VramOffs:word,Align:word,LBitmap:dword\r
- LOCAL BMWidth:byte=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
-\r
- mov ax,SCREEN_SEG ; Point ES to screen segment\r
- mov es,ax\r
- mov di,[VramOffs] ; Point ES:DI to VRAM dest start\r
- mov bx,[Align] ; Set BL to first pixel plane align\r
- and bl,03h\r
-\r
- lds si,[LBitmap] ; DS:SI -> source linear Bitmap\r
- lodsw ; Al = B.M. width (bytes) AH = B.M.\r
- mov bh,ah ; Save source bitmap dimensions\r
- mov [BMWidth],al ;\r
-\r
- mov dx,SC_INDEX ; Initialize Map Mask for plane\r
- mov al,MAP_MASK ; selection\r
- out dx,al\r
- inc dx\r
- xor ch,ch ; clear CH\r
-@@RowLoop:\r
- mov cl,bl ; Set initial plane for current\r
- mov ah,11h ; allignment\r
- shl ah,cl\r
-\r
- mov cl,[BMWidth] ; Initialize column counter\r
-@@ColLoop:\r
- mov al,ah\r
- out dx,al ; set vga write plane\r
- lodsb ; load next LBM pixel\r
- mov es:[di],al ; store it in Video Ram\r
- shl ah,1 ; rotate plane mask\r
- jnb @@NoAddrIncr ; Time to increment dest address ?\r
- inc di ; Yes: increment addr and reset\r
- mov ah,11h ; plane mask to plane 0\r
-@@NoAddrIncr:\r
- loop @@ColLoop ; Loop to next pixel column\r
- cmp ah,11h\r
-; je @@skip\r
- inc di ; Increment dest addr\r
-;@@skip:\r
- dec bh ; Decrement row counter\r
- jnz @@RowLoop ; Jump if more rows to go\r
- mov ax,di ; calculate video RAM consumed and\r
- sub ax,[VramOffs] ; return value\r
-\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_store_vbm_image endp\r
-\r
-\r
-_x_put_masked_vbm proc\r
- ARG X:word,Y:word,ScrnOffs:word,SrcVBM:dword\r
- LOCAL VBMWidth:word,VBMHeight:word,NextLineIncr:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
-\r
- mov ax,SCREEN_SEG ; Point es to VGA segment\r
- mov es,ax\r
- mov ax,[Y] ; Calculate dest screen row\r
- mov cx,[_ScrnLogicalByteWidth] ; by mult. dest Y coord by Screen\r
- mul cx ; width then adding screen offset\r
-\r
- mov di,[ScrnOffs] ; store result in DI\r
- add di,ax\r
- mov si,[X] ; Load X coord into CX and make a\r
- mov bx,si ; copy in DX\r
- shr bx,2 ; Find starting byte in dest row\r
- add di,bx ; add to DI giving screen offset of\r
- ; first pixel's byte\r
-\r
- and si,3 ; get pixel alignment in si\r
-\r
- lds bx,[SrcVBM] ; DS:BX -> VBM data structure\r
- shl si,2 ; si = offset of data for curr\r
- ; alignment\r
-\r
- mov ax,word ptr [bx+ImageHeight] ; Get image height\r
- mov [VBMHeight],ax\r
- mov ax,word ptr [bx+ImageWidth] ; Get image width\r
- mov [VBMWidth],ax\r
-\r
- sub cx,ax ; NextLineIncr = bytes to the begin.\r
- mov [NextLineIncr],cx ; of bitmaps next row on screen\r
- mov dx,[bx+MaskPtr+AlignData+si] ; DS:SI -> mask data\r
- mov bx,[bx+ImagePtr+AlignData+si] ; ES:BX -> source video bitmap\r
- mov si,dx\r
-\r
- mov dx,GC_INDEX ; Set bit mask for all bits from\r
- mov ax,BIT_MASK ; VGA latches and none from CPU\r
- out dx,ax\r
-\r
- mov dx,SC_INDEX ; Point SC register to map mask\r
- mov al,MAP_MASK ; in preperation for masking data\r
- out dx,al\r
- inc dx ; Point dx to SC data register\r
- mov ah,byte ptr [VBMHeight] ; AH = Scanline loop counter\r
-\r
-@@RowLoop:\r
- mov cx,[VBMWidth] ; Width in bytes across\r
-\r
-@@ColumnLoop:\r
- lodsb\r
- out dx,al\r
- mov al,es:[bx] ; load latches from source bitmap\r
- stosb ; store latches to dest. bitmap\r
- inc bx\r
- loop @@ColumnLoop\r
-\r
- add di,[NextLineIncr] ; point to start of next dest row\r
- dec ah ; decrement scan line counter\r
- jnz @@RowLoop ; jump if more scanlines left\r
-\r
- mov dx,GC_INDEX+1 ; Restore bitmask to the default -\r
- mov al,0ffh ; all data from cpu\r
- out dx,al\r
-\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_put_masked_vbm endp\r
-\r
-\r
-_x_put_masked_vbm_clipx proc\r
-ARG X:word,Y:word,ScrnOffs:word,SrcVBM:dword\r
-LOCAL DataInc,LeftSkip,VBMWidth,VBMHeight,NextLineIncr:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
-\r
- mov di,[X] ; load X coord int DI and make a\r
- mov si,di ; copy in SI\r
- sar di,2 ; Find Byte offset of X coord\r
-\r
- and si,3 ; Calculate pixels plane alignment\r
- shl si,2 ; Prepare to lookup mask & data\r
- les bx,[SrcVBM] ; ES:BX -> begining of VBM data\r
-\r
- mov cx,es:[bx+ImageWidth] ; Get image width and save in CX\r
-\r
-\r
-\r
- ;;;;; CLIP PROCESSING FOR LEFT CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
- mov dx,[_LeftClip]\r
- sub dx,di\r
- jle @@NotLeftClip\r
- cmp dx,cx\r
- jnl @@NotVisible\r
- add di,dx\r
- mov [LeftSkip],dx\r
- mov [DataInc],dx\r
- sub cx,dx\r
- jmp short @@HorizClipDone\r
-\r
- ;;;; EXIT FOR COMPLETELY OBSCURED V.B.M's ;;;;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotVisible:\r
- mov ax,1\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-\r
- ;;;;; CLIP PROCESSING FOR RIGHT CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotLeftClip:\r
- mov dx,[_RightClip]\r
- sub dx,di\r
- js @@NotVisible\r
- mov [LeftSkip],0\r
- mov [DataInc],0\r
- cmp dx,cx\r
- jge @@HorizClipDone\r
- inc dx\r
- sub cx,dx\r
- mov [DataInc],cx\r
- mov cx,dx\r
-\r
-@@HorizClipDone:\r
-\r
-\r
- add di,[ScrnOffs] ; Add the current page offset\r
- mov [VBMWidth],cx\r
- mov ax,es:[bx+ImageHeight] ; Get image height and save in AX\r
- mov [VBMHeight],ax\r
-\r
-\r
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-\r
- mov ax,[Y] ; Calculate dest screen row\r
- mov cx,[_ScrnLogicalByteWidth] ; by mult. dest Y coord by Screen\r
- mul cx ; width then adding screen offset\r
- add di,ax ; Add Dest Screen Row to di\r
- sub cx,[VBMWidth]\r
- mov [NextLineIncr],cx\r
-\r
- mov ax,es ; copy ES to DS\r
- mov ds,ax\r
- mov ax,SCREEN_SEG ; Point es to VGA segment\r
- mov es,ax\r
-\r
- mov ax,[bx+MaskPtr+AlignData+si] ; DS:SI -> mask data\r
- mov bx,[bx+ImagePtr+AlignData+si] ; ES:BX -> source video bitmap\r
- mov si,ax\r
-\r
- mov ax,[LeftSkip] ; Skip data/mask bytes in\r
- add bx,ax ; each row that have been clipped\r
- add si,ax ; by the L.H.S border\r
-\r
-\r
- mov dx,GC_INDEX ; Set bit mask for all bits from\r
- mov ax,BIT_MASK ; VGA latches and none from CPU\r
- out dx,ax\r
- mov dx,SC_INDEX ; Point SC register to map mask\r
- mov al,MAP_MASK ; in preperation for masking data\r
- out dx,al\r
- inc dx ; Point dx to SC data register\r
- mov ah,byte ptr [VBMHeight] ; AH = Scanline loop counter\r
-\r
-@@RowLoop:\r
- mov cx,[VBMWidth] ; Width in bytes across\r
-\r
-@@ColumnLoop:\r
- lodsb\r
- out dx,al\r
- mov al,es:[bx] ; load latches from source bitmap\r
- stosb ; store latches to dest. bitmap\r
- inc bx\r
- loop @@ColumnLoop\r
- add bx,[DataInc]\r
- add si,[DataInc]\r
- add di,[NextLineIncr] ; point to start of next dest row\r
- dec byte ptr ah ; decrement scan line counter\r
- jnz @@RowLoop ; jump if more scanlines left\r
-\r
- mov dx,GC_INDEX+1 ; Restore bitmask to the default -\r
- mov al,0ffh ; all data from cpu\r
- out dx,al\r
- xor ax,ax\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_put_masked_vbm_clipx endp\r
-\r
-\r
-_x_put_masked_vbm_clipy proc\r
-ARG X:word,Y:word,ScrnOffs:word,SrcVBM:dword\r
-LOCAL VBMWidth,VBMHeight,TopRow,NextLineIncr:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
-\r
- mov di,[X] ; load X coord int DI and make a\r
- mov si,di ; copy in SI\r
-\r
-\r
- and si,3 ; Calculate pixels plane alignment\r
- shl si,2 ; Prepare to lookup mask & data\r
- les bx,[SrcVBM] ; ES:BX -> begining of VBM data\r
-\r
-\r
- mov ax,es:[bx+ImageHeight] ; Get image height and save in AX\r
-\r
-\r
-\r
- ;;;;; CLIP PROCESSING FOR TOP CLIP BORDER ;;;;;;;;;;;;;;;;;;;;;\r
-\r
- mov dx,[_TopClip] ; Compare u.l. Y coord with Top\r
- sub dx,[Y] ; clipping border\r
- jle @@NotTopClip ; jump if VBM not clipped from above\r
- cmp dx,ax\r
- jnl @@NotVisible ; jump if VBM is completely obscured\r
- mov [TopRow],dx\r
- sub ax,dx\r
- add [Y],dx\r
- jmp short @@VertClipDone\r
-\r
- ;;;; EXIT FOR COMPLETELY OBSCURED V.B.M's ;;;;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotVisible:\r
- mov ax,1\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-\r
- ;;;;; CLIP PROCESSING FOR BOTTOM CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotTopClip:\r
- mov dx,[_BottomClip]\r
- sub dx,[Y]\r
- js @@NotVisible\r
- mov [TopRow],0\r
- cmp dx,ax\r
- jg @@VertClipDone\r
- inc dx\r
- mov ax,dx\r
-\r
-@@VertClipDone:\r
-\r
-\r
- shr di,2 ; Find Byte offset of X coord\r
- add di,[ScrnOffs] ; Add the current page offset\r
- mov cx,es:[bx+ImageWidth] ; Get image width and save in CX\r
- mov [VBMWidth],cx\r
- mov [VBMHeight],ax\r
-\r
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-\r
- mov ax,[Y] ; Calculate dest screen row\r
- mov cx,[_ScrnLogicalByteWidth] ; by mult. dest Y coord by Screen\r
- mul cx ; width then adding screen offset\r
- add di,ax ; Add Dest Screen Row to di\r
- sub cx,[VBMWidth]\r
- mov [NextLineIncr],cx\r
-\r
- mov ax,es ; copy ES to DS\r
- mov ds,ax\r
- mov ax,SCREEN_SEG ; Point es to VGA segment\r
- mov es,ax\r
-\r
- mov ax,[bx+MaskPtr+AlignData+si] ; DS:SI -> mask data\r
- mov bx,[bx+ImagePtr+AlignData+si] ; ES:BX -> source video bitmap\r
- mov si,ax\r
-\r
-\r
-\r
- mov ax,[VBMWidth] ; Increment DS:BX and DS:SI to\r
- mul [TopRow] ; skip image/mask data that has\r
- add bx,ax ; been clipped by the top border\r
- add si,ax\r
-\r
-\r
- mov dx,GC_INDEX ; Set bit mask for all bits from\r
- mov ax,BIT_MASK ; VGA latches and none from CPU\r
- out dx,ax\r
- mov dx,SC_INDEX ; Point SC register to map mask\r
- mov al,MAP_MASK ; in preperation for masking data\r
- out dx,al\r
- inc dx ; Point dx to SC data register\r
- mov ah,byte ptr [VBMHeight] ; AH = Scanline loop counter\r
-\r
-@@RowLoop:\r
- mov cx,[VBMWidth] ; Width in bytes across\r
-\r
-@@ColumnLoop:\r
- lodsb\r
- out dx,al\r
- mov al,es:[bx] ; load latches from source bitmap\r
- stosb ; store latches to dest. bitmap\r
- inc bx\r
- loop @@ColumnLoop\r
- add di,[NextLineIncr] ; point to start of next dest row\r
- dec byte ptr ah ; decrement scan line counter\r
- jnz @@RowLoop ; jump if more scanlines left\r
-\r
- mov dx,GC_INDEX+1 ; Restore bitmask to the default -\r
- mov al,0ffh ; all data from cpu\r
- out dx,al\r
-\r
- xor ax,ax\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_put_masked_vbm_clipy endp\r
-\r
-_x_put_masked_vbm_clipxy proc\r
-ARG X:word,Y:word,ScrnOffs:word,SrcVBM:dword\r
-LOCAL DataInc,LeftSkip,VBMWidth,VBMHeight,TopRow,NextLineIncr:word=LocalStk\r
- push bp\r
- mov bp,sp\r
- sub sp,LocalStk ; Create space for local variables\r
- push si\r
- push di\r
- push ds\r
- cld\r
-\r
- mov di,[X] ; load X coord int DI and make a\r
- mov si,di ; copy in SI\r
- sar di,2 ; Find Byte offset of X coord\r
- and si,3 ; Calculate pixels plane alignment\r
- shl si,2 ; Prepare to lookup mask & data\r
- les bx,[SrcVBM] ; ES:BX -> begining of VBM data\r
-\r
- mov cx,es:[bx+ImageWidth] ; Get image width and save in CX\r
- mov ax,es:[bx+ImageHeight] ; Get image height and save in AX\r
-\r
-\r
-\r
- ;;;;; CLIP PROCESSING FOR TOP CLIP BORDER ;;;;;;;;;;;;;;;;;;;;;\r
-\r
- mov dx,[_TopClip] ; Compare u.l. Y coord with Top\r
- sub dx,[Y] ; clipping border\r
- jle @@NotTopClip ; jump if VBM not clipped from above\r
- cmp dx,ax\r
- jnl @@NotVisible ; jump if VBM is completely obscured\r
- mov [TopRow],dx\r
- sub ax,dx\r
- add [Y],dx\r
- jmp short @@VertClipDone\r
-\r
- ;;;; EXIT FOR COMPLETELY OBSCURED V.B.M's ;;;;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotVisible:\r
- mov ax,1\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-\r
- ;;;;; CLIP PROCESSING FOR BOTTOM CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotTopClip:\r
- mov dx,[_BottomClip]\r
- sub dx,[Y]\r
- js @@NotVisible\r
- mov [TopRow],0\r
- cmp dx,ax\r
- jg @@VertClipDone\r
- inc dx\r
- mov ax,dx\r
-\r
-@@VertClipDone:\r
-\r
- ;;;;; CLIP PROCESSING FOR LEFT CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
-\r
- mov dx,[_LeftClip]\r
- sub dx,di\r
- jle @@NotLeftClip\r
- cmp dx,cx\r
- jnl @@NotVisible\r
- add di,dx\r
- mov [LeftSkip],dx\r
- mov [DataInc],dx\r
- sub cx,dx\r
- jmp short @@HorizClipDone\r
-\r
- ;;;;; CLIP PROCESSING FOR RIGHT CLIP BORDER ;;;;;;;;;;;;;;;;;;;\r
-\r
-@@NotLeftClip:\r
- mov dx,[_RightClip]\r
- sub dx,di\r
- js @@NotVisible\r
- mov [LeftSkip],0\r
- mov [DataInc],0\r
- cmp dx,cx\r
- jge @@HorizClipDone\r
- inc dx\r
- sub cx,dx\r
- mov [DataInc],cx\r
- mov cx,dx\r
-\r
-@@HorizClipDone:\r
-\r
- add di,[ScrnOffs] ; Add the current page offset\r
- mov [VBMWidth],cx\r
- mov [VBMHeight],ax\r
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-\r
- mov ax,[Y] ; Calculate dest screen row\r
- mov cx,[_ScrnLogicalByteWidth] ; by mult. dest Y coord by Screen\r
- mul cx ; width then adding screen offset\r
- add di,ax ; Add Dest Screen Row to di\r
- sub cx,[VBMWidth]\r
- mov [NextLineIncr],cx\r
-\r
- mov ax,es ; copy ES to DS\r
- mov ds,ax\r
- mov ax,SCREEN_SEG ; Point es to VGA segment\r
- mov es,ax\r
-\r
- mov ax,[bx+MaskPtr+AlignData+si] ; DS:SI -> mask data\r
- mov bx,[bx+ImagePtr+AlignData+si] ; ES:BX -> source video bitmap\r
- mov si,ax\r
-\r
-\r
-\r
- mov ax,[VBMWidth] ; Increment DS:BX and DS:SI to\r
- add ax,[DataInc] ; skip image/mask data that has\r
- mul [TopRow] ; been clipped by the top border\r
- add ax,[LeftSkip] ; Skip also data/mask bytes in\r
- add bx,ax ; each row that have been clipped\r
- add si,ax ; by the L.H.S border\r
-\r
-\r
- mov dx,GC_INDEX ; Set bit mask for all bits from\r
- mov ax,BIT_MASK ; VGA latches and none from CPU\r
- out dx,ax\r
- mov dx,SC_INDEX ; Point SC register to map mask\r
- mov al,MAP_MASK ; in preperation for masking data\r
- out dx,al\r
- inc dx ; Point dx to SC data register\r
- mov ah,byte ptr [VBMHeight] ; AH = Scanline loop counter\r
-\r
-@@RowLoop:\r
- mov cx,[VBMWidth] ; Width in bytes across\r
-\r
-@@ColumnLoop:\r
- lodsb\r
- out dx,al\r
- mov al,es:[bx] ; load latches from source bitmap\r
- stosb ; store latches to dest. bitmap\r
- inc bx\r
- loop @@ColumnLoop\r
- add bx,[DataInc]\r
- add si,[DataInc]\r
- add di,[NextLineIncr] ; point to start of next dest row\r
- dec byte ptr ah ; decrement scan line counter\r
- jnz @@RowLoop ; jump if more scanlines left\r
-\r
- mov dx,GC_INDEX+1 ; Restore bitmask to the default -\r
- mov al,0ffh ; all data from cpu\r
- out dx,al\r
- xor ax,ax\r
- pop ds ; restore data segment\r
- pop di ; restore registers\r
- pop si\r
- mov sp,bp ; dealloc local variables\r
- pop bp\r
- ret\r
-_x_put_masked_vbm_clipxy endp\r
-\r
-\r
- end\r
-\r
-\1a
\ No newline at end of file
+++ /dev/null
-/*-----------------------------------------------------------------------\r
-;\r
-; XVBITMAP - header file\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;\r
-; Terminology & notes:\r
-; VRAM == Video RAM\r
-; SRAM == System RAM\r
-; X coordinates are in pixels unless explicitly stated\r
-;\r
-;-----------------------------------------------------------------------*/\r
-\r
-#ifndef _XVBITMAP_H_\r
-#define _XVBITMAP_H_\r
-\r
-\r
-/* FUNCTIONS =========================================================== */\r
-\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-\r
-\r
-void x_put_masked_vbm( /* Copy a planar bitmap from SRAM masking */\r
- int X, /* only non zero pixels to VRAM */\r
- int Y,\r
- WORD ScrnOffs,\r
- BYTE far * VBitmap);\r
-\r
-int x_put_masked_vbm_clipx(/* Copy a planar bitmap from SRAM masking */\r
- int X, /* only non zero pixels to VRAM. Clip X */\r
- int Y,\r
- WORD ScrnOffs,\r
- BYTE far * VBitmap);\r
-\r
-int x_put_masked_vbm_clipy(/* Copy a planar bitmap from SRAM masking */\r
- int X, /* only non zero pixels to VRAM. Clip Y */\r
- int Y,\r
- WORD ScrnOffs,\r
- BYTE far * VBitmap);\r
-\r
-int x_put_masked_vbm_clipxy(/* Copy a planar bitmap from SRAM masking */\r
- int X, /* only non zero pixels to VRAM. Clip X & Y */\r
- int Y,\r
- WORD ScrnOffs,\r
- BYTE far * VBitmap);\r
-\r
-char far * x_make_vbm(\r
- char far *lbm,\r
- WORD *VramStart);\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-\r
-#endif\r
-\r
-\r
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XVBITMAP - Include file\r
-;\r
-; XVBITMAP.ASM export functions\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
- global _x_store_vbm_image :proc\r
- global _x_put_masked_vbm :proc\r
- global _x_put_masked_vbm_clipx :proc\r
- global _x_put_masked_vbm_clipy :proc\r
- global _x_put_masked_vbm_clipxy :proc\r
-\1a
\ No newline at end of file
+++ /dev/null
-;-----------------------------------------------------------------------\r
-;\r
-; XVBMTOOL - Include file\r
-;\r
-; XVBMTOOL.ASM export functions\r
-;\r
-;\r
-;\r
-; ****** XLIB - Mode X graphics library ****************\r
-; ****** ****************\r
-; ****** Written By Themie Gouthas ****************\r
-; ****** Aeronautical Research Laboratory ****************\r
-; ****** Defence Science and Technology Organisation ****************\r
-; ****** Australia ****************\r
-;\r
-; egg@dstos3.dsto.gov.au\r
-; teg@bart.dsto.gov.au\r
-;-----------------------------------------------------------------------\r
-\r
-\r
- global _x_store_vbm_image :proc\r
-\1a
\ No newline at end of file
+++ /dev/null
-; MODULE XVSYNC\r
-; Xlib comptible vsync handler\r
-; Written by Tore Bastiansen\r
-; based on REND386 by Dave Stampe and Bernie Roehl\r
-\r
-include xlib.inc\r
-include xmain.inc\r
-include xvsync.inc\r
-\r
-\r
-TIMER_VECT equ 08h\r
-\r
-PIC_CMD equ 20h\r
-NONSPEC_EOI equ 20h\r
-TIMER_MODE equ 34h\r
-TIMER_CONTROL equ 43h\r
-TIMER_0 equ 40h\r
-\r
-LATCH_COUNT equ 00h\r
-\r
-INT_IN_ADVANCE equ 100\r
-\r
-DOS_GETVECT equ 3500h\r
-DOS_SETVECT equ 2500h\r
-\r
-\r
-.data\r
-_TicksPerSecond dw 0\r
-_VsyncIntTicks label dword\r
-VsyncIntTicksLo dw 0\r
-VsyncIntTicksHi dw 0\r
-_VsyncPeriod dw 0 ;Time (in clicks) between each vsync\r
- ;1 click = 1.193 microseconds\r
-\r
-ClockRate dw 0 ;Clock rate (in clicks) for timer 0\r
-ClockCounter dw 0 ;Counts total clicks modulo 65536\r
-UserVsyncHandler label dword ;Pointer to user routine called\r
-UserVsyncOffs dw 0 ;called once each vsync period.\r
-UserVsyncSeg dw 0\r
-InUserHandler dw 0\r
- db 100h dup(?)\r
-LocalStack label byte ;Local stack for user handler\r
-StackSeg dw 0\r
-StackPtr dw 0\r
-\r
-\r
-ElapsedVrts dw 0\r
-VrtsToSkip dw 1\r
-\r
-.code\r
-get_vsync_period proc near\r
- mov al,TIMER_MODE ;Start timer\r
- out TIMER_CONTROL,al\r
- mov al,0\r
- out TIMER_0,al\r
- out TIMER_0,al\r
-\r
- WaitVsyncStart\r
-\r
- mov al,LATCH_COUNT\r
- out TIMER_CONTROL,al\r
- in al,TIMER_0\r
- mov cl,al\r
- in al,TIMER_0\r
- mov ch,al ;cx=65536-clicks\r
-\r
- WaitVsyncStart\r
-\r
- mov al,LATCH_COUNT\r
- out TIMER_CONTROL,al\r
- in al,TIMER_0\r
- mov dl,al\r
- in al,TIMER_0\r
- mov dh,al ;dx=65536-clicks\r
-\r
- sub cx,dx ;cx=clicks between two vsyncs\r
- mov ax,cx ;return in ax\r
- ret\r
-get_vsync_period endp\r
-\r
-vsync_int proc far\r
- pusha ;Save regs\r
- push ds\r
- push es\r
-\r
- mov ax,@data ;Set the right datasegment\r
- mov ds,ax\r
- add [VsyncIntTicksLo],1 ;Increment _VsyncIntTicks\r
- adc [VsyncIntTicksHi],0\r
-\r
- inc [ElapsedVrts]\r
- mov cx,[ElapsedVrts]\r
- cmp cx,[VrtsToSkip]\r
- jl @@StopClock\r
-\r
- cmp [_StartAddressFlag],1 ;Change in start address\r
- jne @@StopClock\r
-\r
- mov dx,CRTC_INDEX ;Yes, set start address\r
- mov ax,[_WaitingStartLow]\r
- mov bx,[_WaitingStartHigh]\r
- out dx,ax\r
- mov ax,bx\r
- out dx,ax\r
-\r
-@@StopClock:\r
- cli\r
- mov al,TIMER_MODE ;Stop the timer\r
- out TIMER_CONTROL,al ;Dont want any interrupts\r
- mov al,255\r
- out TIMER_0,al\r
- out TIMER_0,al\r
- sti\r
-\r
- cli\r
- mov dx,INPUT_STATUS_0 ;Wait for vsync\r
-@@WaitVS:\r
- in al,dx\r
- test al,08h\r
- jz @@WaitVS\r
-\r
- mov al,TIMER_MODE ;Start timer again\r
- out TIMER_CONTROL,al\r
- mov ax,[ClockRate]\r
- out TIMER_0,al\r
- mov al,ah\r
- out TIMER_0,al\r
-\r
- cmp cx,[VrtsToSkip]\r
- jl @@PaletteInt\r
-\r
- cmp [_StartAddressFlag],1 ;Any change in start address ?\r
- jne @@PaletteInt\r
-\r
- xor cx,cx\r
- mov [ElapsedVrts],cx\r
-\r
- mov ax,[_WaitingPelPan] ;Yes, set pel pan register\r
- mov dx,AC_INDEX\r
- out dx,al\r
- mov al,ah\r
- out dx,al\r
- mov [_StartAddressFlag],0\r
-\r
-@@PaletteInt:\r
- cmp [_VsyncPaletteCount],0 ;Any changes in the palette\r
- je @@MouseInt\r
- mov si, offset _VsyncPaletteBuffer ;Yes\r
- mov cx, [_VsyncPaletteCount]\r
- mov ax, [_VsyncPaletteStart]\r
- mov dx, DAC_WRITE_INDEX\r
- out dx, al\r
- mov dx, DAC_DATA\r
-\r
-@@DacOutLoop:\r
- outsb\r
- outsb\r
- outsb\r
- loop @@DacOutLoop\r
- mov [_VsyncPaletteCount],0\r
-\r
-@@MouseInt:\r
- cmp [_MouseRefreshFlag],1 ; Does the mouse need refresh\r
- jne @@UserInt\r
- call dword ptr [_MouseVsyncHandler] ; Yes\r
- ;(this is not yet implemented)\r
-\r
-@@UserInt:\r
- cmp [UserVsyncSeg], 0 ;Is the a user interrupt routine?\r
- je short @@Sim182\r
- cmp [InUserHandler],0 ;Yes, but is it already active?\r
- jne short @@Sim182\r
- mov [InUserHandler],1 ;No, mark it as active\r
- mov [StackSeg],ss ;make a local stack\r
- mov [StackPtr],sp\r
- push ds\r
- pop ss\r
- mov sp, offset LocalStack\r
- sti\r
- call dword ptr [UserVsyncHandler]\r
- cli\r
- mov sp, [StackPtr] ;Restore old stack\r
- mov ss, [StackSeg]\r
- mov [InUserHandler],0 ;Mark as not active\r
-\r
-; SIM 18.2 Hz\r
-@@Sim182:\r
- mov ax,[_VsyncPeriod] ;Count number of clicks\r
- add [ClockCounter],ax ;If it is bigger than 65536\r
- jnc short @@DontChainOld\r
- pop es ;more than 1/18.2 secs has gone\r
- pop ds\r
- popa\r
- sti\r
- db 0eah ; jmp instruction\r
- OldTimerInt dd 0 ; Pointer to old int8 routine\r
- ; Selfmodyfiing code\r
- ;jmp dword ptr [OldTimerInt] Chain to old\r
-@@DontChainOld:\r
-\r
-; CLEAN UP AND RETURN\r
- mov al,NONSPEC_EOI\r
- out PIC_CMD,al\r
-\r
-\r
- pop es\r
- pop ds\r
- popa\r
- sti\r
- iret\r
-vsync_int endp\r
-\r
-\r
-_x_install_vsync_handler proc\r
-ARG VrtSkipCount:word\r
- push bp\r
- mov bp,sp\r
- mov ax,[VrtSkipCount]\r
- or ax,ax\r
- jnz @@NonZeroCount\r
- mov ax,1\r
-@@NonZeroCount:\r
- mov [VrtsToSkip],ax\r
- mov [ElapsedVrts],0\r
- cmp [_VsyncHandlerActive],TRUE ;Is it already active\r
- je short @@Return\r
- call get_vsync_period ;no, get the vsync period\r
-\r
- mov [_VsyncPeriod],ax\r
- sub ax,INT_IN_ADVANCE ;We need a little extra\r
- mov [ClockRate],ax ;time\r
-\r
- mov dx,18 ;dx:ax=1193000\r
- mov ax,13352\r
- idiv [_VsyncPeriod]\r
- mov [_TicksPerSecond],ax ;1193/_VsyncPeriod\r
-\r
- mov word ptr [_VsyncIntTicks],0\r
- mov word ptr [_VsyncIntTicks+2],0\r
-\r
- cli\r
- mov ax, DOS_GETVECT+TIMER_VECT ;Get address of old timer int\r
- int 21h\r
- mov ax,es\r
- mov word ptr cs:[OldTimerInt],bx ;Store in OldTimerInt\r
- mov word ptr cs:[OldTimerInt+2],ax\r
-\r
- mov [_VsyncHandlerActive],TRUE ;Mark handler as active\r
- mov ax,DOS_SETVECT+TIMER_VECT ;Set the new timer int\r
- push ds\r
- mov dx,seg vsync_int\r
- mov ds,dx\r
- mov dx,offset vsync_int\r
- int 21h\r
- pop ds\r
-\r
- mov al,TIMER_MODE ;Reprogram timer 0\r
- out TIMER_CONTROL,al\r
- mov ax,ClockRate\r
- out TIMER_0,al\r
- mov al,ah\r
- out TIMER_0,al\r
- sti\r
-@@Return:\r
- pop bp\r
- ret\r
-_x_install_vsync_handler endp\r
-\r
-_x_remove_vsync_handler proc\r
- cmp [_VsyncHandlerActive],FALSE\r
- je short @@Return\r
- mov dx, word ptr cs:[OldTimerInt]\r
- mov ax, word ptr cs:[OldTimerInt+2]\r
- push ds\r
- mov ds,ax\r
- mov ax,DOS_SETVECT+TIMER_VECT ;Restore the old timer int\r
- cli\r
- int 21h\r
- pop ds\r
- mov al,TIMER_MODE ;Restore timer 0\r
- out TIMER_CONTROL,al\r
- mov al,0\r
- out TIMER_0,al\r
- out TIMER_0,al\r
- sti\r
-@@Return:\r
- ret\r
-_x_remove_vsync_handler endp\r
-\r
-\r
-; WARNING: The user vsync handler cannot use the 386 specific registers\r
-; (EAX,EBX,ECX,EDX,ESI,EDI,ESP,EBP,FS,GS)\r
-; whithout saving them first.\r
-; It must not do any drawing.\r
-; Only 256 butes of stack is provided.\r
-\r
-_x_set_user_vsync_handler proc\r
-ARG handler_proc:dword\r
- push bp\r
- mov bp,sp\r
- mov ax, word ptr [handler_proc]\r
- mov dx, word ptr [handler_proc+2]\r
- cli\r
- mov word ptr [UserVsyncHandler],ax\r
- mov word ptr [UserVsyncHandler+2],dx\r
- sti\r
- pop bp\r
- ret\r
-_x_set_user_vsync_handler endp\r
-\r
-end\r
+++ /dev/null
-#ifndef _XVSYNC_H_\r
-#define _XVSYNC_H_\r
-\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
- void x_install_vsync_handler(int skipcount);\r
- void x_remove_vsync_handler(void);\r
- void x_set_user_vsync_handler(void far (*)());\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-\r
-extern WORD TicksPerSecond;\r
-extern volatile long VsyncIntTicks;\r
-extern WORD VsyncPeriod;\r
-\r
-#endif\r
+++ /dev/null
-global _x_install_vsync_handler :proc\r
-global _x_remove_vsync_handler :proc\r
-global _x_set_user_vsync_handler :proc\r
-global _TicksPerSecond :word\r
-global _VsyncIntTicks :dword\r
-global _VsyncPeriod :word\r
+++ /dev/null
-pkzip -a xlib06.zip MAKEFILE\r
-\r
-pkzip -a xlib06.zip XBEZIER.ASM\r
-pkzip -a xlib06.zip XBMTOOLS.ASM\r
-pkzip -a xlib06.zip XCBITMAP.ASM\r
-pkzip -a xlib06.zip XCOMPPBM.ASM\r
-pkzip -a xlib06.zip XDETECT.ASM\r
-pkzip -a xlib06.zip XFILEIO.ASM\r
-pkzip -a xlib06.zip XLINE.ASM\r
-pkzip -a xlib06.zip XMAIN.ASM\r
-pkzip -a xlib06.zip XMOUSE.ASM\r
-pkzip -a xlib06.zip XPAL.ASM\r
-pkzip -a xlib06.zip XPBITMAP.ASM\r
-pkzip -a xlib06.zip XPBMCLIP.ASM\r
-pkzip -a xlib06.zip XPOINT.ASM\r
-pkzip -a xlib06.zip XRECT.ASM\r
-pkzip -a xlib06.zip XRLETOOL.ASM\r
-pkzip -a xlib06.zip XTEXT.ASM\r
-pkzip -a xlib06.zip XVBITMAP.ASM\r
-pkzip -a xlib06.zip XCIRCLE.ASM\r
-pkzip -a xlib06.zip XCLIPPBM.ASM\r
-pkzip -a xlib06.zip XPOLYGON.ASM\r
-pkzip -a xlib06.zip XFILL.ASM\r
-pkzip -a xlib06.zip XVSYNC.ASM\r
-\r
-pkzip -a xlib06.zip XCBITM32.C\r
-pkzip -a xlib06.zip DEMO1.C\r
-pkzip -a xlib06.zip DEMO2.C\r
-pkzip -a xlib06.zip DEMO3.C\r
-pkzip -a xlib06.zip DEMO4.C\r
-pkzip -a xlib06.zip DEMO5.C\r
-pkzip -a xlib06.zip DEMO6.C\r
-pkzip -a xlib06.zip DEMO7.C\r
-pkzip -a xlib06.zip DEMO8.C\r
-pkzip -a xlib06.zip DEMO9.C\r
-pkzip -a xlib06.zip DEMO10.CPP\r
-\r
-pkzip -a xlib06.zip XMAKEVBM.C\r
-pkzip -a xlib06.zip XPRINTF.C\r
-pkzip -a xlib06.zip UPDATES.DOC\r
-pkzip -a xlib06.zip XLIBREF1.DOC\r
-pkzip -a xlib06.zip XLIBREF2.DOC\r
-pkzip -a xlib06.zip DEMO7.EXE\r
-pkzip -a xlib06.zip DEMO1.EXE\r
-pkzip -a xlib06.zip DEMO2.EXE\r
-pkzip -a xlib06.zip DEMO3.EXE\r
-pkzip -a xlib06.zip DEMO4.EXE\r
-pkzip -a xlib06.zip DEMO5.EXE\r
-pkzip -a xlib06.zip DEMO6.EXE\r
-pkzip -a xlib06.zip DEMO8.EXE\r
-pkzip -a xlib06.zip DEMO9.EXE\r
-pkzip -a xlib06.zip DEMO10.EXE\r
-\r
-pkzip -a xlib06.zip FIXED6X8.FNT\r
-pkzip -a xlib06.zip VAR6X8.FNT\r
-pkzip -a xlib06.zip VARSWISL.FNT\r
-pkzip -a xlib06.zip VARSWISB.FNT\r
-pkzip -a xlib06.zip TIMPANI.FNT\r
-pkzip -a xlib06.zip MODERNB.FNT\r
-pkzip -a xlib06.zip CRISP6X9.FNT\r
-pkzip -a xlib06.zip TINY4.FNT\r
-pkzip -a xlib06.zip SMALTHIN.FNT\r
-\r
-pkzip -a xlib06.zip XBEZIER.H\r
-pkzip -a xlib06.zip XBMTOOLS.H\r
-pkzip -a xlib06.zip XCBITMAP.H\r
-pkzip -a xlib06.zip XCOMPPBM.H\r
-pkzip -a xlib06.zip XDETECT.H\r
-pkzip -a xlib06.zip XFILEIO.H\r
-pkzip -a xlib06.zip XLIB.H\r
-pkzip -a xlib06.zip XLIB_ALL.H\r
-pkzip -a xlib06.zip XLINE.H\r
-pkzip -a xlib06.zip XMOUSE.H\r
-pkzip -a xlib06.zip XPAL.H\r
-pkzip -a xlib06.zip XPBITMAP.H\r
-pkzip -a xlib06.zip XPBMCLIP.H\r
-pkzip -a xlib06.zip XPOINT.H\r
-pkzip -a xlib06.zip XRECT.H\r
-pkzip -a xlib06.zip XRLETOOL.H\r
-pkzip -a xlib06.zip XTEXT.H\r
-pkzip -a xlib06.zip XVBITMAP.H\r
-pkzip -a xlib06.zip XCIRCLE.H\r
-pkzip -a xlib06.zip XCLIPPBM.H\r
-pkzip -a xlib06.zip XPOLYGON.H\r
-pkzip -a xlib06.zip XFILL.H\r
-pkzip -a xlib06.zip XVSYNC.H\r
-pkzip -a xlib06.zip XCBITM32.H\r
-\r
-pkzip -a xlib06.zip MODEL.INC\r
-pkzip -a xlib06.zip XBEZIER.INC\r
-pkzip -a xlib06.zip XBMTOOLS.INC\r
-pkzip -a xlib06.zip XCBITMAP.INC\r
-pkzip -a xlib06.zip XCOMPPBM.INC\r
-pkzip -a xlib06.zip XDETECT.INC\r
-pkzip -a xlib06.zip XFILEIO.INC\r
-pkzip -a xlib06.zip XLIB.INC\r
-pkzip -a xlib06.zip XLINE.INC\r
-pkzip -a xlib06.zip XMAIN.INC\r
-pkzip -a xlib06.zip XPAL.INC\r
-pkzip -a xlib06.zip XPBITMAP.INC\r
-pkzip -a xlib06.zip XPBMCLIP.INC\r
-pkzip -a xlib06.zip XPOINT.INC\r
-pkzip -a xlib06.zip XRECT.INC\r
-pkzip -a xlib06.zip XRLETOOL.INC\r
-pkzip -a xlib06.zip XTEXT.INC\r
-pkzip -a xlib06.zip XVBITMAP.INC\r
-pkzip -a xlib06.zip XVBMTOOL.INC\r
-pkzip -a xlib06.zip XCIRCLE.INC\r
-pkzip -a xlib06.zip XCLIPPBM.INC\r
-pkzip -a xlib06.zip XPOLYGON.INC\r
-pkzip -a xlib06.zip XFILL.INC\r
-pkzip -a xlib06.zip XVSYNC.INC\r
-\r
-pkzip -a xlib06.zip XLIB04S.LIB\r
-pkzip -a xlib06.zip XLIB04C.LIB\r
-pkzip -a xlib06.zip XLIB04L.LIB\r
-pkzip -a xlib06.zip ZIP.BAT\r
-\r