jmg@cernvax.UUCP (jmg) (10/24/86)
Let's start with the bugs. First, the easy one:- while (!(isalpha(f1 = getchar()))) ; where f1 is a char variable, fails to compile under megamax. Agreed, I should probably use ~ rather than !, but it is OK on other compilers. Mention of ~ reminds me that when I sent over my programs via kermit from this 4.2bsd vax the various ^L put in to force a newline on the listings got translated to something which megamax did not like, but which printed as ~ on the ST. I thus deleted the various ~ by hand (on my C64 I have a program to do it!), including some ~ which were meant to be there! Can megamax have an equivalent/identical character, or at least ignore whatever ^L becomes? Now the main course, which has caused much gnashing of teeth and wails from the family (are you STILL on that bloody computer?). My favourite program (a chess problem solver) works on several machines, but not (yet) on the ST. One of the reasons is shown by the following program. #include <stdio.h> typedef char unsn7; /* 0 to 127 */ typedef char void; /* no return() */ typedef unsn7 piecear[65]; typedef piecear piecemv[8]; typedef piecear *piecept; piecemv king; piecept mset[8]; void main(argc,argv) unsigned argc; char **argv; { unsn7 mysqr; unsn7 dir; piecept piecemat; unsn7 *pieceset; mysqr = 15; dir = 0; king[dir][mysqr] = 24; mset[5] = king; piecemat = mset[5]; pieceset = piecemat[dir]; printf("\npieceset[%2d]=%2d piecemat[%1d][%2d]=%2d king[%1d][%2d]=%2d", mysqr,pieceset[mysqr],dir,mysqr,piecemat[dir][mysqr], dir,mysqr,king[dir][mysqr]); gives the following output pieceset[15]=24 piecemat[0][15]= 1 king[0][15]=24 Having disassembled, the reason is essentially that the code takes piecemat to be the matrix itself, rather than a pointer to it. The disassembled code for piecemat[dir][mysqr] is move.b -1(a6),d0 mysqr into d0 move.b -2(a6),d1 dir into d1 ext d1 extend d1 to 16 bits muls $65,d1 65*dir in d1 !!! lea -6(a6),a0 address of piecemat add.l a0,d1 add 65*dir to d1 ext d0 extend d0 move.l d1,a0 shift d1 to a0 adda d0,a0 add mysqr to a0 move.b (a0),d0 the (false) value There are many ways round this, of which one is to change the typedef for unsn7 to int (yes, this is better anyway, but on 8-bit computers like the C64 I gain a lot with using char). The code then is correct move -2(a6),d0 move -4(a6),d1 muls $130,d1 add.l -8(a6),d1 using the content of piecemat == -8(a6) asl.l $1,d0 move.l d1,a0 adda d0,a0 now a0 really has the right address. I am pretty sure that there are other bugs to do with use of char for small integers, but I don't have the courage to look for them: I have simply changed to int. Incidentally, the definition of void as a typedef is necessary: what a pain. Next problem: my program sometimes goes into suspended animation (loops somewhere), sometimes mushrooms and sometimes shoots back to the desktop. When it loops then I know where it has got to according to the output, but I hoped that the recently-distributed watcher program might get me out: it has no effect. Does it work for anyone? For the cases where the program mushrooms or returns to the desktop I would like to see what was printed right up to the fatal instant, by forcing standard output onto my printer. The manual talks about redirecting output, but I cannot find a way of doing this by a >? parameter to a .ttp program. Anyone done it? Of course, I can send it to a file, but if the program loops the file is never closed, so stays empty. Also, of course, file output is buffered, so that I miss the end part. Another minor grouse is that of missing library routines. I needed bcopy, bcmp and ffs (even the C64 has these). Of course I can easily hack them, but has anyone started a supplementary library? Yet another problem concerns dynamic allocation. I need to build up linked structures (not big, but lots of them), so I use malloc and free. The manual talks about malloc getting 8 kB chunks, but does not explain if these are automatically split for many smaller mallocs. I thought that I could see by printing out a pointer in %x8 format. However, what is printed is only 16 bits (try printing king[0] and king[1] in the above program!). Is there a way? Also, should I try Malloc (possibly increasing the heap size)? Final question (are you asleep yet?): can I link from a RAM disk (containing megamax folder but not the source/object files)? If yes, does it need the RAM disk specified in the list of object files. Which reminds me that the program is split into about a dozen modules, which is too many to link by using the shell and pointing to the files one by one, or even listing them in a link program call. It would have saved me some time if the manual had told me that. (the above means can I do the library search, of course). Just as a point of interest, this program always gives problems when moving to a new compiler. That is because I use it to teach myself about C constructs. If I were trying to write a portable C program I should be much more careful about writing "simple" C. Mike Gerard
braner@batcomputer.TN.CORNELL.EDU (braner) (10/30/86)
[] A few answers/suggestions: Never put a function call inside a macro! E.g.: isalpha(c) is a macro (defined in ctype.h): #define isalpha(c) (c>='A' && c<='Z' || c>='a' && c<='z') which means that isalpha(c=getchar()) calls getchar() 4 times, probably not what you wanted... (to make things worse, getchar() is a macro inside another macro...). BTW, they should have defined isalpha as above but with "(c)" instead of "c" everywhere - that may be why it does not compile... To get stuff out on the screen or whatever, flushing the buffer, use fflush(). The Megamax malloc(), as explained in the manual, is designed to bypass the problems with the OS Malloc(). It takes no less than 8K at a time from the system, and does further splitting itself. It works mighty fine under heavy use, with MANY small malloc()s and free()s, as exemplified by my microEMACS. To print out a pointer, use: printf("%lx", (long)pointer); (remember: from now on, pointers are 32 bits, until they get to be 64!) - Moshe Braner PS - anybody got the upgrade from Megamax yet? Or is it due Friday night?
jmg@cernvax.UUCP (jmg) (11/04/86)
In article <1333@batcomputer.TN.CORNELL.EDU> braner@batcomputer.UUCP (braner) writes: >A few answers/suggestions: > > Never put a function call inside a macro! E.g.: isalpha(c) is >a macro (defined in ctype.h): > > #define isalpha(c) (c>='A' && c<='Z' || c>='a' && c<='z') May I suggest that the real problem is the lousy way that the macro is defined! Look at the BSD4.2 macro to see how things should be done. Library macros should be pretty well equivalent to library functions, with no side effects.
jmg@cernvax.UUCP (jmg) (11/08/86)
In article <1333@batcomputer.TN.CORNELL.EDU> braner@batcomputer.UUCP (braner) writes: > The Megamax malloc(), as explained in the manual, is designed >to bypass the problems with the OS Malloc(). It takes no less than 8K >at a time from the system, and does further splitting itself. It works >mighty fine under heavy use, with MANY small malloc()s and free()s, >as exemplified by my microEMACS. > > To print out a pointer, use: > > printf("%lx", (long)pointer); > >(remember: from now on, pointers are 32 bits, until they get to be 64!) I DO remember, and I HAD already tried that method, and it ONLY prints out the first 16 bits. If anyone can actually get it to print the full 32-bit number I should like to know (maybe %d would work). BTW, I note in my tests that malloc can actually hand out blocks larger than 8K. Any problems with this, since at least one of my correspondents thought that 8K was the maximum. Another bug, though maybe not Megamax. If I try to use the editor to look at a file which is too large to fit into memory then I get a nice dialogue box telling me so, but no amount of mouse clicking gets rid of that dialogue box.