.lq .bd .dw Editor's Forumn .do .bo For those readers that have Internet access, Timo Salmi of Findland has started an Anon-FTP QL Server, garbo.uwasa.fi (128.214.81.1). Garbo is already an MS-DOS server but Timo has set aside a section for the QL. To start things off, he has uploaded a number of his programs. I have uploaded back issues of the QHJ to the server and plan to upload most of the freeware stuff that I have (if it's not too large to transfer to MS-DOS disk). I am trying to get Dave Walker, the porter of C68, to upload the C68 files to Garbo.uwasa.fi. Odds are that most of the files will be archived somehow, but these archivers will be available on the server (I'll put them there). I have two documents/files that might be of interest to QLer's. The first is the Computer Language List. This is a document maintained by Bill Kinnersley of the University of Kansas, that documents all known computer languages. The first version of the document that I recieved had 1300 languages listed. Where as the most recent version has 1700 languages. A lot of the languages are from the early days of computers and most never got out of the lab. To make the list, the language must have been pulished in some sort of tech journal, report, magazine, book, etc. The other document is the Jargon File. This is a compiled list of computer related jargon words and thier meanings as related to computers. Over the years this document has spawned off two books, the most recent being the "Hacker's Dictionary." The version of the Jargon file that I have is should have about 90% of what the book does. The Jargon File documents the history of the words, including who started them and where they started. I've found it interesting from the view point of computer history, but it also have me a better idea of the "real" definition of a number of computer terms. Both documents are available via the Internet, but for those without Internet access (or Anon-FTP access), I can provide them on disk. One thing that I have been doing the last couple of months, is writing to any magazine that misuses the term Hacker. I'm trying to get the press to stop using the term Hacker when they talk about crackers or computer criminals. Now the general public thinks that Hackers are nothing but a bunch of kids breaking into computer systems, wreaking havoc. Michael McClary posted an article to Usenet that really sums up the whole issue: {begin quote A computer "hacker" is a gifted programmer, capable of substituting skil and persistence for quality software tools. A computer "cracker" is a person who defeats system security measures, for whatever reason. Some crakcing is done for legitimate reasons, such as testing system security or honing programming skills. Much more is done to obtain unauthorized access. A computer "vandal" is a person who uses his computer access, however obtained, to damage other people's data, programs, or computer access. A computer "pirate" is a person who obtains improper financial reward for someone else's data or programs, regardless how they obtained them. Saying "hacker" when you mean "cracker", "vandal", or "pirate" is like saying "cowboy" when you mean "cattle rustler." Just as nearly all cattle rustlers are cowboys but few cowboys are cattle rustlers, nearly all crackers are hackers but few hackers are crackers. end quote} So the next time you see some article in the popular press misusing the term Hacker, write a letter to the editor letting them know that they are not using the term correctly. So far I have had "Defense News" and "CIO" have published my letter to the editor on this very matter. .bd .dw New Public Domain/Freeware QL Software .bo .do By Tim Swenson In the past few months I have recieved some disks containing public domain and Freeware software for the QL. The disks came from Howard Clase of Canada, and Franz Herrmann of Germany. For the record, Freeware software is software that is copyright by the author, but everyone is free to copy and distribute the software. Code from Freeware programs can not be used in any commercial program. With Public Domain software, the author gives up all rights to the program. The Freeware concept is heavily encouraged and used the the FreeSoftware Foundation. Here is a list of the stuff from Franz: Intergroup Freeware Exchange Database - We have recieved this once before, but the executable program that provided easy access to the database would not execute. Now everything is running fine. The IFE is functionally like the Quanta Library, but encompasses a number of QL User Groups, most of them in Europe. QED Text Editor - This editor, written by Jan Bredenbeek, looks like it is based on the Metacomco text editor ED. From looking at the help file for QED, I could see that the command set is almost the same as ED. ZOO, HAR, LHX - These three programs are archiving programs, much like the well known PKZIP suite of programs. Where as PKZIP is used mostly for MS-DOS (but being ported to other platforms) ZOO, HAR, and LHX are used widely on a variety of systems. All three allow you to pack a number of files into a single compressed file. File compression is great for uploading a number of files to a BBS as one file, and for putting more data on disks to be sent via the mail. All three programs come with source code. This is convenient for those that want to study the file compression algorithm or tinker with the program. The group also has a copy of QLUNZIP, a program that will unzip files that have been archived using PKZIP. FLEX and YACC - FLEX and YACC are two utilties that are used in creating compilers and interpreters. FLEX is a Freeware version of the Unix utility LEX. FLEX is used to create the code for a lexical analyser. YACC ( short for Yet Another Compiler Compiler) is used to create the code for a parser. These two tools have been used for years in the Unix environment. Learning either one of these programs on the QL also means that your experience is portable to other systems. PROFF - PROFF is a portable version of the Unix text formatter ROFF. ROFF is the basis of the other Unix text formatters, TROFF and NROFF. MKTYPES - This is a suite of programs used to create function declarations in C programs. This is then used in compiling all modules of your program, allowing type checking across modules. For the die-hard C programmer. OCCC - This is a file that contains the winners of the Obfuscated C Contest from 1985 on to about 1991(?). When unarchived, it's a large number of files. Obfuscated means to make unclear or hard to understand. Althought some may say that C is already obfuscated, there is a contest that takes it to the limit. One category is "the hardest / most obscure way to do a simple item." As you can see from the files from Franz, C is being used a lot to port programs to the QL, plus Unix is one of the primary sources for programs. This comes from three facts: 1. C programs are very portable when written properly. 2. Unix, because of it different dialects, has stressed C portablity. 3. Unix has a wealth of Freeware software (with source code ) ready for porting to a new computer. Most MS-DOS programs do not come with source code. If they do, they are too MS-DOSed to be portable. From Howard Clase comes a number of programs that he has had published in QL World and has made publicly avaiable. Where Franz has focused on C, Howard's programs focus on SuperBasic. These descriptions are short because I have not had the time to evaluate each package. The descriptions are based on quick readings of the _doc files. Here is a list of the packages: FTIDY - File Tidy. A program to copy files and tidy up your file system. DIR_EDIT - Directory Edit. "Allows you to edit the directory of a device." Not too sure what this means. GRAPH - Graph Plot Library for inclusion into your own programs. Loads and is used like Toolkit II or other SuperBasic extensions. FOUNTS - Fonts for the QL for use in your programs. A number of different fonts are included as examples. GLAZIER - A screen/window design package for programmers. Allows the user to draw windows on the screen and Glazier will produce the SuperBasic code for those windows. PROCS - A number of misc. SuperBasic procedures for use in your own programs. MISC - A number of short SuperBasic programs. This is the disk for those of you that are into SuperBasic programming. The utilities included can expand the capabilities of your programs and skills. Both of the two disks are available from the QHJ. .bd .dw Software Engineering and OOPS on the QL? .do .bo By Tim Swenson Through subscriptions at work and home, I read a number of computer magazines, including Dr. Dobb's Journal (DDJ), C Users Journal, Unix Review, Sun World, and Info-World. These magazines discuss programming, programming trends, and programming utilities/software. Two of the leading topics of discussions have been Object Oriented Programming (OOP) and Software Engineering, which includes Computer Aided Softwawre Engineering (CASE). Most of my programming at work is short scripts/programs that are used as short term utilities ( because I am the only one willing to tackle AWK, Perl, and Shell Scripts). But I don't get to do any "serious" programming that would allow me to explore these new areas of computers. Because of this practical lack of experience, I still do not have a firm understanding of CASE and especially OOPs. We've all heard about both in the press and the how they both will be the panacea of all computing ills. I've tried to muddle through articles that supposedly explain what OOPs is, but they all introduce concepts with out any tie to past knowledge. We all learn about some new item by comparing it with an old item. Our basis of the new item is founded on what we know of the old item (note that I'm trying to avoid the term "object"). All of the articles on OOPs make no attempt to show what an OO program is by comparing it with one that is not. They sort of jump into the middle of things as if all of their definitions of object, class, hierarchy, etc, are clear to all. I believe it was Jeff Dunteman of DDJ that said "Object Oriented Programming with be the hottest item in the 90's, but no one will know what it is.", or something to that affect. With CASE or just SE, I have not run across any general utilities that easily take high level psuedo-code and turn it into a code. We do have a number of specialized utilities, like YACC and LEX mentioned above, but most articles seem to describe an entire environment that allows code to be built from putting flow-chart boxes on the screen. Where I'm leading to is this: I'm looking for examples of either OOPs or CASE on the QL, even if it's very limited examples drummed up for demo purposes only. I feel the QL should be a usefull tool for exploring both of these concepts. I'm not saying that I want to embrace either of these concepts, I just want enough experience and knowledge with the concepts to form an opinion other than "I dunno." Know I know we've got some sharp people out there working on QLs (other wise we would not have C68 and other great software). I'm hoping that someone out there knows enough about either one of these concepts to explain it to me and other QL programmers. Or for those more masochistic minded, go figure these out for yourself and report back to us on what you find. .dw .bd Random Dot Stereograms .do .bo By Herb Schaaf Random Dot Stereograms (RDS) can give the illusion of depth if you have binocular vision. Instead of the usual pair of stereoscopic pictures, a single 'picture' is made with several swaths side by side, interleaved so as to provide the brain with depth clues when you gaze at the dots in a certain way. It takes a little blinking and practice, but when it 'snaps-in' to view the effect is marvelous. Once seen, it is fairly easy to find again. The best width for a swath is about half the distance between your eyes, say an inch or so. I have been using seven swaths, so that a RDS can be made on the screen that is about 7 inches wide and 6 inches high, and the effect is pleasing. I've done two so far, one a 'splash' like ripples in a pond and another of a pretzel. I've enjoyed working out the procedures and functions in SuperBasic, and a RDS only takes a minute or so to develop. Maybe I'll get (or take) the time to try it in C to speed things up, or even do animation in 3D! I've tried other swath widths, dot sizes, dot densities, and dot quantities, so you can too! A dot size of 1 pixel used to now and then 'hang' the QL into limbo, but since I added a missing END IF it has been OK. Pixels of size 4 are pretty good, and faster. A density of 1% or even less will work! The minimum number of dots per swath seems to be around 42 or so. There is a short program "eyefuse3" to calibrate your setup for the range of separation that you can accomodate. See how close and how far you can still fuse two images into three, and then pick a middle value for your swath width. Simple objects like a sphere are probably easier to find for the beginner, but splashes, pretzles, and saddles, etc. are fun. Some simpler DEFine FuNctions are included. Enjoy! eyefuse3: 100 REMark eyefuse3 125 WTV 126 PAPER 4 :INK 0 127 CLS 135 xo = 50: yo = 50 137 sep = 100 145 n = 8 155 bk = 1 165 explain 175 PAPER 0 : INK 6 180 CLS 200 FOR ac = 1 TO n 210 FOR dn = 1 TO n 220 BLOCK bk*1.5,bk,xo+ac*bk*1.5,yo+dn*bk, ((ac MOD 2 + dn MOD 2) MOD 2)*4 222 BLOCK bk*1.5,bk,100+xo+ac*bk*1.5,yo+dn*bk, ((((ac MOD 2 + dn MOD 2) MOD 2)-1)*-1)*2 230 END FOR dn 240 END FOR ac 247 CURSOR xo+n*1.5,yo :PRINT;"o" 248 CURSOR sep+xo+n*1.5,yo :PRINT;"O" 249 AT 16,2:PRINT;"use <--¸ and ¹--> keys" 250 AT 17,2:PRINT;" to change separation" 251 AT 19,2:PRINT " hold ESC key to exit" 255 REPeat moves 257 AT 10,15: PRINT;sep;" " 258 CURSOR xo+sep , yo 260 IF INKEY$(-1) = CHR$(192) : PAN -1,4 :sep=sep-1 270 IF INKEY$(-1) = CHR$(200) : PAN 1,4 :sep=sep+1 280 IF INKEY$(-1) == CHR$(27) : EXIT moves 290 END REPeat moves 300 DEFine PROCedure explain 310 PRINT " If you have binocular vision and can see fairly well"\ 320 PRINT "with either eye, it is possible that you may be able"\ 330 PRINT "to 'see' objects in depth on your QL monitor screen"\\ 340 PRINT "This exercise will 'calibrate' your eyes and your VDU"\ 350 PRINT\"Make a note of the separation distance in pixels when"\ 360 PRINT "you find it easiest to fuse the two little checker boards" 365 PRINT "into THREE little checkerboards." 370 PRINT "If you see 3 that's great; If you see two or four, change"\ 380 PRINT "something: tilt your head, blink, move away from or closer"\ 390 PRINT "to the screen, change eye-glasses, etc. while trying the"\ 400 PRINT "various pixel separations"\ 410 PRINT "The big 'O' will dominate the little 'o' when you have"\ 420 PRINT "good super-imposition and the center checkerboard will"\ 425 PRINT "be olive-drab"\\"Touch [SPACE BAR] to continue" 435 PAUSE 445 END DEFine explain 455 REMark end of eyefuse3 RDSphere_QLHJ_bas 100 REMark RDSphere_QLHJ_bas 110 REMark H.L Schaaf May 9,1992 120 REMark ref. Mathematica Journal Winter 1991 V.1,N.3, p.69-75 130 REMark 'Random Dot Stereograms' by Dror Bar-Natan @ Princeton 140 REMark dror@math.princeton.edu 150 ipl_dis = -20 :REMark image plane displacement, + is closer 160 obj_dis = 10 :REMark object displacement, - is more distant 170 iwide =360 : ihigh =240 : REMark image width and height 180 ytox = 4/3 : REMark y to x aspect ratio of QL blocks 190 swide = 60 : REMark swath width 200 zscale = 8 : REMark adjust for depth of Z axis 210 MODE 4 : CSIZE#2,1,0:CSIZE#0,0,0 220 WINDOW#1, iwide+8,256,0,0 :PAPER 0 : INK 7 230 WINDOW#2,144,190,368,0 : BORDER#2,2,2 240 PAPER#2,4 : INK #2,0 250 WINDOW#0 ,144,64,368,192 :BORDER #0,2,4 260 nk = 7 : REMark ink color 7 = white 270 CLS#0 : CLS#2 : CLS#1 280 REMark fill in with blocks 290 : 300 REMark ask for density and block size 310 INPUT#2; " % density ? ";dens : density = dens/100 320 INPUT #2;"Block size ? ";bk 330 hb = bk/2 : REMark half block 340 : 350 d_begin = DATE : REMark start timer 360 : 370 ac = swide DIV bk : REMark blocks across (columns) 380 ns = 2*ac : REMark allow for left shifts 390 dn = ihigh DIV bk : REMark blocks down (rows) 395 : 400 REMark create random pattern for first swath 404 RANDOMISE(32000) 410 DIM rdot%(density*ac*dn) 415 cnt = DIMN(rdot%) 417 FOR i = 0 TO cnt 418 rdot%(i) = RND (0 TO ac*dn) 419 END FOR i 420 : 580 REMark recap 590 PRINT#2\\" "; :UNDER#2, 1 600 PRINT#2;"Swath Data:" : UNDER#2, 0 610 PRINT#2;" ";ac;" across" 620 PRINT#2;" ";dn;" down" 630 PRINT#2;" ";ac*dn;" total" 640 PRINT #2;" ";cnt;" dots/swath" 650 PRINT #2;" ";(INT(10000*cnt/(ac*dn)))/100;" % density" 660 : 670 REMark create swaths 680 DIM swaths%(cnt,ns) 690 : 700 REMark put random pattern into first swath 710 REMark y values go into zeroth elements 720 FOR count = 0 TO cnt 730 i = rdot%(count) DIV (ac) 740 j = rdot%(count) - i*(ac) 750 swaths%(count,0)=i*bk 760 swaths%(count,1)=j*bk 765 BLOCK bk,bk,swaths%(count,1),swaths%(count ,0),nk 770 END FOR count 780 : 790 REMark create guides to help get proper 'focus' 800 gdlx=(iwide-swide)/2 : gdly=ihigh+6 810 gdrx=(iwide+swide)/2 : gdry=gdly 820 BLOCK 8,8,gdlx,gdly,nk 830 BLOCK 4,4,gdlx+2,gdly+2,0 840 BLOCK 8,8,gdrx,gdry,nk 850 BLOCK 4,4,gdrx+2,gdry+2,0 860 : 870 REMark geometric reference coordinates 880 xcntr=(iwide-swide)/2 : ycntr = ihigh/2 890 : 900 REMark a function to return the 3D value 910 DEFine FuNction sphere(x,y) 920 LOCal xs,ys,xx,yy 930 radius = 8*8 940 diam = 2*radius 950 diamsq = diam*diam 960 xs=ABS(xcntr-(x+hb)) 970 ys=ABS(ycntr-(y+hb))*ytox 980 xy = (xs*xs+ys*ys) 990 IF xy > diamsq 1000 offset = ipl_dis 1010 ELSE 1020 zz = diamsq-xy 1030 z=SQRT(zz) 1040 offset = z + obj_dis 1050 END IF 1060 RETurn offset DIV zscale 1070 END DEFine 1080 : 1090 REMark build remaining swaths 1100 OVER 1 1110 FOR i = 0 TO cnt 1120 FOR j = 2 TO ns 1130 ZD = sphere(swaths%(i,j-1),swaths%(i,0)) 1140 swaths%(i,j)=swide+(swaths%(i,j-1)) - ZD 1150 IF ((swaths%(i,j)+bk)>iwide) : EXIT j 1160 BLOCK bk,bk,swaths%(i,j),swaths%(i,0),nk 1170 END FOR j 1180 END FOR i 1190 : 1200 d_end = DATE :REMark stop timer 1210 d_lap = d_end - d_begin 1220 PRINT #2\\" Elapsed time:"\" ";d_lap;" seconds" 1230 : 1240 REMark save screen 1250 SBYTES_O ram2_rds_scr,2^17,2^15 1260 PRINT #2\\" sbytes saved to"\" ram2_rds_scr" 1270 : 1280 STOP Following are some other DEFine Functions: (Change line 1130 to suit) A Pyramid of sorts: 900 REMark a function to return the 3D value 910 DEFine FuNction pyr(x,y) 920 LOCal xs,ys,xx,yy 930 baseline = 150 960 xs=ABS(xcntr-(x+hb)) 970 ys=ABS(ycntr-(y+hb))*ytox 980 xy = (xs+ys) 990 IF xy > baseline 1000 offset = ipl_dis 1010 ELSE 1020 zz = baseline-xy 1040 offset = zz + obj_dis 1050 END IF 1060 RETurn offset DIV zscale 1070 END DEFine Imagine a Phillips head cavity ? 900 REMark a function to return the 3D value 910 DEFine FuNction phlhd(x,y) 920 LOCal xs,ys,xx,yy 930 baseline = 80 960 xs=ABS(xcntr-(x+hb)) 970 ys=ABS(ycntr-(y+hb))*ytox 980 xy = SQRT(xs*ys) 990 IF xy > baseline 1000 offset = ipl_dis 1010 ELSE 1020 zz = xy - baseline 1040 offset = zz + obj_dis 1050 END IF 1060 RETurn offset DIV zscale 1070 END DEFine Fan-blades making an X ? 900 REMark a function to return the 3D value 910 DEFine FuNction xvane(x,y) 920 LOCal xs,ys,xx,yy 930 baseline = 50 960 xs=ABS(xcntr-(x+hb)) 970 ys=ABS(ycntr-(y+hb))*ytox 980 xy = (xs-ys) 990 IF ABS(xy) > baseline 1000 offset = ipl_dis 1010 ELSE 1020 zz = baseline - xy 1040 offset = zz + obj_dis 1050 END IF 1060 RETurn offset DIV zscale 1070 END DEFine Diamond shape (similar to pyramid) 900 REMark a function to return the 3D value 910 DEFine FuNction diamond(x,y) 920 LOCal xs,ys,xx,yy 930 baseline = 100 960 xs=ABS(xcntr-(x+hb)) 970 ys=ABS(ycntr-(y+hb))*ytox 980 xy = (2*xs+3*ys)/5 990 IF xy > baseline 1000 offset = ipl_dis 1010 ELSE 1020 zz = baseline - xy 1040 offset = zz + obj_dis 1050 END IF 1060 RETurn offset DIV zscale 1070 END DEFine Sinc - the classic splash, change scales for sombrero 900 REMark a function to return the 3D value 910 DEFine FuNction sinc(x,y) 920 LOCal xs,ys,xx,yy 960 xs=ABS(xcntr-(x+hb))/swide 970 ys=ABS(ycntr-(y+hb))*ytox/swide 980 xy = SQRT(xs*xs+ys*ys)/2 1020 z = 2*PI*xy 1040 offset = 2*swide*(SIN(z)/z) 1050 END IF 1060 RETurn offset DIV zscale 1070 END DEFine P.S. I'm especially proud of my 'pretzle' sometimes known as the Escher knot. If there is interest let the Editor know, and we will show you the complicated way I did it. Even better, show us your interesting RDS FuNctions etc.! .bd .dw Infix to Postfix .bo .do By Tim Swenson In the March 1992 issue of "The C Users Journal", Rex Jaeschke has a column called "Doctor C's Pointers". He has been running a series of articles on data structures in C. In one of the column on stacks, he presents a infix notation to postfix notation translator/convertor. Infix notation is what is used in C, Pascal, Basic, etc. It looks like what we all learned in Algebra I. A equation would look like this: ( 3 + 7 ) - 8. Postfix notation is more stack oriented. It is used in HP calculators, the languages Forth and Postscript, and is also called Reverse Polish Notation (RPN). (Infix notation is sometimes called Polish Notation after it's Polish inventor) The above equation would look like this: 3 7 + 8 -. The C program belows takes in an infix equation and converts it to a postfix equation. Sample input would be: c - d * e + f (c - d * e) + f (((a - b) / (c + d)) * e) The program has a #define TRACE that allows you to see the process as it goes along. intopost1_c: /* File: intopost1_c fuctions for pushing and popping */ #define STACK_SIZE 30 static int stack[STACK_SIZE]; static int stack_ptr = 0; push(value) int value; { #ifdef TRACE printf("pushing: %c\n",value); #endif if ( stack_ptr == STACK_SIZE ) printf("Stack is full\n"); else stack[stack_ptr++] = value; } pop() { if (stack_ptr == 0) { printf("Stack is empty\n"); return(0); } #ifdef TRACE printf("popping: %c\n",stack[stack_ptr-1]); #endif return stack[--stack_ptr]; } intopost2_c: #include /*----------------------------------------------------- FUNCTION: intopost - converts infix to postfix A. Push a ( on the stack. This sentinel allows us to detect when we have flushed out the stack on completion in step I. B. Ingnore white space. C. Pass alphabetic characters through to postfix list. D. Push any ( on the stack. These sentinels allows us to detect when we have flushed out the stack when handling ) and operators. E. Have a ) so pop off the stack and put into postfix list until a ( is popped. Discard that (. F. Have a * or /. Pop off any operators of equal or higher precedence and put them into postfix list. If a ( or lower precedence operator (such as + or -) is popped, put it back and stop looking. Push new * or/. G. Have a + or -. Pop off any operators of equal or higher precedence (that include all of them) and put them into postfix list. If a ( is popped, put it back and stop looking. Push new + or -. H. Report unknown character on input. I. Have processed all input characters. Now flush stack until we find the matching ( put there in step A. J. Terminate the postfix list. ----------------------------------------------------- */ intopost( infix, postfix) char *infix, *postfix; { int st; /* A */ push ('('); while (*infix != '\0') { #ifdef TRACE printf("*infix: %c\n",*infix); #endif /* B */ if ( isspace(*infix)) { ; } /* C */ else if (isalpha(*infix)) { *postfix++ = *infix; } /* D */ else if (*infix == '(') { push('('); } /* E */ else if (*infix == ')') { while ((st = pop()) != '(') *postfix++ = st; } /* F */ else if (*infix == '*' || *infix == '/') { while (1) { if ((st = pop()) == '(' || st == '+' || st == '-') { push(st); break; } *postfix++ = st; } push(*infix); } /* G */ else if (*infix == '+' || *infix == '-') { while (1) { if ((st = pop()) == '(') { push(st); break; } *postfix++ = st; } push(*infix); } /* H */ else { printf("Unknown input character %c\n", *infix); } ++infix; continue; } /* I */ while ((st = pop()) != '(') *postfix++ = st; /* J */ *postfix = '\0'; } intopost3_c: /* convert infix notation to postfix notation */ #define TRACE #include #include "intopost1_c" #include "intopost2_c" main() { char infix_str[200]; char postfix_str[200]; while (1) { printf("Enter Infix: "); if (gets(infix_str) == NULL) break; intopost(infix_str, postfix_str); printf(" postfix: %s\n", postfix_str); } return 0; } .bd .dw Fletcher's Checksum .bo .do By Tim Swenson The May issue of "Dr Dobb's Journal" focused on data communications and included articles on checksums. One article covered Fletcher's Checksum, an algorithm faster than CRC and just as reliable as CRC, except it handles smaller blocks than CRC. CRC checksum will catch a 2 bit error in a 65,535 bit message, where as Fetcher will catch a 2 bit error in a 2040 bit message. The one thing I noticed about the algorithm was how easy it was to implement. Fletcher's Checksum is really two 8-bit checksums. This makes the algorithm easy to implement on any platform. Plus you only have to deal with two bytes instead of a 32 bit number, which would involve determining what order the 32 bit number is spread across bytes. Below is a SuperBasic version of the checksum program. The function calc_fletcher calculates the Fletcher Checksum for a string of characters, calculates the "opposite" checksum, and appends it to the end of the string. What I mean by "opposite" checksum is this: after the checksum is calculated (the two bytes), two other bytes are calculated so that when the whole message is processed at the recieving end, the checksum will equal 0. If the message is equal to say 10, the -10 is added to the message to bring the whole thing to 0. The check_fletcher function calculates the Fletcher Checksum on the message (string) and returns it. If it returns 0, then the message was received with no errors, else there was some error in the message. Those that are interested in 680XX assembly programming should check out the article. The text shows the algorithm in both C and 68000 assembly. The author then goes on to optimize both the C code and 68000 assembly code. The program goes from 17 lines of 68000 code to 4 lines of 68000 code. ** Fletcher's Checksum ** Structured SuperBasic program ** string1$ = "This is test of Fletcher's Checksum" string2$ = calc_fletcher$ (string1$) results = check_fletcher(string2$) IF results = 0 THEN PRINT "Checksum is OK" ELSE PRINT "Checksum is Bad" DEFine FuNCtion calc_fletcher$ ( str$ ) LOCal x, sum1, sum2, check1, check2, length sum1 = 0 sum2 = 0 length = LEN(str$) FOR x = 1 TO length sum1 = ( sum1 + CODE(str$(x)) ) MOD 255 sum2 = ( sum1 + sum2 ) MOD 255 NEXT x check1 = 255 - (( sum1 + sum2 ) MOD 255 ) check2 = 255 - (( sum1 + check1 ) MOD 255 ) str$ = str$ & CHR$(check1) & CHR$(check2) RETURN str$ END DEFine calc_fletcher DEFine FuNction check_fletcher ( str$ ) LOCal sum1, sum2, x, length sum1 = 0 sum2 = 0 length = LEN(str$) FOR x = 1 TO length sum1 = ( sum1 + CODE(str$(x)) ) MOD 255 sum2 = ( sum1 + sum2 ) MOD 255 NEXT x RETURN sum1+sum2 END DEFine check_fletcher