EASy68K Home

DTACK GROUNDED #15
November-December 1982

DTACK GROUNDED, The Journal of Simple 68000 Systems
Issue # 15 November-December 1982 Copyright Digital Acoustics, Inc.

PHASE ZERO REPORT:

Here is a letter received from Phase Zero along with a disk: "Enclosed is an updated version of ASSEM68K. Problems with MOVEQ, MOVEM, LIST, and TRUNC instructions and the .L addressing mode have been fixed (we didn't know about those last two - ed).

"Although we are sending letters to all of our past customers, we would appreciate your mentioning in DTACK GROUNDED, that we will supply this update at no cost. If they will return their original disks to Phase Zero, the revision will be returned promptly."

Consider it mentioned, Dan.


THE DYNAMIC RAM BOARD DESIGN is being finalized AND BLACK TAPE IS BEING LAID ON CLEAR ACETATE. When we reach that last stage, we consider construction under way here at Digital Acoustics. The board will be a 636K MX-80 printer buffer which just happens to have a 68000 an board. You see, all 68000 boards MUST come with incredibly complex operating systems but printer buffers are just a functional utility piece of hardware (and we might want to advertise in BYTE).

Speed is not finalized but we are leaning to a 12.5MHz CPU with one wait state. Refresh is by software assisted by hardware; overhead about 3%. Because of refresh interrupt no timing-critical software can be written and FULL HANDSHAKE must be used by the 6502 at all times (not true of existing 6502 utility software).

636K = five rows of sixteen each 64K DRAMs less 4K at the start of memory to match the existing DTACK board. No provision for parity, hence name is MELKEN, not Dtack Grounded. DTACK is NOT grounded on the MELKEN. Board size identical to Dtack, identical interface & expansion connectors.

Identical size to use real DTACK enclosure which we will really have some day manana.

Page 1, Column 2

To be sold with 1, 2, 3, 4 or 5 rows of DRAMs. Price not yet determined, but (sigh) we HAVE taken a closer look and 252K might be a little over $1K. We COULD sell it for $1K if we didn't want to make a profit, but we do not think the stockholders would go along with that.

MELKEN? Hint: The following quotation has been attributed to H. L. Menken: "Nobody has ever lost a dollar underestimating the taste of the American public."

This board will be suitable for:

  1. Those people who want a really big printer buffer.
  2. Those people who have all of their slots filled but still want a 68000 to play with. Printer buffers plug into slot 1, right?
  3. Those people who do not care about maximum speed, who do not need to write time-crucial software (such as a 68K RWTS) and who can tolerate an occasional bit error because of the nature of their application.
  4. The dummies who think dynamic RAM never has errors. (If they are THAT dumb, somebody is going to take their money and it might as well be us.)

WE BUILD THE DTACK BOARDS so that we can have a high quality and high performance product in which we can take pride. We are going to build the MELKENs because we have greedy stockholders. ARS GRATIA PECUNIA. Besides, our Quadram 64K print buffer gets full if a source listing has more than 1300 lines so we need a bigger print buffer.

ISN'T PROGRESS WONDERFUL? We have long had home trash compactors which will magically transform 13 pounds of garbage into 13 pounds of garbage. Now we can also have a print buffer which will reduce the time to print a long source listing from 48 minutes to 48 minutes.

OPERATING SYSTEMS:

We were certainly naive when we covered the various kinds of operating systems using only two pages in newsletter #10, including a quarter page on UNIX. Having COMPLETELY disposed of the matter we naturally had to expend another page on UNIX in the last issue.

The subject just won't go away. All one reads about in the magazines is comparisons of operating systems. Unfortunately some of those who are writing about the subject don't know much about it. What is even worse is that people are picking up buzzwords like UNIX. An Atari owner gets tired of shooting rocks for awhile and picks up a personal computer magazine which asserts that UNIX is a wonderful operating system (true) and therefore HE, the rock-shooter, wants and needs UNIX. RIDICULOUS!


Page 2, Column 1

We are sure that all of our readers are aware that BYTE magazine is the leading publication for personal computers (above the rock-shooting level). You know, because we called it to your attention recently, that NONE of those 100 vendors of stand-alone 68000 systems advertised in MICRO's special 68000 edition. You probably think that there are lots of 60000 systems advertised in BYTE. Well, there are a heck of a lot MORE that DON'T advertise in BYTE.

So where DO those other 68000 system vendors advertise? Publications like COMPUTER DECISIONS, COMPUTER DESIGN, DATA COMMUNICATIONS, DATAMATION, DIGITAL DESIGN and INFOSYSTEMS. But the flagship publication of this group, as measured by advertising pages (which is surely how we measure BYTE) is MINI-MICRO SYSTEMS. These publications are favored by those vendors who are coming after you and thirty-one of your fellow workers with chains and shackles to chain ALL of you to ONE crummy little microprocessor. The 68000 and UNIX are quite popular among this group. You will never, ever read anything in MINI-MICRO about single user systems. Well, almost never.

In their Aug. '82 issue MINI-MICRO ran an article on desktop personal computers and had to explain to their readers what these things are, we kid you not. MINI-MICRO dismisses the Apple Computer Co. as having pioneered mass marketing of small business computers (in other words, made all the mistakes) so that IBM would know how to do the job. Read Sep '82 pp 122 and 127.

We assume that none of our readers wish to be shackled to one of thirty-two work stations. Unfortunately, that is exactly what most vendors of 68000-based systems want to do to you.

In this newsletter we tell you how such nicer it is to have a microprocessor with 20 units of speed instead of one unit. In MINI-MICRO you learn how much nicer it is to market $200 million worth of workstations instead of a mere $10 million. We are oriented to the individual computer owner/operator. We are not absolutely certain what MINI-MICRO's attitude toward a PET/APPLE owner is, but we suggest that you carry an umbrella if you are going to stand on the sidewalk under their editorial offices.

Page 2, Column 2

It seems that as soon as a microprocessor is developed with minicomputer computational capability that the minicomputer boys move in and try to apply it just like the PDP11/70 was applied in the 1970s. Now can we (you and us) move up to a modern, high-performance microprocessor in a personal computer? Surely the individual computer owner/operator is not to be condemned to a 6502/Z80 ghetto?

True, one answer to those questions is a bit self-serving. But there are others, such as the SAGE (which no longer claims 2 MIPS performance in its recent ads). It does still advertise a $3995 price tag, which is true if you already own a Televideo 925 terminal and can get by with one tiny disk drive, equivalent to an Apple Disk II. But if you buy the terminal and get two floppy disks with USEFUL storage capacity you are at about $5700.

However, it appears that the SAGE system is aimed at the single user and that's us. We don't know such more about the system (would a reader contribute a review?) except the fact that the console is a terminal, which means no HIRES graphics in the Apple II sense and also means that there is no memory-mapped text; the screen will instead be filled at RS-232 rates, presumably 9600 baud. It takes two full seconds at that transmission rate to fill a 24 X 80 screen.

There are some things that one just does not give up after trying them. After switching from cassette to floppy disks one does NOT go back. After having a 24 X 80 CRT with upper-lower case with true descenders, one does NOT go back to a crude 40 column screen with upper case only (which is why this is being keyed on a CBM 8032, NOT an Apple II). And having had HIRES graphics available one does NOT give them up. There is an Apple II sitting five feet from your FNE as he keys this.

For this reason, we do not think many Apple owners are going to switch to the SAGE. It might be attractive to a CBM 8032 owner, however. If you like terminals, the Televideo 925 is an outstanding unit in its price range.

Our personal favorite prospect (we really do not have much detailed information on it) is the Corvus Concept. This is really intended as a work-station (faugh!) but it can be configured as a personal computer by adding floppy disks, taking the price to about $7000. That is NOT cheap! But it has absolutely LOVELY graphics capability: 720 by 560 pixels! In case you are not paying attention, that has the correct 'aspect ratio' so that a plot of 100 pixels horizontally is exactly as long as 100 pixels plotted vertically. We love it!

What we do not know is whether there is (or will be) a good single-user operating system and a good BASIC. Corvus has announced very little software for that machine even in its work-station guise. BUT: 720 by 560!


Page 3, Column 1

GOOD NEWS DEPT:

Motorola has fixed the 12.5 MHz bug, in engineering at least, and will be back in production towards the end of Nov. That sounds like about the time required to move new masks into production. If we assume about two or three weeks to fill the pipeline from the factory to us via distributors, we should be back in the 12.5 MHz business right around HO! HO! HO! time.

Since we get very little done between Xmas and the New Year, if you have one of our TEMP-8 boards, hold onto it so you mill have something to play with over the holidays and then send it in for upgrading early in January. If we get L12's earlier than expected, we will send individual notices to TEMP-8 board owners.

MISCELLANEAE:

IN DEC. '82 CREATIVE COMPUTING MAGAZINE there is an article on a bunch of foreign processor boards for the Apple II which includes our little jewel. We realize, of course, that none of our readers would stoop to subscribing to that rag, so go next door and steal your neighbor's kid's copy. The article is in the page 30 to 40 area.

Perhaps the most interesting thing is that Mike Coffey, C.C.'s technical editor, tried our Dtack board WITH that 3.58 MHz 6502 board by Number Nine. They worked well together and in fact that combination was by far the fastest for the benchmarks tested. Mike also reported that observers were impressed by "a three dimensional demonstration graphics program growing on the screen in real time... but nobody volunteered to duplicate it!"

FADING MEMORIES is the lead for an article from Oct. 18 Electronic News. It seems that some of the minicomputer manufacturers (our very favorite persons) are finally dropping add-on memory prices now that inexpensive 64K RAM chips are here. Wang is charging $16K per megabyte and DEC is down to $9K for one megabyte. Those are the NEW, LOW prices folks! Let's see, now: that means we should price our 5/8 megabyte board at over $5,000 just for the RAM alone and then another $500 or so for the 68000, interface board, software and documentation.

How many of you will pay us $5,645 for our 636K print buffer? PLEASE! sir, there are ladies present!

In the meantime our 10 year old Wang 2200C is getting seriously in need of being taken behind the barn and shot. Unfortunately, that would leave us with over a hundred 8 inch floppy disks filled with useful software. So we checked with the Wang sales office and sure enough they still make a 2200, with the latest version called the SVP. For $6200 we can get a single-user computer complete with terminal and two double-sided double-density 8 inch drives. One megabyte per drive, two megabytes total on line.

Page 3, Column 2

$6200 is the price with 32K user memory. To add another 32K costs another $1200!!! That's right, they are charging $1200 for 16 each SIXTEEN 16 K DRAMs! Those 16K chips are less than a buck each right now. And since their monthly maintenance fee is a percentage of the sale price, they will charge another sixteen bucks a month to maintain those RAMS. In other words, you pay $1200 up front and still have to re-purchase the RAMs each and every month!

If you want to upgrade again, this time from 64K to 128K those good-hearted people want ANOTHER $1200.

The SVP 2200 is, we believe, a 2901 bit-slice machine. The BASIC is microprogrammed, not interpreted in the usual microcomputer fashion. As a result it is a very fast machine, about 40% the speed of our 12.5 MHz board or about the same speed as Motorola's $28,900 EXORMACS. At $6200 including two big floppies it is a bargain. But those people need a mask and a gun when it comes to memory upgrades!

WAYNE GREEN WATCH: In our last issue we told you about '80micro's report that only 2000 Tandy Model 16s had been sold, and that most of those were sitting on dealer's shelves. You MAY have noticed that we did not personally endorse that report. What we DIDN'T tell you is that same issue carried numerous references to a feud that Wayne is having with Jon Shirley, who is Radio Shick's sales honcho for bit-bangers. Of course, Wayne is almost always feuding with someone.

The background for the feud with Jon Shirley is that Radio Shack does not repeat not want foreign parts/boards attached to Radio Shack microcomputers. Since Wayne publishes a magazine which features numerous advertisements for foreign enhancements there is an obvious and immediate conflict in which each participant deeply feels that HE is on the side of the angels.

But one does not really need to have a logical basis to feud with Wayne Green; ask Jim Warren for instance.

Anyhow, our sources tell us the Model 16 is selling well despite the ABSOLUTE TOTAL ABSENCE of software for the 68000. Here are the reasons: 1) The Model 16 is priced only a little higher than the Model II; and both machines sell to businesses, not hackers, go the price is much less sensitive, and besides there MIGHT be some software someday, right? 2) You can get TWO 8 inch drives in the console of the 16 but only ONE in the Model II. This provides a VERY strong incentive to buy the Model 16.

Page 4, Column 1

In any event Tandy's small computer sales climbed from $369 million to $624 million in its fiscal year which just ended. And they say that the Model II and the Model 16 accounted for over a quarter of that, or $160 million. Sounds like more than 2000 Model 16s to us! (Now if only the 68000 in all those computers could do something useful ... )

SCHIZOPHRENIA DEPT:

You may have seen a mention on page 476 of Oct '82 BYTE of a 68000 board by a company called Intellimac. The board is called the MAGNUM 68. The product release stated that it has a 6MHz operating speed, 8MHz optional. Optionally available is an EPROM-resident extended BASIC. 256K DRAMs and Pascal are also available as options. The price for the board and a manual is $745.

The very same company has a full page ad which is running in several publications. We have seen it in one of the electronics hardware mags, EDN we think, and it can also be found on page 46 of Sep '82 MINI-MICRO (how in the world are they going to tie 32 users to that little board?). This advertisement mentions no software except the monitor/debugger which is MACSBUG flavored. The advertisement asserts that the system uses a 6MHz 68000 and cases with a 100+ page manual.

The first product release we saw in trade journals listed the board at $895 (as we recall). When we saw a product release several weeks later for the same board at $745 we decided to take a look-see and arranged for another small company to purchase one for us. Delivery was prompt. Since we HAVE one of these boards, let us tell you about it.

First, the construction is absolutely superb. We cannot ever recall seeing at first hand a product in the personal computer field with equivalent quality. It is a four-layer board and the layout was clearly done using a CAD program and digital platter. The LSTTL parts are hard-soldered to the board and the MOS LSI parts are socketed. The board is obviously designed for automated production. There is no evidence of hand workmanship on our board.

The shipper which arrived with the board stated that the board was serial number one. On the bottom of the board was a paper sticker (Avery label variety) which was almost falling off. The sticker explained that the board was serial number 2 and that the warranty was void if the sticker was removed. There was a 100 page manual which uses large print, lots of double spacing, lots of white space and large illustrations. Page 15 has three lines of print.

Page 4, Column 2

On page 14 we find the following statement:

SYSTEM CLOCK: 8-MHz crystal providing 4-MHz processor operations.

The board they shipped us, whether serial number 1 or 2, has an 8MHz crystal which provides a 4MHz clock signal to pin 15 (CLK) on the 68000, which is a Hitachi HD68000-6. See, they're telling the truth about using a 6MHz CPU in their full page ad. Sure wish it ran at 6MHz. It does have 128K of DRAM. Oh, yes: the board is not expandable in any way.

The board can communicate with a host computer via RS-232 at a maximum rate of 9600 baud, or about 1000 bytes per second. This compares to a data transfer rate of 71,000 bytes per second for our DTACK board, and that is a host-cpu limitation. However, those persons who criticised our board early on will love the Magnus 68; it has TWO RS-232 ports!

The introduction to the manual states that "The 68 MAGNUM has been developed as... an educational tool... ." It certainly will be educational! The board comes with absolutely NO demonstration or utility software listings. Although there is that MACSBUG look-alike in EPROM(s), no listing is provided for that monitor. The user is TOTALLY on his/her own.

Those advertised descriptions do not appear to match the board that we have in hand in all respects. But if you have $745 to spare you can buy a fantastically well made 68000 board which runs somewhere between 4 and 8 MHz and which comes with absolutely no software.

Would the real MAGNUM 68 please stand up?


We got into a very childish "my old man can lick your old man" argument with the vice-president of a software house back on the east coast the other day. Each of us was asserting that his respective company would be absolutely the FIRST to introduce working hardware coupling the National 16081 math chip to the 68000. Which is very interesting because we are a hardware manufacturer but the software house has NOT been, up to now. The vice president dropped a couple of hints that eight lead one to believe that they are working on something close to a TRASH 68, which as you will recall is what we think this industry badly needs.

If that software house really brings out a TRASH 68, or does the level 1/3 BASIC and crummy operating system for a manufacturer of a TRASH 68, we will have to apologize for saying we could hit the market with hardware first. Even if it's true.

And is it remotely possible that there is a connection between the software house and Intellimac?

Page 5, Column 1

ASM BUG REPORT:

The six instructions 'XXXI' (e,g, ADDI) do not assemble correctly using our utility program 'ASM', alias 'Hand Assembler's Helper'. In the Apple version, shorten line 2210 by adding line 2212 and move the last three statements in line 2210 to this new line. Then retype line 2210, inserting "L1=L:L=0:" after 'GOSUB 310:' (but less the three statements which have been moved to the next line).

The fix for the Pet version is the same, except that it is line 2260 which must be changed, inserting "l1=l:l=0" after 'gosub 400:'. First move the last three statements to new line 2262 since this addition will make the line too long for the screen editor.

We have known all along that 'MOVEP' is not implemented. That instruction can't be used with the DTACK board, so we left it off on purpose. We have just now learned, thanks to a diligent reader who has written us TWICE, that we overlooked 'LEA'. He also informs us that the printer option does not work with some variations of the 'MOVE' instruction. Since there are thousands of variations, it would help if he was a little more specific.

(We vigorously deny his assertion that we do not power up our boards before testing them. He was referring to the report of the wire stuck under the sockets. What happened was we had a number of tested boards with various memory sizes racked on their side in a 'desk organizer' located in the production area. A cut resistor lead flew into the air and fell on the board just right (?) to stick under the sockets. When the order came in for that size board, we shipped it.)

Of the various forms of the 'decrement and branch' instruction, the only one we implemented was 'DBF'. This oversight on our part was originally pointed out to us by John Martellaro of Peelings II magazine.

According to a letter from Oliver B. of Hamburg, W. Germany the MOVE (PC)+d and MOVE (PC)+R+d addressing modes do not work. Either Oliver has a VERY old copy of program ASM or he is confused over source versus destination addressing modes. While ALL addressing modes are legal as the source operand for instruction MOVE, only data alterable addressing modes are legal for the destination operand. See page 133 of Motorola's User Manual (3rd Edition) or page B-45 of the 2nd Edition.

Page 5, Column 2

WATCH THOSE GOTCHAS!

In the last newsletter we said that ADDQ and SUBQ work with address registers as well as data registers. That happens to be true. We also said on page 5 that DO SOMETHING, SUBQ #1 An, BNE DO SOMETHING will work. According to the 2nd edition of the User Manual that's true. See page B-80. Unfortunately, when we tried code like that recently it didn't work. After three hour's wrangling we thought to check the 3rd Edition. Page 174 tells you that the flags are NOT set after a SUBQ. Not only that but after a SUBQ.W #x,An the result will be sign extended into the upper 16 bits of the address register.

Mind you, ADDQ and SUBQ DO work with the address registers, but it is important to know exactly HOW they work. So go out and get a 3rd Edition if you do not already have one.

You can't believe everything in the 3rd Edition either. See the bottom of page 188 where it states that (for TST) a size field of 11 = long word. Uh uh, try 10 = long word instead. (We forget who called this to our attention.)


MORE BUGS YET: For you Apple types, there is a bug in UTIL4 sent out in update #3 that we have just identified. The problem is that three groups of three bytes each are in reverse order. Make these changes in text file U4.S using DOS Toolkit's editor:

 line 134:  DFB $A0,DB
      135:  DFB $A9

 line 146:  DFB $EB,$21,
      147:  DFB $20

 line 149:  DFB $48,$A2
      150:  DFB $A5 

Now we need to modify working binary file "UTIL4". Load program "SETUP"; make sure line 20 loads UTIL4, and run the program. This places the binary file in memory. If UTIL4 is locked, unlock it.

Enter the monitor using CALL-151. Modify the three locations by typing these lines:

 8EBB: A0 DB A9 (RETURN) 

 8ECF: EB 21 20 (RETURN) 

 8ED4: 48 A2 A5 (RETURN) 

THE SPACES IN THOSE LINES ARE VERY IMPORTANT! Return to BASIC by keying 3D0G (RETURN) and key in this line:

 BSAVEUTIL4,A$8600,L$1000 

Page 6, Column 1

Finally, lock the file if you wish.

What these bugs would do if not fixed is trash the EXP, TAN and ATN functions IF you had first linked into the Applesoft floating point routines by first CALLing 38383 and THEN de-linked back to the 6502 by CALLing 38380. The bugs are in the de-linking code.

Since we thoroughly tested those routines by comparing the results against the Microsoft calculations for the same random operands, how did this bug sneak through? We performed those tests on our CBM 8032. With an 80 column screen and a screen editor (you Apple types don't know what you are missing) it is MUCH easier to debug 68000 code than on the Apple where every program line must be re-typed in its entirety!


One of our readers has committed the horrible mistake of asserting that your FNE exhibits evidence of literary ability. This is such like telling a 14 year old girl that she is a great actress! So, all of you will have to bear the consequences: following is our brief (thank heavens!) outline of The Great American Novel, silicon gulch variety.

Let's see, now: a novel requires sex, violence, conflict and some other stuff that we forget for the moment. So we start the novel off by telling about this wonderful personal computer firm that started in a garage. You easterners who wonder why those computer firms never start in a basement are advised that there ARE no basements in California. Where were we?

Oh, yes. Well, these two guys start up this personal computer firm and build it up until the sales are quite a few million bucks a year. But one of them has started an affair with the other's wife, and gets caught in flagrante delecto by his partner with permanently fatal results.

In Texas that may be legal grounds for killing off your partner but California has a more laid-back life style and the D.A. puts a warrant out on the guy. He sensibly splits permanently for Peru after cleaning out his various bank accounts. The two wives are not technical types and they sell out to a conglomerate which re-names the outfit the ACME Computer Co. and the wives prepare to spend the rest of their lives clipping coupons in the beauty parlor. All this stuff happens in flash-back format and the story really starts after ACME takes over.

But it gives us a swell shot at some sex and violence right at the start of the book so browsers will get hooked and take the book home. Look, you can sell the 1949 Gdansk telephone directory if the first five pages have some steamy sex scenes.

Page 6, Column 2

It turns out those two guys had designed a dynamite computer and sales continued to climb rapidly for a couple years after they departed (one for Peru, the other's destination questionable but the possibilities heavily weighted considering the circumstances). After a while the new managers look around and start talking about designing a computer themselves; they aren't getting any respect from their peers (the Honchos of the other computer makers) by making big dough off those two guys' design.

The new managers announce to the world that the world's absolute greatest ever personal computer will be forthcoming from the ACME Computer Co. and that you had better believe it. So they set up a 40 person design team and gave them the word to fulfill that claim. So those 40 guys set to work. (Linda, you will not mind the inference that they were all sale type persons when you see how this comes out.)

They made this computer which, when you pushed the integrated circuits into the sockets, the sockets popped them right back out again. They cleverly designed the package so that there were two completely enclosed areas, as in completely enclosed within an aluminum casting so the air could not move. Now, fiberglass and foam are excellent thermal insulators because they trap lots of air so that the air can't move. When air doesn't move the heat doesn't move either. So there they had this computer with parts that normally run hot such as bipolar ROMS and PLAs and such locked into completely enclosed compartments where the air couldn't move. And they were surprised when the parts overheated and the computer would, forthwith, fail. They built an emulation mode so that the wonderful new computer could run software written for the old computer which was not designed by ACME engineers. Naturally, the emulation mode did not work. Oh, yes: they built in a real time clock which, of course, did not work.

So when the world's absolute greatest ever personal computer was released to the public it drew, well, mixed reviews. Actually, they weren't mixed reviews, they were all negative. Actually, they weren't negative, they were... you get the idea.

Back in the board room at ACME there was a meeting at which much spleen was vented (how does one vent spleen?). A resolution was introduced which stated clearly that the fault was not at the high executive levels within ACME management (it passed unanimously). The vice president in charge of production suggests that those engineers who made serious design mistakes be identified and terminated. They would then be replaced by competent types who would rectify (dirty word? check dictionary) the problems.

Page 7, Column 1

The V.P. marketing points out that it would be a shame to blot an engineer's reputation for life by identifying his as personally having made a serious mistake. It would, asserted the V.P., be much more humane to simply terminate all 40 of the development team responsible for the debacle and concomitant dimunition (check the vocabularity!) of the reputations of the upper management of ACME. So that's what they did.

They brought in new engineering talent which put bandaids over some of the problems, fixed some of the problems, and ignored some of the problems as insoluble.

This being sort of accomplished, ACME management split up the new talent, added to it, and began development of not one, not two, but THREE more world-beaters. Time passed, monies were spent and prototypes and production prototypes and pilot production runs ensued (came forth? were constructed? make note to hire ghost). The upper aelerons of ACNE management anxiously waited for word that these new products were ready for introduction. And waited. And...

Well, that word just never came. So the V.P. R & D personally descended from the board room to ascertain the nature of the difficulty, if any. At each of the three groups he discovered that the software was not thoroughly debugged, life testing of the hardware was underway but was incomplete, and well, like that. Since each group had had much more time than needed to do the job, this proved puzzling. So he reported back to the board room that the new products were not ready for introduction. Which they knew already.

Several months passed and the V.P. R & D was sent forth to see to it that those products got introduced immediately! The development groups reported that tests were incomplete. One group pointed out that they were almost certain that a 7400 NAND gate could turn into a NOR gate under certain conditions and that they were exhaustively testing to confirm or disprove this hypothesis. In other words, the development groups were foot-dragging, obfuscating and stonewalling.

Why were the development teats doing this, you may ask? Because they were logical per, um, because they had learned from hist, ah HERE'S the reason, dammit: One of the development group leaders had studied the mistakes of the first engineering group. Here is what he deduced:

  1. Before the new product was released all of them had jobs.
  2. After the new product was released none of them had jobs.
  3. The reason they lost their jobs was that the product was released.

Page 7, Column 2

This group leader discussed the situation with the other two team leaders. They:

  1. Agreed that none of their new products had been released and noted that they and their teams were still employed.
  2. Agreed that this could be a coincidence.
  3. Agreed that termination of employment was not necessarily imminent upon release of their new products.
  4. Agreed that, nevertheless, 100% (1 out of 1) of all of the new product development teams which had released their new design under present ACME management had been terminated en mass.
  5. Agreed that they each and severally had orthodontist's bills and mortgage payments to meet and various and sundry other bills to pay and that the other team members, which they were really thinking about of course, had bills to pay too.
  6. Agreed that under conditions created entirely by present ACME management that releasing their new products would be foolhardy to say the least.


We are kind of stuck at this point in our plot since it seems that ACME management is going to have a strong desire to release something to appease the stockholders and their retail outlets and their stock analysts and enhance their prestige in their peer group and... you get the idea. And the poor engineering groups still have those orthodontist bills to pay. And so nothing is being released which doesn't make sense since the boss is the boss or isn't they?

As soon as this little glitch in the plot gets cleared up we will submit this outline to the more prestigious publishers and begin the first actual draft as soon is we get our $500,000 advance. And all of you will be pleased to be able to say that you read your FNE's work back before he was rich and famous.

What's that? You say that is the dumbest way to run a company that you have ever heard of? Look, pal: novels are FICTIONAL, and this is a novel. If novels were written like real life they would bore you to tears.


Maybe it was the pepperoni pizza, chili and ice cream but against our better judgement we have finally written something sort of related to software piracy in the next two pages. If you have any sense at all you will skip those next two pages. (If we had any sense at all we would have taken a cold shover instead.)

Page 8, Column 1

ETHICS AND COMMERCE:

A possible application for our (eventual) 68008 Apple board would be as a supercharger for the popular electronic spreadsheet. Now, that particular program is locked and it ALSO uses its OWN floating point package. So our standard utility won't work because it speeds up the Applesoft floating point but that program does not use Applesoft's floating point.

Which means that we need to be able to 'unlock' that software package to identify the floating point package format and the entrance points to the various routines just as we have done for the Apple and Pet. Do we then provide the software package with those modifications? No, we do not own that software and we cannot sell it or even give it away. What we CAN sell or give away is the modifications themselves along with the 68000 code to enhance (speed up) the package.

Naturally, it is extremely difficult to break a locked software package. Ahem. Like you, we have NEVER, EVER heard of something called an NMI. But there is an easier way.

You see, we intend that the 68008 card have DMA capability (which the big DTACK board doesn't). If you have DNA capability you can load any locked software whatever into the Apple and let the DMA device read it out! There are various ways to store the code; we had in mind sending it via (emulated) RS232 to a second processor. Emulated means that the timing of the signal is RS232 but the connector does not have 25 pins and the signal swings are TTL.

We would then provide the 'hooks' to the electronic spreadsheet program pretty much in the same form as our existing enhancement code. Except that the modifications would be done via DMA without the 6502 knowing what had happened.

The ethical problem we were having was, do we tell people how to do this? The possibilities for mis-use of the technique are apparent. We don't think what WE had (have) in mind is unethical because the user would still have to have the locked disk to run the enhancements provided by our 68008 board. But the same technique can obviously be used to unlock various rock-shooting games.

We need not worry about informing you of this technique because the Oct 11 issue of INFOWORLD carried not one but TWO advertisements of products which are specifically designed to 'unlock' locked code via DMA. They have gone one step further in that the devices save the code directly back onto unlocked disk in DOS 3.3 format. So no second processor is needed. (We have LOTS of processors; the use of two processors is not disadvantageous to us!)

Page 8, Column 2

Please understand that we are talking about hardware devices which plug into one of the Apple's I/O slots, NOT just a software program. The first ad was a quarter-pager on p. 28 for "CRACK-SHOT, The Ultimate in Copy De-protection." The ad goes on to state that it even "...cracks all bit copiers in fifteen seconds." Now, THERE is poetic justice. CRACK-SHOT will even unlock those locked 'unlocking' disks!!!

The other ad occupies ALL, would you believe, of page 47. This one is WILDCARD. After carefully explaining that WILDCARD will un-protect ALL repeat ALL 'locked' (6502 variety) software, the advert concludes with the admonishment that you are to use this ONLY for the completely legal purpose of providing archival and backup copies of your locked software. "...and you are not permitted to utilize it for any other use, other than that specified." Hmmm...

We will either develop our own technique or else buy one of these two devices for our own use (one is $150 and the other $130). The fact is that as a businessman your FNE definitely does NOT like not having a backup copy of important software for which we have paid. Sending off the defunct disk (with a usually negligible fee) and hoping for fast turn-around and hoping that the producers of the software have not gone out of business does NOT appeal to us. We want a back-up copy right there where we can get our hands on it, NOW!

In our opinion, this is an ethical viewpoint. There is absolutely no questioning the fact that, under the new copyright law, it is LEGAL. Regrettably, what is ethical is not always congruent with what is legal.

We can be certain that the suppliers of that locked software will disagree with us.

We can also be certain that the presence of those two hardware products are going to move the 'locked disk' war (Apple section) to the next higher level. Let's face it, many Apple user groups exist only to distribute ripped-off software. Any user group can pass the hat and come up with $130-$150. Makes us glad we made the decision to go with unlocked demo software.


REMEMBER THE 'OSBORNE ONE'? That's the computer which, for $1795, you get (as we recall) the computer plus $1800 worth of free software.

Page 9, Column 1

DO NOT REVEAL THIS SECRET:

(whispered) The Osborne Co. does not really pay $1800 for that software that they give away with the $1795 (retail, not wholesale) computer. If we assume their dealer margins are 25% (they may be more or less) than Osborne wholesales the computer AND the software for about $1350. What Osborne is paying for the software over and above the cost of printing the manuals and copying the disks we don't know, but we would guess it is probably at least $50 but almost certainly not as great as $125. Let's try $80, and assume the repro cost is another $45 for all those packages. (Adam, if these figures are so far off that you get angry, just provide us with the correct figures and we will publish them!)

Assuming our figures are correct, this means the purchaser of an Osborne computer is getting, for $125, software that YOU will have to pay $1800 list for! Since there are lots of places where you can find discounts off the list price of that software we will assume that you are clever and have obtained a 30% discount so you will have paid $1260 plus sales tax.

This means that the software producers (and their distribution chain including but not limited to the retail store) want YOU to pay $1215 ($1260 -$45) above the media cost but they will sell to the Osborne Co. for only $80 over the media cost. Which means that either Adam is stealing them blind or that YOU are being shafted for $1135! If you prefer, you can think that you are being charged 1,419% as such as Adam, after the cost of the media is deducted.

We are not absolutely certain but we think this is what is called a two-tier pricing structure.

Let us break this down a little further. We will assume that one of those software packages provided 'free' with the Osborne One retails for $350 list. Assuming that the software producer's share of the total package is proportionate including the media cost, that producer is accepting $15.56 from Adam after media costs are deducted. Assuming a 50% distribution discount, he gets $175 less media cost of $8.75 or $168.25 above the cost of media.

TRY THIS SCENARIO: Ten impecunious college professors (is there any other kind?) band together to purchase one copy of this software package. They then make nine copies so that each of them can use the software on their ten separate computers. We will suppose further that the software producer not only finds out about this but obtains irrefutable proof, acceptable in court, of the professors' actions. Now what?

Now what? is probably either a lawsuit (we've got to make an example of these rotten thieves) or the threat of a lawsuit and most certainly some foaming-at-the-mouth letters to various editors in the style pioneered by Microsoft's Bill Gates.

Page 9, Column 2

What is the terrible, illegal, unforgivable thing that those ten profs did to the software producer? Each of them paid the producer $16.82 above the cost of the media for his software. That's $1.26 MORE repeat MORE than the producer happily sells the same package to Adam for!

Our legal system unquestionably permits the establishment of two-tier pricing, even when the two tiers are as ridiculously far apart as in this example. That's ONE of the reasons we stated earlier that 'legal' and 'ethical' AIN'T congruent!

Some of the problems those software producers are having is a direct result of their ridiculous, irrational, greedy (and in our opinion unethical) pricing posture.

You don't like the figures we used? Plug in your own. You will come to the same conclusion we did.

You think the problem is limited to the few software suppliers dealing with Osborne? No, others such as NLS (and their KAYCOMP) and Morrow Designs are making essentially identical deals with other software vendors.

Look, we believe in the free enterprise system. Let those software vendors set whatever price they like and live with the resulting sales figures. But DO NOT sell a package to someone else for $15.56 and then offer it to US for $350. We are likely to get (you know what!). SURE IT'S LEGAL! But it is unethical as hell.

A company called J.R.T. wrote a CP/M based PASCAL and offered it for sale at $300. A few months later they had sold maybe two or three dozen copies, whoopee. So they (disgustedly?) offered the package for $29.95. Presto! They had about 40,000 sales almost immediately, and they are apparently continuing to sell well because you see full page ads in BYTE and INFOWORLD for that package. Subtract $8.00 media cost from 30 bucks, multiply times 100K+ and subtract 30-50K advertising costs, pay the rent and the front line troops and what do you have left? You figure it out.

For 30 bucks the package can't be any good, right? According to a professional systems-level programmer, it is a very good and very well documented packages and the best CP/M PASCAL available for short programs!

NOT INCIDENTALLY:

We at Digital Acoustics have taken no little amount of flak, especially from retailers, over our 'one price to all' policy for our DTACK GROUNDED line of products.

And we trust that all of our readers are aware of the per copy cost of publishing 10,000 manuals versus making one copy of a disk on demand.


Page 10, Column 1

MORE iAPX 286 STUFF:

Back in newsletter #10, we briefly discussed the impending iAPX 286, hereafter called the 286. That was a prediction not a report because there was relatively little information available at that time. We can now present a report.

AVAILABILITY: Some working parts now exist and in fact working circuit boards also exist; our local Intel representative states that some companies, specifically including Microsoft, have a board. We believe that. However, the status is currently that of 'limited sampling'. That means Microsoft can get one, General Dynamics can get one, but Digital Acoustics will have to wait for awhile.

When new processors are in the limited sampling stage, they often have a few minor glitches. This is normal; the Z8000, 68000 and 8087 all had glitches during this phase. One reason for 'limited sampling' status aside from an actual shortage of wafers is that companies naturally do not like to publicize these problems.

As we recall, the 68000 reached 'limited sampling status' around Feb '80, so the 286 is about 20 months behind the 68000 at this stage. The 68000 in turn was about two years behind the 8086.

PRICING: The 286 is a VERY large chip. According to sources at a competitor, they can only get 40 die on a 4 inch wafer, and at that die size the yield will only be one or two good parts per wafer. And that means that the price will be high.

On the other hand, Intel is now asserting a price of $237, quantity 100. We caution that Intel's prices are not cast in concrete (whose ARE, in this industry?). 8087 prices, predicted and real, have gyrated wildly.

ARCHITECTURE: We had thought that Intel would have added new registers or extended the length of the existing 8086 registers but they did none of the above. In fact, the 286 can best be described as a very modern and high performance memory management chip which, almost as an afterthought, happens to have in on-board microprocessor.

As a result the 286 is spectacularly superior to the 68000 in certain specific areas and spectacularly inferior in others. If you think this means that it is difficult to directly compare the performance of the two units you are wrong. The fact is, it is IMPOSSIBLE to directly compare the two units!

Page 10, Column 2

MEMORY MANAGEMENT AND PROTECTION: The 286 has more sophisticated memory management and protection than any microprocessor (by far) and, we think, than any extant 16 bit minicomputer. For instance, the 68000 has two levels, supervisor and user. The old PDP 11/45 had/has three levels, the highest called the 'kernal'. The 286 his FOUR levels, we kid you not. You will have to get a top secret security clearance before performing a register-to-register add.

The four levels are called 'kernal', 'system services', 'custom extensions' and 'applications'. In addition to these vertical levels of protection, there is also HORIZONTAL protection between tasks! Yes, this is absolutely an ideal multi-tasking system which can use its memory management unit to isolate each user into his or her own segment. THAT SEGMENT MUST BE 64K BYTES OR SMALLER!

ADDRESSING: You will find this hard to believe but with a chip with very nearly DOUBLE the number of devices as the 68000, the maximum linearly addressable memory is 64K bytes. This is for a high performance chip appearing commercially at the SAME time as 256K X 1 dynamic RAMS. Which means the minimum memory size that can be built using one row of sixteen each DRAMs is 1/2 megabyte. Which means the 286 can address that much memory only by using at least EIGHT different segments.

You should also keep in mind that 1 meg DRAMs will appear in about 2 1/2 years, at which time full production shipments of computers using the 286 will just be beginning. The minimum size memory that can be built for the 286 using 1 meg X 1 DRAMs is 16 megabytes, just enough to assign 256 users to his/her own 64K segment. The 286 is fast but it is NOT fast enough for 256 users!

We think restricting the 286 to 64K linearly addressable memory is a mistake, but then what do WE know? Besides, it was probably something that was forced on Intel to maintain downward compatibility with the 8086 and the 8080.

PROMOTION: Intel has begun an advertising campaign which asserts that the 286 is a whole bunch faster than an 8MHz 68000 with memory management. That happens to be true. Let us make an analogy:

Suppose that you are in the market for a motor vehicle. Which should you buy, a Porsche or a stake-bed truck? If you are having troubles making a decision between the two then you have REAL TROUBLES, and we do not mean selecting-a-vehicle type trouble.

If you need to transport 32 sheep from a railroad siding to a lamb chop and mutton factory, you will definitely want to use the stake-bed truck. If you want to transport a friendly-inclined personage of in opposing gender to your pad, surely the Porsche is more appropriate.

Page 11, Column 1

The Porsche is, of course, no other than our old friend the 60000. It is ideal as a spiffy high performance CPU with a huge memory space for one user. The stake-bed truck is the 286, which is ideally suited to accommodate 32 sheep, providing up to 64K RAM for each critter.

WE WERE TELLING THE TRUTH when we said that it was impossible to compare the two devices directly. Instead it should be immediately obvious to the most casual observer that one or the other is best suited to the task at hand. If you prefer the 286 we have this one little question:

Are you going to drive the truck or ride in the back?


While it is impossible to accurately compare the 286 and the 68000, it IS possible to compare them in a SPECIFIC application. In fact, this is exactly what Intel is doing in their adverts - comparing them in a multi-user multi-tasking memory managed and protected environment. Surely you do not expect Intel to publish ads in which the 68000 wins?

So let us compare those two devices in a very simple single-user single-tasking environment such as that favored by us. (Again, such a comparison is unfair to Intel because they did not design the 286 for such an application.) Even in such a clearly-defined circumstance it is difficult to compare the two devices. Consider the following:

  1. The 286 is vastly superior to the 68000 in string handling within a small memory space. Small means under 64K. The reason is that the 286 has microprogrammed string instructions and the 68000 does not, at least not now. Space HAS been reserved in the instruction set of the 60000 for microprogrammed string instructions, but who knows when they will be implemented?
  2. The 286 is significantly faster than the 68000 when performing a 16 bit register to register add.
  3. The 60000 is significantly faster than the 286 when performing a 32 bit register to register add.
  4. The 60000 is vastly superior to the 286 when working with 32 bit (or longer) data in a large memory space. Large means over 64K.

    Review the data above and tell us which is the better part for our simple application. WE can't decide, assuming the decision is to be made on performance alone. As it happens, there are other factors to consider:

    Page 11, Column 2

  5. Nobody who has worked with a microprocessor such as the 68000 (or the 16032) with a large directly addressable memory will ever willingly get trapped into 64K segments again. The personal computer users who switch to the 286 will come from the ranks of the 8080, Z80, 8085, 8088 users.
  6. Nobody who has been using the various '80' machines and therefore HAS A SUBSTANTIAL BASE OF USEFUL ASSEMBLY CODE ROUTINES will ever switch to a non-software compatible machine such as the 68000. Besides, these people are accustomed to bank switching. It is a fundamental law of nature that one must segment switch to obtain access to a large memory space, no?
  7. Nobody who has ever programmed a nice clean machine like the PDP 11 series or the 68000 will ever willingly switch to the convoluted and obscure programming methods needed in the '80' world. Even experienced 6502 users will find a natural affinity with the 68000, even though the 6502 is such less 'natural' to program.
  8. We therefore conclude that no one who is presently in the '80' camp will select the 68000 over the 286, and vice versa. It's the old Apple-Radio Shack story all over again: Those are two separate worlds and never the twain shall meet. And please do not point out that the Tandy 16 uses a 68000, it does not either USE the 68000!


An idle thought: we wonder who would be stupid enough to take a processor selling in the $200-$400 range (like the 286) and sell it into a simplistic application such as a simple attached processor for the IBM PC?


WHEN IS AN EXTENSION A RETRACTION? When we have the 80287, which is an 'extension' of the 8087 for use with the 286. You see, the 8087 has its own addressing modes, including memory direct. It is necessary to restrict the addressing modes of the 80287 to those which are filtered through the 286s' memory management scheme. Which means the 80287 is an 8087 with some addressing modes deleted. Which means it is a retraction, NOT in extension. Just thought you'd like to know.


IF WE WERE NICE PEOPLE, we wouldn't write what follows: although we have agreed up to now that the 68000 is also an appropriate vehicle for enormously complex systems as well as simple systems such as the ones we favor, it may be time to back away from that agreement. National has actually begun to ship 16032s (our local National distributor has moved "at least four" over the counter to real customers) and limited samples of the 286 exist AND samples of the 68010 either exist or are about to. And all three of those are better computing engines for enormously complex systems than the 60000.

Page 12, Column 1

The reason they are better is the built-in multi-tasking 'hooks' that are missing in the 68000. At least one of them, the 68010, is actually FASTER slightly) than the 68000. And the 286 is faster in some applications.

BUT: the 68000 is beginning to look like what we have been calling it all along: the logical successor to the 6502 as the new generations' fastest and cleanest, as in cleanness of programming, personal microprocessor. Personal as in single-user single-tasker. AND YET: Motorola continues to sandbag and promote the 68000 for complex stuff only. Sigh.

Either Motorola is awfully stupid or we are wrong in our viewpoint (and hence awfully stupid). Since Motorola has hordes of very smart technical types obviously we must be the ones who are wrong, right?


WE HAD PLANNED to publish a list of all the companies offering computers which meet the following three criteria:

  1. Have a 68000 as the main computing element.
  2. EITHER support real Bell Labs UNIX, and have a 10 meg or larger disk to prove it,

    OR support a genuine UNIX look-alike which runs on an 87K floppy but is, no lie, almost completely compatible with Unix.

  3. Are not meeting their sales projections for some unknown reason.

HOWEVER, we decided not to print the list since the press run would bankrupt us. Instead, we are publishing our matrix routine, which now works, along with the 6502 utility code and the Applesoft program listing AND the complete source code of the double precision floating point package. All 62 bits of it.

(About fifteen months ago we were urged, by two different Motorola types, not to give away our floating point package or sell it ridiculously cheaply. Instead we should sell it for $750 to $1500. We were informed that the 68000 was really a minicomputer and that 68000 software should be sold for minicomputer prices.)

(That attitude has resulted in the present lack of software for the 100 or so different brands of 68000 desktop computers.)

Page 12, Column 2

THOSE TOSHIBA RAMS AREN'T AS RELIABLE AS WE THOUGHT! Our new memory test has actually found a few bad 2016s. It looks as if the failure rate is about 1 in 1000, so if you have a 92K DTACK board, there is about one chance in 20 that you have a bad RAM chip. And to think that the motivation for writing that new, better memory test was to check 'bit pattern sensitivity' in our forthcoming dynamic RAM board!

The nice thing about static RAM is that when it is good it stays good and when it is bad it stays bad. Be sure to run your memory test at the highest operating temperature the RAMs are likely to encounter. Which means toward the END of a working day, not at the start.

THE PROJECTED DELIVERY of the dynamic RAM board is about FEB 1 so it will naturally be a couple of months later. Remember, this is our FIRST dynamic RAM product, so development will not be as simple as our other boards. Besides, we want to do everything we can to assure that it is compatible with the new 256K DRAMs.

If we do manage that compatibility, we will have a very nice 2 1/2 megabyte printer buffer on one board,

LATE NEWS FLASHES:

HEWLETT PACKARD has just shot down LISA. The new 68000-based Series 200 model 16 costs $3650 less disk drives. That is less than half LISA's price. For $3650 you get an 80 X 25 CRT display which also supports 400 X 300 HIRES graphics, 128K RAM (expandable to 768K) and a detachable keyboard. For another $1775 they will throw in a dual 3.5 inch floppy, 270K per disk. The disk rotates it 600 RPM, double the usual floppy rate. We will probably buy one to play with.

BY THE WAY, when we arrived at work on 9 Nov, there were two NEC 7220 graphics controller chips on our desk. At $120 each, we obviously purchased them for use as paper weights. For those of you not in the know, the 7220 can draw lines, arcs and circles at 800 nanoseconds per pixel. And it directly supports a 1024 X 1024 display with up to 4 bit planes.

THE FOLLOWING TRADEMARKS ARE ACKNOWLEDGED: Apple, II and soft: Apple Computer Co. Pet: Commodore Business Machines. DTACK GROUNDED and HALGOL: Digital Acoustics, Inc.

SUBSCRIPTIONS: You can subscribe by sending $15/6 issues U.S. and CANADA or $25/6 issues elsewhere. Tell us which issue number to begin with. Make the check out to DTACK GROUNDED. The address is:

DTACK GROUNDED
1415 E. McFadden, Ste, F
SANTA ANA CA 92705

Page 13, Column 1

IN THIS MONTH'S UNCOPYABLE REDLANDS we have (in reverse order) a 62 bit floating point package that works, a matrix inversion routine in 60000 assembly language that works, the 6502 machine code that transfers the array to the 68000 and then fetches the inverted array back AND a sample (and very simple) Applesoft program which can utilize the code.

There are some things which should never be done for the first time, such as riding a bicycle, writing a floating point package, a transcendental package or (and here we get relevant to this issue) a matrix inversion program. The matrix inversion printed here is our FIRST. Any criticism will be both unkind and valid. We didn't even do any 'pivot point' nonsense. In our defense, we will point out that we wrote for advice to two of our subscribers who know more about this stuff than we do, but we have not yet heard from either Ted or Charles.

IN THE MEANTIME, we sent out a half-dozen floppies as soon as we had the program essentially working. We mailed them on 5 Nov and received feedback from two sources within two working days. Bill J. reported that a very well conditioned 77 X 77 matrix was inverted on his 8MHz Dtack board in 50 seconds. That is equivalent to 70 sec for a 100 X 100 matrix using a 12.5MHz Dtack board. His test matrix was the 'minimum of I,J'. That is, A(3,7) = 3 and A(51,14) = 14.

Bob P. reports that a 40 X 40 matrix of random numbers inverted in 3 minutes 9 seconds using Ampersoft and in 10 seconds on his 12.5MHz Dtack board. That is equivalent to 156 seconds for a 100 X 100 matrix.

Page 13, Column 2

The reason Bill's matrix inverted twice as fast as Bob's is that the 'very well conditioned' numbers he used feature mantissas with lots of zeros, and that runs such faster than a matrix featuring random data and therefore random bit patterns in the mantissa.

And the reason for equating to a 100 X 100 matrix is that it requires one million multiplies and one million additions to invert that size matrix. Therefore, a 156 second inversion time means that it takes the 68000 156 microseconds to perform one addition and one multiplication plus the required data movement. And that is a VERY interesting number since it takes the Intel 8087 about 90 microseconds to perform the same two operations, 27 microseconds of which is the time required to load three numbers and 20 of which is the time required to store the result. This means the 8087 is faster than the 68000, right?

WRONG AGAIN, GUYS! To perform a matrix inversion using the 8087, one needs TWO processors, one of which is an 8086 or 8088. And these two processors will set you back several hundred dollars. Therefore they should be fairly compared to TWO 12.5MHz 68000s!! And those two 12.5MHz 68000s can run almost exactly twice as fast as one when performing matrix inversions. So it requires the 8086 and 8087 90 microseconds to perform the same number-crunching task that the 68000 and the 68000 can perform in about 79 microseconds.

(We will now sit back and wait for an indignant letter pointing out that the 8087 calculates using a 52 bit mantissa while OUR double-precision floating point package uses a mere 48 bit mantissa.)

Oh, yes: a 92K Dtack board is big enough to invert a 100 X 100 matrix with double precision (8 byte per number) format. And two 12.5MHz 68000s cost less than an 808X/8087 combo.

Code Listing 1

100  HOME : TEXT :P = 38383:Q = P - 102
110  PRINT CHR$ (4);"BLOADUTILXM,A$7F00"
120  INPUT "INPUT N (SIZE OF MATRIX) ";N
130  DIM A(N - 1,N - 1): REM N X N MATRIX
140  FOR I = 0 TO N - 1: FOR J = 0 TO N - I
150  PRINT "INPUT DATUM FOR ROW ";I + 1;" COL ";J + 1
160  INPUT "                     "; X
170 A(J,I) = X: NEXT J: NEXT I
180  CALL P: CALL P - 3
190  CALL Q: REM 07 002000 7F00 0700
200  CALL Q: REM 02 002000
210  CALL P - 12
220  PRINT "HERE IS ITS' INVERSE:"
230  PRINT : FOR I = 0 TO N - 1: FOR J = 0 TO N - 1
240  PRINT A(J,I),: NEXT J: PRINT : PRINT : NEXT I
250  END

Code Listing 2

943F           00001           ORG     $943F
               00002  ;
005E           00003  UPA      EQU     $5E
0060           00004  UPB      EQU     $60
006B           00005  SOA      EQU     $6B
009B           00006  UPC      EQU     $9B
91AA           00007  SUB05    EQU     $91AA
C0A0           00008  RDDATA   EQU     $C0A0
C0A0           00009  WRDATA   EQU     $C0A0
C0A1           00010  RDSTAT   EQU     $C0A1
DEC9           00011  SYNERR   EQU     $DEC9
E8D5           00012  OVFL     EQU     $E8D5
EAE1           00013  DIVBY0   EQU     $EAE1
               00014  
               00015  ; THIS CODE INVERTS THE FIRST ARRAY IN MEMORY
               00016  ;
               00017  ; FIRST CHECK THAT THE # OF DIMENSIONS = 2
               00018  ;
               00019  ; THEN SEND THE TWO DIMENSIONS TO THE 68000.
               00020  ;
               00021  ; IF THE 68000 RETURNS A ZERO, WE HAVE A
               00022  ; SQUARE MATRIX, ELSE REPORT A SYNTAX ERROR.
               00023  ;
               00024  ; IF WE HAVE A SQUARE MATRIX, THE 68000 RETURNS
               00025  ; N SQUARED, WHICH IS THE NUMBER OF FIVE BYTE
               00026  ; FLOATING POINT NUMBERS WHICH NEED TO BE SENT
               00027  ; TO THE 68000.
               00028  ;
               00029  ; SEND THIS NUMBER OF FP#S AND THEN RECEIVE THEM
               00030  ; BACK, CHECKING EACH VARIABLE FOR AN OVERLFOW.
               00031  ;
943F A5 6B     00032  MAT     LDA  SOA       ;-- SET THE PTR TO START
9441 85 5E     00033          STA  UPA       ;   OF THE FIRST ARRAY --
9443 A5 6C     00034          LDA  SOA+1
9445 85 5F     00035          STA  UPA+1
9447 A0 04     00036          LDY  #4
9449 B1 5E     00037          LDA  (UPA),Y   ;GET THE # OF DIMENSIONS
944B C9 02     00038          CMP  #2        ;MUST BE TWO
944D F0 03     00039          BEQ  DOK       ;SKIP IF OK
944F 4C C9 DE  00040          JMP  SYNERR
               00041  ;
9452 20 E7 94  00042  DOK     JSR  OUT4      ;SEND THE TWO DIMENSIONS
9455 20 F3 94  00043          JSR  GET1      ;RECV 0 IF THE MATRIX IS SQUARE
9458 F0 03     00044          BEQ  SQOK      ;SKIP IF SQUARE
945A 4C C9 DE  00045          JMP  SYNERR
               00046  ;
               00047  ; GET THE COUNT AND SAVE IT UN UPB AND UPC
               00048  ;
945D 20 F3 94  00049  SQOK    JSR  GET1      ;HIGH ORDER COUNT
9460 85 61     00050          STA  UPB+1
9462 85 9C     00051          STA  UPC+1
9464 20 F3 94  00052          JSR  GET1      ;LOW ORDER COUNT
9467 85 60     00053          STA  UPB
9469 85 9B     00054          STA  UPC
               00055  ;
               00056  ; SET POINTER UPA TO THE START OF THE ARRAY
               00057  ;
946B 18        00058          CLC            ;ADD #9 TO UPA
946C A9 09     00059          LDA  #9
946E 65 5E     00060          ADC  UPA
9470 85 5E     00061          STA  UPA
9472 90 02     00062          BCC  NOCY
9474 E6 5F     00063          INC  UPA+1
               00064  ;
               00065  ; NOW WE SEND THE MATRIX TO THE 68000
               00066  ;
               00067  ; SEND A FIVE BYTE FP# TO THE 68000
               00068  ;
9476 A0 00     00069  NOCY    LDY  #0
9478 B1 5E     00070  SEND5   LDA  (UPA),Y   ;FETCH A BYTE FROM THE ARRAY
947A 2C A1 C0  00071  SND5A   BIT  RDSTAT    ;-- WAIT UNTIL THE 68000
947D 70 FB     00072          BVS  SND5A     ;    IS READY FOR DATA --
947F 8D A0 C0  00073          STA  WRDATA    ;SEND THE BYTE TO THE 68000
9482 C8        00074          INY
9483 C0 05     00075          CPY  #5        ;IS Y = 5 ?
9485 D0 F1     00076          BNE  SEND5     ;LOOP IF Y IS NOT 5
               00077  ;
               00078  ; ADD #5 TO THE POINTER UPA
               00079  ;
9487 18        00080          CLC
9488 98        00081          TYA            ;SET ACC = #5
9489 65 5E     00082          ADC  UPA
948B 85 5E     00083          STA  UPA
948D 90 02     00084          BCC  NOCY1
948F E6 5F     00085          INC  UPA+1
               00086  ;
               00087  ; SUBTRACT ONE FROM THE COUNT IN UPC
               00088  ;
9491 38        00089  NOCY1   SEC
9492 A5 9B     00090          LDA  UPC
9494 E9 01     00091          SBC  #1
9496 85 9B     00092          STA  UPC
9498 B0 02     00093          BCS  CYOK
949A C6 9C     00094          DEC  UPC+1
               00095  ;
               00096  ; TEST FOR ZERO COUNT
               00097  ;
949C 05 9C     00098  CYOK    ORA  UPC+1
949E D0 D6     00099          BNE  NOCY      ;LOOP IF NOT ZERO
               00100  ;
               00101  ; SET POINTER UPA TO THE START OF THE ARRAY
               00102  ;
94A0 18        00103          CLC
94A1 A5 6B     00104          LDA  SOA
94A3 69 09     00105          ADC  #9
94A5 85 5E     00106          STA  UPA
94A7 A5 6C     00107          LDA  SOA+1
94A9 69 00     00108          ADC  #0
94AB 85 5F     00109          STA  UPA+1
               00110  ;
               00111  ; NOW WE RECEIVE THE MATRIX BACK FROM THE 68000
               00112  ;
94AD AD A1 C0  00113  GETN    LDA  RDSTAT    ;BYTE AVAILABLE?
94B0 10 FB     00114          BPL  GETN      ;WAIT FOR BYTE
94B2 AD A0 C0  00115          LDA  RDDATA    ;GET ERROR BYTE
94B5 F0 0A     00116          BEQ  NOERR     ;O.K. IF ZERO
94B7 C9 01     00117          CMP  #1        ;OVERFLOW?
94B9 D0 03     00118          BNE  DIVERR    ;DIV BY 0 IF NOT
94BB 4C D5 E8  00119          JMP  OVFL      ;REPORT OVERFLOW
94BE 4C E1 EA  00120  DIVERR  JMP  DIVBY0    ;REPORT DIV BY 0
               00121  ;
94C1 A0 00     00122  NOERR   LDY  #0
94C3 AD A0 C0  00123  GET5    LDA  RDDATA    ;FETCH A BYTE
94C6 91 5E     00124          STA  (UPA),Y   ;STORE IN ARRAY
94C8 C8        00125          INY
94C9 C0 05     00126          CPY  #5
94CB D0 F6     00127          BNE  GET5      ;LOOP FOR 5 BYTES
               00128  ;
               00129  ; ADD #5 TO THE POINTER UPA
               00130  ;
94CD 18        00131          CLC
94CE 98        00132          TYA            ;SET ACC = #5
94CF 65 5E     00133          ADC  UPA
94D1 85 5E     00134          STA  UPA
94D3 90 02     00135          BCC  NOCY2
94D5 E6 5F     00136          INC  UPA+1
               00137  ;
               00138  ; SUBTRACT ONE FROM THE COUNT IN UPB
               00139  ;
94D7 38        00140  NOCY2   SEC
94D8 A5 60     00141          LDA  UPB
94DA E9 01     00142          SBC  #1
94DC 85 60     00143          STA  UPB
94DE B0 02     00144          BCS  CYOK1
94E0 C6 61     00145          DEC  UPB+1
               00146  ;
94E2 05 61     00147  CYOK1   ORA  UPB+1
94E4 D0 C7     00148          BNE  GETN      ;LOOP IF COUNT IS NOT ZERO
               00149  ;
94E6 60        00150          RTS            ;MATRIX INVERSION COMPLETED
               00151  ;
               00152  ; SEND 1, 2 OR 4 BYTES;  FIRST INCREMENTING Y
               00153  ;
94E7 20 EA 94  00154  OUT4    JSR  OUT2
94EA 20 ED 94  00155  OUT2    JSR  OUT1
94ED C8        00156  OUT1    INY            ;INCR INDEX Y
94EE B1 5E     00157          LDA  (UPA),Y
94F0 4C AA 91  00158          JMP  SUB05     ;OUTPUT THE BYTE
               00159  ;
               00160  ; GET A BYTE FROM THE 68000
               00161  ;
94F3 AD A1 C0  00162  GET1    LDA  RDSTAT    ;BYTE AVAILABLE?
94F6 10 FB     00163          BPL  GET1      ;WAIT FOR BYTE
94F8 AD A0 C0  00164          LDA  RDDATA    ;READ THE INPUT PORT
94FB 60        00165          RTS            ;RETURN WITH BYTE

Code Listing 3

                          1          OPT     P=68000,BRS,FRS
                          2 ; NOTE: SEE BUG FIXES IN DG#17P3,P4;DG#18P32.
                          3 
                          4 ; ***** MATRIX INVERSION ROUTINE FOR HALGOL *****
                          5 ;
                          6 ; COPYRIGHT 1982 DIGITAL ACOUSTICS INC.
                          7 ;
                          8 ; THIS PACKAGE INCLUDES A DOUBLE PRECISION
                          9 ; FLOATING POINT PACKAGE WITH A 48 BIT MANTISSA
                         10 ;
                         11 ;
                         12 ; FOLLOWING ARE I/O ASSIGNMENTS:
                         13 ;
   # 00000FFA            14 STATUS   EQU     $0FFA
   # 00000FF8            15 DATIN    EQU     $0FF8
   # 00000FFA            16 DATOUT   EQU     $0FFA
                         17 ;
                         18 ; FOLLOWING ARE MEMORY ASSIGNMENTS
                         19 ; USED BY THE BOOTSTRAP ROM (MONITOR):
                         20 ;
   # 00000122            21 IDLE     EQU     $0122
   # 0000109C            22 ADR      EQU     $109C
   # 000010A0            23 NSTAR    EQU     $10A0
   # 000010A2            24 T        EQU     $10A2
                         25 ;
                         26 ; FOLLOWING ARE MEMORY ASSIGNMENTS FOR THIS CODE:
                         27 ;
   # 000018F4            28 R        EQU     $18F4
   # 00001902            29 S1       EQU     R+14
   # 00001904            30 M1       EQU     S1+2
   # 0000190A            31 S2       EQU     S1+8
   # 0000190C            32 M2       EQU     S2+2
   # 00001912            33 FPT      EQU     S2+8
   # 0000191A            34 FPU      EQU     FPT+8
   # 00001922            35 LOGX     EQU     FPU+8
   # 00001922            36 BCDX     EQU     LOGX
   # 00001922            37 SINSGN   EQU     LOGX
   # 00001924            38 SERCNT   EQU     LOGX+2
   # 00001926            39 EXPADD   EQU     LOGX+4         ;EXP ADDER
   # 0000192F            40 ERRID    EQU     LOGX+13        ;ERROR ID #
   # 00001930            41 ERRPTR   EQU     LOGX+14        ;ERROR POINTER
   # 00001932            42 STR      EQU     LOGX+16        ;MISC STRING AREA
                         43 ;
                         44 
002000                   45          ORG     $2000          ;TEMP FOR DEV
                         46 ;
002000  4EB8 2112        47          JSR     GETN           ;GET N, MATRIX
002004  61 08            48          BSR     INVMAT         ;INVERT MATRIX
002006  4EB8 2206        49          JSR     SENDN          ;RETN MAT TO HOST
00200A  4EF8 0122        50          JMP     IDLE           ;RETURN TO BOOT
                         51 ;
                         52 ; INVERT A MATRIX BY PERFORMING N FRAMES
                         53 ;
00200E  11F8 26C7 1926   54 INVMAT   MOVE.B  N+3,FCTR       ;SET UP FRAMT CTR
                         55 ;
                         56 ; PERFORM ONE FRAME OF THE INVERSION PROCESS
                         57 ;
                         58 ; FIRST WE WILL CALC A(1,1) = 1/A(1,1)
                         59 ;
002014  3C7C 26D0        60 FLOOP    MOVE.W  #RPTR,A6       ;PT TO ROW1 PTR
002018  225E             61          MOVE.L  (A6)+,A1       ;A2 IS ROW1 PTR
00201A  3478 26CE        62          MOVE.W  CPTR,A2        ;A2 PT TO COL1 PTR
00201E  2049             63          MOVE.L  A1,A0          ;ROW START ADDR
002020  D1DA             64          ADDA.L  (A2)+,A0       ;ADD COL1 OFFSET
                         65 ;
                         66 ; A0 POINTS AT ELEMENT 1,1
                         67 ;
002022  21D8 1902        68          MOVE.L  (A0)+,S1       ;A(1,1) TO FPACC1
002026  21D8 1906        69          MOVE.L  (A0)+,M1+2
00202A  21FC 10018000    70          MOVE.L  #$10018000,S2  ;#1 TO FPACC2
        190A
002032  42B8 190E        71          CLR.L   M2+2
002036  4EB8 2302        72          JSR     LDIV1          ;CALC RECIPROCAL
00203A  2678 1906        73          MOVE.L  M1+2,A3
00203E  2878 1902        74          MOVE.L  S1,A4          ;RESULT IN A4,A3
002042  210B             75          MOVE.L  A3,-(A0)
002044  210C             76          MOVE.L  A4,-(A0)       ;STORE 1/A(1,1)
                         77 ;
                         78 ; FOR I = 2 TO N, A(1,I)=A(1,I) TIMES 1/A(1,1)
                         79 ;
002046  1038 26C7        80          MOVE.B  N+3,D0         ;FETCH N AS BYTE
00204A  5300             81          SUBQ.B  #1,D0          ;N - 1
00204C  11C0 1924        82          MOVE.B  D0,SERCNT      ;SET LOOP COUNT
                         83 ;
002050  2049             84 ROW1     MOVE.L  A1,A0          ;A0 IS ROW START
002052  D1DA             85          ADDA.L  (A2)+,A0       ;ADD COL OFFSET
002054  21CC 1902        86          MOVE.L  A4,S1          ;1/A(1,1) TO FPACC1
002058  21CB 1906        87          MOVE.L  A3,M1+2
00205C  4EB8 2220        88          JSR     LMUL           ;FPACC1 * (A0)
002060  2138 1906        89          MOVE.L  M1+2,-(A0)
002064  2138 1902        90          MOVE.L  S1,-(A0)       ;STORE RESULT
002068  5338 1924        91          SUBQ.B  #1,SERCNT      ;DECREMENT COUNT
00206C  66 E2            92          BNE     ROW1           ;LOOP UNTIL DONE
                         93 ;
                         94 
                         95 ; TO COMPLETE THE FRAME, PERFORM THESE CALCS:
                         96 ;
                         97 ; FOR R = 2 TO N: B = -A(R,1): A(R,1)=0
                         98 ; FOR C = 1 TO N: A(R,C) = A(R,C) + B * A(1,C)
                         99 ; NEXT C: NEXT R: FRAME IS THEN COMPLETE
                        100 ;
                        101 ; A1 IS PTR TO 1ST ROW
                        102 ; A2 IS PTR TO COL PTR
                        103 ; A5 IS PTR TO ROW R
                        104 ; A6 IS PTR TO ROW PTR
                        105 ; RETAIN B IN A4, A3
                        106 ;
   # 00001922           107 RCTR     EQU     LOGX
   # 00001925           108 CCTR     EQU     LOGX+3
                        109 ;
00206E  1038 26C7       110          MOVE.B  N+3,D0         ;FETCH N AS BYTE
002072  5300            111          SUBQ.B  #1,D0
002074  11C0 1922       112          MOVE.B  D0,RCTR        ;OUTER LOOP CTR
                        113 ;
002078  2A5E            114 RLOOP    MOVE.L  (A6)+,A5       ;A5 IS ROW R PTR
00207A  3478 26CE       115          MOVE.W  CPTR,A2        ;A2 IS COL1 PTR
00207E  204D            116          MOVE.L  A5,A0
002080  D1D2            117          ADDA.L  (A2),A0        ;A0 PTS TO A(R,1)
002082  0850 0007       118          BCHG    #7,(A0)        ;CHANGE THE SIGN
002086  2850            119          MOVE.L  (A0),A4
002088  4298            120          CLR.L   (A0)+
00208A  2650            121          MOVE.L  (A0),A3        ;B TO A4,A3
00208C  4290            122          CLR.L   (A0)           ;A(R,1) = 0
                        123 ;
00208E  11F8 26C7 1925  124          MOVE.B  N+3,CCTR       ;SET UP COL CTR
002094  2049            125 CLOOP    MOVE.L  A1,A0          ;A0 PTS TO A(1,1)
002096  D1D2            126          ADDA.L  (A2),A0        ;A0 PTS TO A(1,C)
002098  21CC 1902       127          MOVE.L  A4,S1
00209C  21CB 1906       128          MOVE.L  A3,M1+2        ;B TO FPACC1
0020A0  4EB8 2220       129          JSR     LMUL           ;CALC B * A(1,C)
                        130 ;
0020A4  204D            131          MOVE.L  A5,A0
0020A6  D1DA            132          ADDA.L  (A2)+,A0       ;A0 PTS TO A(R,C)
0020A8  4EB8 23A8       133          JSR     LADD           ;A(R,C)+B*A(1,C)
                        134 ;
0020AC  2138 1906       135          MOVE.L  M1+2,-(A0)
0020B0  2138 1902       136          MOVE.L  S1,-(A0)       ;RESULT TO A(R,C)
                        137 ;
0020B4  5338 1925       138          SUBQ.B  #1,CCTR        ;DECR COL CTR
0020B8  66 DA           139          BNE     CLOOP          ;LOOP UNTIL DONE
                        140 ;
0020BA  5338 1922       141          SUBQ.B  #1,RCTR        ;DECR ROW CTR
0020BE  66 B8           142          BNE     RLOOP          ;LOOP UNTIL DONE
                        143 ;
                        144 ; NOW ROTATE THE ROW AND COLUMN POINTERS
                        145 ;
0020C0  61 0A           146          BSR     ROTCR          ;ROTATE THEM
                        147 ;
0020C2  5338 1926       148          SUBQ.B  #1,FCTR        ;DECR FRAME CTR
0020C6  6600 FF4C       149          BNE     FLOOP          ;LOOP UNTIL DONE
                        150 ;
0020CA  4E75            151          RTS                    ;MATRIX INVERTED
                        152 ;
                        153 
                        154 ; ROTATE THE COLUMN AND ROW POINTERS
                        155 ;
0020CC  307C 26D0       156 ROTCR    MOVE.W  #RPTR,A0       ;POINT A0 AT ROW 0
0020D0  4EB8 20D4       157          JSR     ROT            ;ROTATE COLUMNS
                        158 ;
                        159 ; SUBR' ROT LEAVES A0 POINTING AT COL OFFSET 0.
                        160 ; NOW WE USE SUBROUTINE ROT A SECOND TIME
                        161 ; TO ROTATE THE COLUMN OFFSETS.
                        162 ;
0020D4  1038 26C7       163 ROT      MOVE.B  N+3,D0         ;GET BYTE VALUE
0020D8  5300            164          SUBQ.B  #1,D0          ;D0 = N - 1
0020DA  3248            165          MOVE.W  A0,A1
0020DC  2F19            166          MOVE.L  (A1)+,-(A7)    ;1ST PTR TO STK
                        167 ;
0020DE  20D9            168 ROT1     MOVE.L  (A1)+,(A0)+    ;MOVE 1 PTR
0020E0  5300            169          SUBQ.B  #1,D0          ;DECR CTR
0020E2  66 FA           170          BNE     ROT1           ;LOOP N-1 TIMES
                        171 ;
0020E4  20DF            172          MOVE.L  (A7)+,(A0)+    ;LAST PTR WAS 1ST
0020E6  4E75            173          RTS
                        174 ;
                        175 ; SET UP THE ROW AND COLUMN POINTERS
                        176 ;
0020E8  2038 26C4       177 SURCP    MOVE.L  N,D0           ;N AS 32 BIT VALUE
0020EC  2200            178          MOVE.L  D0,D1
0020EE  E749            179          LSL.W   #3,D1          ;D1 = 8 * N
0020F0  307C 26D0       180          MOVE.W  #RPTR,A0       ;A0 = ROW PTR START
0020F4  2408            181          MOVE.L  A0,D2          ;UPPER WORD IS ZERO
0020F6  D481            182          ADD.L   D1,D2          ;D2 = ARRAY START
0020F8  31C2 26CC       183          MOVE.W  D2,ARYST       ;ST STARTING ADDR
0020FC  61 08           184          BSR     STORPT         ;STORE ROW PTRS
                        185 ;
0020FE  31C8 26CE       186          MOVE.W  A0,CPTR        ;ST COL START ADR
002102  72 08           187          MOVEQ   #8,D1          ;SET D1 = 8
002104  4282            188          CLR.L   D2             ;SET D2 = 0
                        189 ;
                        190 ; EXIT, STORING COL OFFSETS
                        191 ;
002106  1600            192 STORPT   MOVE.B  D0,D3          ;COUNT N TO D3
002108  20C2            193 STO1     MOVE.L  D2,(A0)+       ;STORE A POINTER
00210A  D481            194          ADD.L   D1,D2          ;CALC NX PTR
00210C  5303            195          SUBQ.B  #1,D3          ;DECR COUNT
00210E  66 F8           196          BNE     STO1           ;LOOP UNTIL DONE
002110  4E75            197          RTS                    ;DONE
                        198 ;
                        199 
                        200 ; SUBROUTINE;  GET N AND TEST FOR SQUARE MATRIX
                        201 ;
002112  307C 0FFA       202 GETN     MOVE.W  #STATUS,A0     ;-- SET UP THE
002116  327C 0FF8       203          MOVE.W  #DATIN,A1      ;   I/O PARMS --
00211A  7E 07           204          MOVEQ   #7,D7
00211C  7C 06           205          MOVEQ   #6,D6
00211E  4281            206          CLR.L   D1
002120  61 38           207          BSR     GET2           ;FETCH N = DIM
002122  21C1 26C4       208          MOVE.L  D1,N           ;STORE N IN MEM
002126  2401            209          MOVE.L  D1,D2
002128  61 30           210          BSR     GET2           ;GET 2ND DIM
00212A  B441            211          CMP.W   D1,D2          ;SQUARE MATRIX?
                        212 
00212C  6600 00AA       213          BNE.W   ERR1           ;ERROR IF NOT SQ
                        214 
002130  C2C2            215          MULU    D2,D1          ;D1 = # OF VARS
002132  2A01            216          MOVE.L  D1,D5          ;SAVE #VAR'S IN D5
002134  21C1 26C8       217          MOVE.L  D1,NSQD        ;SAVE FOR LATER
                        218 ;
                        219 ; RETURN A ZERO ERROR CODE
                        220 ;
002138  4240            221          CLR.W   D0             ;D0 = ZERO
00213A  0D10            222 GETN1    BTST    D6,(A0)        ;READY FOR BYTE
00213C  66 FC           223          BNE     GETN1          ;WAIT TIL RDY
00213E  1080            224          MOVE.B  D0,(A0)        ;SEND ZERO BYTE
                        225 ;
                        226 ; SEND THE NUMBER OF VARIABLES ( = N SQUARED )
                        227 ;
002140  61 58           228          BSR     SEND2          ;# VAR'S TO HOST
002142  4EB8 20E8       229          JSR     SURCP          ;ROWS & COL'S
002146  307C 0FFA       230          MOVE.W  #STATUS,A0     ;RESTORE A0
00214A  3478 26CC       231          MOVE.W  ARYST,A2       ;A2 = ARRAY START
00214E  61 18           232 GETN2    BSR     GETFP          ;GET AN FP#
002150  24C0            233          MOVE.L  D0,(A2)+       ;STORE IT
002152  24C1            234          MOVE.L  D1,(A2)+       ;( 8 BYTES )
002154  5345            235          SUBQ.W  #1,D5          ;DECR VAR COUNT
002156  66 F6           236          BNE     GETN2          ;LOOP TIL DONE
002158  4E75            237          RTS
                        238 ;
                        239 ; SUBROUTINE;  GET TWO BYTES FROM HOST
                        240 ;
00215A  0F10            241 GET2     BTST    D7,(A0)        ;BYTE AVAIL?
00215C  67 FC           242          BEQ     GET2           ;WAIT FOR BYTE
00215E  3211            243          MOVE.W  (A1),D1
002160  0F10            244 GET2A    BTST    D7,(A0)        ;NEXT BYTE RDY?
002162  67 FC           245          BEQ     GET2A          ;WAIT FOR BYTE
002164  1211            246          MOVE.B  (A1),D1
002166  4E75            247          RTS
                        248 ;
                        249 
                        250 ; SUBR; ACCEPT A MICROSOFT FORMAT F.P. # FROM THE
                        251 ; HOST AND EXPAND IT INTO THE 62 BIT F.P. FORMAT
                        252 ;
002168  0F10            253 GETFP    BTST    D7,(A0)        ;BYTE READY?
00216A  67 FC           254          BEQ     GETFP          ;WAIT FOR BYTE
00216C  4240            255          CLR.W   D0
00216E  1011            256          MOVE.B  (A1),D0        ;FETCH THE EXP
002170  67 1E           257          BEQ     FPZERO         ;SKIP IF ZERO
                        258 ;
002172  0640 0F80       259          ADDI.W  #$0F80,D0      ;CORRECT THE OFFSET
002176  61 E2           260          BSR     GET2           ;HIGH 16 MANT BITS
                        261 ;
                        262 ; RECOVER SIGN FROM D7 OF HOST MANT
002178  3401            263          MOVE.W  D1,D2          ;COPY MANT TO D2
00217A  0241 8000       264          ANDI.W  #$8000,D1      ;SIGN IN D1
00217E  8041            265          OR.W    D1,D0          ;ADD SIGN TO EXP
002180  0042 8000       266          ORI.W   #$8000,D2      ;MANT MSBIT = 1
002184  4840            267          SWAP    D0
002186  3002            268          MOVE.W  D2,D0          ;32 BITS IN D0
002188  61 D0           269          BSR     GET2           ;GET REST OF MANT
00218A  4841            270          SWAP    D1
00218C  4241            271          CLR.W   D1
00218E  4E75            272          RTS                    ;FP# IN D0,D1
                        273 ;
002190  61 C8           274 FPZERO   BSR     GET2           ;DISCARD 4 BYTES
002192  61 C6           275          BSR     GET2
002194  4280            276          CLR.L   D0             ;RESULT IS ZERO
002196  4281            277          CLR.L   D1
002198  4E75            278          RTS                    ;FP# IN D0, D1
                        279 ;
                        280 ; SUBROUTINE; SEND D1 TO HOST AS TWO BYTE NUMBER
                        281 ;
00219A  0D10            282 SEND2    BTST    D6,(A0)        ;HOST RDY FOR BYTE?
00219C  66 FC           283          BNE     SEND2          ;WAIT TIL RDY
00219E  3081            284          MOVE.W  D1,(A0)        ;SEND M.S.BYT
0021A0  0D10            285 SEND2A   BTST    D6,(A0)
0021A2  66 FC           286          BNE     SEND2A
0021A4  1081            287          MOVE.B  D1,(A0)        ;SEND L.S.BYT
0021A6  4E75            288          RTS
                        289 ;
                        290 ; SUBROUTINE; UNPACK 62 BIT F.P. # TO THE HOST'S
                        291 ; FIVE BYTE FORMAT, REPORTING OVERFLOWS.
                        292 ;
0021A8  4238 1901       293 XMITFP   CLR.B   S1-1           ;CLEAR ERROR BYTE
0021AC  4C91 000F       294          MOVEM.W (A1),D0-D3     ;FETCH 8 BYTES
0021B0  5089            295          ADDQ.L  #8,A1          ;PTR TO NEXT FP#
                        296 ;
                        297 ; ROUND THE 48 BIT MANT TO 32 BITS
                        298 ;
0021B2  3803            299          MOVE.W  D3,D4          ;TEST MSB
0021B4  6A 0A           300          BPL     CMPR           ;SKIP IF ZERO
0021B6  5242            301          ADDQ.W  #1,D2
0021B8  64 06           302          BCC     CMPR
0021BA  5241            303          ADDQ.W  #1,D1
0021BC  64 02           304          BCC     CMPR
0021BE  5240            305          ADDQ.W  #1,D0          ;INCR EXP
                        306 ;
                        307 
                        308 ; MASK THE SIGN ONTO THE MSB OF THE MANT
                        309 ;
0021C0  3600            310 CMPR     MOVE.W  D0,D3
0021C2  0043 7FFF       311          ORI.W   #$7FFF,D3      ;D3 = 7FFF OR FFFF
0021C6  C243            312          AND.W   D3,D1          ;SIGN TO MANT MSB
0021C8  0240 7FFF       313          ANDI.W  #$7FFF,D0      ;ZERO THE SIGN
                        314 ;
0021CC  0440 0F80       315          SUBI.W  #$0F80,D0      ;CORRECT OFFSET
0021D0  6B 2C           316          BMI     RZERO          ;ZERO ON UNDFL
0021D2  0C40 0100       317          CMPI.W  #256,D0        ;OVERFLOW
0021D6  65 12           318          BCS     CMPR0          ;SKIP IF O.K.
                        319 ;
0021D8  7E 01           320 ERR1     MOVEQ   #1,D7
0021DA  0838 0006 0FFA  321 ERROR    BTST    #6,STATUS      ;HOST RDY?
0021E0  66 F8           322          BNE     ERROR          ;WAIT TIL RDY
0021E2  11C7 0FFA       323          MOVE.B  D7,DATOUT      ;SEND ERR I.D.
0021E6  4EF8 0122       324          JMP     IDLE           ;RETURN TO BOOT
                        325 ;
                        326 ; FIRST SEND THE ERROR BYTE
                        327 ;
0021EA  0D10            328 CMPR0    BTST    D6,(A0)        ;HOST RDY FOR BYT?
0021EC  66 FC           329          BNE     CMPR0          ;WAIT TIL RDY
0021EE  10B8 1901       330          MOVE.B  S1-1,(A0)      ;SEND ERR CODE
                        331 ;
                        332 ; NOW SEND THE FLOATING POINT NUMBER, 5 BYTES
                        333 ;
0021F2  0D10            334 CMPR1    BTST    D6,(A0)        ;HOST RDY FOR BYTE?
0021F4  66 FC           335          BNE     CMPR1          ;WAIT TIL RDY
0021F6  1080            336          MOVE.B  D0,(A0)        ;SEND EXP
                        337 ;
0021F8  61 A0           338          BSR     SEND2          ;SEND D1
0021FA  3202            339          MOVE.W  D2,D1
0021FC  60 9C           340          BRA     SEND2          ;EXIT, SEND'G 2
                        341 ;
0021FE  4240            342 RZERO    CLR.W   D0             ;RESULT IS ZERO
002200  4241            343          CLR.W   D1
002202  4242            344          CLR.W   D2
002204  60 E4           345          BRA     CMPR0          ;SEND THE ZERO
                        346 ;
                        347 ; SEND THE INVERTED MATRIX BACK TO THE HOST
                        348 ;
002206  307C 0FFA       349 SENDN    MOVE.W  #STATUS,A0
00220A  7C 06           350          MOVEQ   #6,D6
00220C  3278 26CC       351          MOVE.W  ARYST,A1
002210  2A38 26C8       352          MOVE.L  NSQD,D5        ;SET VAR COUNT
                        353 ;
002214  61 92           354 SENDN2   BSR     XMITFP         ;5 BYTE FP#
002216  5345            355          SUBQ.W  #1,D5          ;DECR VAR CNT
002218  66 FA           356          BNE     SENDN2         ;LOOP TIL DONE
00221A  4E75            357          RTS                    ;DONE
                        358 ;
                        359 
                        360 ; STORE A ZERO IN FPACC1
                        361 ;
00221C  4EF8 22F0       362 RZER     JMP     RZER1
                        363 ;
                        364 ; FETCH AN 8 BYTE F.P. NUMBER TO FPACC#2
                        365 ;
002220  21D8 190A       366 LMUL     MOVE.L  (A0)+,S2
002224  21D8 190E       367          MOVE.L  (A0)+,M2+2
                        368 ;
                        369 ; PERFORM A 62 BIT FLOATING POINT MULTIPLY
                        370 ;
002228  4CB8 00FF 1902  371 LMUL1    MOVEM.W S1,D0-D7       ;FETCH BOTH #S
00222E  3F00            372          MOVE.W  D0,-(A7)       ;PUSH S1
002230  B940            373          EOR     D4,D0
002232  0240 8000       374          ANDI.W  #$8000,D0
002236  31C0 1902       375          MOVE.W  D0,S1          ;STORE THE SIGN
00223A  301F            376          MOVE.W  (A7)+,D0       ;RESTORE X1
00223C  E348            377          LSL.W   #1,D0          ;TEST FOR ZERO
00223E  67 DC           378          BEQ     RZER           ;EXIT IF FPACC1 0
002240  E34C            379          LSL.W   #1,D4          ;TEST FOR ZERO
002242  67 D8           380          BEQ     RZER           ;EXIT IF FPACC2 0
002244  D044            381          ADD.W   D4,D0          ;ADD EXPONENTS
002246  E248            382          LSR.W   #1,D0          ;CORRECT FOR SHIFT
002248  0440 1000       383          SUBI.W  #$1000,D0      ;CORRECT OFFSET
00224C  6B CE           384          BMI     RZER           ;ZERO IF
00224E  3F00            385          MOVE.W  D0,-(A7)       ;PUSH EXP
002250  3003            386          MOVE.W  D3,D0          ;USE D0 AS SCRATCH
002252  C0C7            387          MULU    D7,D0          ;A0 * B0
002254  4240            388          CLR.W   D0             ;DISCARD LOWER 16
002256  4840            389          SWAP    D0             ;D0 = $0000HHHH
002258  4244            390          CLR.W   D4             ;D4 IS SCRATCH
00225A  3202            391          MOVE.W  D2,D1          ;DESTROYS A2
00225C  C2C7            392          MULU    D7,D1          ;A1 * B0
00225E  D081            393          ADD.L   D1,D0          ;SUM PARTIALS
002260  64 02           394          BCC     LMUL2          ;SKIP IF NO CY
002262  5204            395          ADDQ.B  #1,D4          ;ACCUM CYS IN D4
002264  3203            396 LMUL2    MOVE.W  D3,D1
002266  C2C6            397          MULU    D6,D1          ;A0 * B1
002268  D081            398          ADD.L   D1,D0          ;SUM PARTIALS
00226A  64 02           399          BCC     LMUL3          ;SKIP IF NO CY
00226C  5204            400          ADDQ.B  #1,D4          ;ACCUM CYS IN D4
                        401 ;
                        402 ; THE NEXT TWO INSTRUCTIONS CLEVERLY DISCARDS
                        403 ; THE LOWER 16 BITS WHILE MOVING THE CARRIES
                        404 ; FROM D4 INTO THEIR PROPER POSITION
                        405 ;
00226E  3004            406 LMUL3    MOVE.W  D4,D0
002270  4840            407          SWAP    D0
                        408 ;
002272  4244            409          CLR.W   D4             ;CLR FOR MORE CY'S
002274  C6C5            410          MULU    D5,D3          ;B2 * A0
                        411 ;
                        412 
                        413 ; D3 IS NOW AVAILABLE AS SCRATCH REGISTER
                        414 ;
002276  D083            415          ADD.L   D3,D0          ;ADD PARTIALS
002278  64 02           416          BCC     LMUL4          ;SKIP IF NO CY
00227A  5204            417          ADDQ.B  #1,D4
00227C  3202            418 LMUL4    MOVE.W  D2,D1
00227E  C2C6            419          MULU    D6,D1          ;B1 * A1
002280  D081            420          ADD.L   D1,D0
002282  64 02           421          BCC     LMUL5
002284  5204            422          ADDQ.B  #1,D4
002286  3638 1904       423 LMUL5    MOVE.W  M1,D3          ;A2 IS IN D3
00228A  CEC3            424          MULU    D3,D7          ;A2 * B0
00228C  D087            425          ADD.L   D7,D0
                        426 ;
                        427 ; D7 IS NOW AVAILABLE AS A SCRATCH REGISTER
                        428 ;
00228E  64 02           429          BCC     LMUL6
002290  5204            430          ADDQ.B  #1,D4
002292  3E00            431 LMUL6    MOVE.W  D0,D7          ;SAVE GUARD WORD
                        432 ;
                        433 ; GET CLEVER AGAIN
                        434 ;
002294  3004            435          MOVE.W  D4,D0
002296  4840            436          SWAP    D0
002298  4244            437          CLR.W   D4             ;READY FOR CY'S
00229A  3203            438          MOVE.W  D3,D1
00229C  C2C6            439          MULU    D6,D1          ;B1 * A2
00229E  D081            440          ADD.L   D1,D0
0022A0  64 02           441          BCC     LMUL7
0022A2  5204            442          ADDQ.B  #1,D4
0022A4  C4C5            443 LMUL7    MULU    D5,D2          ;B2 * A1
0022A6  D082            444          ADD.L   D2,D0
                        445 ;
                        446 ; D2 IS NOW AVAILABLE AS SCRATCH REGISTER
                        447 ;
0022A8  64 02           448          BCC     LMUL8
0022AA  5204            449          ADDQ.B  #1,D4
0022AC  3400            450 LMUL8    MOVE.W  D0,D2          ;SAVE 16 BITS
0022AE  3004            451          MOVE.W  D4,D0
0022B0  4840            452          SWAP    D0             ;SLIGHTLY CLEVER
0022B2  321F            453          MOVE.W  (A7)+,D1       ;POP EXP TO D1
0022B4  C6C5            454          MULU    D5,D3          ;B2 * A2
0022B6  D083            455          ADD.L   D3,D0          ;NO CY POSSIBLE
0022B8  6B 0C           456          BMI     LMUL9          ;SKIP IF B31 = 1
0022BA  E34F            457          LSL.W   #1,D7
0022BC  E352            458          ROXL.W  #1,D2
0022BE  E390            459          ROXL.L  #1,D0          ;SHIFT RESULT L 1
                        460 ;
                        461 ; NEXT BRANCH TAKEN ONLY IF MANTS IMPROPER
                        462 ;
0022C0  6A 2E           463          BPL     RZER1
0022C2  5341            464          SUBQ.W  #1,D1          ;DECR EXP BY 1
0022C4  6B 2A           465          BMI     RZER1          ;ZERO IF UNDFL
                        466 ;
                        467 
                        468 ; ROUND THE RESULT
                        469 ;
0022C6  E34F            470 LMUL9    LSL.W   #1,D7          ;SHIFT GUARD
0022C8  64 0A           471          BCC     LMUL10         ;DONE IF B-1 IS 0
0022CA  5242            472          ADDQ.W  #1,D2          ;ELSE ROUND UP
0022CC  64 06           473          BCC     LMUL10         ;SKIP IF NO CY
0022CE  5280            474          ADDQ.L  #1,D0          ;ADD CY TO D0
0022D0  64 02           475          BCC     LMUL10         ;SKIP I NO OVFL
0022D2  5241            476          ADDQ.W  #1,D1          ;INCREMENT EXP
                        477 ;
0022D4  3601            478 LMUL10   MOVE.W  D1,D3          ;SET FLAGS
0022D6  67 18           479          BEQ     RZER1          ;ZERO IF EXP 0
0022D8  0243 6000       480          ANDI.W  #$6000,D3      ;TEST EXP OVFL
0022DC  66 0E           481          BNE     OVFL           ;REPORT OVERFLOW
                        482 ;
                        483 ; MULTIPLICATION IS COMPLETE, STORE THE RESULT
                        484 ;
0022DE  8378 1902       485          OR      D1,S1          ;STORE EXP
0022E2  21C0 1904       486          MOVE.L  D0,M1
0022E6  31C2 1908       487          MOVE.W  D2,M1+4        ;STORE MANTISSA
0022EA  4E75            488          RTS
                        489 ;
                        490 ; THE FLOATING POINT MULTIPLY ROUTINE IS COMPLETED
                        491 ;
0022EC  4EF8 21D8       492 OVFL     JMP     ERR1           ;REPORT OVERFLOW
                        493 ;
                        494 
                        495 ; STORE A ZERO IN FPACC1
                        496 ;
0022F0  42B8 1902       497 RZER1    CLR.L   S1
0022F4  42B8 1906       498          CLR.L   M1+2
0022F8  4E75            499          RTS
                        500 ;
                        501 ; FETCH AN 8 BYTE F.P. NUMBER TO FPACC#2
                        502 ;
0022FA  21D8 190A       503 LDIV     MOVE.L  (A0)+,S2
0022FE  21D8 190E       504          MOVE.L  (A0)+,M2+2
                        505 ;
                        506 ; PERFORM A 62 BIT FLOATING POINT DIVIDE
                        507 ;
002302  4CB8 00FF 1902  508 LDIV1    MOVEM.W S1,D0-D7       ;FETCH BOTH #S
002308  3F00            509          MOVE.W  D0,-(A7)       ;PUSH S1
00230A  B940            510          EOR.W   D4,D0
00230C  0240 8000       511          ANDI.W  #$8000,D0
002310  31C0 1902       512          MOVE.W  D0,S1          ;STORE THE SIGN
002314  301F            513          MOVE.W  (A7)+,D0       ;RESTORE X2
002316  E348            514          LSL.W   #1,D0          ;TEST FOR ZERO
002318  67 76           515          BEQ     DIV0           ;ERR IF FPACC1 0
00231A  E34C            516          LSL.W   #1,D4          ;TEST FOR ZERO
00231C  67 D2           517          BEQ     RZER1          ;EXIT IF FPACC2 0
00231E  9840            518          SUB.W   D0,D4          ;SUB EXPONENTS
002320  E244            519          ASR.W   #1,D4          ;CORRECT FOR SHIFT
002322  0644 1000       520          ADDI.W  #$1000,D4      ;CORRECT OFFSET
                        521 ;
                        522 ; DO NOT TEST FOR OVERFLOW OR UNDERFLOW YET
                        523 ;
002326  4841            524          SWAP    D1
002328  3202            525          MOVE.W  D2,D1          ;M1 IN D1.L, D3.W
00232A  4845            526          SWAP    D5
00232C  3A06            527          MOVE.W  D6,D5          ;M2 IN D5.L, D7.W
00232E  4282            528          CLR.L   D2
002330  7C 32           529          MOVEQ   #50,D6         ;SET FOR 50 LOOPS
002332  60 06           530          BRA     LDIV3
                        531 ;
                        532 ; SHIFT THE NUMERATOR 1 BIT LEFT
                        533 ;
002334  E34F            534 LDIV2    LSL.W   #1,D7
002336  E395            535          ROXL.L  #1,D5
002338  65 0C           536          BCS     SUBDO          ;SUB IF CY = 1
                        537 ;
00233A  B285            538 LDIV3    CMP.L   D5,D1          ;COMPARE HIGH ORDER
00233C  65 08           539          BCS     SUBDO
00233E  66 0C           540          BNE     NOSUB
                        541 ;
002340  B647            542          CMP.W   D7,D3          ;COMPARE LOW ORDER
002342  65 02           543          BCS     SUBDO
002344  66 06           544          BNE     NOSUB
                        545 ;
002346  9E43            546 SUBDO    SUB.W   D3,D7
002348  9B81            547          SUBX.L  D1,D5
00234A  5202            548          ADDQ.B  #1,D2          ;BIT 1 TO D2,B0
                        549 ;
                        550 
                        551 ; SHIFT A 1 OR ZERO INTO THE RESULT
                        552 ;
00234C  E38A            553 NOSUB    LSL.L   #1,D2
00234E  E390            554          ROXL.L  #1,D0          ;64 BIT SHIFT L
                        555 ;
002350  5306            556          SUBQ.B  #1,D6
002352  66 E0           557          BNE     LDIV2          ;LOOP UNTIL ZERO
                        558 ;
                        559 ; TEST WHETHER THE MSB IS 1.  IF SO, SHIFT THE
                        560 ; RESULT 1 BIT RIGHT AND ADD #1 TO EXP
                        561 ;
002354  0800 0012       562          BTST    #18,D0         ;TEST B18
002358  67 06           563          BEQ     LDIV4          ;SKIP IF BIT ZERO
00235A  E288            564          LSR.L   #1,D0
00235C  E292            565          ROXR.L  #1,D2          ;SHIFT RESULT #1 R
00235E  5244            566          ADDQ.W  #1,D4          ;ADD 1 TO EXP
                        567 ;
                        568 ; ROUND THE RESULT
                        569 ;
002360  E288            570 LDIV4    LSR.L   #1,D0
002362  E292            571          ROXR.L  #1,D2          ;SHIFT ONCE
002364  E288            572          LSR.L   #1,D0
002366  E292            573          ROXR.L  #1,D2          ;B-1 TO CY
002368  64 0C           574          BCC     LDIV5          ;SKIP IF NO ROUND
00236A  5282            575          ADDQ.L  #1,D2          ;ADD CY TO MANT1
00236C  64 08           576          BCC     LDIV5          ;OK IF NO CY
00236E  5240            577          ADDQ.W  #1,D0          ;ADD CY TO HI ORD
002370  64 04           578          BCC     LDIV5          ;OK IF NO CY
002372  E288            579          LSR.L   #1,D0          ;MANT IS $8000...
002374  5344            580          SUBQ.W  #1,D4          DECR D4
                        581 ;
                        582 ; EXP IN D4; MANT IN D0.W, D2.L
                        583 ;
002376  3C04            584 LDIV5    MOVE.W  D4,D6          ;EXP TO D6 FOR TEST
002378  6B00 FF76       585          BMI     RZER1          ;ZERO ON UNDERFLOW
00237C  0246 2000       586          ANDI.W  #$2000,D6      ;TEST OVERFLOW
002380  66 14           587          BNE     DOVFL          ;REPORT OVERFLOW
002382  8978 1902       588          OR      D4,S1          ;STORE EXPONENT
002386  31C0 1904       589          MOVE.W  D0,M1
00238A  21C2 1906       590          MOVE.L  D2,M1+2        ;STORE MANTISSA
00238E  4E75            591 RETN1    RTS
                        592 ;
002390  7E 02           593 DIV0     MOVEQ   #2,D7          ;ERR2 IS DIV BY 0
002392  4EF8 21DA       594          JMP     ERROR          ;REPORT THE ERROR
                        595 ;
002396  4EF8 21D8       596 DOVFL    JMP     ERR1           ;REPORT OVERFLOW
                        597 ;
                        598 
                        599 ; START OF 62 BIT FLOATING POINT SUBTRACT
                        600 ;
00239A  0878 0007 1902  601 LSUB1    BCHG    #7,S1          ;TOGGLE D7 OF S1
0023A0  60 0E           602          BRA     LADD1          ;FPACC2 IS LOADED
                        603 ;
0023A2  0878 0007 1902  604 LSUB     BCHG    #7,S1          ;TOGGLE D7 OF S1
                        605 ;
                        606 ; FETCH AN 8 BYTE FP NUMBER TO FPACC#2
                        607 ;
0023A8  21D8 190A       608 LADD     MOVE.L  (A0)+,S2       ;A0 IS PTR TO FP#
0023AC  21D8 190E       609          MOVE.L  (A0)+,M2+2
                        610 ;
                        611 ; PERFORM A 62 BIT FLOATING POINT SIGNED ADD
                        612 ;
                        613 ; FIRST TEST WHETHER EITHER # IS ZERO
                        614 ;
0023B0  3838 190A       615 LADD1    MOVE.W  S2,D4          ;X2 TO D4
0023B4  E34C            616          LSL.W   #1,D4          ;TEST FOR ZERO
0023B6  67 D6           617          BEQ     RETN1          ;DONE IF X2 = 0
                        618 ;
0023B8  3038 1902       619          MOVE.W  S1,D0          ;X1 TO D0
0023BC  E348            620          LSL.W   #1,D0          ;TEST FOR ZERO
0023BE  66 0E           621          BNE     ADDNZ          ;SKIP IF NOT ZERO
                        622 ;
                        623 ; FPACC1 IS ZERO; MOVE FPACC2 TO FPACC1 AND EXIT
                        624 ;
0023C0  21F8 190A 1902  625          MOVE.L  S2,S1          ;RESULT IS FPACC2
0023C6  21F8 190E 1906  626          MOVE.L  M2+2,M1+2
0023CC  4E75            627          RTS                    ;RETURN
                        628 ;
                        629 ; WE MUST PLACE THE NUMBER WHOSE ABSOLUTE VALUE
                        630 ; IS GREATEST IN FPACC1.  FIRST WE TEST THE
                        631 ; EXPONENTS, THEN THE MOST SIGNIFICANT 32
                        632 ; BITS OF THE MANTISSAS AND FINALLY THE LEAST
                        633 ; SIGNIFICANT 16 BITS OF THE MANTISSAS.
                        634 ;
0023CE  B840            635 ADDNZ    CMP.W   D0,D4          ;COMPARE EXPS
0023D0  65 36           636          BCS     ONEGT2         ;OK IF X1 > X2
0023D2  66 16           637          BNE     MSWAP          ;SWAP IF X1 < X2
                        638 ;
0023D4  2238 190C       639          MOVE.L  M2,D1
0023D8  B2B8 1904       640          CMP.L   M1,D1          ;COMP MOST SIG 32
0023DC  65 2A           641          BCS     ONEGT2         ;OK IF M1 > M2
0023DE  66 0A           642          BNE     MSWAP          ;SWAP IF M1 < M2
                        643 ;
0023E0  3438 1908       644          MOVE.W  M1+4,D2
0023E4  B478 1910       645          CMP.W   M2+4,D2        ;COMP LAST 16 BITS
0023E8  64 1E           646          BCC     ONEGT2         ;OK IF M1>=M2
                        647 ;
                        648 
                        649 ; SWAP THE TWO FLOATING POINT ACCUMULATORS
                        650 ;
0023EA  2638 1902       651 MSWAP    MOVE.L  S1,D3          ;FPACC1 TO D3, D7
0023EE  2E38 1906       652          MOVE.L  M1+2,D7
0023F2  21F8 190A 1902  653          MOVE.L  S2,S1          ;FPACC2 TO FPACC1
0023F8  21F8 190E 1906  654          MOVE.L  M2+2,M1+2
0023FE  21C3 190A       655          MOVE.L  D3,S2          ;D3, D7 TO FPACC2
002402  21C7 190E       656          MOVE.L  D7,M2+2
002406  C144            657          EXG     D0,D4          ;EXCHANGE EXPONENTS
                        658 ;
                        659 ; ABS(FPACC1) IS NOT > OR = ABS(FPACC2)
                        660 ;
002408  4241            661 ONEGT2   CLR.W   D1             ;CLEAR D1
00240A  9044            662          SUB.W   D4,D0          ;D0 = X1 - X2
                        663 
00240C  6700 00A0       664          BEQ.W   ALIGND         ;SKIP IF EXP'S EQ
                        665 
002410  E248            666          LSR.W   #1,D0          ;COMP'SAT FOR LSL'S
                        667 ;
                        668 ; FIRST TEST FOR 16 OR FEWER SHIFTS
                        669 ;
002412  0C40 0010       670          CMPI.W  #16,D0         ;16 OR LESS SHIFTS?
002416  65 60           671          BCS     LT16           ;SKIP IF < 16
002418  67 4E           672          BEQ     EQ16           ;SKIP IF 16 SHIFTS
                        673 ;
                        674 ; NEXT TEST FOR 32 OR FEWER SHIFTS
                        675 ;
00241A  0C40 0020       676          CMPI.W  #32,D0         ;32 OR MORE SHIFTS?
00241E  65 32           677          BCS     LT32           ;LT32 IF < 32
002420  67 24           678          BEQ     EQ32           ;EQ32 IF 32 SHIFTS
                        679 ;
                        680 ; FINALLY TEST FOR 33 OR MORE SHIFTS
                        681 ;
002422  0C40 0030       682          CMPI.W  #48,D0         ;TOO MANY SHIFTS?
002426  67 16           683          BEQ     EQ48           ;EQ48 IF 48 SHIFTS
002428  6400 FF64       684          BCC     RETN1          ;DONE IF DIFF >#48
                        685 ;
                        686 ; THERE ARE FEWER THAN 48 BIT SHIFTS BUT > 32
                        687 ;
00242C  3E38 190C       688          MOVE.W  M2,D7
002430  4286            689          CLR.L   D6
002432  74 20           690          MOVEQ   #32,D2
002434  9042            691          SUB.W   D2,D0
002436  E06F            692          LSR.W   D0,D7
002438  E351            693          ROXL.W  #1,D1          ;SH BIT -1 TO D1
00243A  D042            694          ADD.W   D2,D0
00243C  60 7C           695          BRA     ALIGN3
                        696 ;
                        697 ; THE NUMBER OF BIT SHIFTS IS EXACTLY #48
                        698 ;
00243E  4286            699 EQ48     CLR.L   D6             ;SET MANT2 = 0
002440  4247            700          CLR.W   D7
002442  72 01           701          MOVEQ   #1,D1          ;SET BIT -1 = 1
002444  60 74           702          BRA     ALIGN3
                        703 ;
                        704 ; THE NUMBER OF SHIFTS IS EXACTLY #32
                        705 ;
002446  4286            706 EQ32     CLR.L   D6
002448  3E38 190C       707          MOVE.W  M2,D7
00244C  E3F8 190E       708          LSL     M2+2           ;SH BIT -1 TO CY
002450  60 66           709          BRA     ALIGN2
                        710 ;
                        711 ; THERE ARE MORE THAN 16 SHIFTS BUT LESS THAN 32
                        712 ;
002452  2E38 190C       713 LT32     MOVE.L  M2,D7
002456  74 10           714          MOVEQ   #16,D2
002458  9042            715          SUB.W   D2,D0
00245A  E0AF            716          LSR.L   D0,D7
00245C  E351            717          ROXL.W  #1,D1          ;SH BIT -1 TO D1
00245E  D042            718          ADD.W   D2,D0
002460  2C07            719          MOVE.L  D7,D6
002462  4246            720          CLR.W   D6
002464  4846            721          SWAP    D6
002466  60 52           722          BRA     ALIGN3
                        723 ;
                        724 ; THE NUMBER OF BIT SHIFTS IS EXACTLY 16
                        725 ;
002468  4286            726 EQ16     CLR.L   D6             ;CLEAR B31-B16
00246A  3C38 190C       727          MOVE.W  M2,D6
00246E  3E38 190E       728          MOVE.W  M2+2,D7
002472  E3F8 1910       729          LSL     M2+4           ;SH BIT -1 TO CY
002476  60 40           730          BRA     ALIGN2
                        731 ;
                        732 ; THERE ARE FEWER THAN 16 SHIFTS; SELECT BEST WAY
                        733 ;
002478  2C38 190C       734 LT16     MOVE.L  M2,D6
00247C  3E38 1910       735          MOVE.W  M2+4,D7        ;MANT 1 TO D6,D7
002480  0C40 0003       736          CMPI.W  #3,D0
002484  62 16           737          BHI     OV3            ;SKIP IF > 3
                        738 ;
                        739 ; SHIFT 1, 2 OR 3 BIT POSITIONS:  WHICH?
                        740 ;
002486  67 06           741          BEQ     ASH3           ;SKIP IF = 3
002488  5340            742          SUBQ.W  #1,D0
00248A  67 0A           743          BEQ     ASH1
00248C  60 04           744          BRA     ASH2
                        745 ;
                        746 ; THIS IS QUICKEST WAY TO SHIFT 1, 2 OR 3 BITS
                        747 ;
00248E  E28E            748 ASH3     LSR.L   #1,D6
002490  E257            749          ROXR.W  #1,D7
002492  E28E            750 ASH2     LSR.L   #1,D6
002494  E257            751          ROXR.W  #1,D7
002496  E28E            752 ASH1     LSR.L   #1,D6
002498  E257            753          ROXR.W  #1,D7
00249A  60 1C           754          BRA     ALIGN2
                        755 ;
                        756 ; THERE ARE MORE THAN 3 BIT SHIFTS BUT LESS
                        757 ; THAN 16;  THE # OF SHIFTS IS IN D0.
                        758 ;
00249C  3606            759 OV3      MOVE.W  D6,D3
00249E  E0AE            760          LSR.L   D0,D6
0024A0  78 10           761          MOVEQ   #16,D4         ;- D4 IS EQUAL TO
0024A2  9840            762          SUB.W   D0,D4          ;16 - # IF SH'S -
0024A4  E96B            763          LSL.W   D4,D3
0024A6  E06F            764          LSR.W   D0,D7
0024A8  E351            765          ROXL.W  #1,D1          ;SH BIT -1 TO D1
0024AA  8E43            766          OR.W    D3,D7
0024AC  60 0C           767          BRA     ALIGN3
                        768 ;
                        769 
0024AE  2C38 190C       770 ALIGND   MOVE.L  M2,D6          ;MANT2 TO D6, D7
0024B2  3E38 1910       771          MOVE.W  M2+4,D7
0024B6  60 02           772          BRA     ALIGN3         ;DO NOT TEST CY
                        773 ;
                        774 ; MANT2 IS NOW ALIGNED TO CORRESPOND TO EQUAL
                        775 ; EXPONENTS FOR FPACC1 AND FPACC2.
                        776 ;
0024B8  E351            777 ALIGN2   ROXL.W  #1,D1          ;SH BIT -1 TO D1
0024BA  2838 1904       778 ALIGN3   MOVE.L  M1,D4          ;MANT1 TO D4, D5
0024BE  3A38 1908       779          MOVE.W  M1+4,D5
                        780 ;
                        781 ; TEST THE SIGNS;  SUBTRACT IF DIFFERENT
                        782 ;
0024C2  3038 1902       783          MOVE.W  S1,D0
0024C6  D078 190A       784          ADD.W   S2,D0
0024CA  6B 3E           785          BMI     FSUB2          ;DIFF SIGNS; SUB
                        786 ;
                        787 ; THE SIGNS ARE THE SAME; PERFORM ADDITION
                        788 ;
0024CC  DA47            789          ADD.W   D7,D5          ;ADD M2 TO M1
0024CE  D986            790          ADDX.L  D6,D4
0024D0  64 1E           791          BCC     ARND           ;ARND IF NO OVFL
                        792 ;
0024D2  E294            793          ROXR.L  #1,D4          ;SHIFT MANT1 R TO
0024D4  E255            794          ROXR.W  #1,D5          ;COMPENSATE OVFL
0024D6  64 06           795          BCC     COVF1          ;NO ROUND IF CY=0
                        796 ;
0024D8  5245            797          ADDQ.W  #1,D5          ;ADD #1 TO 1ST 16;
0024DA  64 02           798          BCC     COVF1          ;COVF1 IF CY = 0 --
0024DC  5284            799          ADDQ.L  #1,D4          ;NO OVFL POSS HERE
                        800 ;
                        801 ; ADJUST EXPONENT TO COMPENSATE FOR OVERFLOW
                        802 ;
0024DE  5278 1902       803 COVF1    ADDQ.W  #1,S1          ;ADD 1 TO EXP
0024E2  0838 0005 1902  804          BTST    #5,S1          ;TEST FOR OVERFLOW
0024E8  67 16           805          BEQ     ADDX           ;OK IF NO OVFL
                        806 ;
0024EA  7E 01           807          MOVEQ   #1,D7          ;ERR1 = OVERFLOW
0024EC  4EF8 21DA       808          JMP     ERROR
                        809 ;
0024F0  E249            810 ARND     LSR.W   #1,D1          ;BIT -1 TO CY
0024F2  64 0C           811          BCC     ADDX
0024F4  5245            812          ADDQ.W  #1,D5
0024F6  64 08           813          BCC     ADDX
0024F8  5284            814          ADDQ.L  #1,D4
0024FA  64 04           815          BCC     ADDX
                        816 ;
                        817 ; SET MANT1 = $8000 0000 0000
                        818 ;
0024FC  E294            819          ROXR.L  #1,D4          ;CY TO MSB
0024FE  60 DE           820          BRA     COVF1          ;ADJ EXP
                        821 ;
002500  21C4 1904       822 ADDX     MOVE.L  D4,M1          ;STORE MAN1
002504  31C5 1908       823          MOVE.W  D5,M1+4
002508  4E75            824          RTS                    ;ADDITION DONE
                        825 ;
                        826 
                        827 ; THE SIGNS ARE DIFFERENT; SUBTRACT
                        828 ;
00250A  3001            829 FSUB2    MOVE.W  D1,D0          ;BIT -1 TO D0
00250C  4E71            830          NOP                    ;POSS ADDQ.W #1,D0
00250E  E248            831          LSR.W   #1,D0          ;SH BIT-1 INTO CY
002510  9B47            832          SUBX.W  D7,D5          ;D4,5 - M1 - M2
002512  9986            833          SUBX.L  D6,D4          ;NO UNDFL POSS
                        834 ;
                        835 ; NORMALIZE; MANT1 IS IN D4.L & D5.W; S1,X1 IN MEM
                        836 ;            BIT -1 IS IN DATA REG 1, BIT 1
                        837 ;
002514  2604            838 NORM     MOVE.L  D4,D3          ;TEST B31-B16
002516  6B E8           839          BMI     ADDX           ;OK OF B31 - 1
002518  5378 1902       840          SUBQ.W  #1,S1          ;DECR EXP
00251C  E249            841          LSR.W   #1,D1          ;SH BIT -1 INTO M1
00251E  E355            842          ROXL.W  #1,D5
002520  E394            843          ROXL.L  #1,D4
002522  6B 4C           844          BMI     SUBX           ;SKIP IF NORM'D
                        845 ;
002524  66 1A           846          BNE     NORM1          ;NORM1 IF B47-16>0
                        847 ;
                        848 ; THE MOST SIG 32 BITS OF THE MANT ARE ZERO
                        849 ;
002526  72 20           850          MOVEQ   #32,D1         ;SHIFT CTR = #32
002528  3805            851          MOVE.W  D5,D4          ;TEST LAST 16 BITS
00252A  6700 FDC4       852          BEQ     RZER1          ;RESULT IS ZERO
00252E  6B 06           853          BMI     SHW1           ;SHW1 IF NORML'ZD
                        854 ;
                        855 ; SHIFT MANT1 (16 BITS) LEFT UNTIL NORMALIZED)
                        856 ;
002530  5241            857 SHW      ADDQ    #1,D1          ;INCR SHIFT CTR
002532  E34C            858          LSL.W   #1,D4          ;SHIFT MANT 1 LEFT
002534  6A FA           859          BPL     SHW            ;DO UNTIL NORM'D
                        860 ;
                        861 ; MANT1 (16 BITS) IS NOT NORMALIZED; STORE IT
                        862 ;
002536  31C4 1904       863 SHW1     MOVE.W  D4,M1          ;STORE B47-B32
00253A  42B8 1906       864          CLR.L   M1+2           ;CLR B31-B0
00253E  60 2C           865          BRA     SLT16X         ;DECR X1 & EXIT
                        866 ;
002540  0C84 00010000   867 NORM1    CMPI.L  #$10000,D4
002546  64 1A           868          BCC     SLT16          ;SHIFT LESS THAN 16
                        869 ;
                        870 ; D4 IS < $10000; SWAP HALVES AND
                        871 ; GATHER 32 BIT MANT1 IN D4.
                        872 ;
002548  72 10           873          MOVEQ   #16,D1         ;SHIFT COUNT = 16
00254A  4844            874          SWAP    D4
00254C  3805            875          MOVE.W  D5,D4          ;32 BIT M1 IN D4
                        876 ;
                        877 
                        878 ; TEST WHETHER 32 BIT MANT1 IS NORMALIZED
                        879 ;
00254E  2A04            880          MOVE.L  D4,D5          ;TEST BIT #31
002550  6B 06           881          BMI     SHL1           ;SHL1 IF B31 = 1
                        882 ;
                        883 ; SHIFT MANT1 (32 BITS) LEFT UNTIL NORMALIZED
                        884 ;
002552  5241            885 SHL      ADDQ.W  #1,D1          ;INCR SHIFT CTR
002554  E38C            886          LSL.L   #1,D4          ;SHIFT MANT LEFT
002556  6A FA           887          BPL     SHL            ;LOOP UNTIL B31 = 0
                        888 ;
                        889 ; MANT1 (32 BITS) IS NOT NORMALIZED; STORE IT
                        890 ;
002558  21C4 1904       891 SHL1     MOVE.L  D4,M1          ;STORE MANT1
00255C  4278 1908       892          CLR.W   M1+4           ;CLR B15-0
002560  60 0A           893          BRA     SLT16X         ;DECR EXP & EXIT
                        894 ;
                        895 ; THERE ARE FEWER THAN 16 BIT SHIFTS
                        896 ; SHIFT MANT1 (48 BITS) LEFT UNTIL NORMALIZED
                        897 ;
002562  4241            898 SLT16    CLR.W   D1             ;SHIFT COUNT = 0
002564  5241            899 SLT16A   ADDQ.W  #1,D1          ;INCR SHIFT CTR
002566  E34D            900          LSL.W   #1,D5          ;SHIFT MANT1 LEFT
002568  E394            901          ROXL.L  #1,D4
00256A  6A F8           902          BPL     SLT16A         ;LOOP UNTIL B31 =1
                        903 ;
                        904 ; MANT1 (48 BITS) IS NOW NORMALIZED
                        905 ;
                        906 ; SUBTRACT THE SHIFT COUNT FROM THE EXPONENT
                        907 ; AND THEN TEST FOR UNDERFLOW.
                        908 ;
00256C  9378 1902       909 SLT16X   SUB.W   D1,S1          ;DECR EXP
002570  0838 0006 1902  910 SUBX     BTST    #6,S1          ;TEST FOR UNDFL
002576  6600 FD78       911          BNE     RZER1          ;ZERO ON UNDFL
00257A  21C4 1904       912          MOVE.L  D4,M1          ;STORE MANT1
00257E  31C5 1908       913          MOVE.W  D5,M1+4
                        914 ;
002582  4E75            915          RTS                    ;NORM OR SUB DONE
                        916 ;
002584  <140>           917          DS.L    80
                        918 ;
0026C4  00000000        919 N        DC.L    $00000000      ;LONG WORD
   @ 000026C8           920 NSQD     EQU     N+4            ;N SQUARED
   @ 000026CC           921 ARYST    EQU     NSQD+4         ;WORD
   @ 000026CE           922 CPTR     EQU     ARYST+2        ;WORD
   @ 000026D0           923 RPTR     EQU     CPTR+2         ;START OF ROW VECT
   # 00001926           924 FCTR     EQU     EXPADD