Advertisement
Guest User

CP/M-86 Aztec C 3.2d VGA TEST lines.c

a guest
Sep 30th, 2021
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.19 KB | None | 0 0
  1. /**************************************************************************
  2.  * lines.c                                                                *
  3.  * written by David Brackeen                                              *
  4.  * http://www.brackeen.com/home/vga/                                      *
  5.  *                                                                        *
  6.  * This is a 16-bit program.                                              *
  7.  * Tab stops are set to 2.                                                *
  8.  * Remember to compile in the SMALL memory model!                         *
  9.  * To compile in CP/M-86 Aztec C 3.2d                                     *
  10.  *      cc line.c                                                         *
  11.  *      ln line.o m.lib c.lib                                             *
  12.  *                                                                        *
  13.  * This program will only work on CP/M86 systems with a                   *
  14.  * VGA, SuperVGA or compatible video adapter.                             *
  15.  *                                                                        *
  16.  * Please feel free to copy this source code.                             *
  17.  *                                                                        *
  18.  * DESCRIPTION: This program demostrates drawing how much faster it is to *
  19.  * draw lines without using multiplication or division.                   *
  20.  **************************************************************************/
  21.  
  22. #include <stdio.h>
  23. /*
  24. #include <stdlib.h>
  25. #include <dos.h>
  26. */
  27. #include <regs.h>
  28. #include <math.h>
  29.  
  30. #define VIDEO_INT           0x10      /* the BIOS video interrupt. */
  31. #define SET_MODE            0x00      /* BIOS func to set the video mode. */
  32. #define VGA_256_COLOR_MODE  0x13      /* use to set 256-color mode. */
  33. #define TEXT_MODE           0x03      /* use to set 80x25 text mode. */
  34.  
  35. #define SCREEN_WIDTH        320       /* width in pixels of mode 0x13 */
  36. #define SCREEN_HEIGHT       200       /* height in pixels of mode 0x13 */
  37. #define NUM_COLORS          256       /* number of colors in mode 0x13 */
  38.  
  39. #define sgn(x) ((x<0)?-1:((x>0)?1:0)) /* macro to return the sign of a
  40.                                          number */
  41.  
  42. typedef unsigned char  byte;
  43. typedef unsigned short word;
  44.  
  45. /* byte *VGA=(byte *)0xA0000000L; */       /* this points to video memory. */
  46. word VGA_SEG = 0xa000;
  47.  
  48. /* word *my_clock=(word *)0x0000046C;  */    /* this points to the 18.2hz system
  49.                                          clock. */
  50. word my_clk_seg = 0x0000;
  51. word my_clk_ofst = 0x046c;
  52.  
  53. word peekw();
  54.  
  55. #define abs(x) ((x>=0)?x:(-(x)))
  56.  
  57. int rand(){
  58.     int a;
  59.     a = (int)(ran() * 32767.0);
  60.     if (a < 0) a = -a;
  61.     return a;
  62. }
  63.  
  64. /**************************************************************************
  65.  *  set_mode                                                              *
  66.  *     Sets the video mode.                                               *
  67.  **************************************************************************/
  68.  
  69. void set_mode(mode)
  70. byte mode;
  71. {
  72.   union REGS regs;
  73.  
  74.   regs.h.ah = SET_MODE;
  75.   regs.h.al = mode;
  76.   int86(VIDEO_INT, &regs, &regs);
  77. }
  78.  
  79. /**************************************************************************
  80.  *  plot_pixel                                                            *
  81.  *    Plot a pixel by directly writing to video memory, with no           *
  82.  *    multiplication.                                                     *
  83.  **************************************************************************/
  84.  
  85. void plot_pixel(x, y, color)
  86. int x;
  87. int y;
  88. byte color;
  89. {
  90.   /*  y*320 = y*256 + y*64 = y*2^8 + y*2^6   */
  91. /*  VGA[(y<<8)+(y<<6)+x]=color; */
  92.   pokeb((y<<8)+(y<<6)+x, VGA_SEG, color);
  93. }
  94.  
  95. /**************************************************************************
  96.  *  line_slow                                                             *
  97.  *    draws a line using multiplication and division.                     *
  98.  **************************************************************************/
  99.  
  100. void line_slow(x1, y1, x2, y2, color)
  101. int x1;
  102. int y1;
  103. int x2;
  104. int y2;
  105. byte color;
  106. {
  107.   int dx,dy,sdx,sdy,px,py,dxabs,dyabs,i;
  108.   float slope;
  109.  
  110.   dx=x2-x1;      /* the horizontal distance of the line */
  111.   dy=y2-y1;      /* the vertical distance of the line */
  112.   dxabs=abs(dx);
  113.   dyabs=abs(dy);
  114.   sdx=sgn(dx);
  115.   sdy=sgn(dy);
  116.   if (dxabs>=dyabs) /* the line is more horizontal than vertical */
  117.   {
  118.     slope=(float)dy / (float)dx;
  119.     for(i=0;i!=dx;i+=sdx)
  120.     {
  121.       px=i+x1;
  122.       py=slope*i+y1;
  123.       plot_pixel(px,py,color);
  124.     }
  125.   }
  126.   else /* the line is more vertical than horizontal */
  127.   {
  128.     slope=(float)dx / (float)dy;
  129.     for(i=0;i!=dy;i+=sdy)
  130.     {
  131.       px=slope*i+x1;
  132.       py=i+y1;
  133.       plot_pixel(px,py,color);
  134.     }
  135.   }
  136. }
  137.  
  138. /**************************************************************************
  139.  *  line_fast                                                             *
  140.  *    draws a line using Bresenham's line-drawing algorithm, which uses   *
  141.  *    no multiplication or division.                                      *
  142.  **************************************************************************/
  143.  
  144. void line_fast(x1, y1, x2, y2, color)
  145. int x1;
  146. int y1;
  147. int x2;
  148. int y2;
  149. byte color;
  150. {
  151.   int i,dx,dy,sdx,sdy,dxabs,dyabs,x,y,px,py;
  152.  
  153.   dx=x2-x1;      /* the horizontal distance of the line */
  154.   dy=y2-y1;      /* the vertical distance of the line */
  155.   dxabs=abs(dx);
  156.   dyabs=abs(dy);
  157.   sdx=sgn(dx);
  158.   sdy=sgn(dy);
  159.   x=dyabs>>1;
  160.   y=dxabs>>1;
  161.   px=x1;
  162.   py=y1;
  163.  
  164. /*  VGA[(py<<8)+(py<<6)+px]=color; */
  165.   pokeb((py<<8)+(py<<6)+px, VGA_SEG, color);
  166.  
  167.   if (dxabs>=dyabs) /* the line is more horizontal than vertical */
  168.   {
  169.     for(i=0;i<dxabs;i++)
  170.     {
  171.       y+=dyabs;
  172.       if (y>=dxabs)
  173.       {
  174.         y-=dxabs;
  175.         py+=sdy;
  176.       }
  177.       px+=sdx;
  178.       plot_pixel(px,py,color);
  179.     }
  180.   }
  181.   else /* the line is more vertical than horizontal */
  182.   {
  183.     for(i=0;i<dyabs;i++)
  184.     {
  185.       x+=dxabs;
  186.       if (x>=dyabs)
  187.       {
  188.         x-=dyabs;
  189.         px+=sdx;
  190.       }
  191.       py+=sdy;
  192.       plot_pixel(px,py,color);
  193.     }
  194.   }
  195. }
  196.  
  197. /**************************************************************************
  198.  *  Main                                                                  *
  199.  *    Draws 5000 lines                                                    *
  200.  **************************************************************************/
  201.  
  202. main()
  203. {
  204.   int x1,y1,x2,y2,color;
  205.   float t1,t2;
  206.   word i,start;
  207.  
  208. /*  srand(*my_clock); */                   /* seed the number generator. */
  209.   set_mode(VGA_256_COLOR_MODE);       /* set the video mode. */
  210.  
  211. /*  start=*my_clock; */                    /* record the starting time. */
  212.   start = peekw(my_clk_ofst, my_clk_seg);
  213.  
  214.   for(i=0;i<5000;i++)                 /* randomly draw 5000 lines. */
  215.   {
  216.     x1=rand()%SCREEN_WIDTH;
  217.     y1=rand()%SCREEN_HEIGHT;
  218.     x2=rand()%SCREEN_WIDTH;
  219.     y2=rand()%SCREEN_HEIGHT;
  220.     color=rand()%NUM_COLORS;
  221.     line_slow(x1,y1,x2,y2,color);
  222.   }
  223.  
  224. /*  t1=(*my_clock-start)/18.2; */          /* calculate how long it took. */
  225.   t1 = (peekw(my_clk_ofst, my_clk_seg) - start)/18.2;
  226.  
  227.   set_mode(VGA_256_COLOR_MODE);       /* set the video mode again in order
  228.                                          to clear the screen. */
  229.  
  230. /*  start=*my_clock; */                    /* record the starting time. */
  231.   start = peekw(my_clk_ofst, my_clk_seg);
  232.  
  233.   for(i=0;i<5000;i++)                 /* randomly draw 5000 lines. */
  234.   {
  235.     x1=rand()%SCREEN_WIDTH;
  236.     y1=rand()%SCREEN_HEIGHT;
  237.     x2=rand()%SCREEN_WIDTH;
  238.     y2=rand()%SCREEN_HEIGHT;
  239.     color=rand()%NUM_COLORS;
  240.     line_fast(x1,y1,x2,y2,color);
  241.   }
  242.  
  243. /*  t2=(*my_clock-start)/18.2; */         /* calculate how long it took. */
  244.   t2 = (peekw(my_clk_ofst, my_clk_seg) - start)/18.2;
  245.  
  246.   set_mode(TEXT_MODE);                /* set the video mode back to
  247.                                          text mode. */
  248.  
  249.   /* output the results... */
  250.   printf("\n");
  251.   printf("Slow line drawing took %f seconds.\n",t1);
  252.   printf("Fast line drawing took %f seconds.\n",t2);
  253.   if (t2 != 0) printf("Fast line drawing was %f times faster.\n",t1/t2);
  254.  
  255.   return 0;
  256. }
  257.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement