[net.micro.atari16] Megamax bugs and queries

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.