Apr 88 Letters
Volume Number: | | 4
|
Issue Number: | | 4
|
Column Tag: | | Letters & Editorial
|
The Great DataBase Challenge
By David E. Smith, Editor & Publisher
But Can It Do Columns?
For several years, I have been interested in a relational DataBase application that keeps track of families and family members. I started out on an Apple II, using various DataBase products, whose names now escape me, to keep track of Church membership lists. Such an application is relational since you must track both the family information, and the member information for each member that is linked to that family. Since the Mac came out, I have tried various Mac products and have learned a lot about the problem of real world processing on the Mac.
One thing I have discovered is that nearly every Macintosh DataBase is incapable of formatting a report of families and family members in the same double column format we use for MacTutor, with a hairline box around the page and a line down the middle. The problem is the products cannot determine how many members are in each family and how many families will fit in the column before moving to the top of the next column. So I offer this DataBase challenge to any Macintosh DataBase product to see if they can create such a report. The winning product gets a free ad in MacTutor and a glowing editorial review. Here are my results so far.
I first tried Helix. However, I quickly became buried in icons and gave up after a few days. Then I tried MacLion. But they went out of business before I even got started. Next came FileMaker. Although this is a flat DataBase, I was able to accomplish the goal by setting up the file with both the family and members of family combined into a single record for each family. When I needed reports dealing only with members, I used a program written in Basic to flatten the DataBase and extract the members without the family information. The very good export and import functions of Filemaker make nearly anything possible. By placing the family report in Pagemaker, I was able to format it in columns. However, all this pre-processing got tiring after a few months, so I moved on.
Next came Omni 3 Plus. However, it soon became apparent that the relational aspect of Omni 3 had been tacked on to what was once a flat DataBase product, so that working with multiple relations between files was very difficult and not at all obvious. Although I was told there is a technical note for programming Omni 3 to format in columns from a relational DataBase, the complexity of the whole thing discouraged me and I gave up on it.
My most recent attempt has been with Borlands Reflex Plus. As I reported in a recent issue of MacTutor, Reflex Plus can solve the formatted double column report requirement, at least so I thought! Reflex Plus is particularly easy and nice when it comes to setting up multiple related files and anything can be quickly changed at any time. I love it! Which is why I am so frustrated that it cant format a page in double columns correctly. Oh you can set up the necessary calculations to group the families and members into a double column listing, but the page break option is brain damaged and cant figure out when to move to the top of the next page when using two independent repeating collections. As a result of this bug, you cant keep the family members grouped together without a break at the bottom of each page. And because the export function is also brain damaged, you cant export a report with nested repeating collections into Pagemaker and format the double columns there! So you are just stuck! So close, yet so far! (It also lacks the ability to make the box around the page and line down the middle and have them repeat on each page!)
That leaves dBase Mac and 4th Dimension as our next candidates. Stay tuned!
doMessage Proc Listing Missing
In the MacDraw Plotter program we published in the Feb. 88 issue of MacTutor, we left out the doMessage procedure, which was contained in a unit called Misc. This procedure puts up a simple dialog box, using four strings which are passed to it, and are stuffed into the low memory globals defined by ParamText toolbox call. This is an easy way to get messages up on the screen while you are developing a program. Later, the messages can be moved to a resource file as strings to preserve the international flavor of the Mac way of doing things. We regret this little proc was left out, but it has been published in other issues of MacTutor, notably, Jeff Foxs Code Testor from the November 1987 issue of MacTutor.
UNIT Misc;
INTERFACE
USES
ROM85, PrintTraps, PlotGlobals;
PROCEDURE doMessage (message0 : str255;
message1 : str255;
message2 : str255;
message3 : str255);
IMPLEMENTATION
PROCEDURE doMessage; {(message0 : str255}
{message1 : str255}
{message2 : str255}
{message3 : str255)}
VAR
dialogP : DialogPtr;
item : integer;
BEGIN
ParamText(message0, message1, message2, message3);
dialogP := GetNewDialog(MessageDialog, NIL, pointer(-1));
IF dialogP = NIL THEN
BEGIN
SysBeep(5);
ExitToShell;
END;
initCursor; {change to arrow}
ModalDialog(NIL, item);
DisposDialog(dialogP);
END;
END.
68030 Specs Available
Barry Hill-Tout
Ontario, Canada
The thinking behind the 68030 microprocessor was discussed by Thomas L. Johnson in The RISV/VISV Melting Pot, Byte, April 1987. Johnson said that, Although the 030 certainly has a complex instruction set, it embodies many RISC design principles. The article following in that Byte, by Mark Ackerman and Gary Baum, made a similar claim for The Fairchild Clipper; the RISC principles were more visible there. Programmers, at least, were probably left wanting to know how that thinking translated into the instruction set and timings for the 030.
I got a look at 68030 specs today! I was told it was only recently made publicly available, and although a number of MacTutor readers probably know all this, under non-disclosure agreements, it may be of general interest.
The 030 is an enhancement of a subset of the 020 union the 851. The main enhancements are:
having a 256 data cache,
burst mode memory accesses of 16 bytes in, it seems, 4 bus cycles(or less?: 5 clocks, where normally its 2 clocks/bus cycle),
improved parallelism on chip, and of course
the improvements in speed possible by having address translation on chip; when the translated address is in the chips address translation cache there is no penalty for the translation.
I was told the 030 has up to 6 times the speed of a 68020/851 (presumably at the same clock speed). At a guess on optimum conditions for the 030, that might be repetitive read accesses to the same 256 bytes of data, not in a small loop: such code would take advantage of the data cache and burst mode of the 030, and negate the value of the instruction cache on the 020. What an average improvement is I have no idea -- but I expect it would have a large standard deviation!
All (?) the functionality of the 020 is on the chip. The one doubtful point is the rather exotic module support of the CALLM and RTM instructions: a technical summary sheet includes it in its list of instructions, but Motorolas Users Manual (the grey book) doesnt. Someone has not been letting his left hand know what his right hand is doing...
Although the main capacities of the 851 are on chip, most of the instructions are not: only PFLUSH, PLOAD, PMOVE (for certain registers only) and PTEST are in the 030 instruction set. It does have one functional enhancement to memory management, a transparent translation ( which appears to mean, no translation of one or two fixed blocks of logical addresses). Other 851 features are to be emulated by line 1111 traps. For the most part this seems like a good way to embody the RISC principle of reserving microprocessor silicon for the things done most frequently. I must, however, confess I am completely mystified by the absence of any conditional instructions, even PBcc: how can one program without conditionals? How can one emulate them? Bits in the status register everywhere, nor any bit to branch on.
The 030 is not, contrary to one optimistic rumor, pin compatible with the 020, even in the sense of a pin superset, It has 128 pins, 14 more than the 020, but for reasons best known to Motorola the ones in common are not all in the same place. However there are guidelines for adapting a 030 to a 020/851 system, we will probably see such adaptors, possibly as early as the MacWorld Expo.
The Man from Motorola also said he thought they were phasing out the 68881 (no great surprise). This means Apple will have to supply Mac IIs with 882s, which shouldnt hurt anyones feelings. Well, maybe the last people to buy ones with 881s... Apple, and likewise Levco and other people making enhancement boards for the Plus and SE, switch early!
Timing is pretty complicated already for the 68020; the enhancements to the 030 make it considerably more so. However, a few comments (most of which, I see on reading them over, apply to the 020 too).
Although, as Motorola makes a big point of saying, overlap can reduce the effective execution time of an instruction to zero, it seems this overlap would be of limited effect in general code: most instructions can overlap the previous instruction for several cycles if any. Since the actual overlap is the minimum of these head and Tail times, its usually zero.
The alignment of long words frequently matters. all compilers should give them long-word alignment when possible ( i.e., when packing doesnt force short word alignment). Unfortunately some data structures originally designed for the anorexic (128K) Mac require such mis-alignment. The evil that men do lives after them...
Since there is no penalty for address translation when the address is in the translation cache, it would seem best to have a rather large page size for the pages at the bottom of the address translation tree: the bigger they are, the more hits there will be.
A particular case of special interest for the Mac: A-line traps take 18 or 20 clock cycles (9 or 10 bus cycles), depending on whether the instruction is in the (instruction) cache or not. The 020 takes 20 in the in-cache case, so thats down two. Of course, that is only a small portion of the overhead for such traps -- and they wont be in the cache all that often.
It will leave Intels 80386 in the dust, as the 68882 will the 80387.
Mouse-up Problems
Delmer A. Johnson
Castle Rock, CO
A few weeks ago I encountered a problem similar to the one described in Mike Steiners Mousehole Report posting. I couldnt get icons in the finder to open when I double clicked. I could select them with a single or double-click and open them using the File menu or a command key. I discovered that the problem stemmed from another program which masked out mouse-up events. Evidently this is what the finder looks for when the user double-clicks on an icon.
Inside Macintosh II-70 warns against using SetEventMask for any purpose other than enabling key-up events. Unfortunately this advice is not heeded in the original edition of Macintosh Revealed vol. II, where mouse-up events are disabled (p. 26). The next time this problem arises, try writing a short program calling SetEventMask with EveryEvent. [Ive also seen this problem. Thanks for finding out what causes it. -Ed]
Changing the subject, I would appreciate an article explaining how to display a text file longer than 32k using Textedit. Can a person connect several Text Edit records together?
Upgrading DataFrames
Jack W. Howarth
Houston, TX
When I purchased my DataFrame XP20 over a year ago, it was casually mentioned that the controller card for the XP20 and XP40 were identical and therefore an upgrade to 40 megabyte should be possible for XP20 owners. Unfortunately, SuperMac Technologies is very reluctant to provide end-users with detailed technical documentation. I am eager to hear from anyone who has successfully upgraded their XP20 hard drive. The details of that procedure would make an excellent short MacTutor article and probably mark the first hard drive upgrade for the Mac. With 40 megabyte drives below $400, it will be very cost effective for XP20 owners to keep their controller cards and cases for the DataFrames. Thanks in advance.
Inside Macintosh Error
Mike Cohen
Burbank, CA
First of all, I disagree with Douglas Becks complaint about LightSpeed Cs string handling in the Feb. 88 issue of MacTutor. I find LightSpeeds string handling exactly as it should be. Any C compiler that generates extra code to convert between C and Pascal-type strings unless specifically requested is unacceptable. Its against the nature of C for a compiler to do strange things behind your back like string format conversions. The extra overhead makes such a compiler unusable for commercial development.
I prefer to use Pascal-type strings wherever possible and have written alternatives to most standard string functions as well as an additional %p format for printf.
I have also noticed the double-click problem mentioned in the MouseHole Report and have tracked it down to using MaxWrite, a shareware color word processor. MaxWrite looks nice, but is still pretty much buggy and unusable because of the 32k text limit.
One error Ive stumbled across in IM Vol. 5 is that GetAuxWin returns an AuxWinHndl in the second parameter rather than a CTabHandle. Use GetAuxWin to get the window frame color (second entry in the color table)if you have custom areas which must be drawn in the same color. I use it for an icon in the lower left corner that switches views. Using the window frame color makes it appear to be a natural part of the window such as the grow box, while drawing it in black is ugly.
In working with Color Quickdraw and multiple monitors on a Mac II, Ive come across several unusual quirks. Has anyone noticed any of these or figured out any work-arounds?
My application has several Color Windows which use the Hilite mode for selecting text or icons. When I change the hilite color with the control panel using Color or Kolor, one of my windows is updated to the new hilite color and all others retain the old hilite color.
When a window is positioned between two monitors (one displaying color and the other displaying B&W), any graphics scrolled from the B&W monitor to the color monitor remains black and white.
All popup menus always appear on the primary screen even if the area clicked is on the other screen.
Not really a bug, but the performance of ScrollRect is pretty awful in 8-bit mode. Scrolling large areas cause lots of display glitches.
[Quick, call Andy for QuickerDraw! Andy Hertzfeld got bored over Christmas so he re-wrote nearly all the low lever quickdraw drawing primitives that are used for color quickdraw, and speeded them up by a factor of four or more. Then he casually came to San Francisco and began telling people about it. Apple has since bought the rights to QuickerDraw and it will probably show up in a system file update. In the meantime, its on the nets. -Ed]
Whos Out There?
Neil S. Ticktin
Encino, CA
I am curious, how many Macintosh programmers are there out there (novice and professional). No one seems to have any idea. I know that between APDA membership and your subscriptions there should be at least 30,000 people, but that seems kind of low. The only thing that I can think of is to sum the number of copies of each compiler there are out there. Do you or any of your readers have any idea? [MacTutor has a distribution of 13,000 per month and the APDA membership is something like 18 to 20K, including Apple II people. Dr. Dobbs recently surveyed their readership and found some 30K plus were also Macintosh users. I expect the market for MacTutor and hence, Macintosh programmers is around 30,000 right now, but that is probably increasing rapidly as normal programmers discover the Mac II workstation. Ed]
Macintosh vs. IBM-PCs
Byron A. Palmer
Los Alamos, NM
Please enter my subscription to your MacTutor journal. It is a difficult journal to find but well worth the effort. I have been programming on the Macintosh for three months and I am finding it to be the best environment to work in that I have found; I have had 23 years of programming experience and consider myself an excellent programmer. The Macintosh offers the programmer the ease of making an excellent program for users without the trouble of writing everything from scratch. I was using IBM-PCs for my work but found the incompatibilities impossible to contend with. I do a lot of graphics and in a few weeks was able to duplicate what I had done on the IBM-PC in 3 months. The Macintosh is harder to start to program and requires a different point of view, but once developed it really goes quickly.
I would like to see some articles on programming for Multi-Finder. [See the Feb. 88 issue. -Ed] I would also like to see some push toward compilers that give us very fast code. Maybe and article on the various compilers and the speed which code works, both with 68000s and with 68020s and the 68881.
Cricket Graph Data From Basic
Steven Leach
Santa Clara, CA
I greatly enjoy MacTutor, and have written for your magazine several times, but I must take exception to the article The Workstation Mac by Paul Zarchan in the February 1988 issue.
Besides needing a spelling checker, he must not be very familiar with MS BASIC on the Macintosh, since I have been writing Cricket Graph compatible files for as long as the product has been commercially available. They specifically included a section of pascal code to write the tab delineated files, which was extremely simple to write in BASIC as well. When the 1.1 version of Cricket Graph became available, I did find that my BASIC program had to be modified because of the tendency of the new version to treat the leading space in the BASIC file string for the negative sign as an alpha character rather than a numeric character. This problem was easily fixed using the print using statement in BASIC.
When my data files became too large to load quickly using the tab delineated format, I simply called up Cricket and they kindly sent me a single page description of the fast file format. This format I have incorporated into all my BASIC diagrams, some of which have been available commercially and as shareware for some time.
I have included honest-to-gosh subroutines which can be used for exactly these purposes. So you can see that there is no problem in writing Cricket Graph compatible files. It is this type of misunderstanding and lack of curiosity that has relegated BASIC and FORTRAN to the engineering community, or to the toy factory. I personally program in Pascal, C, FORTRAN or BASIC which ever will do the job more simply, quickly and efficiently, although with the interpreter, compiler combination it is becoming tougher to justify not using BASIC when I dont need special data structures.
LIBRARY MS Tools
This is just a sample routine that fills an array
Saves it to Disk as a Cricket Graph file
and then retrieves data and displays it on the screen
N.col% = 5
DIM test.data(N.col%,10),test.title$(N.col%)
RESTORE
FOR indx% = 0 TO N.col%
READ test.title$(indx%)
NEXT
DATA Sample 0,Sample 1",Sample 2",Sample 3",Sample 4",SAmple 5"
FOR cindx% = 0 TO N.col%
FOR rindx% = 0 TO UBOUND(test.data,2)
test.data(cindx%,rindx%) = rindx%+100*cindx%
NEXT
NEXT
file.name$ = FILES$(0,Name for File ?)
IF LEN(file.name$) < 5 THEN END
CALL save.Cricket.tab(test.data(),test.title$(),N.col%, file.name$)
CLS
ERASE test.data,test.title$
DIM test.data(N.col%,10),test.title$(N.col%)
CALL open.cricket.tab(test.data(),test.title$(),N.col%,file.name$)
FOR cindx% = 0 TO N.col%
PRINT test.title$(cindx%)
FOR rindx% = 0 TO UBOUND(test.data,2)
PRINT test.data(cindx%,rindx%),cindx%,rindx%
NEXT
NEXT
END
This subroutine reads in the Data ffrom a Cricket Graph Fast Format
file
SUB Open.Cricket(array(2),array.title$(1),N.col%,file.name$) STATIC
watch% = 4
changecursor watch%
OPEN file.name$ FOR INPUT AS #1
tmp% = ASC(INPUT$(1,1))
tmp% = ASC(INPUT$(1,1))
IF tmp% <> N.col%+1 THEN
INITCURSOR
msg$ = This file is not compatible with this Data Array
CALL errormsg(msg$)
EXIT SUB
END IF
FOR indx% = 0 TO N.col%
tmp% = ASC(INPUT$(1,1))
array.title$(indx%) = INPUT$(tmp%,1)
IF tmp% < 15 THEN tmp$ = INPUT$(15-tmp%,1)
tmp% = 256*ASC(INPUT$(1,1))
t.col% = tmp%+ASC(INPUT$(1,1))
count% = 0
indx2% = 0
WHILE count% < t.col%
LINE INPUT #1,tmp$
count% = count% + LEN(tmp$)+1
array(indx%,indx2%) = VAL(tmp$)
indx2% = indx2% +1
WEND
NEXT
CLOSE #1
END SUB
This subroutine writes the array as a Cricket graph Fast format file
SUB Save.Cricket(array(2),array.title$(1),N.col%,file.name$) STATIC
watch% = 4
N.pts% = UBOUND(array,2)
changecursor watch%
OPEN file.name$ FOR OUTPUT AS #1
tmp% = N.col%+1
tmp% = INT(tmp%/16)
PRINT #1,CHR$(tmp%);
tmp% = N.col%-16*tmp%+1
PRINT #1,CHR$(tmp%);
FOR indx% = 0 TO N.col%
IF LEN(array.title$(indx%)) = 0 THEN array.title$(indx%) =
?
IF LEN(array.title$(indx%)) < 15 THEN
PRINT #1,CHR$(LEN(array.title$(indx%)));
PRINT #1,array.title$(indx%);
FOR indx2% = LEN(array.title$(indx%))+1 TO 14
PRINT #1,CHR$(0);
NEXT
PRINT #1,CHR$(1);
ELSE
PRINT #1,CHR$(15);
PRINT #1,LEFT$(array.title$(indx%),15);
END IF
tmp = 12*(N.pts%+1)
tmp1 = INT(tmp/256)
PRINT #1,CHR$(tmp1);
tmp1 = tmp-256*tmp1
PRINT #1,CHR$(tmp1);
FOR indx2% = 0 TO N.pts%
PRINT #1,USING##.####^^^^;CSNG(array(indx%,
indx2%))
NEXT
NEXT
CLOSE #1
NAME file.name$ AS file.name$ , STWK
setCreate file.name$ , CGRF
END SUB
SUB errormsg ( msg$ ) STATIC
win = WINDOW(0)
PRINT CHR$(7)
IF win = 4 THEN
PRINT THERE ARE TOO MANY OUTPUT WINDOWS OPEN TO OUPUT ERROR
RESET
MENU RESET
END
END IF
WINDOW win+1,ERROR WINDOW, (10,100)-(450,210),-4
PRINT msg$
default 5,OK,50,50,80,80
WHILE DIALOG(0) <> 1 AND DIALOG(0) <> 6 : WEND
BUTTON CLOSE 5
WINDOW CLOSE ( win+1 )
END SUB
This subroutine save the Array as a Cricket Graph Delimited Format
This is old Code I used to use this years ago
SUB save.Cricket.tab(array(),array.title$(),N.col%,file.name$) STATIC
watch% = 4
ttab$ = CHR$(9)
N.pts% = UBOUND(array,2)
OPEN file.name$ FOR OUTPUT AS #1
PRINT #1,*
FOR indx% = 0 TO N.col%-1
PRINT #1, array.title$(indx%);ttab$;
NEXT
PRINT #1, array.title$(N.col%)
FOR rindx% = 0 TO N.pts%
FOR cindx% = 0 TO N.col% -1
PRINT #1,USING##.####^^^^;array(cindx%, rindx%);
PRINT #1,ttab$;
NEXT
PRINT #1,USING##.####^^^^;array(N.col%, rindx%)
NEXT
CLOSE #1
NAME file.name$ AS file.name$,CGTX
setCreate file.name$,CGRF
END SUB
this routine reads a Cricket Graph Tab delimited format from the
Disk
SUB open.cricket.tab(array(),array.title$(),N.col%,file.name$) STATIC
watch% = 4
changecursor watch%
N.pts% = UBOUND(array,2)
ttab$ = CHR$(9)
OPEN file.name$ FOR INPUT AS #1
INPUT #1,tmp$
IF tmp$ <> * THEN
msg$ = This file is not compatible with this program
CALL errormsg(msg$)
EXIT SUB
END IF
LINE INPUT #1,tmp$
cindx% = 0
tmp% = INSTR(tmp$,ttab$)
WHILE tmp% > 0
array.title$(cindx%) = LEFT$(tmp$,tmp%)
tmp$ = RIGHT$(tmp$,LEN(tmp$)-tmp%)
tmp% = INSTR(tmp$,ttab$)
cindx% = cindx%+1
WEND
array.title$(cindx%) = tmp$
N.col% = cindx%
FOR rindx% = 0 TO N.pts%
LINE INPUT #1,tmp$
FOR cindx% = 0 TO N.col%-1
tmp% = INSTR(tmp$,ttab$)
array(cindx%,rindx%) =VAL( LEFT$(tmp$,tmp%))
tmp$ = RIGHT$(tmp$,LEN(tmp$)-tmp%)
NEXT
array(N.col%,rindx%) = VAL(tmp$)
NEXT
END SUB
SUB default (BUTTONID%,Title$,Left%,Top%,Right%,Bottom%) STATIC
DIM R%(3)
BUTTON BUTTONID%,1,Title$,(Left%,Top%)-(Right%,Bottom%),1
setRect R%(0),Left%-3,Top%-3,Right%+3,Bottom%+3
PENSIZE 2,2
CALL FRAMEROUNDRECT(VARPTR(R%(0)),16,16)
PENSIZE 1,1
ERASE R%
tmp = FRE(0)
END SUB
MPW Changes in 2.0
W. Powell
Salt Lake, UT
Since I wrote the MPW article in the January MacTutor, a final MPW v.2.0 has been released through APDA. While there has been little change in the MPW script language, readers attempting to use the information published earlier should note the following differences between version 2.0, (used with System v. 4.1 or later) and version 1.0 used in the earlier article.
Application launch directory: The MPW shell now forces the directory holding an application being launched to become the default directory at launch time. Several of my shell scripts changed the default directory prior to launching applications, primarily to control the folder first encountered in SFGetFile dialogs in the applications. That technique no longer works. There may be an alternative way to force SFGetFile to start at a non-default folder -- Apples FindFile DA seems to do this for example. I find it irritating to move from the application folder out to the root directory and back down to my project folder every time I launch an application and open a file, so for me, this change in the shell was a net loss in functionality. Id be interested to hear if anyone knows an alternate way to control the SFGetFile dialogs initial folder from the MPW shell.
Variable scope: My article exploited an undocumented change in shell variable scope associated with the launching of applications. Version 2.0 behaves the same as vers. 1.0 in this respect.
Saving selections: A change of text selection made manually with the mouse is saved when the window is closed. A change of text selection made by commands such as Find is still NOT changed unless there is also a change of text content. My technique of adding white space to the file to force saving a selection still works, but the MPW 2.0 Mark command is a more elegant alternative. Changed marks are always saved.
Set Paths DA: The vers. 2.5 release of TML Pascal includes a new version of the Set Paths INIT and DA. The new DA no longer uses a file of STR resources, so the script file MakePPath in my article is not compatible with the new Set Paths. I never had trouble with the old Set Paths, so I just kept the old INIT and DA with the new TML applications.
FileMaker Is The Best
S.C. Kim Hunter
Laguna Hills, CA
As you say, FileMaker Plus is the best flat database. In my opinion, it is the best database, and THE WORLDS BEST SOFTWARE PRODUCT EVER. InfoWorld published those words from me in September, 1985, and I stick by them, No product has yet come along to temper my enthusiasm.
As evidence of my conviction, I spend more time pruning out my FileMaker files than I do with any other product. Hypercard and 4th Dimension files take up more space on my hard disk, but, in terms of actual data, excluding demo files FileMaker is always at the top of the list when I do a Finder View by Size.
Everyone raves about relational software in the trade press - about all the flexibility. But Im willing to bet $1,000 that, if you took a tally of all the database information stored on Macs in the world as of today, you would find more bytes of real live database data stored in FileMaker Plus files than all the rest of them combined. and Ill go even farther, and bet $100 that there is more FileMaker data stored than all the database data on all the computers in the world. Ill probably loose the later bet based on the worlds mainframe capacity, so let me hedge it a bit by saying useful data, i.e., data that is used everyday in the business world, thereby excluding hordes of data collected at taxpayer expense of which never more than 2% is ever examined by humans,
As the result of reading Inside Macintosh and MacTutor, I managed to write a desk accessory, MakeRecords, which converts FileMaker Plus repeating field line items into single records.
Creating a desk accessory was fun, but not nearly as fun as having a vast range of Macintosh users call me about their particular database problems - doctors, lawyers, bee keepers, button makers, building cleaners, matchmakers, headhunters, librarians - on, ad infinitum. By my experience I can say that the most fun for a Mac programmer is creating a tool that does a very specialized job, one thing, but does it very well, then having the world beat your path to your door by word of mouth - not one dime for full page slick ads and no need to go the shareware or freeway route- (many want MakeRecords sent by Next Day Air).
In talking to all these naive experts - naive of the Mac, Experts in making their businesses click, Ive heard the same over and over: I bought_______ relational database program, but dont have time to figure out how use it. FileMaker works OK for my business, but I cant figure out how to ___. So I tell them how to do ___, and they go on about their business. what a blast.
So how come FileMaker isnt relational? Thanks to the good sense of the folks at Nashoba Systems, the world will NEVER SEE RELATIONAL FILEMAKER. I talk to Nashoba at least once a week, yammering for relational FileMaker. But they are stubbornly committed to keeping FileMaker SIMPLE-SIMPLE-SIMPLE. Nashoba interface designers are constantly attune to the needs of the basic FileMaker user. Wed do it in a minute if we could figure out how to make it simple but we dont have a handle on the interface.
If you want, and can handle, a current state of the art relational database, by all means use it if it solves your problem. But dont ding FileMaker because it doesnt emulate your idea of what a relational data management system should be. there are thousands of people out there struggling to understand just the current capabilities of FileMaker, and they are managing to make it work for them while other software shepards no more than its demo files.
MacTutor has a unique obligation: it caters to the Mac gurus- and does it very well. But what the gurus produce only makes waves if aunt Madge and her bee keeping business can make use of it. I found the key with an enhancement to FileMaker. If you can find a way to make FileMaker relational, but still useable by aunt Madge, run, dont walk, to Nashoba. They will greet you with open, but suspicious, arms. Lots of luck. If you trip, its my foot. Can you beat me to the punch? Best of Luck! [I did use FileMaker for a relational application for awhile as mentioned in my editorial comments. By making use of simple Basic utilities, I was able to suppress the relational nature of the data whenever I needed a report dealing only with members and not sorted by families, as was the default. So it can be done, but it gets to be a pain after awhile. -Ed]
Finding The Area Of A Region in C
James Plamondon
Albuquerque, NM
I received my MacTutor today, and was delighted with it, as always (even if my article on random numbers still languishes on the back burner). I was particularly interested in the article Regions with Aztec C in the C Workshop column [October 87, v3 n10 p27-32].
The article was concerned, in part, with estimating the area of a given Quickdraw region. The authors accomplished this with a function, countpix(). Countpix() considered each pixel in the regions enclosing rectangle, and determined whether each fell inside or outside the region in question.
This, to use the authors own words, is a brutal kludge. The authors intended to find the areas of regions which had been drawn freehand; accuracy can hardly be at a premium. Further, the authors state repeatedly that they are estimating the area of the region -- so why work too hard at an estimation?
No assembly-language optimization will rescue an inefficient algorithm from inefficiency; it will just waste time faster. A more appropriate algorithm would be one based on a probabilistic estimation of the area of the region, based on a random sample of points in its enclosing rectangle. The number of points sampled could be very large (hundreds) and still be only a small percentage of the total number of pixels in a large region.
Consider a region bounded by a rectangle with its top-left vertex at (l, t) and its bottom-right vertex at (r, b). Assume a function (GetIntURand()) which would return a uniformly-distributed pseudo-random short integer in the range [l, r) or [t, b). We can re-write countpix() to return a 32-bit integer (a C long int), which gives an estimate of the area of the region in pixels:
long countpix(rh)
rgnHandle rh;
{
Point p;
short i, t, l, b, r;
long count;
t = (*rh)->rgnbbox.a.top;
l = (*rh)->rgnbbox.a.left;
b = (*rh)->rgnbbox.a.bottom;
r = (*rh)->rgnbbox.a.right;
for (i = 0; i < NUM_PTS; i++) {
p.a.v = GetIntURand(t, b);
p.a.h = GetIntURand(l, r);
if (PtInRgn(&p, rh))
count++;
}
return((count * (b - t) * (r - l)) / NUM_PTS);
}
/* end of countpix() */
NUM_PTS will determine the accuracy of the estimation. It may be either a #defined constant or a variable, proportional to the area of the enclosing rectangle (or the length of one side). In both cases, the accuracy of the estimation will vary with the density of the region (ie., how fully it fills its enclosing rectangle). If NUM_PTS is a constant, the accuracy of the estimation will also vary with the size of the region.
This method is not as accurate as the method proposed by the authors. However, it is much more appropriate for their stated desire, it is much faster, and it, too, is amenable to assembly-language optimization.
XCMDs And XFCNs With Non-MPW
Steve Roti
Portland, OR
In response to Danny Goodmans call for more information on writing XCMDs and XFCNs with non-MPW compilers (reported in Joel Wests column, December 87), I am submitting my comments on using Consulairs MacC version 5.0 for this purpose.
First, grab the include file HyperXCmd.h from the disk supplied with the HyperCard Technical Reference Package from APDA. This file contains the definition of the XCmdBlock structure used for passing information between HyperCard and the XCMD. The C source file must have a typedef to account for the type Boolean used in XCmdBlock. The following C code shows how to set up the source file.
#Options +Z
typedef char Boolean;
#include <HyperXCmd.h>
pascal void main(paramPtr)
XCmdBlockPtr paramPtr;
{
/* body of XCMD */
}
The only real surprise here is that the function name must be main rather than the actual name of the XCMD (otherwise the linker will moan about not finding the label main). The other difference is that I was not able to get the include file XCmdGlue.inc.c to compile in MacC, so I dont include it at the end of the source file. The callback routines should be able to be called using the same approach as in Pascal (procedure DoJsr), but I havent had the need to call any of them yet since the input parameters and return value can be accessed directly from the XCmdBlock structure.
The following Link Control File shows how to link the XCMD.
/Output XCMD
/Type RSRC
XCMD
Standard Library
/End
The name of the compiled file containing the XCMD must precede the Standard Library file so that the XCMD code will be the first thing in the resulting segment. After compiling and linking, fire up ResEdit and open the linked file, which will contain three CODE resources. Open the CODE resource with ID=1, select from address 00000004 to the end (this will eliminate the four header bytes from the segment), and copy the selection to the clipboard. Close the linked file and open the stack that will contain the XCMD. Create a new XCMD resource and paste the code from the clipboard into it. Choose the menu item Get Info for the new XCMD, type in the exact name of the XCMD, and check the Purgeable box. Save the changes to the stack and quit ResEdit.
Finally, a working XCMD! (You did code it correctly didnt you?) Note: everything said here applies to XFCNs as well.
New Version Of Shift Mod Patch
Andy Voelker
Long Beach, CA
Here is a new version of the Shift Mod Patch that you published in the September, 1987, issue. This version will work with Desk Accessories; the previous version did not.
The ShiftMod Patch in the September, 1987, issue of MacTutor didnt work properly for desk accessories. Here is a patch to the original code that will fix the problem. It puts a prologue patch on _SystemEvent that uses the same code as our _GetNextEvent patch to modify keyDown and autoKey events if both the Caps Lock and Shift Key are held down at the same time (in which case it will return a lower case letter).
This modification to the patch is in two parts. The new code is surrounded by comments of asterisks. I have given a line or two of the original code on either side of the modifications so you can find where to put the modifications in the original code.
First modification: during the installation part that patches _GetNextEvent. Add some code to patch _SystemEvent just before the call to _BlockMove:
/* set the trap address to the space we
* just got in the system heap. */
move #GetNextEvent,D0
_SetTrapAddress
/********************************/
#define SystemEvent0xA9B2
/* set up the address of the SystemEvent
* JMP instruction */
move #SystemEvent,D0
_GetTrapAddress
lea @sysEventAddr,A1
move.l A0,(A1)
/* patch SystemEvent */
move #SystemEvent,D0
/* calculate the after-move address of
* the _SystemEvent patch */
lea @newSysEvent,A0
lea @first,A1
suba.l A1,A0
adda.l (SP),A0
_SetTrapAddress
/********************************/
/* now move it into place */
lea @first,A0
move.l (SP)+,A1
move.l D3,D0
_BlockMove
Second modification: the patch to _SystemEvent. Put it after the patch
to _GetNextEvent, but before the label @last.
@eventPtr dc.l 0
/********************************/
#define RTS 0x4E75
@newSysEvent
lea @patchExit,A0
move #RTS,(A0)
bsr @tailPatch
lea @patchExit,A0
move #JMP,(A0)
dcJMP
@sysEventAddr
nopb ~
nop
/********************************/
@last
Thermal Cycling Revisited
Ed Leach
White Bear Lake, MN
Just wanted to let you know that I greatly appreciate your publication. I recently began a subscription after having regularly purchased MacTutor at the local news stand. I am a retired widower with a 2 Meg Mac Plus, a 50 Meg Jasmine HD and a passion for exploring the Macintosh universe. Over the last year I have been trying to teach myself how to program (on a modest basis to be sure) and find your mag as well as Nibble Mac invaluable. Im strictly an amateur, but its more fun than a barrel of monkeys.
Im sure that all your experts, who both contribute and just read MacTutor, are much more versed in the ways of the Mac than I, but maybe the following tip might be of use to someone out there.
Using a Mac everyday means a great deal of thermal cycling, even with a fan, and one of the symptoms of the effect of said cycling is an occasional blossom-like flash or a split-second brightening of the screen (on the Mac+) shortly after a fresh start-up. A simple and periodic maintenance procedure appears to remedy this problem. Remove the cabinet and very carefully loosen and re-tighten the two grounds that are readily accessible on the chassis. One is at the Upper left corner of the CTR and the other on the right hand side of the rear of the chassis near the modem & printer sockets.
Macintosh At Work In An IBM Lab
Mathew Snyder
South Bend, IN
I am writing to ask you to send me an authors kit, but let me first compliment you on your magazine.
I am a student at the University of Notre Dame, and I work in a research lab sponsored by IBM. The lab specializes in cooperative processing between various computer architectures. The systems in the lab include many IBM {PCs and PS/2s, several IBM PC/RTs running a UNIX-like operating system, a 4341 and a 9370 ( both 370-based minicomputers running VM and CMS), and a few 68010-based UNIX machines. When I joined the lab, I became responsible for introducing a new architecture into the network: the Macintosh.
It wasnt long before your magazine was recommended to me by many sources, including APDA and Steve Jasik. I ordered a subscription for the lab, and was not disappointed. I have found so much useful information in every issue that I purchased a copy of the volume II collection for myself. As a testament to the usefulness of the information in the magazine, this letter was printed on an electronics typewriter by a Macintosh running MacWrite, using the Daisy printer driver provided in your most recent issue.
Now about the Authors kit... I have been working on a little project of my own recently, and in the process I developed a very small and simple Lightspeed C library that I call EV Simulator. It provides everything necessary to allow programmers to insert simulated events into the toolbox event queue.
Without comments, it consists of about 100 lines of code, and it provides 7 functions. Among the events it allows you to simulate are mousedowns, mouseups, and keystrokes. It also makes it possible to have the events time delayed.
I have used the event simulator to make FKEYs and DAs that produce a series of mousedowns and keystrokes to automate certain activities easy. To make the installation of FKEYs easy, I have a code resource that can be combined with the FKEY code resource to create an application that automatically installs the FKEY into the System file.
Please let me know it you think my library would make an appropriate topic for an article. [It would! -Ed]
MacTutor Best Source Of Information
Keith Bale
Elmhurst, IL
I am requesting an authors kit from MacTutor. I am currently working on projects for the Mac II that include the following topics: real time graphical simulation of petroleum refineries, implementation of on-line expert systems in refineries and advanced process control. All programming is in Madula II and Pascal with future concentration in Modula II. I am currently using the SemperSoft Modula II version 1.06 compiler for MPW. I would be interested in writing on any of these topics for your publication.
My background had been programming real-time simulators for two years at UOP Inc. a division of Allied Signal after three years of research in process development. My education is Chemical Engineering with a specialization in computers and process control. Currently our company is converting our simulators from Intel based computers to the Mac II.
Other topics for consideration include writing code that will be portable between the IBM OS/2-windows -Presentation Manager environment , X-windows under Unix on the MicroVax and the Mac II windowing operating system. Also if sufficient interest is present, a regular Modula II column is possible. A review of Modula II compilers for the Macintosh with benchmarks between TML, TDI, and SemperSoft is another possible article. I have written in C and Pascal. These articles were published in the Morrow Owners Review.
MacTutor is the best source of information for programming but has lacked the articles on Modula II. Now that several professional compilers are on the Mac, I hope to bring that information to Mac Programmers. [How many readers are using Modula-2? We would like some feedback on the Modula-2 market penetration from the Mac programming community. -Ed]