home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol140 / speedup.c < prev    next >
Encoding:
C/C++ Source or Header  |  1984-04-29  |  5.8 KB  |  272 lines

  1. /*
  2.  * SPEEDUP    O B J E C T  C O D E  'O P T I M I S E R'
  3.  *        
  4.  *        (c) Chris Undery 1983
  5.  *        11 Margaret st Newtown 2042
  6.  *        Sydney Australia.
  7.  
  8.  Desription:-
  9.  
  10.  This program was written to 'optimise' bds c object code to take 
  11. advantage of the undocumented instructions of the Intel 8085 mpu.
  12.  
  13. see cpu.asm for macros to enable assembly of these instructions.
  14.     
  15.     hl <- (de)    
  16.     hl -> (de)    
  17.     16 bit shifts
  18.         16 bit subtraction
  19.     stack + offset references
  20.     conditional branch with dcx inx using the x5 flag
  21.     restart on overflow
  22.  
  23. These instructions 'live' in all Intel 8085 mpus. They were
  24. not published when the mpu was first realeased for some weird
  25. marketing reason. Taken in perspective they really shed new 
  26. light on the Z80 8085 comparison stakes.
  27.  
  28. The file supplied .. CPU.ASM should be assembled using MAC
  29. or M80 and loaded to binary format (use link, load or ddt/sid).
  30. This program should be invoked as:-
  31.  
  32.     speedup infile_name outfile_name cpu.com
  33.  
  34. The result of this is that BDS C programs will run faster. Programs
  35. which make use of much pointer work and string comparisons will be
  36. most effected by this tom foolery. There are many more code sequences
  37. generated by the bds compiler which could be worked over..see who
  38. can get the fastest sieve benchmark going!
  39.  
  40. Heavily disk io bound software will not see much improvement by the
  41. use of speedup, but other software will. Dont expect too much for 
  42. nothing. I have not doctored the 16 bit rotates in c.ccc, they are
  43. good candidates for optimising using the 16 bit rotate instructions
  44. play around and have fun.
  45.  
  46. */
  47.  
  48.  
  49. #include bdscio.h
  50.  
  51. #define BUFSECS 20000 / 128    /* # of sectors which fit in buf*/
  52.  
  53. #define NO    0        /* booleans            */
  54. #define YES    1
  55.  
  56. #define TEXT    char
  57. #define UCOUNT    unsigned
  58. #define COUNT    int
  59. #define BYTE    char
  60.  
  61. /* leading byte on rules file holds cpu type */
  62. #define I8080    0
  63. #define I8085    1
  64. #define Z80    2
  65. #define I8886    3
  66. #define ASCII    4
  67.  
  68. /* Global Data Storage    */
  69. TEXT    object[20000],        /* object code buffer        */
  70.     rules[256][64],        /* transformation table        */
  71.     rulebuf[BUFSIZ],    /* file buffer for rules    */
  72.     cpu,            /* cpu descriptor        */
  73.     rule;            /* current rule being checked    */
  74.  
  75. UCOUNT    infile,            /* input file descriptor    */
  76.     outfile,        /* output file descriptor    */
  77.     size,            /* no of sects read from input    */
  78.     bytes,            /* bytes transferred        */
  79.     num_rules,        /* max number of sequences    */
  80.     modified;        /* total bytes modified        */
  81.  
  82.  
  83. main(argc,argv)
  84. TEXT **argv;
  85. {
  86.  
  87.     num_rules = modified =  size = NULL;
  88.     if (argc < 4)        
  89.         {
  90.         puts("Usage: SPEEDUP input_file  output_file  mask_file\n");
  91.         exit();
  92.         }
  93.     puts("\nSPEEDUP Object Code 'Optimiser' V 1.0 (C) Chris Undery 1983\n");
  94.  
  95.     if (fopen(argv[3],rulebuf) == ERROR)
  96.         {
  97.         printf("%s not found\n",argv[3]);
  98.         exit();
  99.         }
  100.  
  101.  
  102.     load_rules();            /* load rules table from file */
  103.  
  104.     if ((infile = open(argv[1],0)) == ERROR)
  105.         {
  106.         printf("%s not found\n",argv[1]);
  107.         exit();
  108.         }
  109.  
  110.     if ((outfile = creat(argv[2])) == ERROR)
  111.         {
  112.         printf("Can't create %s\n",argv[2]);
  113.         exit();
  114.         }
  115.  
  116.     size = read(infile,object,BUFSECS);    /* gulp        */
  117.     
  118.     if (size == ERROR)
  119.         {
  120.         printf("Error reading %s\n",argv[1]);
  121.         exit();
  122.         }
  123.  
  124.     printf("Now processing %s [file size = %d]\n",argv[1],size*128);
  125.     optimise();            /* modify the com file    */
  126.  
  127.     if (write(outfile,object,size) != size)
  128.         {
  129.         printf("Error writing %s, check disk space\n",argv[2]);
  130.         exit();
  131.         }
  132.  
  133.     close(infile);
  134.  
  135.     if (close(outfile) == ERROR)
  136.         {
  137.         printf("Error closing %s\n",argv[2]);
  138.         exit();
  139.         }
  140.  
  141.     puts("CPU type = ");
  142.     switch (cpu) 
  143.         {
  144.         case I8080: puts("8080");
  145.                 break;
  146.         case I8085: puts("8085");break;
  147.         case I8886: puts("8088 / 8086");break;
  148.         case Z80:   puts("Z80"); break;
  149.         default:    puts("ASCII TEXT  replacement");
  150.         }
  151.  
  152.     printf(" Bytes altered = %5u\n",modified);
  153.     
  154. }
  155.  
  156.  
  157. /* scan rules table until all transformations completed */
  158. optimise()
  159. {
  160.     COUNT k, j, loop;
  161.     TEXT *msecs,*secs,*mins;
  162.  
  163.     msecs = 0xe837; secs = 0xe838; mins = 0xe839;
  164.     *msecs = *secs = *mins = k = j = NULL;
  165.     while (k < num_rules)
  166.         {
  167.         printf("Pass %02d, Replacements      ",k+1);
  168.         transform(j);
  169.         j += 2;
  170.         k++;
  171.         if (k == num_rules) break;
  172.         puts("\r                         \r");
  173.         }
  174.     puts("\n");
  175.  
  176. /*
  177.     printf("Cpu time <%02d:%02d:%03d>\n",
  178.         *mins,*secs,*msecs);
  179. */
  180.  
  181. }
  182.  
  183. /* scan object code for match in rules table */
  184. transform(k)
  185. COUNT k;
  186. {
  187.     COUNT pos;        /* result of index function */
  188.     TEXT *p;        /* pointer to nex element in object */
  189.     COUNT subs;
  190.         
  191.     subs = pos = NULL;
  192.     p = &object[0];        /* assign to start of object */
  193.     /*
  194.      * rules[k][0]         length of search mask 
  195.      * rules[k][1..31]     search mask
  196.      * rules[k+1][0]     length of replacement data
  197.      * rules[k+1][1..31]     replacement data
  198.     */
  199.  
  200.     while (pos != ERROR )
  201.         {
  202.         pos = match(p,(size * 128) - pos ,&rules[k][1],rules[k][0]);
  203.         if (pos == ERROR) break;
  204.         p += pos;    /* add the offset needed */
  205.         movmem(&rules[k+1][1],p,rules[k+1][0]);
  206.         modified += rules[k+1][0];
  207.         back(5);
  208.         puts("     ");
  209.         back(5);
  210.         printf("%5u",++subs);
  211.         }
  212. }
  213.  
  214. /* find pattern in buffer , match for n characters */
  215. match(s,s_len,t,t_len)
  216. TEXT s[],
  217.      t[];
  218. COUNT s_len,
  219.       t_len;
  220. {
  221.     COUNT i, j, k;
  222.  
  223.     for (i = 0; i < s_len; i++)
  224.         {
  225.         for (j = i, k= 0; s[j] == t[k]; j++, k++)
  226.             ;
  227.         if (k == t_len) return i; /* return valid index */
  228.         }
  229.     return ERROR;    /* no match found in buffer */
  230. }
  231.  
  232. /* load search masks and replacement patterns */
  233. load_rules()
  234. {
  235.     COUNT c, j, k, i;
  236.  
  237.     i = j = NULL;
  238.     if ((c = getc(rulebuf)) != CPMEOF)
  239.         cpu = c;
  240.     else return YES;
  241.     while ((c = getc(rulebuf)) != CPMEOF)
  242.         {
  243.         k = rules[i][0] = c;
  244.         if (!c) return YES;    /* count feild = zero */
  245.         while (k--)
  246.             {     /* load sequence string */
  247.             rules[i][++j] = getc(rulebuf);
  248.             if (j > 63)
  249.                 {
  250.                 printf("Sequence %d too long ",i);
  251.                 puts("or format error\n");
  252.                 exit();
  253.                 }
  254.             }
  255.         i++;
  256.         j = 0;
  257.         num_rules += (i % 2);
  258.         if (num_rules > 128) return YES;
  259.         }
  260. }
  261.  
  262. /* run cursor backwards n spaces */
  263. back(n)
  264. COUNT n;
  265. {
  266.     COUNT j;
  267.  
  268.     for (j = 0 ; j < n; j++) putchar(0x08);
  269. }
  270.  
  271.  
  272.