oster@lapis.berkeley.edu (David Phillip Oster) (01/08/87)
My report of bugs in LSC V.2 was premature and wrong in many places. My apologies to the net and to THINK, Inc. for causing un-necessary worry. Here were the 4 problems and their resolutions: My thanks to Think and in particular to one of their programmers. I couldn't quite catch his name of the phone.: He looked up my home phone number and called me long-distance to track down the bugs I had reported. That is great service for a product I bought in a retail store 6 months ago. 1.) The windows menu can't handle files with names that start with "-" This is a real bug. The only real bug in the posting. Pretty minor, eh? 2.) The shift arrow keys are the same as the +=\* keys on the numeric keypad. As has been pointed out to me by Think's programmer, by Meredith Lesly <mlesly@labs-b.bbn.com> and by my own experiments (I actually wrote a program to check.) You really can't tell the difference, the keyboard sends the same keycodes in each case. So, this is a bug, but it is a bug in the keyboard ROMs and there is nothing Think can do about it. 3.) Not correctly making fresh "suitcase" files. - the associated reesources didn't get copied. I haven't been able to replicate this. It may just have been my eyes playing tricks on me that once. 4.) Incorrect code generation for calling routines declared "pascal". Well this is the big one. This is also the one that Think would have tested most carefully. I did some investigation, and I'm handing the people from Think the following letter at their MaxExpo booth: The code LSC V.2 generates is not what I expect in one case: problem: enum { ZERO, ONE, TWO }; pascal void Psubr(z,i)long int z;int i;{ } void Csubr(z,i)long int z;int i;{ } main(){ Psubr(0L,TWO); Csubr(0L,TWO); } In this example we have two routines, Csubr, and Psubr, that are idenitcal except for the fact that Psubr is declared to use the pascal calling syntax. We call each one with an enumerated type, 2, that has the value 2. this generates the following code: main: clr.l -(sp) move.b #2,-(sp) jsr Psubr move.w #2,-(sp) clr.l -(sp) jsr Csubr rts discussion: The reason it used a move.byte for the pascal version is that TWO is an enum, a byte length variable, and it is doing what I said, pushing it on the stack in a pascal compatible manner. The reason for the move.word when we call the C version is that enums are byte length variables, and the C language coerces byte length variables to word length variables when you call a procedure. You can't really push a byte onto the stack. The 68000 always aligns the stackpointer to an even boundary. The difference between a move.b #2,-(sp) and a move.w #2,-(sp) is that the byte version leaves garbage in the low byte of the integer cell at top of stack and puts the data in the high byte while the word version has a zero in the high byte of the integer cell on the top of the stack, and the data in the low byte. Now, the compiler was smart enough to know that Psubr is a pascal routine and should, therefore, get its parameters in the opposite order from Csubr, so I thought it would be smart enough to know that Psubr was declared to take its second parameter as an Integer, i.e. via a move.w. I was wrong. The solution is: Use function prototypes!