         Q L   H A C K E R ' S   J O U R N A L
      ===========================================
           Supporting  All  QL  Programmers
      ===========================================
         #3                        April 1991
      
    The QL Hacker's Journal (QHJ) is published by Tim
Swenson as a service to the QL Community.  The QHJ is
freely distributable.  Past issues are available on disk,
via e-mail, or via the Anon-FTP server, garbo.uwasa.fi. 
The QHJ is always on the look out for article submissions.

        QL Hacker's Journal
     c/o Tim Swenson
     5615 Botkins Rd 
     Huber Heights, OH 45424 USA
     (513) 233-2178
     swensontc@mail.serve.com
     http://www.serve.com/swensont/

Table of Contents
         
Editor's Forum .................................... 1
Herb Schaaf's Small C Programs .................... 2
File Comparison ................................... 10
Real Windows for SuperBasic ....................... 15
C Compiler Comparison ............................. 17
         
         
         
         Editor's Forum
              By Timothy Swenson
         
               After putting out  two issues rather  quickly, your all
         probably wondering what happened to this issue.  There is one
         simple explanation: bad keyboard.  My QL feel ill by the most
         common  ailment of older QL systems, a bad connection between
         the keyboard matrix and the motherboard.
         
               My QL went bad in early  February, just after I got the
         last  issue out.  I tried to buy a keyboard replacement. like
         Schon,  but no one had it (plus I heard some negative reviews
         about  the Schon keyboard).   I found that  Paul Holmgren had
         new keyboard  matrixes.  I sent  my check and  waited for the
         matrix to arrive.  After a few weeks, I called Paul back.  It
         seemed that the  the U.S.  Snail mail  had lost  the package.
         Paul had to send another keyboard.  After about 4 weeks, I am
         now back up and running.
         
               An other item that helped with the delay, was my moving
         to another  apartment.  See the  back of the  Journal for the
         new  address.  It's  not very,  since we  stayed in  the same
         apartment complex.   Just after mailing  the last newsletter,
         my wife  informed me that we will  be needed a second bedroom
         in, oh, about 9 months.
         
              When  my QL was down, I was  faced with the idea that my
         QL will not last forever.  I was pondering about what type of
         system  to move to.  I  wanted one that would  last for a few
         years, so my older computers were out.  The idea of moving to
         MS-DOS did not  appeal to me.   I know MS-DOS  well, but it's
         not that interesting.  A Unix system would be nice, but thier
         sort of expensive, plus low on good application software.
         
              I finally came to the conclusion that the Atari ST would
         be  a good system to move to.   Primarily because it has a QL


                                    page 1
         emulator  available for it.  This means  that I could move up
         to newer hardware, but still use QDOS.  I don't know how well
         the  emulator is, but I do know that it is twice as fast as a
         normal  QL.  One of  the members of  CATS has an  ST with QL,
         IBM, and MAC emulators.  I'll have to talk to him about it.
         
              I'm not saying that I will run down and buy an ST in the
         next month or two.  I'm going to stick with my QL for as long
         as  possible.  My  QL has  been pretty  reliable so  far.  No
         chips  have blown, and only one  microdrive has gone bad.  No
         big deal since I have  gone  entirely  to  disks.   The  only
         problem is the  keyboard.  I'm  investigating a  product from
         the  German company ABC, that allows the QL to use a standard
         IBM keyboard.
         
              In the November 1990  issue  of  "Dr.  Dobb's  Journal",
         there is  an article  about Software  Patents written  by the
         Leage for Programming Freedom.  It's the kind of article that
         all  programmer's should read.  I really recommend that every
         one read it.  If you can't  find  that  issue  at  the  local
         library, let me know and I'll send you a copy.
         
               I've been following  the Software Patent  and "look and
         feel"  copyright suits in the  computer press.  After reading
         the above mentioned article, I  can  see  the  importance  of
         these current  suits.  Where  I work,  I deal  with a  lot of
         computer  users that are  not computer people.   Most of them
         complain  that they have to learn a new command set/interface
         with each program.  They would like more programs to work the
         same.  But the software  industry  is  working  against  this
         principle.  With  these patents  and suits,  programmer's are
         forced to  make thier software as  different as possible from
         the others.  If they choose not to, they either have to pay a
         license fee or go to  court.   The  industry  needs  to  stop
         looking at just the  bottom line  and look  at what  the user
         really needs.
         
              Well,  time to get off my  soapbox.  Hope you enjoy this
         issue and  find it usefull.  I encourage  all of your to send
         me a line and tell me how you feel about the Journal.
         
         
         Herb Schaaf's Small C Programs
              By Herb Schaaf
         
         [Editor's  Note - Herb Schaaf has sent me a couple of Small C
         programs via e-mail.  He did not include an article about the
         two  programs, so I am just presenting them as is.  One is an
         update  of my  previous find_c.   Be aware  that Herb  adds a
         number  of bells and whistles in  his programs.  They are not
         short and sweet.]
         
         /*  find1f_c    Feb 23   8:45 am  
         *  from QL Hacker's Journal Feb 1991 page 1-4
         *  trying another approach seems to work ungets()?
         */
         
         #include <stdio_h>
         #define LOOKLEN 21
         #define BUFSIZE LOOKLEN   /*  * see K&R page 79 Ex. 4-7  *
         */
         char buf[BUFSIZE], *s;  
         int fd, b, bufp, len;


                                    page 2
         main()
         
         {
         char c, l, search[LOOKLEN], lookfor[LOOKLEN],
         initok[LOOKLEN], file[42];
         int  file_count, str_len, i, pat_find, fd2, ; 
            /*  abcdefghijklmnopqrstuvwxyz  0123456789 xyxyz test
         string  */ 
            /*  aabbccaaabbbccc a ab abc aababc vividvivid
         more_tests  */
            /*  ABC Abc ABc aBC abC  aaaaaaaaaxYzaxyZaaaaaaaaaaABC
         */
         file_count = pat_find = bufp = 0;   /*  Initialize to Zero
         */
         strset(search,'\0');
         strset(lookfor,'\0');
         strset(initok,'\0');
         strset(file,'\0');
         strset(buf,'\0');
         printf("Enter name of file to be searched : ");
         gets(file);
         printf("%s\n",file);
         printf("Enter string (%d characters or less) to be
         matched\n",LOOKLEN-1);
         printf("      Search will be case insensitive \n");
         gets(search);
         if (strlen(search)>=LOOKLEN)      
            {
            strncpy(initok,search,LOOKLEN-1);
            strncpy(search,initok,LOOKLEN-1);
            strset(initok,'\0');
            }
         fd = fopen(file,"r");
         if (fd == NULL)
            {
            printf("Did not open file\n");
            printf("file in use?          example:  ram3_find1e_c\n");
         
            printf("Any key to exit\n");
            getchar(c);
            exit(1);
            }
         fd2 = fopen("ram3_find1f_log","w+");   
         if (fd2 == NULL)
            {
            printf("Did not open ram3_find1f_log file\n"); 
            printf("Any key to exit\n");
            getchar(c);
            exit(1);
            }
         else
            printf("file :  ram3_find1f_log is open for w+ \n");   
         str_len = strlen(search);
         fputs(search,fd2);
         strncpy(lookfor,search,str_len);
         l = lookfor[0];
         printf("Searching file: %s\n",file);
         fprintf(fd2,"\nSearching file: %s\n",file);
         printf("        looking for %s \n",lookfor);
         fprintf(fd2,"looking for %s \n",lookfor);
         while(( c = getch()) != EOF)
            {
            ++file_count;


                                    page 3
            if((lexorder(c,l)) == 0)
               {
               strset(initok,'\0');
               initok[0] = c;
               for(i=1; i<str_len; i++)
                  {
                  initok[i]=getch();
                  }
               ungets(initok);
               getch();   
               if(lexcmp(lookfor,initok) == 0)
                  {
          pat_find++;
                  printf("%s <==> %s  @ %u  # %u\n",lookfor,initok
         ,file_count,pat_find);
          fprintf(fd2,"%s <==> %s @ %u # %u\n",lookfor,initok
         ,file_count,pat_find);
          }
               }
            }
            printf("\nFound %d patterns that match %s\n",pat_find,
         search);
            fprintf(fd2,"\nFound %d patterns that match %s\n",
         pat_find,search);
            fclose(fd2);
            fclose(fd);
            printf("A log of this session is in ram3_find1f_log\nAny
         key to exit\n");
            getchar();
         }  
         
         /* FUNCTION CALLS - getch, ungetch, ungets, strset */
         
         getch()  /*  * get a pushed back character   *  */
         {
         if(bufp > 0)
         {
         b = buf[--bufp];
         return b;
         }
         else
         {
         b = getc(fd);
         return b;
         }
         }
         
         ungetch(b) /*  * push character back on input *  */
         int b;
         {
         if(bufp >= BUFSIZE)
            {
            printf("ungetch: too many characters\n");
            }
         else
            {
            buf[bufp++] = b;
            }
         }
                     
         ungets(s)
         char *s;
         {


                                    page 4
         len = strlen(s);
         while( (len > 0) )
            ungetch(s[--len]);
         }   
         
         strset(string,chr)   /*  * fill string with a character  *
         */
         char *chr, *string;
         {
         int i, length;
         length = strlen(string);
         for(i=0; i<length; i++)
            {
            *string++ = *chr;
            }
         return *string;
         }
         
         /*  *    test string abAbCaababcaa
           XYz   vivid vivid       aabababcabc
         aaaaaa ababcaaabcaaaabcabbcabcabbabcABC
         */
         
         
         /*    msp1k_c                    Feb 24th 1991 1pm
         *    try  printing this file ? 
         *    driving Citizen MSP-10 printer ( = FX-80 ) from Small-C 
         */
         
         #include <stdio_h>
         char file[42], c;
         int  fd, *msp;
         
         main() {
            printf("Enter name of file to be sent to MSP-10
         printer:\n");
            gets(file);
            fd = fopen(file,"r");
            if(fd == NULL)   {
               printf("Unable to open file: %s\n",file);
               printf("\nAny key to exit\n");
               getchar(c);
               exit(1);
            }
            else   {   
               printf("Ready to send %s to MSP-10\n",file);
            }
            msp = fopen("ser1hc","w");
            printf("fd = %d   msp = %d\n",fd,msp);
            printf("If above looks ok [SPACE BAR] to continue\n  x to
         exit\n");
            c = getchar();
            if(c == 'x') {
               exit(1);
            }
            if (msp != NULL)  {
               stdprint(msp);
               epsfont(msp);
               fputc(27,msp);          /*  sets printer for    */
               fputc(109,msp);         /*     Standard         */   
               fputc(0,msp);           /*       EPSON          */
               fputc(EOF,msp);         /*   Character Set      */
         


                                    page 5
               printfile(fd,msp);   
               fclose(fd);
               leave(msp);
            }      
            printf(" + once more to really exit(1); !!\n");
            getchar(c);
            exit(1);
         }
         
         /* E N D  O F  M A I N  - - - - - - - - - - - - - - */
         
         /*  FUNCTION CALLS : 
         
          stdprint(msp)       standardize printer to default settings 
          epsfont(msp)        set printer for Epson FX styles
          ibmfont(msp)        set printer for ibm styles
          newline(msp)        CR + LF + '\n'
          leave(msp)          close file to printer and leave this
         exercise
          printit(c,msp)      printer does one character at a time
          printfile(fd,msp)   send entire file to printer
          epsstd(c,msp)       printer does entire Epson standard set
          epsgra(c,msp)       printer does entire Epson graphics set
          ibmstd(c,msp)       printer does entire IBM character set
          ibmacc(c,msp)       printer does entire IBM accented
         character set
         
         */
         
         /*  * STDPRINT set printer to power on defaults *  */
         stdprint(msp)
            int msp; {
               printf("@ stdprint : msp = %d\n",msp);
               if (msp != NULL)   {
                  fputc(27,msp);
                  fputc(64,msp);
                  newline(msp);
               }
            }  
         
         /*  * EPSFONT  select Epson FX fonts *  */
         epsfont(msp)
            int msp; {
               printf("@ epsfont : msp = %d\n",msp);
               if (msp != NULL)  {
                  /* fputs("@ epsfont",msp);    */
                  newline(msp);
                  fputc(EOF,msp);
                  fputc(27,msp);
                  fputc(126,msp);
                  fputc(53,msp);
                  fputc(0,msp);
                  fputc(EOF,msp);
               }
            }
         
         /*  * IBMFONT select IBM Graphics fonts *  */
         ibmfont(msp)
            int msp; {
               printf("@ ibmfont : msp = %d\n",msp);
               if (msp != NULL)  {
                  /* fputs("@ ibmfont",msp);    */
                  newline(msp);


                                    page 6
                  fputc(27,msp);
                  fputc(126,msp);
                  fputc(53,msp);
                  fputc(1,msp);
               }
            }
         
         /*  * NEWLINE line feed and carriage return *  */
         newline(msp)
            int msp; {
               /* printf("@ newline : msp = %d\n",msp);     */
               if (msp != NULL)  {
                  fputc(10,msp);
          fputc(13,msp);
          fputc(138,msp);
          fputc(141,msp);
                  printf("\n");
               }
            }
         
         /*  * LEAVE  leave this program *  */
         leave(msp)
            int msp; {
               printf("\n@ leave : msp = %d\n",msp);
               if (msp != NULL)  {
                  printf("\n\nAny key when you're ready to leave\n");
                  getchar();
                  fclose(msp); 
               }
            }
         
         /*  * PRINTIT  print to screen and to printer *  */
         printit(c,msp)
            char c;
            int msp; {
               if (msp != NULL)  {
                  fputc(c,msp);
                  fputc(c,stdout);
               }
            }
         
         /*  * PRINTFILE prints file to stdout & to printer *  */
         printfile(fd,msp)
            int fd, msp;   {
               char c;
               int i;
               while(((msp != NULL) && (( c = getc(fd)) != EOF)))  {
                  fputc(c,msp);
                  fputc(c,stdout);
                  if(iscntrl(c)) {
                     if( c == 10 )  {
                        fputc(10,msp);
                fputc(13,msp);             
                fputc(138,msp);
                fputc(141,msp); 
                     }
                     if( c == 9 )   {
                        fputc(27,msp);
                fputc(102,msp);
                fputc(0,msp);
                        fputc(3,msp);  /* sets printhead 3 spaces
         right  */
             } 


                                    page 7
                  }
               }
            }
         
         /*  *  EPSON  STANDARD  CHARACTER  SET  *  */
         epsstd(c,msp)
            char c;
            int msp; {
               printf("@ epsstd : msp = %d\n",msp);
               if (msp != NULL)  {
                  printf("@ epsstd Doing Standard Epson Character
         Set\n");
                  fputc(EOF,msp);
                  stdprint(msp);
                  epsfont(msp);
                  fputc(27,msp);
                  fputc(109,msp);
                  fputc(0,msp);
                  fputc(EOF,msp);
                  for(c=32; c<=126; c++)  {
                     printit(c,msp);
                  }
                  newline(msp);   
                  for(c=161; c<=254; c++) {
                     printit(c,msp);
                  }
                  newline(msp);   
               }
            }
         
         /*  *  EPSON  GRAPHICS  SET  *  */
         epsgra(c,msp)
            char c;
            int msp; {
               printf("@ epsgra : msp = %d\n",msp);
               if (msp != NULL)  {
                  fputs("@ epsgra",msp);
                  fputc(EOF,msp);
                  printf("Doing Epson Graphics Only Characters\n");
                  stdprint(msp);
                  epsfont(msp);
                  fputc(27,msp);
                  fputc(109,msp);
                  fputc(4,msp);
                  fputc(EOF,msp);
                  for(c=128; c<=159; c++) {
                     printit(c,msp);
                  }
                  newline(msp);   
               }
            }
         
         /*  *  IBM  STANDARD  CHARACTER  SET  *  */
         ibmstd(c,msp)
            char c;
            int msp; {
               printf("@ ibmstd : msp = %d\n",msp);
               if (msp != NULL)  {
                  fputs("@ ibmstd",msp);
                  newline(msp);
                  printf("Doing IBM Standard Character Set\n");
                  stdprint(msp);
                  ibmfont(msp);


                                    page 8
                  fputc(27,msp);
                  fputc(55,msp);
                  fputc(EOF,msp);
                  printit(21,msp);
                  for(c=32; c<=126; c++)  {
                     printit(c,msp);
                  }
                  newline(msp);
                  fputs("IBM Extended",msp);
                  newline(msp);
                  fputc(EOF,msp);
                  for(c=160; c<=254; c++) {
                     printit(c,msp);
                  }
                  newline(msp);   
               }
            }
         
         /*  * IBM  ACCENTED  CHARACTERS  *  */
         ibmacc(c,msp)
            char c;
            int msp; {
               printf("@ ibmacc : msp = %d\n",msp);
               if (msp != NULL)  {
                  fputs("@ ibmacc",msp);
                  newline(msp);
                  printf("Doing IBM Accented Characters Set\n");
                  stdprint(msp);
                  ibmfont(msp);
                  fputc(27,msp);
                  fputc(54,msp);
                  for(c=3; c<=6; c++)  {
                     printit(c,msp);
                  } 
                  for(c=128; c<=159; c++) {
                     printit(c,msp);
                  }
                  newline(msp);   
               }
            }
         
         
         File Comparison
             By Timothy Swenson
         
             Fcomp_c is another C program from the C User's Journal
         disk #236 (Highly Portable Utilites).  I only had to make a
         few minor changes to port it to the QL.  The biggest change
         being uncommenting the #define NO_STRING_H.
         
              I have tried the program out with two short test files.
         Below is the two files and the output from fcomp_c.
         
         File #1:
         This is fcomp_c test file number 1.
         
         Line number 1
         Line number 2
         
         Line number 3
         Line number 4
         Line number 5
         Line number 6


                                    page 9
         
         File #2:
         This is fcomp_c test file number .
         
         Line number 1
         
         Line number 2
         
         Line number 3
         This line is added
         Line number 4
         Line number 6
         
         Output From fcomp_c
         Changed line 1
          This is fcomp_c test file number 1.
         To:
          This is fcomp_c test file number 2.
         Inserted after line 3:
         
         Inserted after line 6:
          This line added
         
         Deleted line 8
          Line number 5
         
         /*
            HEADER:      CUG236;
            TITLE:      Compare Text Files;
            DATE:      05/17/1987;
            DESCRIPTION:   "Best version of DIFF (file comparator)
         from Jan '86
                  issue of Software Practice and Experience.";
            VERSION:   1.1;
            KEYWORDS:   File Comparator, File Compare, File
         Comparison, File
                  Comparison Utility;
            FILENAME:   FCOMP.C;
            SEE-ALSO:   DIFF;
            COMPILERS:   vanilla;
            AUTHORS:   Chuck Allison;
         */
         
         /* fcomp.c:   file comparator that beats DIFF! */
         
         #include <flp1_stdio_h>
         
         /*
          * Portability Note:  8-bit systems often don't have header
         file string.h.
          * If your system doesn't have it, uncomment the following
         #define.
          */
         
         
         #define NO_STRING_H
         
         
         /*
          * Portability Note:  Back in K & R days, standard library
         function malloc()
          * was called alloc().   Some compilers (e.g. Eco-C under
         CP/M) haven't made


                                    page 10
          * the name change.  If yours is one of these compilers,
         uncomment the
          * following #define:
          */
         
         /*
         #define malloc(p)   alloc(p)
         */
         
         /*
          * Portability Note:  The AZTEC C compilers handle the
         binary/text file
          * dichotomy differently from most other compilers.
         Uncomment the following
          * pair of #defines if you are running AZTEC C:
          */
         
         /*
         #define getc(f)      agetc(f)
         #define putc(c,f)   aputc(c,f)
         */
         
         #ifdef   NO_STRING_H
         int strcmp(), strlen();
         #else
         #include <string.h>
         #endif
         
         #define MAXLINES 1000
         #define ORIGIN MAXLINES
         #define INSERT 1
         #define DELETE 2
         
         struct edit {
            struct edit *link;
            int op;
            int line1;
            int line2;
         };
         
         char *A[MAXLINES], *B[MAXLINES];
         
         void exit();
         
         void main(argc,argv)
         int argc;
         char *argv[];
         {
            int    col, d, k, lower, m, max_d, n, row, upper;
            int last_d[2*MAXLINES+1];
            struct edit *new, *script[2*MAXLINES+1];
            char *malloc();
            int atoi(), in_file();
            void exceed(), fatal(), put_scr();
         
            if (argc > 1 && argv[1][0] == '-')
            {
               max_d = atoi(&argv[1][1]);
               ++argv;
               --argc;
            }
            else
               max_d = 2*MAXLINES;


                                    page 11
         
            if(argc != 3)
               fatal("fcomp requires two file names.");
         
            m = in_file(argv[1],A);
            n = in_file(argv[2],B);
         
            for (row=0 ; row<m && row < n && strcmp(A[row],B[row]) ==
         0 ; ++row)
               ;
            last_d[ORIGIN] = row;
            script[ORIGIN] = NULL;
            lower = (row == m) ? ORIGIN + 1 : ORIGIN - 1;
            upper = (row == n) ? ORIGIN - 1 : ORIGIN + 1;
            if (lower > upper)
            {
               puts("The files are identical.");
               exit(0);
            }
         
            for (d = 1 ; d <= max_d ; ++d)
            {
               for ( k = lower ; k <= upper ; k +=2)
               {
             new = (struct edit *) malloc(sizeof(struct edit));
             if (new == NULL)
                exceed(d);
         
             if (k == ORIGIN-d || k != ORIGIN+d && last_d[k+1] >=
         last_d[k-1])
             {
                row = last_d[k+1]+1;
                new->link = script[k+1];
                new->op = DELETE;
             }
             else
             {
                row = last_d[k-1];
                new->link = script[k-1];
                new->op = INSERT;
             }
             new->line1 = row;
             new->line2 = col = row + k - ORIGIN;
             script[k] = new;
         
             while(row < m && col < n && strcmp(A[row],B[col]) == 0)
             {
                ++row;
                ++col;
             }
             last_d[k] = row;
         
             if (row == m && col == n)
             {
                put_scr(script[k]);
                exit(!0);
             }
             if (row == m)
                lower = k+2;
         
             if (col == n)
                upper = k-2;
               }


                                    page 12
               --lower;
               ++upper;
            }
            exceed(d);
         }
         
         int in_file(filename,P)
         char *filename, *P[];
         {
            char buf[100], *malloc(), *save, *b;
            FILE *fp;
            int lines = 0;
            void fatal();
         
            if ((fp = fopen(filename,"r")) == NULL)
            {
               fprintf(stderr, "Cannot open file %s.\n",filename);
               exit(!0);
            }
         
            while(fgets(buf,100,fp) != NULL)
            {
               if (lines >= MAXLINES)
             fatal("File is too large for diff.");
               if ((save = malloc(strlen(buf)+1)) == NULL)
             fatal("Not enough room to save the files.");
               P[lines++] = save;
               for (b = buf ; *save++ = *b++ ; )
             ;
            }
            fclose(fp);
            return(lines);
         }
         
         void put_scr(start)
         struct edit *start;
         {
            struct edit *ep, *behind, *ahead, *a, *b;
            int change;
         
            ahead = start;
            ep = NULL;
            while (ahead != NULL)
            {
               behind = ep;
               ep = ahead;
               ahead = ahead->link;
               ep->link = behind;
            }
         
            while( ep != NULL)
            {
               b = ep;
               if (ep->op == INSERT)
             printf("Inserted after line %d:\n",ep->line1);
               else
               {
             do
             {
                a = b;
                b = b->link;
             } while (b!=NULL && b->op == DELETE && b->line1 ==
         a->line1+1);


                                    page 13
         
             change = (b!=NULL && b->op == INSERT && b->line1 ==
         a->line1);
             if (change)
                printf("\nChanged ");
             else
                printf("\nDeleted ");
             if (a == ep)
                printf("line %d\n",ep->line1);
             else
                printf("lines %d-%d:\n",ep->line1,a->line1);
         
             do
             {
                printf(" %s",A[ep->line1-1]);
                ep = ep->link;
             } while (ep != b);
         
             if (!change)
                continue;
             printf("To:\n");
               }
               do
               {
             printf(" %s",B[ep->line2-1]);
             ep = ep->link;
               } while (ep != NULL && ep->op == INSERT && ep->line1 ==
         b->line1);
            }
         }
         
         void fatal(msg)
         char *msg;
         {
            fprintf(stderr,"%s\n",msg);
            exit(!0);
         }
         
         void exceed(d)
         int d;
         {
            fprintf(stderr,"The files differ in at least %d lines.
         \n",d);
            exit(!0);
         }
         
         
         Real Windows for SuperBasic
              by Timothy Swenson
         
              The QUANTA library has a number of routines that will
         allow real non-destructive windows in SuperBasic.  Since I
         started working with C, I wanted the same feature written to
         used with both C compilers.
         
              Before going straight into C, I decided to test my
         algorithm in SuperBasic.  SuperBasic is far easier to do
         developmental testing on.  I was not initially going for
         speed, but correctness of my algorithm.  I'm glad I used
         SuperBasic, because my first couple of algorithms were way
         off the mark.  After totally revamping my algorithm, I
         finally got the program to work.
         


                                    page 14
              Below is the SSB code for real windows in SuperBasic.
         It is slow, even when compiled.  I'm presenting it here for
         it's alroithm and not for actual use.  I hope to translate it
         to both Small C and Lattice C, but so far a have a few
         details to work out.  I hope you find it usefull.
         
              Since the program does not keep track of the dimensions
         of each window created, you can use the procedures to move a
         piece of the screen to another part of the screen.  Save the
         part you want to move, then give different coordinates when
         you load it.
         
         
         ** This number may need to be changed as needed
         DIM store(5000)
         
         DEFine PROCedure save_bg (length, height, x, y)
            LOCal   mem, i, j
         
            mem = 1
         
            FOR i = 131072+(y*128) TO 131072+((y+height)*128) STEP 128
               FOR j = i+(x/4) TO i+((x+length)/4) STEP 2
                  store(mem) = PEEK_W(j)
                  mem = mem + 1
               END FOR j
            END FOR i
         END DEFine save_bg
         
         DEFine PROCedure load_bg (length, height, x, y)
            LOCal   mem, i, j
         
            mem = 1
         
            FOR i = 131072+(y*128) TO 131072+((y+height)*128) STEP 128
               FOR j = i+(x/4) TO i+((x+length)/4) STEP 2
                  POKE_W j,store(mem)
                  mem = mem + 1
               END FOR j
            END FOR i
         END DEFine load_bg
         
         Here is an example program using the procedures:
         
         100 save_bg 80, 100, 40, 20
         110 OPEN #3, con_80x100a40x20_32
         120 PAPER #3,0: INK #3,7
         130 CLS #3
         140 PRINT #3,"This is a test"
         150 PRINT #3,"of real windows"
         160 PAUSE 100
         170 CLS #3
         180 PRINT #3,"Hit Return"
         190 PRINT #3,"to make this"
         200 PRINT #3,"go away"
         210 INPUT #3,in$
         220 CLOSE #3
         230 load_bg 80, 100, 40, 20
         
         
         
         
         C Compiler Comparison


                                    page 15
              By Tim Swenson
         
              A while back I was thinking about the two C compilers
         available for the QL.  The Small C compiler is easy to use,
         quick to compile, but limited in it's scope of the C
         language.  The Lattice C compiler is not so easy to use, slow
         to compiler, but supports the full C language.  The question
         is which one to use.  Personally, I prefer the Small C
         compiler.  When ever possible I will use it in my projects.
         
              After comparing how much time each compler takes to
         compile, I decided to find out which one produced faster
         code.  With the Lattice C longer compile time, I expected it
         to spend some of that compile time optimising it's code.
         
              I used two simple benchmark programs.  One for number
         crunching (prime numbers) and the other for recursion
         (fibonacci sequence).  The prime number benchmark comes from
         an the CATS newsletter (Jan. 1990), by Duane Parker.  Herb
         Schaaf wrote the C version for both compilers.  The second
         program is from Dr. Dobb's Journal (see code for issue).
         
              Below is the results of these tests:
         
         Prime Numbers       Small C           Lattice C
             29000-32767      5 sec              3 sec
             1000-32767      32 sec             20 sec
         
         Recursion
                            189 sec            193 sec
         
              After I ran the first benchmark, I expected Lattice C to
         out perform Small C on all benchmarks.  I was surprised to
         see the second results.
         
              It looks like Lattice C is faster for number crunching,
         but for recursive procedure calls, Small C is just a bit
         faster.  The next time you are writting a C program consider
         which compiler might be better suited for your needs.  With
         recursive programs, you won't loose speed with Small C.
         
         /* The Fibonacci benchmark tests
              recursive procedure calls.
         
             From Dr. Dobb's Journal
                  Feb. '89 P. 40
            Small C Version
         */
         
         #include <stdio_h>
         
         #define NUMBER 24
         #define NTIMES 34
         
         main() {
            int i, value, secs, d1[2], d2[2];
         
            *d1 = date();
         
            printf("%d iterations: ", NTIMES);
         
            for (i=1; i <= NTIMES; i++)
               value = fib(NUMBER);


                                    page 16
         
            printf("\n");
            *d2 = date();
            secs = d2[1] - d1[1];
            printf("%d seconds\n",secs);
         }
         
         fib(x)
            int x;
         
            {
            if ( x > 2 )
                  return (fib(x-1) + fib(x-2));
            else
                  return (1);
         }
         
         
         /* The Fibonacci benchmark tests
              recursive procedure calls.
         
             From Dr. Dobb's Journal
                  Feb. '89 P. 40
            Lattice C Version
         */
         
         #include <flp1_stdio_h>
         #include <flp1_qdos_h>
         
         #define NUMBER 24
         #define NTIMES 34
         
         main() {
            int i, value, secs, d1, d2;
         
            d1 = readclock();
         
            printf("%d iterations: ", NTIMES);
         
            for (i=1; i <= NTIMES; i++)
               value = fib(NUMBER);
         
            printf("\n");
            d2 = readclock();
            secs = d2 - d1;
            printf("%d seconds\n",secs);
         }
         
         fib(x)
            int x;
         
            {
            if ( x > 2 )
                  return (fib(x-1) + fib(x-2));
            else
                  return (1);
         }
         
         readclock(time)
            int time;
         {
            struct REGS in, out;
            in.D0 = 19;


                                    page 17
            QDOS1(&in,&out);
            time = out.D1;
            return(time);
         }
         
         



























































                                    page 18
