Q & A Stack 4.0.5
Table of Contents
Devices & Hardware
Graphics, Imaging & Printing
Networking & Communications
Operating System
Platforms & Tools
Toolbox & IAC
Devices & Hardware: A/ROSE & MCP Card: NuBus’90 and MCP card timing
The Macintosh Coprocessor (MCP) card uses the NuBus 10 MHz clock for the system clock and the NuBus’90 clock is 20 MHz, so how can the cards continue to work? The 68000 isn’t rated for 20 MHz. Is there a new pinout for NuBus’90 that provides both clocks?
The NuBus’90 CLK signal (pin C32) is 10 MHz (didn’t change); the 20 MHz clock signal is the CLK2X signal, which is pin B24 (previously -5.2 Volts).
Devices & Hardware: A/ROSE & MCP Card: A/ROSE NetCopy process description
How does the NetCopy cVirtualToReal routine work in the oscglue.a file of the Portable A/ROSE code? I’m trying to emulate the NetCopy command in my A/ROSE code. II want the copy routine to work without requiring the user to use the LockRealArea command on the MacOS side, but this means that I have to worry about the addressing being passed in as being virtual. Is the A/ROSE kernal on the board providing the virtual-to-real mapping or does it just send a message back to A/ROSEprep to do it and then uses the results?
What cVirtualToReal() does is take as input, a transaction ID (TID), a virtual address and a size. It returns a NuBus address and a size. If the returned size is zero, cVirtualToReal() could not find a corresponding NuBus address for the virtual address. If the returned size is non-zero, this size is the size of the contiguous address range for the virtual address starting at the NuBus address.
This is how cVirtualToReal() works: cVirtualToReal() examines the TID to find out the slot (call it slot s) associated with the TID. cVirtualToReal() looks at the iccm communications area of slot s looking at MapCnt, MapPtr, and MapChk. (Please refer to iccmDefs.h or iccmDefs.a in the iccm commucations area record ca_Rec.)
If MapCnt is zero, the virtual address is assumed to be the same as the NuBus address. In this case, cVirtualToReal() sets the returned NuBus address value to be that of the virtual address and returns the size the same as the size on input.
If MapCnt is non-zero, the slot either has an address scheme where the virtual address that the TID on slot s uses cannot be the same as the NuBus address (say the processor was a 68020 with no PMMU and required that local card addresses have zero for the high address byte) or the slot has something like VM (which is what happens on the main-logic board). cVirtualToReal() will use the address map pointed to by MapPtr on slot s to try to resolve the virtual address to a NuBus address. MapPtr is a pointer to a linked list of struct AddrMap (defined in os.h or os.a). If cVirtualToReal() can resolve the virtual address by looking at the AddrMap entries, it will do so. If cVirtualToReal() cannot, it will return zero for the size. The MapChk and MapCnt variables in ca_Rec are used for concurrancy. cVirtualToReal() will fetch a pointer from the MapPtr structure and then check to see if MapChk has changed. cVirtualToReal() knows that the pointers in MapPtr and the AddrMap entry have not changed if MapChk has not changed. cVirtualToReal() starts its search over at the beginning of the MapPtr list should MapChk change. cVirtualToReal() knows that it can start searching the MapPtr list only when MapCnt equals MapChk.
What cLockRealArea() does is take as input a virtual address and size and returns on output the NuBus address/length pairs associated with that virtual address and size. cLockRealArea() also returns a success/failure status indicating if cLockRealArea() successfully “locked” the pages in memory associated with the virtual address and size.
Please note: there is a cLockRealArea() on the main logic board used to lock memory on the main logic board. There is also a cLockRealArea() in the A/ROSE kernel on the NuBus card which WOULD lock memory on the NuBus card. The cLockRealArea() on the NuBus card acts as a no-op at this moment and is present for compatibility reasons.
Here's a descritpion of how cLockRealArea() works: cLockRealArea() on a NuBus card acts as a no-op. cLockRealArea() on a NuBus card returns a NuBus address/length pair as one would expect but otherwise does nothing.
cLockRealArea() on the mainlogic board is much more interesting. cLockRealArea() on the main-logic board tries to lock down the pages associated with the virtual address/size (assuming a PMMU is present and the appropriate a_line traps are present) calling either _LockMemory or _LockMemoryContiguous . Next, if _LockMemory or _LockMemoryContiguous works, cLockRealArea() tries to create an AddrMap entry to store the NuBus addresses associated with the virtual address. cLockRealArea() needs to call _LockMemoryContiguous on this AddrMap entry to lock it down as well. Finally, if cLockRealArea() has made it this far, cLockRealArea() will try to insert the AddrMap entry into the linked list pointed to by MapPtr in the iccm communications area ca_Rec. cLockRealArea() will change MapChk, insert the AddrMap entry, and then change MapCnt to be the same value as MapChk.
What cNetCopy() does is take as input a source TID/source address, destination TID/destination address, and size. cNetCopy() calls cVirtualToReal() to convert the source TID/source address and the destination TID/destination address into NuBus addresses. If cVirtualToReal() can convert the addresses, cNetCopy() will perform a blockmove() operation moving the data itself. If cVirtualToReal() cannot convert the addresses, cNetCopy() will send an A/ROSE IPC message to the NuBus slot (please note that the main logic board is NuBus slot zero) asking the iccm (please note that iccm is built into the A/ROSE driver on the main logic board) to perform the copy. Iccm will perform the copy and send a reply back to cNetCopy() when the copy is complete.
At this moment, the only slot that can have virtual addresses that cVirtualToReal() cannot convert to NuBus addresses are main-logic board addresses. cVirtualToReal() can always resolve virtual addresses that exist on NuBus cards.
If the user on the MacOS side does not use LockRealArea() and PMMU is believed to be active, an A/ROSE IPC message is sent from the NuBus card to the iccm portion of the A/ROSE driver on the main logic board to perform the copy. The iccm portion of the A/ROSE driver will send back a reply when it has performed the copy.
One unasked question is could the card request that memory on the main-logic board be locked down from the card. The answer to this question is no. The LockRealArea() routine on the main-logic board which does the locking down of memory on the main logic board associates the memory that it is locking down with the TID of the main-logic board process that is calling LockRealArea().
Devices & Hardware: A/ROSE & MCP Card: gCommon addresses and downloading card-dependent routines
After upgrading to A/ROSE 1.1.2, when I download to my board, it doesn’t call my board-specific routines in the resource 'hlta' that I installed into A/ROSE prep.
Check the gCommon area on the card at locations gCardInit0, gCardInit1, and gCardInit2. These are the addresses where the Download subroutine would have placed the card-dependent routines when placing the routines on the card. You can find these addresses in the :A/ROSE:includes:arose.a header file.
If these addresses are zero, that means either the Download subroutine failed to find the card-dependent routines when doing the downloading, or the Download subroutine is the wrong version and doesn’t know about card-dependent routines, or the application doing the downloading was not linked with a recent enough version of Download-Lib.o and contains the old Download subroutine code. The actual code for doing downloading has been moved from the application to the A/ROSE Prep file and glue code is now in the Download-Lib.o file, which is what the application really calls. This glue code knows how to load the actual downloading code.
If these addresses are non-zero, A/ROSE, during its initialization, should call these routines. If A/ROSE is not calling them, check to see where the A/ROSE kernel is coming from. Was the A/ROSE kernel linked in with the code. In this case, you need to relink your code with a more recent version of the A/ROSE kernel.
Devices & Hardware: A/ROSE & MCP Card: A/ROSE & MCP card for real-time priority multitasking
Our application communicates via serial I/O with real-time devices in the field. Some functions of our application must run at a higher “priority” than anything else on the Macintosh®, even if a MultiFinder®-hostile application takes over the CPU to do animation or whatever. Our initial approach is to perform these critical functions at ioCompletion (interrupt) time, but this is a royal pain in the neck to implement. We’d rather not require A/UX® because it increases the price and complexity of our system. What’s the best way to make it all hang together?
The Macintosh, by itself, is not a valid platform for real time processes or priority multitasking. A/ROSE™ (Apple/Real-time Operating System Environment) which runs concurrent prioritized processes on compatible coprocessor NuBus cards should fit your needs nicely.
A/ROSE runs as a driver under the standard Macintosh operating system. It downloads, starts, stops, sets priorities, and communicates with real-time processes that run on any A/ROSE compatible NuBus card. The Apple (Macintosh Coprocessor Platform™ (MCP) card is available from APDA® (Macintosh Coprocessor Platform Developers Kit #M0793LL/A) and provides you with an MCP card, A/ROSE, A/ROSE documentation and development information on how to design your own (if you prefer) coprocessor card. There is also an excellent article in Issue 4 on developing with A/ROSE and MCP.
An alternative development environment for real-time programming would be to license and develop your application under A/UX on the Macintosh.
I would not suggest trying to ‘tough it out’ at interrupt level as this will put you at odds with the way the Macintosh operates; accRun time will never provide you with ‘priority’ runtime, only time that is otherwise available. Patching StillDown is just not a supportable option. Were I attempting this project I would head straight for A/ROSE and run it on either the Apple Serial NB card (A/ROSE compatible with on-board 10 MHz 68000 and 4 dedicated serial ports) or design my own serial hardware on the MCP card.
Devices & Hardware: A/ROSE & MCP Card: A/ROSE & MCP development questions
What restrictions (power, speed, and so on) does the Macintosh Coprocessor Platform™ (MCP) impose on the hardware added to the platform? Can we use A/ROSE™ on a board which we design ourselves from scratch? If so, we have the following questions concerning the hardware requirements for a board running A/ROSE: Must the CPU running A/ROSE be a 68000 or could it be a 68020 or 68030? Can A/ROSE handle master transfers under NuBus control between the card and main board memory? Is the source code for A/ROSE (and specifically the InterCard Communication Manager) available if we needed to tailor that code to our system?
To the knowledge of the A/ROSE engineer, A/ROSE requires modification in order to permit master transfers under NuBus control between the card and main board memory. The engineer succeeded in designing a routine to perform the write operation from A/ROSE; however, the read operation proved to be a challenge. A solution to your problem would be to release the source code. However, at this time this isn’t possible. There has been consideration on this subject but no final decision.
In response to your other questions, MCP doesn’t impose any restrictions on the hardware. There are some card dependencies imposed by A/ROSE, described in the document, “A/ROSE Card Dependency,” available on AppleLink.
I’m familiar with a couple of cards based on the MCP board. On one card in particular, the processor was swapped with a 68020 using A/ROSE.
Devices & Hardware: A/ROSE & MCP Card: Ordering a Macintosh Coprocessor Platform (MCP) card
How do I order a Macintosh Coprocessor Platform™ (MCP) card and software? What do I get when I order it?
You can order the MCP card and software through Apple Software Licensing. The card comes with the MCP platform and software which contains the appropriate libraries and header files. On the card is the 68000, ROM (256K), RAM (512K), and the NuBus Logic to drive the card in both master and slave modes. There is also blank space on the board, left there for your communications hardware. Basic documentation is also included.
Devices & Hardware: Apple Desktop Bus: ADBReinit clarification
ADBReinit doesn’t seem to work exactly as described in the Apple Desktop Bus (ADB) documentation. Please clarify.
A SendReset command byte is never sent across the bus, as Inside Macintosh and other documentation seems to imply. In fact, when the ADB Manager is asked to SendReset, it actually instructs the ADB transceiver to assert an Global Reset pulse.
The Talk R3 sequence after a reset is as follows: each of the 16 device addresses is polled once, and then the ADB Manager returns to the addresses that did not time out (addresses which contain at least one device) and retries those addresses (moving devices between default and temporary addresses) multiple times (50 in the current implementation) until it is satisfied that devices have separated properly.
This initialization task is patched out by System 6.0.5 and later, so every machine can use the new, improved ADB Manager which debuted with the Macintosh IIci ROM.
Devices & Hardware: Apple Desktop Bus: Minimizing ADB Manager address resolution collision potential
Minimizing ADB Manager address resolution collision potential
Apple offers two suggestions to minimize the potential for collisions during address resolution using the Apple Desktop Bus (ADB) Manager:
1. Use a somewhat random stop-to-start time in the range 140 µs ≤ Tlt ≤ 260 µs. Don’t be too generous here, however. Tlt is one of the more sensitive ADB timing parameters and it’s best to be near the middle of the window—try not to be too close to the endpoints or you may notice erratic behavior. Of course, there is a finite amount of time in the Tlt window and there are a finite number of random addresses a device may return, but in most cases devices should be able to resolve themselves properly. If they do not, it should be a rare coincidence which can be resolved by rebooting or simply using a utility program which executes the
_ADBReinit trap.
2. Return a random number in the R3 address field. In fact, you’re never required to respond with your actual address in response to a Talk R3. You only must keep track of what your current address is and readdress in accordance with Listen R3 commands from the host. By returning a random number in the address field, you minimize the possibility that two devices are transmitting exactly the same data on the bus at exactly the same time. This is the only instance where a well-designed algorithm would fail to detect a collision.
A well-designed algorithm detects collisions by sensing the ADB data line asserted when it is not expected to be. It must monitor for this condition before transmitting and any time the device is transmitting and expects the data line to be negated. One check per bit cell is typically not sufficient. Monitoring for collision should be a key, repetitive part of the transmission process.
Devices & Hardware: Apple Desktop Bus: Apple Desktop Bus (ADB) startup timing
I need exact Apple Desktop Bus (ADB) startup timing data for each Macintosh model. When does the ADB query to devices first go out and when does it receive confirmation of a device present? When does the File Manager start loading the control files? What type of signal is sent and received--a pulse of what parameters?
It’s not possible to tell you when ADB devices are initialized after power- up with any accuracy, because it depends on factors such as how much RAM is in the machine and what kind of screens are connected to it. When the system begins loading control files, it’s even more variable, depending on things like disk speeds and if the user is booting off a floppy. In general, timing issues are difficult with the Macintosh, as it doesn’t even approach being a real-time machine.
Regarding the characteristics of the ADB startup sequence, the best thing to do is get the ADB Specification from Apple’s Software Licensing; it contains all the information you need (along with Inside Macintosh and the Macintosh Hardware Reference) to build an ADB device.
Devices & Hardware: Apple Desktop Bus: Apple IIGS and ADB device differentiation
The Apple IIGS® does not seem to sort out equivalent devices on the Apple Desktop Bus™ (ADB) as the Macintosh® does and as outlined in the ADB specification. We want multiple keyboard support, but the Apple IIGS ADB micro just begins reading blindly from addresses 2 and 3, assuming one keyboard and one mouse are attached. Is this information correct?
The Apple IIGS does not do the same kind of dynamic device mapping and remapping that the Macintosh ADB Manager does. The “Apple Desktop Bus Tool Set” chapter of the Apple IIGS Toolbox Reference gives instructions on how to remap devices dynamically yourself. Essentially, you have two options:
• You can leave the second keyboard address as 2, allowing input from multiple keyboards, but the keyboards’ modifier key input will be mixed.
• You can dynamically remap the keyboards in your program or in an INIT (although some forms of remapping require the user to press a key on the device to be remapped) and then a second keyboard will not appear as the standard keyboard—requiring all who use it to do their own ADB requests to get at the information entered from a second keyboard.
If you don’t expect many developers to use a second keyboard, you might just choose to remap it inside any program that uses it. You could write an external library or functions that remap a second keyboard and read from it.
Devices & Hardware: Apple Desktop Bus: ADB power requirements on Macintosh LC
What is the maximum power draw on the Apple Desktop Bus™ (ADB) on the Macintosh® LC? The low-power mouse specifications state that the mouse shall consume no more than 10 mA. Why does Apple specify 80 mA for a mouse on the Macintosh LC? What does Apple recommend for maximum power consumption for a third-party ADB device?
The power budget for the Macintosh LC’s ADB port changed after the information was compiled for its product information sheets. The Macintosh LC can supply the standard 500 mA that all ADB hosts are supposed to supply.
The standard keyboard and mouse are specified to draw no more than 100 mA. Because any of these devices may be attached to a Macintosh LC, it is necessary to specify the machine for significantly more than the 10 mA actually drawn by “low-power” ADB peripherals.
Apple has always recommended that ADB devices requiring 100 mA or more be designed to provide their own 5 V power source. The ADB engineering specification (062-0267), which you get when you license our ADB technology, has both the host and the device power loading information on page 4.
Devices & Hardware: Apple Desktop Bus: Timing extremes & undefined transaction sizes cause ADB problems
Why do my ADB devices fail often after a restart on my Macintosh® IIfx, but work fine on other Macintosh models? Why do they simply not work on the Macintosh IIsi and Macintosh LC?
With each new system release and each new machine we hear a few more complaints about broken ADB devices. This is true of system software versions 6.0.4 and 6.0.5, and the Macintosh IIci, IIfx, IIsi, and LC.
A little historical perspective is in order. The Apple Desktop Bus™ specification is pretty sloppy with tolerances as high as ±30% on some signal timings. This has led to many marginal implementations for ADB devices, both within Apple and from third parties. Unfortunately, the first generation of machines supporting ADB could have been even more lenient than the specification, so that devices which were -35% might have worked just fine. In at least one instance, a minimum timing was not enforced at all! Our more recent products and system software, while remaining within specifications, are relatively stricter about allowable tolerances.
The most common manifestation of an ADB timing problem is during device initialization. Developers must adhere strictly to the minimum and maximum delay times for initialization transactions and they should aim for the middle of the tolerance window, not the edge. Of particular importance recently is the Tlt (stop to start time) parameter from the ADB Specification. Nominally it is 200 µs. The minimum delay is 140 µs. Many devices which do not initialize properly are found to respond more quickly than this minimum delay during the TalkR3 initialization sequence.
The problem with the Macintosh IIsi and LC is one of protocols. The ADB specification requires a transaction to consist of at least two bytes. Some device/driver combinations have been getting away with “single-byte” transactions. These will not necessarily slip by newer implementations.
Devices & Hardware: Apple Desktop Bus: ADB name mapping
Where is the translation of ADB (Apple Desktop Bus™) type from an unsigned integer (e.g., 1) to the “real” thing (e.g., “mouse”) documented? If so, what is it?
The only mappings of device IDs and addresses to names that you can rely on are the ones that appear in Inside Macintosh. Most devices appear like one of those devices. However, there isn’t any other ID to name mappings.
Devices & Hardware: Apple Desktop Bus: “How to ADB” Apple Desktop Bus references
I understand that doing Apple Desktop Bus™ (ADB) development for mice (or is it mouses) can be difficult. Are there many undocumented technical issues which I need to be aware of in order to effectively communicate with the ADB bus?
You should have the following bits o’ info:
• Inside Macintosh®, Volume V, Chapter 20, “Apple Desktop Bus”
• Macintosh Technical Note #206, “Space Aliens Ate My Mouse (ADB-The Untold Story)”
• Macintosh Technical Note #266, “Absolute Pointing Device Memory Structure”
• Macintosh Technical Note #160, “Key Mapping”
• Apple Desktop Bus specifications package. This is a package of official
Apple Specifications covering the ADB protocol, and Apple-manufactured ADB Devices. This is available from Apple’s software licensing department upon execution of an ADB License Agreement. Contact the licensing department at:
Apple Software Licensing
Apple Computer, Inc.,
20525 Mariani Avenue, M/S 38-I
Cupertino, CA, 95014
(408) 974-4667
AppleLink®: SW.LICENSE
Additional ADB references:
Inside Macintosh, Volume V, The Apple Desktop Bus
Macintosh Family Hardware Reference
Apple IIGS® Hardware Reference Manual
Apple IIGS Firmware Reference Manual
IMPORTANT NOTE: In the case of a discrepancy between the ADB specification and a reference manual, the specification supersedes.
Baum, Peter.
“Boarding the Bus,” MacUser, July 1987, p. 142.
“An Overview of Apple Desktop Bus,” Call A.P.P.L.E., June 1987, p. 24.
In addition to the written word, there are some code samples that will probably prove useful:
• MacDTS Sample Code #SC.017.TbltDrvr - An example pointing device driver for the Macintosh
• ADBLister - A simple program that uses the ADB manager to display information about devices connected to ADB. (On the Developer Series CD, in a folder called “Cameron’s Source”).
Finally, for any remaining questions, contact Macintosh Developer Technical Support via AppleLink at “MacDTS” or via the US Mail at:
Macintosh Developer Technical Support
Apple Computer, Inc.
20400 Stevens Creek Blvd. MS 75-3T
Cupertino, CA 95014
Devices & Hardware: Apple Desktop Bus: Using the LEDs on the Apple Extended Keyboard
How can I use the LEDs on the Apple® Extended Keyboard?
Using the LEDs on the extended keyboard involves the _ADBOp call. Once you determine that you have an extended keyboard (with _CountADBs and _GetIndADB), then register 2 of the extended keyboard has the LED toggles in the low 3 bits.
Therefore, you would do a Talk to register 2 to have the device send you the contents of register 2, manipulate the low 3 bits to set the LEDs, and then pass the modified register 2 back to the device with a Listen to register 2 command.
The Apple Extended Keyboard has an ID of 02 and a device handler ID of 02, while the Apple Standard Keyboard has an ID of 02 and a device handler ID of 01.
Note: At this point it is not clear what Apple has in mind for these LEDs, so you are using them at your own risk.
Devices & Hardware: Apple Desktop Bus: _ADBOp call service routines and data areas
I am confused about the service routines and data areas passed in the _ADBOp call. What does it all mean?
That’s a good question.
FUNCTION ADBOp (data:Ptr; compRout:ProcPtr; buffer:Ptr;
commandNum:INTEGER) : oserr;
data is a pointer to the “optional data area.”
This area is provided for the use
of the service routine (if needed).
compRout is a pointer to the completion or service
routine to be called when the _ADBOp command
has been completed. It has the same meaning
as the service routine passed to the
_SetADBInfo call.
buffer is a pointer to a Pascal string, which may
contain 0 to 8 bytes of information. These
are the 2 to 8 bytes that a particular
register of an ADB device is capable of
sending and receiving.
commandNum is an integer that describes the command to
be sent over the bus.
There is some confusion over the way that the completion routines are called from _ADBOp. This calling may be done in one of the following three ways:
(1) You do not wish to have a completion routine called, as in a Listen command. Pass a NIL pointer to _ADBOp.
(2) You wish to call the routine already in use by the system for that address (as installed by _SetADBInfo). Call _GetADBInfo before calling _ADBOp, and pass the routine pointer returned by _GetADBInfo to _ADBOp.
(3) You wish to provide your own completion routine and data area for the _ADBOp call. In this case, simply pass your own pointers to the _ADBOp call.
Remember, there rarely should be a reason to call _ADBOp. Most cases are handled by the system’s polling and service request mechanism. In the cases where it is necessary to call _ADBOp, it should not be done in a polling fashion, but as a mechanism of telling the device something (for example, change modes, or in the case of our extended keyboard, turn on or off an LED).
Devices & Hardware: Apple Desktop Bus: Using ADB to auto power up the Macintosh
How can I make my Macintosh® II or IIx power up automatically after a power outage?
The Macintosh II and IIx power can be turned on via the keyboard through the Apple Desktop Bus™ port (ADB) since the reset key is wired to pin 2 of the ADB connector. When you press this key, it pulls pin 2 to ground and initiates a power-on sequence. You can emulate this feature with a momentary switch connected to the ADB port. Note that the switch on the back panel of a Macintosh IIcx can be locked in the On position to automatically restart after a power outage.
An idea for a power-on circuit would be to have a momentary (one-shot) relay powered by the same outlet that powers the machine and have the contacts close pin 2 of the ADB connector. (Without having tried this, I am concerned that you may need a delay before the relay fires to give the AC time to stabilize, etc.)
Devices & Hardware: Apple Desktop Bus: Boot time ADB device address conflict resolution
I’m confused about the way Apple Desktop Bus™ (ADB) device address conflicts are resolved at boot time.
The method used by the host to separate and identify the devices at boot time is not well documented, so I’ll try to describe it with some clarity.
The host issues a Talk R3 command to an address. Let’s say there are two devices at that address. Both try to respond to the command, and when they try to put the random number (the address field of register 3) on the bus, one of them should detect a collision. The one that detects the collision backs off and marks itself (internally) as unmovable.
The device that did respond successfully is then told to move to a new address (the highest free address). By definition, moving to a new address means that it now responds only to commands addressed to this new address, and it ignores commands to the original address.
The host then issues another Talk R3 command to the original address. This time the second device responds without detecting a collision. When it successfully completes a Talk R3 response, it marks itself as movable. It then is told to move to a new address.
The host again issues a Talk R3 command to the original address. Since there are no more devices at that address, the bus times out, and the host moves the last device back to the original address. At this point, the host moves up to the next address that has a device and begins the process all over.
Generally, when you have trouble separating devices on the ADB, it is because the collision detection doesn’t work well. In fact, this problem is evident on Apple® keyboards. The bug is that the random number returned in R3 isn’t really a random number. Since the microcontrollers on the keyboards are clocked with a crystal, they tend to generate the same “random” number, so when the system attempts to separate them with a Talk R3 command, they never detect the collision.
One possible solution is to use a low-tolerance capacitor on the reset line of the microcontroller, thereby forcing the time from power on to the time reset is negated to be fairly random. In this way, the microcontroller can start a count until it receives the first Talk R3 command, and hopefully it is a different number from the number of another device at the same address on the bus.
If you find your device shows up at all addresses, it may be because it is responding to the move address command when it should be marked as unmovable.
Finally, if the device doesn’t show up at all, it may be because it is unable to respond to the Talk R3 command at boot time (that is, it is not able to initialize itself and start watching the bus in time).
Devices & Hardware: Apple Desktop Bus: Distinguishing between two keyboards on the Macintosh
I connected two keyboards to my Macintosh®, but I can’t distinguish between the two. How can I tell which keyboard a key press came from?
Because of a problem in the Apple Desktop Bus™ (ADB) code, keyboards do not always correctly resolve collisions (multiple devices of the same type on the bus). This problem is in the keyboard, not in the Macintosh. For some applications, simply trying different keyboards until you find two that are assigned different IDs may be a workable solution. An Apple® Keyboard and an Apple Extended Keyboard should not collide when connected on the same bus.
Devices & Hardware: Apple Desktop Bus: Use of Apple’s ADB Transceiver IC for complex signal timing
I want to design the next best-selling graphics pad for Macintosh®. I plan to use Apple Desktop Bus™ (ADB). Is there a chip set available to implement the complex signal timing of the ADB specification?
Sorry. Apple’s ADB Transceiver IC is proprietary and not currently for sale or licensing. This is the greatest hurdle in designing your own ADB device and requires that you implement your own logic via a dedicated processor or application-specific integrated circuit (ASIC).
Devices & Hardware: Apple Desktop Bus: Apple Desktop Bus (ADB) licensing information
Apple Desktop Bus (ADB) licensing information
To license the Apple Desktop Bus™ and ADB Device Specifications, contact:
Apple Software Licensing
Apple Computer, Inc.
20525 Mariani Ave., M/S 38-I
Cupertino, CA 95014
1-408-974-4667
AppleLink: SW.LICENSE
Devices & Hardware: Apple II: Macintosh LC Apple IIe Card technical reference
Does the Apple IIe Card for the Macintosh LC have a technical reference manual?
There’s no separate technical reference manual. Use the Apple IIe Technical Reference (Addison-Wesley), together with Apple IIe Technical Note #10, “The Apple IIe Card for the Macintosh LC.”
Devices & Hardware: Cache: Apple IIGS caching logic if GS/OS cachePriority word is zero
Matt, I found your Apple IIGS® caching article to be very informative, but I’m confused about the driver level of caching. You say that if the cachePriority word on GS/OS direct page is zero, the driver should not write the block to the cache. If the block was already in the cache, won’t this mean the disk has a different block than is in the cache, messing things up drastically?
Thanks, and yes. When a driver is supposed to ignore the cache on a write call (because the cachePriority field is zero), it still must deal with the possibility that the block may already be in the cache. When writing with cachePriority zero, drivers may not add new blocks to the cache but must update blocks that are already in the cache. This step is necessary because the next time someone reads with caching enabled, the block in the cache will be returned. Next time I forget something, I promise that it will be less important.
Devices & Hardware: CD-ROM: CD-ROM and File Sharing
How do I make a single CD-ROM drive visible to users over the network? When I connect the CD-ROM drive to a machine running System 7.0 with File Sharing turned on, the CD-ROM drive doesn’t show up in the volume list at startup.
Unless a CD is specifically mastered to be compatible with File Sharing, it won’t be sharable. It doesn’t work as it does for hard drives because not all CDs are in HFS format and have the appropriate directory information that File Sharing requires. The easiest way to determine whether the CD you have is sharable, go to your System 7 machine, try selecting the disc, and then select “Sharing…” from the File menu. It will tell you if the disc can’t be shared. This may be the most likely reason why you couldn’t see the CD from a remote workstation. However, if that’s not the reason, it may be one that follows.
Folders from a CD-ROM disc can be shared the same way as a folder on a local hard disk. However, to be shared, the CD-ROM must be inserted before File Sharing is turned on. To switch between CD-ROMs, File Sharing must first be turned off, the new CD-ROM inserted, and File sharing turned back on.
If you insert a CD-ROM while File Sharing is on, you can eject and insert the disc, but you can’t share it. If a CD-ROM is inserted before File Sharing is on, then you have to turn File Sharing off to eject it.
Devices & Hardware: CD-ROM: File Sharing and CD-ROM discs
When I tried to disconnect (unmount) a CD-ROM in System 7.0, I got the message, “Can’t put away. Disk is being shared.” However, File Sharing status shows no volumes/folders shared. Restarting the Macintosh fixes the problem.
When File Sharing starts up, it takes a snapshot of the volumes available on the current desktop. All volumes (excluding floppies, which cannot be shared) are implicitly shared. This occurs even if no one is connected to your system, and you have not explicitly shared any folders/volumes via the Sharing menu.
The reason for this is that when you start File Sharing, you are making all volumes on the machine available to the owner from anywhere on the network. Therefore, your CD-ROM, and any other removable media, such as removable hard drives and optical drives, are now being shared for the owner and can't be removed.
If you make a volume available to your system after File Sharing has been started, that volume won't be available to the owner unless you explicitly share it via the Sharing menu. Therefore, once you start File Sharing either by booting with it active, or through the Sharing Setup Control Panel, you can mount and unmount new volumes as often as you like until they are explicitly shared.
If you wish to remove a volume that has been implicitly shared from your desktop, turn File Sharing off, remove the volume, and then turn File Sharing back on without restarting your system.
Restarting your Macintosh works because your CD-ROM ejects at restart, File Sharing is reset, and then you re-insert the CD-ROM.
(This Q&A was stolen from AppleLink’s Tech Info Library for Dev Tech Answers because developers ask this question frequently.)
Devices & Hardware: CD-ROM: HyperCard 2.0 and High Sierra format
With HyperCard 2.0 when accessing files in High Sierra format, the same stack that works OK on our hard disk fails to work on a CD-ROM. Some text files aren’t opened with the “open fname” instruction. Is it the “HOME.;1” syndrome—that is, should scripts say “open fname.;1”?
The problem probably does lie in the fact that the standard ISO naming convention has the “;1” appended. The workaround is to see if “open fname;1” works, but there may be a problem with the Home stack. You can insist that the home stack be copied to a local disk, or you can edit the string in HyperCard that has the name of the Home stack. In HyperCard 2.1 it’s in STR# 128 (“Misc”), item 17. Or you could violate the ISO naming convention and select your own name without the suffix.
Devices & Hardware: CD-ROM: Using the Macintosh ISO 9960 FST with another drive
How can I write an extension to the CD-ROM driver, such as a 'ufob' like the ISO 9660 module, or how can I use the 9960 with some other kind of drive?
You can use the ISO 9960 File System Translator with any type of drive. The only requirement is that the drive contain a file system in the ISO format. The file system just doesn’t care. The file system on the Macintosh® looks something like this:
Application (could be the Finder™)
|
V
File Manager
/ \
HFS Volume / \ Some Other Format Volume
/ \
(HFS) External File System (FFA, AppleShare®)
| |
| ISO, High Sierra, Audio CD
| File System Translators
| |
| |
Block Oriented Device Driver
(CD-ROM, Hard Disk, Floppy Disk, etc.)
||
\/
Data on Disk
Basically, what’s going on is if HFS doesn’t recognize a volume it passes control on to the External File System hook, which tries to decode the volume format of the unrecognized disk. You can think of the ISO FST as a decoder for Foreign File Access that “knows” what ISO disks look like. It in turn makes calls to the low-level driver associated with the device in question. The net result is that you can use FFA with any block-oriented device. All that needs to be written is a driver.
That’s the good news. Writing a Foreign File System or even an FST is an incredibly difficult procedure. Because the documentation is so poor and the mechanisms so convolved, it’s so hairy that DTS is unable to support it. It probably would take between 25 and 35 man-months of *extremely* talented Macintosh programmers to pull it off.
Devices & Hardware: CD-ROM: CD Remote INIT must be in System 7’s System Folder root
How can I use the CD Remote DA under Macintosh® System 7.0? I installed from the new CD utilities, but I get the message “can’t find the INIT.”
CD Remote INIT versions prior to 3.1 must be in the System Folder, not in the Extensions Folder. CD Remote INIT version 3.1 installs itself in the proper place, and has other bug fixes as well. Because of the bug fixes, you should upgrade to the current version, included with System 7.0 packages and available on AppleLink®.
(Placing an INIT in System 7.0's System Folder generally helps if you encounter a similar incompatibility problem. Some third-party products need to be upgraded to know about the various folders available. If you’re using a product that needs upgrading, make sure its developer is aware of the problem.)
Devices & Hardware: CD-ROM: Mounting audio CDs under MultiFinder
Using Macintosh® System 6.0.5, and/or System 6.0.7, and Apple CD-ROM driver set version 3.0.1 and/or version 3.0.2, I cannot mount Audio CDs under MultiFinder® or Finder™. I get the message “Please unlock the disk ‘Audio CD 1’ and try again. The desktop file couldn’t be created.”
However, if I am using a single application (say, HyperCard® 2.0), with MultiFinder turned off, I am able to mount an Audio CD without trouble.
That’s an odd problem. So why don’t you just unlock the Audio CDs? Sorry, just kidding! You should be able to mount CD-ROM discs from MultiFinder without any problem at all. I have a few suggestions for you to try:
First, try starting up your computer on the CD Installation disk. This assures that there are no strange INITs or anything loaded other than the CD-ROM software. If this works fine, this indicates some strange INITs in your System Folder.
Also, make sure your RAM cache is set to a value other than 32K. System 7.0ß1 has a bug in that if the RAM cache is set to 32K, it won’t allow you to mount CDs.
Last, try different combinations of SCSI cables, computers, and CD-ROM discs if you have the spares.
Devices & Hardware: CD-ROM: No changes to AppleCD SC driver 3.0.2
What’s the difference between the Macintosh AppleCD SC® software 3.0.2 uploaded to “Apple SW Updates” on AppleLink® and the old 3.0.1 update? According to the ResEqual utility in MPW®, all files are the same. So what’s the story?
There really aren’t any “real” changes with the AppleCD SC driver between 3.0.1 and 3.0.2. Basically all that was changed was the Installer script to make it compatible with Macintosh® System 6.0.7.
Devices & Hardware: CD-ROM: Why does my CD-ROM take so long to mount?
Why does my CD-ROM take so long to mount?
Slow loading can happen in several ways. For example, slow loading happens if you (or the CD-ROM mastering company) forgot to dismount the hard disk volume before making a copy for mastering. Whenever an HFS disk is mounted, a bit is set in the volume’s header, and it’s cleared again when you dismount the disk or shut down the Macintosh® normally. (Ever wondered what “You may now shut off your Mac safely” means? Now you know!) The purpose of this bit is a “crash flag”—if the Mac dies abnormally, leaving the bit set, at the next boot the Mac will recheck the integrity of the file structure and Desktop of the disk, just in case something got smashed during the crash. So if you master from a hard disk that has the bit set because you didn’t dismount it, the Mac will think your CD-ROM is potentially crashed every time you load it, and will spend a lot of time rechecking EVERYTHING on the CD.
If you are pressing a CD-ROM in High Sierra or ISO 9660 format, and it has a lot of files, the 2.0.1 version of our High Sierra/ISO 9660 support takes a lot time to mount the CD. This will be fixed in a future release.
Devices & Hardware: CD-ROM: Avoiding invalid boot blocks on a CD-ROM
How do I make sure that my CD-ROM doesn’t contain invalid boot blocks?
The normal way of pressing a Macintosh® HFS CD-ROM is by making an image copy of a hard disk. Unfortunately, this means that the boot blocks are copied as well. The startup code for a hard disk isn’t the same as for a CD-ROM (for example, a CD-ROM starts up in 2048-byte block mode, whereas hard disks start up in 512-byte block mode.)
To invalidate the boot blocks, use a volume editor to zero out the first 2 bytes on the volume. (These bytes contain the characters “LK” if the boot blocks are present.) By zeroing out these bytes, the Macintosh will not try to use the invalid boot blocks that have been copied from the hard disk.
Devices & Hardware: CD-ROM: -120 (dirNFerr) on a Macintosh
Why do I get a -120 (dirNFErr) on a High Sierra CD-ROM, but not on a HFS CD?
Your program is probably saving directory IDs as a 16-bit quantity. Directory IDs are 32-bit values. On most HFS disks, this doesn’t matter; you must have many, many files on a disk to get a directory id that is a long value. Because of the implementation of our support for High Sierra and ISO 9660 CDs, the directory ID is always a long value.
Devices & Hardware: CD-ROM: Identifying a CD-ROM in the drive queue or volume queue
What is a reliable way to tell which element in the drive queue or volume queue is a CD-ROM? I am trying to write a routine that prompts a user to insert specific volumes by name and ejects any that may be in the drive.
For a CD in High Sierra, ISO 9660, or Audio only formats, you can use PBHGetVInfo to check for the ioVFSID (file system ID.
High Sierra disks always have a FSID of 0x4242.
ISO 9660 disks always have a FSID of 0x4147.
Audio CDs always have an FSID of 0x4A48.
You should also check for a hardware locked device by checking the ioVAtrb field. The bits for this are defined on page 167 of Inside Macintosh® Volume IV.
For the AppleCD SC® drive, you can call the driver with a PBstatus call of 97. csParam+1 contains bits corresponding to each of the 8 possible SCSI IDs. SCSI ID 0 is the right-most bit. A bit is set if an AppleCD SC drive exists at that SCSI ID. See the “AppleCD SC Developer’s Guide,” available from APDA®, for further details.
Devices & Hardware: CD-ROM: System 7.0b1 crashes when I insert a CD into my CD-ROM drive
Macintosh® System 7.0b1 crashes when I insert a CD into my CD-ROM drive.
System 7.0b1 wants the size of your Apple Disk Cache to be 128K or more. You can set it using System 7’s Memory ‘cdev’ in the control panel.
Devices & Hardware: CD-ROM: CD-ROM ignored by System 7.0b1 if 32-bit addressing is enabled
My CD-ROM drive is ignored by Macintosh® System 7.0b1 if 32-bit addressing is enabled.
Don’t use 32-bit addressing if you want to read from a CD using this beta system software.
Devices & Hardware: CD-ROM: Where Macintosh System 7 wants CD-ROM files placed
Is there a way to load the INITs for the CD-ROM drive in a fashion that System 7 accepts, so the drive appears on the Macintosh® desktop?
You’re encountering problems installing the CD-ROM drivers on System 7? Imagine that! Not to be too glib, but that’s a common problem.
Here’s the scoop: The “CD Remote” DA goes into the Apple Menu items folder; the “Foreign File Access” and “Apple CD ROM” files go into the Extensions folder; and “CD Remote INIT,” “CD Remote Programs (if you have this file),” “ISO 9660 File Access,” “High Sierra File Access,” and “Audio CD Access” all go into the top level of your System Folder.
The easiest way to accomplish this is to run the CD-ROM installer and then rearrange the files as necessary. Even if you have the files in the right place the first time, if it still doesn’t work, you should erase them and run the installer. For some reason it may take a second try.
Devices & Hardware: CD-ROM: CD-ROM technical references
CD-ROM technical references:
- AppleCD SC® Developer’s Guide
- Macintosh® Technical Note #209, “High Sierra & ISO
9660 CD ROM Formats”
Devices & Hardware: CD-ROM: Pressing a CD-ROM
How do I press my own CD-ROM?
We’ll assume that you’re looking at a moderate number of CDs (one hundred to several thousand) for your needs. It makes sense to press a CD if you have 10 megabytes or more of data and need 100 or more copies of it.
CDs behave just like a locked, very fast, very big floppy. If you can run your program or HyperCard® stack on a locked floppy, it will run on a CD.
To press a CD-ROM, you have two options; the easy way and the hard way. The easy way gives you a Macintosh® CD that’s a copy of a hard disk. The hard way gives you the Macintosh CD plus the ability to create audio CD quality sound tracks, or to create a CD that can be used across many operating systems in a format called High Sierra.
The easy way is to put your data onto a hard disk and send the hard disk to one of the companies listed below (call before sending). They will create an image copy of your hard disk (an exact duplicate) and put that image onto CDs. Easy, quick, and painless. To create such a CD, you’ll be charged a mastering charge (for creating the initial image) plus a duplication charge per CD. The mastering charge varies, but is usually under $1500. The duplication charge is around $1.85 per CD, including packaging. The average turnaround time is 5 to 10 days.
If you want faster turnaround time, you’ll pay more. Typical mastering charges for one day turnaround starts under $3000. If you want zillions and zillions of CDs, you’ll pay less money. Any of the production companies will be thrilled to hear from you.
The hard way of pressing a CD-ROM involves using a premastering system to create a tape that a pressing plant can use to create CDs. This provides much more flexibility, since you control what goes on the tape. You need much more technical knowledge, and you need access to a premastering facility. You can purchase a premastering system; you’ve got names in the Apple CD-ROM Development Resource Guide. There are companies that will rent you time on their premastering system and help you out with the details (for a fee).
If you want to press a CD that can be used on many different operating systems, you want to use a volume format called High Sierra (also known by the name of its international standard, ISO 9660). If you press a CD in this format, you can read the data on many different operating systems. You’ll need to plan your data carefully so that it can be used on many machines; for example, many spreadsheets can read a common format, and almost every word processor can read plain text. HyperCard uses a proprietary format that can only be used on the Macintosh, so it’s generally not a good choice for a High Sierra CD.
For a good overview of CD-ROM, read the AppleCD SC® Developer’s Guide, available from APDA®. There is a new magazine called CD-ROM EndUser, available from DDRI, 6609 Rosecroft Place, Falls Church, VA 22043.
Some companies to contact regarding CD-ROM production (in no particular order):
3M Optical Recording DADC
Building 223-5S-01 / 3M Ctr. 1800 N. Fruitridge Avenue
St. Paul, MN 55144 Terre Haute, IN 47804
612-736-3274 812-462-8100
Mark Arps/Dick Tendill Linda Watson/Kozo Arai
AppleLink: D2462 AppleLink: D2125
Discovery Systems Philips Dupont Optical
7001 Discovery Blvd 1409 Foulk Road, Suite 200
Dublin, Ohio 43017 Wilmington, DE 19803
614-761-4287 800-433-3475
Jack Ryan Jill Jones
AppleLink: D1191 AppleLink: D2173
Nimbus Information Systems Denon America
SR 629, Guildford Farm 222 New Road
Ruckersville, VA 22968 Parsippany, NJ 07054
800-782-0778 201-575-2532
Larry Boden Nob Tokutake/Ben Garcia
Disctronics
1120 Cosby Way
Anaheim, CA 92806
714-630-6700
Wan Seegmiller
Some technical hints:
• Don’t put 1000 files in one folder. The Finder is very slow at opening such folders.
• Make your disk contiguous for speed. Either back up, reformat the disk, and copy everything on again, or use a commercial disk organizer such as DiskExpress by AlSoft or SUM by Symantec.
• Waste disk instead of cycles. Precompute information that speeds up your program or stack; you’ve got 660 megabytes to waste. Use them.
• Take advantage of the static nature of CD-ROM. Put absolute file names in your HyperCard® stacks.
(The legal beagles want me to tell you: All company names and prices are here for your information, but Apple Computer, Inc., does not recommend or endorse any particular company listed. Apple, HyperCard and Macintosh are registered trademarks of Apple Computer, Inc. AppleCD SC and APDA are trademarks of Apple Computer, Inc. DiskExpress is a trademark of AlSoft, Inc. SUM is a trademark of Symantec, Inc.)
Devices & Hardware: Custom ICs: Why Macintosh IIci and IIsi don’t support direct video
What prevents the RBV (Ram Based Video) chip in the Macintosh® IIsi from displaying 16-bit color on the new 12" Macintosh RGB monitor similar to the Macintosh LC?
The RBV chip is not able to supply data directly to its D/A converters; thus it bypasses the color lookup step completely. The Macintosh IIci and IIsi hardware is not capable of supporting direct video.
Devices & Hardware: Custom ICs: Don’t access Macintosh RBV chip VIA emulation registers directly
Are the VIA emulation registers of the Macintosh® RBV chip documented? If not, what are the offsets to the VIA emulation registers on the RBV chip? Is there more than one way to access the RBV registers?
The VIA emulation registers of the RBV chip are not documented because Apple does not want developers to use them. We have not supported the use of the VIA registers and we do not plan on supporting the registers of the various new ASICs that Apple has developed. If you decide to use these registers anyway, you are on your own. We don’t know of another way to access the RBV registers.
Devices & Hardware: Custom ICs: Where to find out how to control the Apple IIc Plus accelerator
How can I control the speed of the Apple® IIc Plus?
Firmware routines exist to allow the programming of the accelerator in the Apple IIc Plus. These routines are documented in the Apple IIc Technical Reference, 2nd Edition, available from APDA®. Apple encourages all developers with products that run on the Apple IIc to replace previous IIc documentation with this book.
Devices & Hardware: Device Manager: Determining if a file is read from CD-ROM or hard disk
How can we tell whether a particular Macintosh file is being read from a CD- ROM or a hard disk?
You can call the Device Manager routine OpenDriver using the “.AppleCD” string to find a driver reference number of the AppleCD SC drive. If there is more than one AppleCD SC drive hooked up, then additional “.AppleCD” driver reference numbers can be obtained by using the PBControl call with a csCode = 97 (WhoIsThere). This command returns a mask of which SCSI devices are being serviced by the “.AppleCD” driver (that is, which other drives are AppleCD SCs).
The following code returns the driver reference number for an “.AppleCD” driver instance. The input parameter CDDrive specifies which logical AppleCD SC drive in the SCSI chain to open.
#define csWhoIsThere 97
typedef unsigned short Word;
typedef unsigned long Long;
typedef struct WhoIsThereRec {
ParamBlockHeader
short ioRefNum;
short csCode;
struct {
Byte fill;
Byte SCSIMask;
} csParam;
} WhoIsThereRec;
pascal OSErr OpenCD(Byte CDDrive, short *ioRefNum) {
auto OSErr osErr;
auto short ioRefNumTemp,
CDDriveCount,
SCSIID;
auto WhoIsThereRec *pb;
pb = (WhoIsThereRec *) NewPtrClear(sizeof (*pb));
osErr = MemError();
if (0 != pb && noErr == osErr) {
osErr = OpenDriver("\p.AppleCD", &ioRefNumTemp);
if (noErr == osErr) {
(*pb).ioRefNum = ioRefNumTemp;
(*pb).csCode = csWhoIsThere;
osErr = PBStatus((ParmBlkPtr)pb, false);
if (noErr == osErr) {
CDDriveCount = 0;
for (SCSIID = 0; SCSIID < 7; ++SCSIID) {
if (BitTst(&(*pb).csParam.SCSIMask, 7 - SCSIID)) {
++CDDriveCount;
if (CDDrive == CDDriveCount) {
*ioRefNum = -(32 + SCSIID) - 1;
DisposPtr((Ptr) pb);
return noErr;
}
}
}
osErr = paramErr;
}
}
DisposPtr((Ptr) pb);
}
return osErr;
}
You can modify OpenCD to do exactly what it is you need it to do. Or, you might use it to iterate over the logical CD drive numbers from 0 to 6 until OpenCD returns something other than noErr. If you modify the OpenCD routine, you’ll need the “AppleCD SC Developers Guide, Revised Edition” (APDA #A7G0023/A, $25.00) to be successful. Note also that all unused fields of a parameter block used with the “.AppleCD” driver must be set to zero before calling PBControl.
Iterating over the seven possibilities will result in a table of known “.AppleCD” drive entries—perhaps something like the following structure:
struct {
int count;
short cdDRefNum[7];
} knownCDDRefNum;
With this table in hand, you can match the driver reference number for the volume of any file. In most cases you know which volume the file was on when you opened it. Also, the routines PBGetFCBInfo and PBGetCatInfo both return the volume reference number for a file.
Once you determine the volume reference numbers, either traverse the VCB table or call PBGetVInfo to get the driver reference number. This driver reference number is the driver handling all requests made by the File System for your file!
If that driver reference number for the file is in our “knownCDDRefNum” table, then that file resides on an AppleCD SC drive. This technique works only for Apple or Apple-compatible drivers. An alternate approach to the problem is stepping through the driver table and locating all entries with the name “.AppleCD,” noting their driver reference numbers, and then following the procedure outlined above to determine if a file is on a volume owned by that driver.
The csCode method is far clearer than this one, and should be used whenever possible. The bottom line is that there is no guaranteed method of locating a CD-ROM drive due to the lack of a standardized driver model.
X-Ref:
Device Manager chapters of Inside Macintosh Volumes II, IV, and V “Finding a Slot for a Driver” note on latest Developer CD Series disc
Devices & Hardware: Device Manager: Accessing a Macintosh driver resource fork at accRun time
How do I get Macintosh® resources from a driver Init file at accRun time? I can’t think of a way other that getting the full path name, which is discouraged.
Basically, you need to call PBGetFCBInfo at INIT time to grab the filename, directory ID and volume reference number for the INIT’s resource fork. You can then store these in your INIT and pull them out at accRun time. At accRun, just call HOpenResFile to get to your resources. This method is _much_ better than using a full pathname, since this still works in the case where the user re-names the folder containing your INIT.
Here’s some sample code that does what you need:
OSErr GetCurResLocn(short *saveVRefNum,long *saveDirID,StringPtr saveFName)
{
FCBPBRec pb;
OSErr err;
short theFile;
Str255 fName;
theFile = CurResFile();
pb.ioFCBIndx = 0;
pb.ioVRefNum = 0;
pb.ioRefNum = theFile;
pb.ioNamePtr = saveFName;
err = PBGetFCBInfo (&pb,false);
*saveVRefNum = pb.ioFCBVRefNum;
*saveDirID = pb.ioFCBParID;
return err;
}
OSErr SetCurResLocn(short saveVRefNum,long saveDirID,StringPtr saveFName,
short *newResFile)
{
short resRef;
OSErr err;
HOpenResFile(saveVRefNum,saveDirID,saveFName,fsRdWrPerm);
err = ResError();
if (err!=noErr)
return err;
UseResFile(resRef); /* <-- needed in case the res. file was
prev. open */
*newResFile = resRef;
return ResError();
}
void main()
{
OSErr err;
short saveVRefNum;
long saveDirID;
Str255 saveFName;
short newResFile;
err = GetCurResLocn(&saveVRefNum,&saveDirID,saveFName);
if (err!=noErr)
return;
/* … pass control off to computer here (we're an app, so we
fake it) … */
err = SetCurResLocn(saveVRefNum,saveDirID,saveFName,&newResFile);
if (err!=noErr)
DebugStr("\pfailed");
}
As you can see, this is an application, so you’ll have to do some minor modifications (possibly convert to 680x0). It’s pretty straightforward, and the HOpenResFile call is included in MPW® glue for MPW 3.0 and is a built-in call for System 7.
Devices & Hardware: Device Manager: New info on Macintosh Device Manager calls
Are Macintosh® Device Manager status calls with csCode=1 calls filtered out? Also, are all high-level Device Manager routines always executed synchronously? If all the calls are synchronous, why is there a high level KillIO routine (to terminate current and pending processes)?
Yes, a Status call made with a csCode of 1 never calls your driver. Instead, it returns (in the csParam field) the handle to your driver’s Device Control Entry from the Unit Table.
High-level Device Manager calls are executed synchronously. Only the low-level calls can be specified to execute asynchronously. The high-level KillIO routine is useful for terminating I/O pending from a low-level call, which may have been initiated by someone else.
Devices & Hardware: Device Manager: JMP or JSR when calling IODone
After an I/O call to a Macintosh® slot device driver, shouldn’t the IODone routine be called by a JSR instead of a JMP instruction in order for a slot device to return to it with D0 set to an appropriate value depending on whether the interrupt was serviced?
You only call IODone when the queued up I/O request has been fully completed. If the interrupt handler is completing an asynchronous call, then you need to call IODone. IODone returns via an RTS, and preserves D0. Therefore, what you should do is have your interrupt service routine set D0 and then jump to IODone (via JIODone*). IODone will do its thing return via an RTS instruction. The sequence would be something like:
0. A program is running
1. The interrupt occurs
2. The Device Manager does a JSR to your Interrupt Service Routine (ISR)
3. The I/O request is complete, so your ISR sets D0 and jumps through JIODone
4. IODone does an RTS, which will be back to the Device Manager
5. The Device Manager does an RTE back to the program
6. The program continues
*The J (in JIODone) stands for Jump, so the ISR pushes JIODone onto the stack, which puts the address of what’s in JIODone ($8FC) on the stack. This is followed by an RTS instruction which executes it. So JIODone can be thought of as a vector to IODone.
If you are just handling a hardware interrupt or the I/O is not yet complete, don’t call IODone. Do an RTS like the example in Designing Cards and Drivers for the Macintosh Family (Chapter 9 source example, starting with the BeginIH label).
Devices & Hardware: Device Manager: Given a Macintosh gdRefNum, how can I find the associated slot?
Given a Macintosh® gdRefNum, how can I find the associated slot?
Get the slot number from the auxiliary DCE. The following code snippet indexes through the GDevices (it’s assumed the check showed the presence of Color QuickDraw™), and pulls the slot number from each GDevice record:
gGDHandle := GetDeviceList; {get the first GDevice list handle}
repeat
if gGDHandle <> nil then
begin
gAuxDCEHandle :=
AuxDCEHandle(GetDCtlEntry(gGDHandle^^.gdRefNum));
{ do whatever slot specific work is desired, now that
the slot }
{ number is known }
gGDHandle := GetNextDevice(gGDHandle);
{ pass in present GDHandle; the next one is returned }
end;
until gGDHandle = nil;
Devices & Hardware: Device Manager: Macintosh Device Manager handles queuing and asynchronous calls
How can the Macintosh® Device Manager help my driver handle things like asynchronous calls, queueing, and so on?
The Device Manager will handle all the queueing and asynchronous niceties for you with the jFetch, jStash, and jIODone calls. jIODone handles queueing and calling completion routines for asynchronous calls. jFetch, and jStash are for the interrupt handlers, and provide the mechanism for knowing how far along you are in a particular request.
When you call jIODone, the entry that was being handled will be removed from the queue, its completion routine is called, and then if there is another entry in the queue, your driver will be called to handle it.
If you return via an RTS rather than jIODone (you haven’t yet completed the operation requested—that is, waiting for more bytes), the queue entry will remain in the queue, and others behind it will not execute until the next jIODone is called. Queued entries are always executed in sequence. If your driver is not asynchronous, you still need to call jIODOne to clear the queue for the next entry (unless the IMMED bit is set in the ioTrap field).
jFetch and jStash are two calls provided to assist an interrupt driven asynchronous driver. From within your interrupt routine, you can call jFetch to get the next byte from the caller’s buffer, or jStash to place the next byte in the caller’s buffer. In addition to dealing with the caller’s buffer, these two calls also handle the ioActCount and let you know when you have completed the current request (see Inside Macintosh Volume II, pages 194-195).
A good example of this is the serial drivers. In the case of the output driver, if the calling application makes a pbWrite call to the serial output driver, and specifies a buffer of 200 characters, the Device Manager places the request in the queue for the Serial Driver and calls the prime routine. The prime routine gets the first character from the buffer by using the jFetch call, and places it in the transmit buffer of the SCC chip and simply does an RTS. The SCC chip has the ability to generate an interrupt when the transmit buffer is empty, so when that happens, the interrupt handler gets the next character from jFetch, and sticks it in the transmit buffer. When jFetch finally gets the last character, the interrupt routine places it in the transmit buffer, and calls jIODone, which then removes that request from the queue, calls the completion routine, if any, and executes the next queued request, if any.
If your driver is supporting non-interrupt driven hardware, you can just receive the prime call, and use jFetch (for example) to get the requested bytes from the buffer, send them to your hardware, and repeat until jFetch returns buffer empty, then return via jIODone. This is an example of synchronous operation that still uses the queueing mechanism, except that no new requests will ever have a chance to get queued until the previous request is completed.
Devices & Hardware: Device Manager: How do I support locked and ejectable SCSI devices?
How do I support locked and ejectable SCSI devices?
The only things you should have to support are the _DriveStatus call and modify the DrvQEl record. The rest will be handled by the Macintosh® system. The _DriveStatus call gives the information for srvStsCode. This is how the system will know what your disk can support. It is typically only used by floppy (or removable) disk drives. The sample SCSI driver from Apple doesn’t need to support it, because it doesn’t support any of the information in the _DriveStatus call.
The DrvSts record contains some information of no concern here. The diskInPlace, twoSideFmt, and needsFlush are probably ignored for your device. It’s best to zero them out. The DrvSts information is pretty much just the same information returned in the DrvQEl record.
Also, people sometimes get into trouble while developing a driver because current File Manager documentation about the drive queue element is vague. There are 4 bytes in front of a DrvQEl record. These determine the device’s abilities, but THESE BYTES ARE NOT ALLOCATED BY THE SYSTEM. When creating the DrvQEl record, you need to add these four bytes in front of the record yourself. The pointer to a DrvQEl will be the actual record, which is AFTER these 4 bytes. To read these bytes yourself, you’ll have to subtract 4 bytes from the DrvQEl pointer.
It is important to note that the Disk Switch error dialog is not an actual dialog, but the system error. It is handled by the same code as SysError which shows the system bomb alert. While this window is present, _SystemTask is not being called. This means the driver will not get an accRun call. To work around this, you will need a VBL task. When the VBL is called it checks the SCSI bus for being free and if so, tests for a new cartridge. Once found, posts a diskInsertEvt. This will be received by the driver.
While the media is inserted, the VBL should not be running until after the cartridge is ejected. Otherwise, the SCSI bus will continue to be accessed unnecessarily, which slows the bus. The VBL task could also slow the system while virtual memory is running.
Devices & Hardware: Device Manager: Macintosh journaling mechanism
How can I use the journaling mechanism described in Inside Macintosh®?
The old journaling mechanism isn’t supported any more. It is no longer necessary because of MacroMaker and similar products. MacroMaker now “owns” the older driver, and any future journaling will be done through MacroMaker. Currently there is no technical documentation available for MacroMaker. The current abilities of MacroMaker may not support what some developers will want to do with journaling. Future versions of MacroMaker may add more features.
Devices & Hardware: Disk Driver: Macintosh disk drivers and System 7 compatibility
Is there anything special that a Macintosh hard disk or a removable cartridge driver must do to be fully compatible with System 7?
One important thing you should be aware of regarding removable cartridges is that a cartridge can’t be removable if VM is to use it for a backing store. Some removables allow you to fix this with a SCSI command to prohibit ejection and, just as important, the drive must be marked nonejectable in the drive queue.
Here are a couple of suggestions: Read Macintosh Technical Note #285, “Coping with VM and Memory Mappings.” Also, take a look at the Memory Management chapter of Inside Macintosh Volume VI and the Virtual Memory paper (Goodies:VM Goodies:VM Paper) on the System 7 Golden Master CD.
Devices & Hardware: Disk Driver: System 7 disk driver reentrancy requirements
What are the reentrancy requirements for System 7 disk device drivers?
If and only if multiple DCEs point to the same shared code in memory, it is possible for a disk driver to be reentered by VM. This will only happen when the driver is busy with one drive and VM wants to access another one controlled by the same driver as a result of a page fault at interrupt time. To prevent reentrancy problems, a disk driver should maintain a separate independent set of variables for each drive it supports, and it should access those variables only through the DCtlPtr passed to the driver in A1 when it is called.
Many disk drivers don’t even need to worry about this because a separate copy loads for each entry in the unit table.
X-Ref:
Macintosh Technical Note #285, “Coping with VM and Memory Mappings”
Devices & Hardware: Disk Driver: Low-level Macintosh floppy disk access
I need to be able to modify the number of sectors per track and the interleave the disk drive looks for. There must be some way to do this through the driver. Do you have any example code of accessing the driver directly?
The only floppy access we support is through the driver, as documented in Technical Note #272. The driver only handles block-level access, except that if you’re using a Macintosh® IIfx, the Raw Track Dump call gives direct read access to the data on the track. This may be just what you need; unfortunately, we don’t have any example code that covers this call.
Devices & Hardware: Disk Driver: Macintosh RAM disk driver tricks
How are you able to keep the Macintosh® Portable’s RAM Disk from being destroyed after it has been dragged to the trash? Could we pull that trick with our RAM disk too? How does the RAM Disk’s memory stay protected during system startup? Also, the Finder’s “Get Info” window for the RAM disk shows “Where: Internal RAM disk” rather than “Where: AppleTalk.” How does the driver convey this information to the operating system?
At the time that your driver receives a disk eject, post a disk insertion event to the OS event queue. Your icon will disappear and reappear like magic.
The Macintosh Portable has a special version of the disk driver that looks for special header blocks for a RAM disk and multiple ROM disks in the ROM expansion address space. If it finds the correct header, it tells the system initialization (again specially coded for the Macintosh Portable) to not check the RAM mapped out by the RAM disk header.
The ‘Get Info’ dialog gets the “Where” information from the standard control call to the disk driver. Your driver should respond to a Status call with a csCode =21 as documented in Inside Macintosh Volume V, page 470.
Devices & Hardware: Disk Driver: System 7.0 and color volume icons
Now that Macintosh® Finder™ icons can be in color, is it possible to have color volume icons as well, and, if so, would you share the specifics?
Unfortunately, there’s no way for the driver to provide the default icon in color—that is, there are no calls newer than those described in Macintosh Technical Note #28, “Finders and Foreign Drives.”
The System 7.0 Finder can display a custom color icon for a volume, though. The user can paste a new color icon over the old one in the volume’s Get Info box. (Click the icon in the box to select it, then Paste.)
Devices & Hardware: Disk Driver: System 7 requires disk driver updates
I can’t get the 7.0 beta to run on either of my Macintosh® systems. The problem seems to be tied to my third-party hard disks. System 7 wouldn’t install on one third-party hard drive, and my other system crashed at startup attempting to access another third-party hard drive.
With System 7.0, we provided the Apple HD SC Setup utility with new HD drivers to update the drivers for our hard disks. Third parties will have to update the drivers for their equipment to be compatible with 7.0.
Devices & Hardware: Disk Driver: Macintosh Finder eject on Unmount
Why doesn’t dragging a mounted hard disk partition into the Trash Can generate an Eject call to the device driver?
Only ejectable media such as floppy disks generate an eject call. All others generate an Unmount call. If you were to set the ejectable bit (which is documented in Inside Macintosh® Volume II, page 127-8), you will get an eject call for a hard disk which will then result in a continuous “Please insert <your hard disk>” alert.
Devices & Hardware: Disk Driver: Logical-to-physical sector information for 800K disks
Does the translation between logical and physical sectors on an 800K disk work in the same manner as a 400K disk (as per Inside Macintosh®). If so, do track/sector numbers alternate between sides? Is this information available elsewhere, or should we be able to figure this out from data available from FEdit?
The translation between logical and physical sectors on an 800K disk follows in a manner similar to that for the 400K disk (Inside Macintosh, Volume II, page 211), except that sectors alternate between sides before moving on to the next track as you suggested.
First we’ll define side 0 and side 1. Similar to the 400K disk, there are 80 tracks on each side. Track 0 is outermost, track 79 is innermost. The sectors per track are grouped in a similar manner to the 400K disk.
The first 12 sectors for an 800K disk map to side 0, track 0, sectors 0-11, similar to the corresponding sectors on the 400K disk. The next 12 sectors for the 800K disk map to side 1 in a similar manner—side 1, track 0, sectors 0-11. Logical sectors 24-36 map to side 0, track 1, sectors 0-11, and so on. The following chart demonstrates this:
Side Track Sectors Physical Logical
Per Track Sectors Sectors
0 0 12 0-11 0-11
1 0 12 0-11 12-23
0 1 12 0-11 24-35
1 1 12 0-11 36-47
...
1 15 12 0-11 372-383
0 16 11 0-10 384-394
1 16 11 0-10 395-405
0 17 11 0-10 405-415
...
1 31 11 0-10 725-735
0 32 10 0-9 736-745
1 32 10 0-9 746-755
0 33 10 0-9 756-765
...
1 47 10 0-9 1046-1055
0 48 9 0-8 1056-1064
1 48 9 0-8 1065-1073
0 49 9 0-8 1074-1082
...
1 63 9 0-8 1335-1343
0 64 8 0-7 1344-1351
1 64 8 0-7 1352-1359
0 65 8 0-7 1360-1367
...
1 79 8 0-7 1592-1599
Devices & Hardware: Disk Driver: How to determine if a disk drive supports ejectable media
How can I determine if a disk drive supports ejectable media?
The disk driver in Macintosh® System 6.0.2 (and later) supports control calls with cscode = 23; this call returns information about the drive’s physical location, size, and other characteristics described as follows:
Return Drive Info (csCode = 23) csParam = long;
Most of the bits are not used at the moment and are being reserved for future expansion. The drive type field is in bits 0 through 3 and describes the type of drive that is connected. The supported types are as follows:
0 no such drive
1 unspecified drive
2 400K
3 800K
4 High Density drive FDHD
5 reserved
6 reserved
7 Hard Disk 20
8-15 reserved
The attributes field occupies bits 8 through 11 and describes the following:
bit 8 0 - Internal 1 - external
bit 9 0 - IWM 1 - SCSI
bit 10 0 - removable 1 - fixed media
bit 11 0 - primary 1 - secondary
So, bit 10 in csParm tells whether the drive in question supports ejectable media or not.
Drivers from other manufacturers may not support this control call, in which case it becomes necessary to traverse the queue in order to secure the information. The following little assembly language routine shows how to do it the old-fashioned way, as mentioned in Inside Macintosh Volume II (page 128) and Volume IV (page 181):
;--------------------------------------------------------------
; FUNCTION DoItTheOldWay(ioDrvNum: INTEGER): integer;
; returns: 0 = is ejectable
; -1 = is not ejectable
; 1 = error occurred (could not find specified drive)
;--------------------------------------------------------------
DoItTheOldWay PROC
MOVE.L (sp)+,A0 ; save the return address
MOVE (sp)+,D1 ; get target drive #
MOVE.L DrvQHdr+QHead, A1 ; Point to the drive queue
@0 CMP.W DQDrive(A1), D1 ; is it the right drive #?
BEQ.S @1 ; if so, skip out
MOVE.L QLink(A1), A1 ; Get the link to the next
vol
MOVE.L A1, D0 ; is it NIL?
BNE.S @0 ; if not, go back.
MOVE.W #1,(SP)
JMP (A0)
@1
CMP.B #8,-3(A1) ; ejectable value??
@5 SGE (SP) ; record if it isn't ok
JMP (A0)
ENDP
Devices & Hardware: Disk Driver: DTS’s copy protection position
How can I protect my software? I want to prevent my software from being illegally copied and distributed.
Apple Developer Technical Support’s official position is that software copy protection is a bad idea, so we don’t support development of protection schemes. Here is a summary of arguments against copy protection:
(1) You will have to put your valuable resources into engineering a scheme, which usually means disassembling the ROM to understand the disk drivers, HFS, MFS, and so on, as well as fully understanding how the hardware for each machine your software runs on works. This extra work adds time to your development schedule.
(2) You’ll have to maintain your software when it doesn’t work on future machines or system software releases. Virtually every copy protection scheme devised so far (that we know about) has required revision for new Apple® CPUs.
(3) You’ll have to test the software on all machines and products, including third-party hardware and file system software.
(4) You’ll have to support possibly angry users who have problems using the software because of the protection scheme, or have broken “key” disks, etc. Users may be frustrated by an inability to copy software to a hard disk, make backups, or immediately use the software with new hardware or software.
(5) Every copy protection scheme devised so far (that we know about) can be defeated by commercial products that remove or circumvent the protection.
(6) Protected software frequently receives poor reviews or mentions in the press because of the protection scheme.
We feel that copy protection is not a worthwhile use of development time. We cannot help you develop a protection scheme, or provide support when protected software breaks with future hardware or software.
Devices & Hardware: Disk Initialization Package: Apple HD SC Setup and third-party hard drives
The Apple HD Setup utility formats my third-party drive, but it reports an error mounting the drive before partitioning it.
The Apple HD SC Setup utility is written for Apple drives—or, more specifically, for the controller on Apple drives. Even if the hard drive you are trying to format with the utility is from an Apple supplier, it may have a different controller than an Apple drive. You should use the formatting utility that was included with your drive.
Devices & Hardware: Disk Initialization Package: GS/OS volumes and ProDOS 32 MB file system limit
Adv.Disk.Util on the Apple IIGS® System 5.0.4 System Tools disk lets me create a 60 MB partition, I can only format it for 32 MB, effectively loosing 28 MB in the partition. Is there any way to get around this?
GS/OS® volumes can be any size up to four gigabytes. However, GS/OS has no native file system and relies on file system translators (FSTs) to read any physical file layout on any disk.
Currently, the main FST used for the Apple IIGS is for the ProDOS® file system, and ProDOS volumes can't be larger than 32 MB because the file system structures don't allow access to more than 65,536 512-byte blocks.
You can make any volume size you want, but ProDOS can only use the first 32 MB of any volume. Other FSTs (like AppleShare®) do not have this limitation.
Devices & Hardware: Disk Initialization Package: System 7.0, Disk First Aid 7.0, and Hard Disk Setup 2.0.4
We were told that it would be highly advisable to do a file-by-file back-up of all hard drives, a fresh format, and a restore because of a bug in the B-Tree algorithms that’s been fixed in the System 7.0 Golden Master. Can we do this and then return to System 6.0.7 safely? Is Apple going to make any sort of general announcement about this problem? Also, can we expect that it is not a “contagious” problem in any way—that is, can we back things up and restore without worrying about it moving from disk to disk?
Apple is recommending that users run the final version of Disk First Aid (version 7.0) on all their hard drives to determine if there are any problems with the B-Trees. The reason for this is that a bug has existed in the Macintosh® (HFS) operating system from its inception such that the B-Tree structures for devices would become corrupted under certain EXTREMELY RARE circumstances. If and only if DFA reports a problem that it cannot fix (it will tell you if it can or can’t) should users perform a file-by-file back up of their data, then reformat all Apple hard drives using HD Setup before copying files back. Making a mirror backup of your data will only put the damaged B-Tree catalog back onto the drive when you restore, so be sure to make your backup file-by-file.
Apple does not intend to make any general published announcement about this because it is addressed in the System 7.0 documentation. As for the commonly asked question, “Why should we back up our data before upgrading to System 7.0? Are we in danger of losing our data?”: Backing up your data on a regular basis is always a good idea, and we are recommending it prior to installing System 7.0 only because there is always a chance of data loss when major changes are made to any system configuration. Since System 7.0 is very different in many ways from previous system software versions, some software packages are no longer compatible under this release and conflicts can potentially cause loss of data integrity.
There has been some confusion as to what, exactly, Disk First Aid version 7.0 can do. This version can detect problems with the B-Tree structures (whereas previous versions could not—the only clue it would offer is the “unable to verify status of disk” error). It cannot fix the damage, however. Another bug that DFA 7.0 can correct lies in the Directory Valance. This bug went generally unnoticed for years; it usually resulted in VERY INfrequent occurrences of some annoying behaviors such as not being able to throw away an empty folder (remember the old “Trash could not be emptied because a file was busy or locked” error?). Like the B-Tree structure corruption, this is a bug, not a virus, and is in no way contagious.
If you reformat the drive then reinstall System 6.0.x, you run the risk of damaging the B-Tree structures again because the bug is still present in the B-Tree Manager in ROM. Again, however, let me reiterate that it isn’t easy to take it that far. Suffice it to say, you will, in fact, be almost assuredly safe if you run DFA 7.0 occasionally to make sure your B-Tree structures are OK. If it says everything is fine, it is. If not, back up your data and reformat.
Another important step in your upgrade to System 7.0 is updating all SCSI device drivers by using the Hard Disk Setup (2.0.4 or later) utility for Apple hard drives that accompanies the System 7.0 software (for third-party devices, refer to the vendor to determine if updated drivers are necessary) BEFORE upgrading to System 7.0. The reason for this is that these newer drivers are incompatible with Virtual Memory. Failure to update these structures will prohibit using VM—it won’t even turn on—however, you’ll be able to use all other features of System 7.0 without any problems provided, of course, that your configuration meets the recommended memory requirements and all your software is fully compatible with this system software release.
Devices & Hardware: Disk Initialization Package: Macintosh System 6.0.4 and HD Setup 2.0.1
Is it OK to initialize a Macintosh® IIci with Apple HD Setup 2.0.1 (shipped with System 6.0.5) to get the interleave factor of 1 instead of 2, but then install and use System 6.0.4 instead of System 6.0.5?
Yes, it’s OK to initialize any Macintosh, including the Macintosh IIci, using HD Setup 2.0.1, which was shipped with System 6.0.5. It’s better, however, to use HD Setup 7.0, included on the System 7.0 CD, with Virtual Memory and File Share disk driver support.
System 6.0.4 is no longer recommended for use on either the Macintosh Portable or the Macintosh IIci.
Devices & Hardware: Disk Initialization Package: Multiple Macintosh disk partitions
I want to divide my 80 MB internal hard disk into two 40 MB Macintosh® partitions to keep Systems 6.0.x and 7.0 on the same disk and to speed up 40 MB tape backups, but “Apple HD SC Setup” doesn’t seem to support multiple Macintosh partitions.
While Apple’s own “HD SC Setup” utility does not allow multiple Macintosh partitions, several third-party products, such as SilverLining from La Cie, allow you to partition your drive with 2 or more Macintosh partitions.
You could also have two system folders on your one partition, one for System 6.x and one for 7.0, and switch between them.
Devices & Hardware: Display & Video Hardware: Adding video device to slotless Macintosh desktop
My video driver for Macintosh 68000 SE-type models installs itself as a driver, but since there’s no Graphics Device Manager in the ROM, it can’t add itself to the desktop by creating a GDevice using NewGDevice and putting itself into the DeviceList. Do I need to add my region to the region whose handle is in GrayRgn and patch the QuickDraw bottlenecks to divert drawing to my VRAM, or is there an easier way?
For the Macintosh Plus, SE, Classic, and Portable, your idea of how to add your video device to the system is right on: Add your region to the region whose handle is in GrayRgn and patch the QuickDraw bottlenecks to divert drawing to your VRAM. You didn’t ask for implementation details, so this is just a confirmation that your approach is good.
Devices & Hardware: Display & Video Hardware: QuickDraw 32-bit video RAM access and boundaries
Is there a way to let QuickDraw access video RAM in 32-bit mode, but on a word boundary ? Usually QuickDraw reads/writes on word boundaries, but sometimes it takes advantage of the 68020/30 and reads not a word boundary.
QuickDraw optimizes whenever it can to make efficient frame buffer accesses, but there isn’t a way for you to control how it makes accesses itself. That is, video hardware MUST be able to handle all flavors of accesses. This is because the user can position a window or other object on the screen that is not on a long/word boundry. However, some applications—HyperCard being a prime example—create their windows on aligned boundries and allow movement only to boundaries, so you’ll see a “snap”-to-grid kind of effect. Your application can do so as well, but that’s as far as you should go.
Devices & Hardware: Display & Video Hardware: Adding video device to slotless Macintosh desktop
My video driver for Macintosh 68000 SE-type models installs itself as a driver, but since there’s no Graphics Device Manager in the ROM, it can’t add itself to the desktop by creating a GDevice using NewGDevice and putting itself into the DeviceList. Do I need to add my region to the region whose handle is in GrayRgn and patch the QuickDraw bottlenecks to divert drawing to my VRam, or is there an easier way?
For the Macintosh Plus, SE, Classic, and Portable, your idea of how to add your video device to the system is right on: Add your region to the region whose handle is in GrayRgn and patch the QuickDraw bottlenecks to divert drawing to your VRam.
Devices & Hardware: Display & Video Hardware: Saving and restoring Apple IIGS SHR screen(s)
What’s the proper method of saving the Apple IIGS Super Hi-Res (SHR) screens? If my application both uses shadowing and is fast-port aware, the restored screen colors are garbaged. Can I simply use HandToPtr with ptr representing the screen addresses, or will this mess up the scan-line control byte (SCB) restoration since these are read-modify-write locations?
The shadowed screen’s SCBs may not be correct, so by saving and restoring them you’re causing random data to be restored into the standard SCBs. Your best bet, if shadowing is on, is to turn shadowing off, restore the bank $01 screen, including its SCBs and color tables, turn shadowing on, and restore the $E1 screen and contents. If you don’t want to double-restore the $E1 screen and $01 screen, you should turn shadowing off, restore the bank $01 color tables/SCBs, turn shadowing on, and restore the $01 screen. But, since these screens are never guaranteed to be the same when you save, you should always restore both screens separately.
QuickDraw never touches the shadowed screen SCBs, so if the fastPort flag is set you can ignore the restoring of the bank $01 SCBs/color tables, since the application promised not to interfere with them. But since this won’t save very much time, you probably shouldn’t worry about it.
Devices & Hardware: Display & Video Hardware: Determining if Graphics Devices Manager calls are supported
Is SysEnvirons’ hasColorQD a good way to determine if I can make Graphic Device calls?
SysEnvirons’ hasColorQD field is a good way to check whether the Graphics Device calls are available. Another good way is to see if Gestalt returns something ≥ gestalt8BitQD. You can tell if you have GWorlds (see the Graphics Devices chapter of Inside Macintosh VI) if Gestalt returns something (> gestaltOriginalQD and < gestalt8BitQD) or ≥ gestalt32BitQD.
Devices & Hardware: Display & Video Hardware: SetEntries and setting CLUT asynchronously
I want to call the device driver Control function on my screen device to set the CLUT asynchronously, so that it won’t wait until vertical retrace time like SetEntries does, causing an average delay of half the screen refresh rate, which is too much for my application. Does the firmware in the Apple video boards support asynchronous operation, or do I need to write a VBL task to handle the setting of the CLUT?
The control call (SetEntries) in the video card is designed to turn off interrupts in the machine until it can sync to the VBL and then change the CLUT. It does this because otherwise the update to the CLUT will look really bad. You can call PBControl to make the SetEntries call (basically what the Color Manager is doing). There is a flag for making the control call Async, but it will not take care of the problem with waiting for the VBL. This limit is due to the way the video cards are designed. There may be some video cards which don’t do this, but you probably don’t want to be hardware dependent. If you are interested in using the PBControl call, then you may want to take a look at the Cards and Drivers manual.
In general, DTS doesn’t recommend using SetEntries to animate the CLUT. It is not a very clean way to change the CLUT, and you don’t really gain anything by using it over the Palette Manager. For more information about the two ways,take a look at the “Palette Manager Animation” article in issue #5 of develop.
Devices & Hardware: Display & Video Hardware: Main versus application screens with multiple displays
On a multiple-display system, most commercial software comes up on the primary screen, even though it may need the color screen next door. Is there a utility for changing the default screen to a different one AFTER startup so I can switch to a color screen for certain applications without having to reboot?
A user can use Monitors to change the main screen (the one with the menu bar). If an application or utility were to change the main screen whenever it wants, then every time you run a new application, the menu bar would be moved on you. This would get reeeeeeally ugly. If commercial applications need (or run better on) one screen over another, they should do the right thing and look for the right screen instead of the main screen. The code to do this is very easy. This is not the job for a utility package.
You need to reboot the machine each time you change the main screen, because the Macintosh does a lot of caching of information and building internal structures early in the boot process, which need to be changed each time the screen information is changed. It might be possible to do this, but it would require a lot of patches to the system, as well as a deep knowledge of the internals of the ROM and OS. You’ll also run into a lot of compatibility problems.
Devices & Hardware: Display & Video Hardware: Where to place video board gamma table & custom option menu code
Can I put both my custom option menu and my custom gamma table in the firmware of my color video board, or must I have an 'INIT'?
The gamma table information can be stored in the ROM of the video card; in fact, in most cases that is where you will want it. The monitor extension, however will need to be in the system folder. You can find a fair amount of information about making a monitor extension, including sample code, in Chapter 10 of Inside Macintosh® Volume VI.
Devices & Hardware: Display & Video Hardware: Maximum Macintosh color monitor cable length
How long a cable can be used between a Macintosh® IIsi and a 13-inch color monitor?
Apple formally supports only the monitor cables and cable lengths available through Apple, but theoretically, using 75-ohm impedance value cable (usually RG-59U standard coaxial video cable), the signal will be very reliable up to 50 feet. The distance is limited by the loss of signal strength through attenuation within the cable:
Specifications: 75 ohm impedance cable
Signal strength: 13.33 milliamps @ 1 volt into 75 ohms load
Signal in MHz: 30.24
The DB loss per foot (or attenuation) using an RG-59U standard cable is approximately .0015. This gives a power loss of 4% of the original 1 volt signal at 100 feet.
The signal will drop to 50% at 2000 feet, with a 3 DB drop in power. Apple recommends staying within 95% percent of the signal, which would be under 150 feet. Increasing the monitor brightness control can correct for some of the signal loss.
(NOTE: Because of the TTL sync signal for the Apple High Resolution Monitors, it is unlikely the monitor will work correctly with sync signals under 4 volts, which would be a cable about 650 feet in length.)
Devices & Hardware: Display & Video Hardware: Apple monitors and gDevice pixel map hRes and vRes fields
It seems to me that the Apple® portrait monitor is an 80 dpi graphics device yet the hRes and vRes fields of the pixel map contained in the gDevice list state that it is a 72 dpi device.
Most monitors claim to be 72 dpi devices for compatibility with the original Macintosh®. Bitmap fonts expect 72 dpi resolution, for example. In reality each type of monitor is a little different, varying somewhere between 68 dpi and 80 dpi. Monochrome displays tend to have a slightly higher resolution than do color displays. These minor variations should be insignificant. The Macintosh goal is WYSIWYG, not necessarily WYMIWYG (What You Measure Is What You Get).
Devices & Hardware: Display & Video Hardware: Macintosh Display Cards 4*8 & 8*24 and third-party monitors
What do I need to determine if my third-party monitor is compatible with an Apple video display card?
The Macintosh® Display Cards 4•8 & 8•24 support any monitor that meets one of the following specifications:
- - - - - - MHz - - - - -
Sense pins Hor x Vert Dot Vert Horiz
10 7 4 Display Pixels Clock Refrsh Refrs
------- --------------------- ---------- ------ ----- ------
0 0 0 21-inch Color Monitor 1152 x 870 100 75 68.7
0 0 1 Apple Portrait Display 640 x 870 57.2832 75 68.9
0 1 1 Apple Two-Page Monitor 1152 x 870 100 75 68.7
1 1 0 12” Apple
Monochrome Monitor 640 x 480 30.24 66.7 35.0
1 1 0 13” AppleColor
RGB Monitor 640 x 480 30.24 66.7 35.0
0 - Grounded 1 - Not Connected
Note that sense pins 4, 7, and 10 are referred to as SENSE0, SENSE1, and SENSE2 in video connector pinout tables, such as the table in “Macintosh Display Cards 4•8 and 8•24 Developer Note.”
Here are the pinouts for the Macintosh Display Cards:
Pin Description
--- -----------
1 Red Video Ground
2 Red Video
3 Composite Sync
4 SENSE0
5 Green Video
6 Green Video Ground
7 SENSE1
8 Not Connected
9 Blue Video
10 SENSE2
11 Composite Sync and Vertical Sync Ground
12 Vertical Sync
13 Blue Video Ground
14 Horizontal Sync Ground
15 Horizontal Sync
Shell Chassis Ground
Devices & Hardware: Display & Video Hardware: 8*24 GC card memory management
How does the 8•24 GC card handle its memory management, such as caching, memory swapping, and out-of-memory handling?
The article, “Macintosh® Display Card 8•24 GC: The Naked Truth,” in issue #3 of develop has a good description of the card’s inner workings. You needn’t need to worry about what’s going on behind your back as far as memory management goes.
Devices & Hardware: Display & Video Hardware: Apple color video cards work on all Macintosh II models
Can I use a color video card from a Macintosh® IIfx to upgrade an old Mac II to color?
Yes, the RGB video cards for the Macintosh II series computers are interchangeable. If you are using Apple’s Hi-Res RGB monitor you have several video card choices (such as the “4•8” or the “8•24”).
Devices & Hardware: Display & Video Hardware: Recognizing a 32-bit address mode video card
How do I get the Macintosh® system to recognize that I have a video card installed that only supports 32-bit addressing?
Two bits need to be set in the sRsrcFlags field: fOpenAtStart (bit 1) and f32BitMode (bit 2). If you do not have these bits set, SecondaryInit will not get called and QuickDraw™ will not realize that your card is a 32-bit address only card. These bits are documented in the second edition of Designing Cards and Drivers for the Macintosh Family on page 123.
Devices & Hardware: Display & Video Hardware: 8•24 GC card pinouts and resolution
Can you provide me with the video pinouts for Apple’s 24-bit QuickDraw™ accelerator card so I can use another display instead of Apple’s RGB? Also, what is the maximum pixel height and width that the card can display?
The Apple 8•24 GC video card supports any large color monitor with the same resolution and timing as the Apple® Two-Page display. Currently, the only one I am aware of is sold by SuperMac. It is only 8 bits though, not 24. Pinouts for the 8•24 GC card are the same as for Apple’s other display cards (4•8 and 8•24).
For further information about this, please refer to the Tech Info Library on AppleLink® for a video card pinout listing and for monitor cable details.
Devices & Hardware: Display & Video Hardware: Eliminating 1-bit per pixel mode
How do I declare 8- and 24-bit modes without having 1 bit-per-pixel (bbp) mode in my sResources?
The trick is that your first video mode (which, in your code, would be 8 bpp) must start with ID 128. The modes have to be sequential so the next mode (24 bpp in your case) would be ID 129.
Besides Designing Cards and Drivers for the Macintosh® Family (2nd edition), there are some MacDraw® drawings of configuration ROMs, one of which shows an old Apple® video card (sometimes referred to as the “TFB” card). It is out of date, especially with regard to 32-Bit QuickDraw™ and multiple mode families, but it will give you an idea about how these things interact. A picture showing the exploded ROM and all these video sResource components may help when reading C&D. You can find these drawings on our developer CD and on AppleLink® under the MacDTS folder of Developer Services (look for the hardware hints/slots folder).
The only other gotcha I can think of is whether or not you can be the startup device if you don’t have 1 bit per pixel. And I think this was due to older MacsBugs not being able to handle more than 1 bpp, which of course is fixed now.
Devices & Hardware: Display & Video Hardware: Macintosh video connector pinouts J26 and J2
What are the pinout and signal descriptions of the tiny little connector marked J26, located on the main logic board near the external video connector. Also, what is the part number and manufacturer of the mating connector?
You seem to be asking about the external connector (J26), but my guess is that you really want to know about the internal connector (J2), so I will tell you about both. J26 is the external connector and is documented in the Developer Notes for the Macintosh® LC on page 13. The pin assignments are as follows:
1 Red video ground
2 Red video
3 Composite horizontal and video synch
4 Monitor ID bit 1
5 Green video
6 green video ground
7 monitor ID bit 2
8 not used
9 blue video
10 monitor ID bit 3
11 CSYNC ground
12 Vertical sync
13 blue video ground
14 not used
15 not user
16 shield ground
This connector is a standard DB-15 external connector.
Connector J2 is the internal connector that is documented in the Developer Notes on pages 37 and 38. The pinouts are as follows.:
1 ground
2 green video
3 ground
4 red video
5 ground
6 blue video
7 ground
8 composite blanking
9 ground
10 overlay signal
11 ground
12 composite horizontal and video sync signal
One source for the mating connector is Amp Incorporated, Harrisburg, PA 17105.
The part number of the connector is 4-174904-2.
Devices & Hardware: Display & Video Hardware: When to put Macintosh configuration ROM at top of 16-MB slot space
Is it OK to put the configuration ROM on my board at the top of the 16-MB slot space?
As long as the card is installed on all Macintosh® systems after the Rev A Macintosh II (the very first Macintosh II systems that were shipped), you will not have a problem with putting your configuration ROM at the top of the 16-MB space; in fact, we recommend this. To determine if the machine is a Rev A Macintosh II, you can use the tester application that is on the developer CD. Just run the application and if the machine is one of the old ones, a dialog box displays that tells the user to upgrade (for free) to a new motherboard.
Devices & Hardware: Display & Video Hardware: Macintosh 8•24 GC card 4-MB SIMM testing and pinouts
Does the current Macintosh® 8•24 GC card work with 4-MB SIMMs? What are the pinouts for the higher density SIMM?
We have made 4-MB SIMMs for the 8•24 GC card, tested them, and they work just fine. The 'cdev' sees them and they work. One way to test your SIMMs is to do a memory test over NuBus on addresses $sD000000 to $sD3FFFFF (Bank A) and $sD400000 to $sD7FFFFF (Bank B).
The pinouts for the DRAM SIMMs are as follows:
D0-2 d16-33 a0-10 CAS0-8
D1-3 d17-34 a1-28 CAS1-26
D2-5 d18-36 a2-6 CAS2-39
D3-4 d19-35 a3-15 CAS3-57
D4-14 d20-45 a4-16 Vcc-18,37,47,56
D5-13 d21-44 a5-50 GND-1,19,25,38,48,55,59,64
D6-11 d22-42 a6-9
d7-12 d23-43 a7-7
d8-20 d24-51 a8-40
d9-21 d25-52 a9-41
d10-23 d26-54 RAS-46
d11-22 d27-53 OE-27
d12-32 d28-63 WE0-58
d13-31 d29-62 WE1-49
d14-29 d30-60 WE2-24
d15-30 d31-61 WE3-17
Devices & Hardware: Display & Video Hardware: Video depth on Macintosh IIsi and LC Systems
Is there any way to get 24-bit color with a Macintosh® IIsi or LC? For the Macintosh LC, is it possible to substitute a 1-MB Video RAM SIMM for the 512K VRAM SIMM, which substitutes for the 256K stock VRAM?
Neither the Macintosh IIsi nor the Macintosh LC is designed to support 24-bit video.
The on-board video hardware and the video driver on the Macintosh IIsi are only designed to support 1, 2, 4, and 8-bit video. Putting more memory in the SIMMs or any hacks you might come up with will not get 24-bit video on the on- board video hardware.
The on-board video hardware on the Macintosh LC is capable of supporting 16- bit video on the 12" monitor, but it is still limited to 8-bit video on the 13" monitor. If you try to put 1-MB of VRAM into the video RAM SIMM, you probably will not be able to boot the machine. At best the machine will only see 512K of the VRAM. So, on the Macintosh LC the video hardware and the video driver only support 1,2,4,8 bits on Apple’s 13" monitor and 1,2,4,8,16 bits on Apple’s 12" monitor.
Devices & Hardware: Display & Video Hardware: All modes must have same starting address for a frame buffer
Does Macintosh® QuickDraw™ require that all modes have the same starting address for a frame buffer? In other words, I can’t have 1-bit mode start at offset 1024 and 8-bit mode start at offset 2048, right?
Yes, QuickDraw requires that all modes have the same starting address for a frame buffer.
Devices & Hardware: Display & Video Hardware: Upgrade old Macintosh II ROMs to use with 8•24 GC card
Why does our Macintosh® II with old ROMs not boot up with the 8•24 GC card, but it works fine on a Macintosh IIfx?
There is a problem with the really old Macintosh II ROMs that prevents them from working correctly with cards that have more than 1 MB of memory. The upgrade program is still available so take your machine to your friendly dealer and ask for a new board.
Devices & Hardware: Display & Video Hardware: Macintosh II video connector pinouts
What are the pinouts for the Macintosh® II video card and IIci built-in video connector?
Here are the pinouts for the Apple 13" RGB and 12" Monochrome monitors for
Macintosh II video cards and IIci built-in video:
12" B/W
Pin Signal Description 13" RBG 15" B & W
-- ----- ---------- ------ ---------
1 RED.GND Red Video Ground RED.GND n/c
2 RED.VID Red Video RED.VID n/c
3 CSYNC~ Composite Sync CSYNC~ n/c
4 MON.ID1 Monitor ID, Bit 1 ID1.GND n/c
5 GRN.VID Green Video GRN.VID n/c
6 GRN.GND Green Video Ground GND.GND n/c
7 MON.ID2 Monitor ID, Bit 2 n/c ID2.GND
8 n/c n/c n/c
9 BLU.VID Blue Video BLU.VID BLU.VID
10 MON.DI3 Monitor ID, Bit 3 n/c ID3.GND
11 C&VSYNC.GND CSYNC & VSYNC Ground CSYNC.GND VSYNC.GND
12 VSYNC~ Vertical Sync n/c VSYNC~
13 BLU.GND Blue Video Ground BLU.GND BLU.GND
14 HSYNC.GND HSYNC Ground n/c HSYNC.GND
15 HSYNC~ Horizontal Sync n/c HSYNC~
shell CHASSIS.GND Chassis Ground CHASSIS.GND CHASSIS.GND
Macintosh IIci video MON.ID information
‘0’ means that the line is grounded inside the monitor to provide information to the Macintosh IIci as to what kind of monitor is connected. If no monitor is connected to the IIci’s built-in video port, then the port is automatically disabled at startup.
ID3 ID2 ID1 Monitor Type
--------------------------------------------------------
0 0 0 Unsupported
0 0 1 15" B&W Portrait Monitor (640x870)
0 1 0 RESERVED for use be Apple
0 1 1 Unsupported
1 0 0 Unsupported
1 0 1 RESERVED for use by Apple
1 1 0 Mac II 12" B&W, 13" Hi-Res RGB (640x480)
1 1 1 No external monitor connected (automatic)
--------------------------------------------------------
Devices & Hardware: Electrical Issues: Power Manager BatteryStatus returns voltage & charger details
How can we check if a Macintosh Portable is charging?
The Power Manager chapter of Inside Macintosh Volume VI (pages 31-23 and 31- 24) describes the BatteryStatus call, which provides you with the following information:
• Whether the charger is connected (status bit 0)
• Whether the charger is in High or Normal charge
• If the battery voltage is below the warning threshold
• A power value from which you can calculate the battery’s current voltage
To calculate a battery’s current voltage, you’ll need to average the voltage over an extended time period (tens of seconds to several minutes for good accuracy). The power load within the Portable is a dynamic environment, so the current draw of the various subsystems on the battery will affect the voltage that you read.
Devices & Hardware: Electrical Issues: IEC 801-2 ESD testing standard
Where can I get specs for environmental and electrostatic discharge (ESD) testing?
Apple doesn’t disclose its testing specs; however, there is an international ESD testing standard specification called the IEC 801-2 Athough not every company adheres to it, as ESD testing becomes written into law, it is almost a sure thing to say that this specification will be the standard on which that law is written up. As it stands now, the manufacturers of the testing equipment are already setting their machines to test at the levels set forth in the specification.
For more information regarding this issue, contact your source for ESD testing equipment. Since that portion of the industry has already taken notice of and implemented the specification, they’d be the best source for the kind of information you’re looking for.
Devices & Hardware: Electrical Issues: Apple Serial NuBus Card metal plate supplier
What vendor supplies the metal plate on the Apple Serial NB Card that holds the D-62 connector and covers the hole in the RF shielding?
North American Tool and Die (NATD) makes Apple’s metal plates (shields). Their address is as follows:
North American Tool and Die
999 Beecher Street
San Leandro, CA 94577
(415) 352-5500
Before ordering the shield (part #805-5101), you must first obtain authorization through MacDTS.
Devices & Hardware: Electrical Issues: Auto-restarting a Macintosh II after a power failure
What does it take to make a Macintosh II auto-restart after a power failure?
To get the Macintosh II to auto-restart after a power failure, the “reserved” Apple Desktop Bus (ADB) pin #2 (PWRON) must be grounded for a couple of seconds when the power comes up.
Devices & Hardware: Electrical Issues: Macintosh IIsi external floppy drive port power specs
How much current is available at +5V and +12V at the Macintosh® IIsi external floppy drive port? Assume an internal hard drive is in use.
According to Inside Macintosh Volume III, page 33, this connector was designed for a Macintosh 3 1/2-inch disk drive, which represents a load of 500 milliamps at +12 volts, 500 milliamps at +5 volts, and 0 milliamps at –12 volts. If any other device uses this connector, it must not exceed these loads by more than 100 milliamps at +12 volts, 200 milliamps at +5 volts, and 10 milliamps at –12 volts, including loads from all other connectors combined.
Devices & Hardware: Electrical Issues: Macintosh Classic, LC, & IIsi internal hard disk power specs
What is the maximum current available on the +5V and +12V hard disk power lines on the Macintosh IIsi, LC, and Classic?
Here are Apple's internal hard disk drive power specifications for the Macintosh Classic, Macintosh LC and Macintosh IIsi computers:
+5V +12V Total Power
----- ------ -----------
Startup 700mA 1000mA (see explanation below)
Accessing 700mA 300mA ≤ 5.5 Watts (see explanation below)
Operating (Idle) 500mA 300mA ≤ 5.5 Watts (see explanation below)
• The initial power consumption during startup must be less than 10 Watts RMS as measured during the first 2 seconds. After 2 seconds, the accessing/operating requirements govern.
• These specifications include terminator power which must be supplied by the drive.
• These are the absolute maximum allowable numbers (not the mean of a distribution of drives). Any drive that operates above any one of these numbers may not work.
• There is a discrepancy in maximum total operating power in Watts (5.5W) and standard power calculations (500mA * 5V) + (300mA * 12V) = 6.1W). This means that drives cannot draw the maximum current from both the +5V and +12V supplies.
• On the Macintosh Classic, there must be a delay of at least 700 msec before hard disk spin-up to prevent the +12V startup peak from happening at the same time as the Macintosh Classic's floppy drive’s startup head recalibration.
Devices & Hardware: Electrical Issues: Where to find information on Coaxial card Twinax connector
Is there any documentation on how to gain access to the Twinax connector on the Macintosh® Coaxial card?
Andrew/KMW Systems has developed a device interface for the Twinax connector on the Macintosh Coaxial card for their product. For more information, you can contact them at the following address:
Andrew/KWM Systems
6034 West Courtyard Drive
Suite 100
Austin, TX
78730-5014
AppleLink: D0500
For additional documentation, you might want to contact National Semiconductor for a copy of their technical documentation on the Biphase Communications Processor - DP8344A. Also, some Twinax technical documentation might be available from IBM.
Devices & Hardware: Electrical Issues: Macintosh power supply limits
Table 6-24 on page 263 of the 2nd edition of the Macintosh® Family Hardware Guide gives a limit of 18 amps @ 5 volts on the Macintosh® power supply. Can we exceed the recommended 6 x 2 = 12 amp limit at +5V on our cards?
It would not be a very good idea to exceed this limit, unless you don’t plan to have the card work in machines with internal hard drives or single-slot Macintosh systems such as the Macintosh IIsi. The remainder of the 18 amps not used by NuBus™ are used by the motherboard and the hard drive. If you do go with machines that do not have internal hard drives, then you will be able to use a little more power, but you will still need to leave some power for the video card. This leaves you back at about a 12-amp limit. If you put your own power converter on your card, you could convert the 12-volt power to 5 volts, but this is not going to gain a lot. In general, third parties who use more power than they should have ended up adding an external power source to their cards. In some cases there have been cards that required replacing the entire Macintosh power supply. Adding power will also require a bigger fan—that is, these limits aren’t just electrical; they represent maximum thermal values as well. This is particularly important in the Macintosh IIsi.
Devices & Hardware: Electrical Issues: Macintosh Classic and Macintosh LC power information
We need a cable to use our external card with the Macintosh® Classic® and Macintosh LC. The only available powered port seems to be the Apple Desktop Bus™ (ADB). How much power does the ADB on the Classic and LC supply?
You can approach your problem a couple of ways. We suggest that developers do not steal power from any of the CPU’s ports but if you insist on doing otherwise, then consider the following:
Maximum ADB power available is low—only about 125 ma per device at +5. You would have to provide an in-and-out connector since our newest CPUs have only one ADB port on them. We suggest that only three devices be used on each ADB port, and your device would count as one of those devices. See Chapter 8, page 295, of the Guide To Macintosh Family Hardware, Second Edition.
Power is available on the floppy drive port (+12, +5) and the maximum current available is higher than ADB. Allowing for a floppy drive plugged into your adapter, you would still have 200 ma @ +5 with a 400K drive connected and 340 ma @ +5 with an 800K drive connected. You must also provide a way for a floppy to be plugged into your adapter using a DB19 connector back to back on the Classic and you would have to run a cable out the back from the second floppy port on the inside of the LC. See Chapter 9, page 335, of the Guide To Macintosh Family Hardware, Second Edition, for more information.
If you still decide to use the ADB, remember that your device must support the following: ADB pass through and only about 100-125 ma @+5 current draw. Also, remember to add documentation to your product user’s manual that your device counts as one of the three allowed devices per ADB connector.
Devices & Hardware: Electrical Issues: Where to get connectors for making Apple-compatible cables
Where can I get connectors for making Apple®-compatible cables?
Here are some suppliers of the mini-DIN connectors. This list is provided for information only—Apple does not endorse any of the vendors.
Hosiden America/Harmonix Sales
Mike Ferrera
10090 Pasadena Avenue, Suite A-2
Cupertino, CA 95014
408-725-2424
CompuCable
Bob Mickey
180 Vallecitos De Oro
San Marcos, CA 92069
619-744-2789
800-222-2332 (outside CA)
TRW
Illinois
Gene Kazmarek aka Kaz
408-720-8727
HB Associates
Hank Lorta
415-487-3933
Union City, CA
Harbor Electronics
Ron Marsilio
650 Danbury Road
Ridgefield, CT 06877
203-438-9625
Also try AMP; they may supply the 8-pin variety.
Devices & Hardware: Input Devices: Apple Extended Keyboard values recognized by Apple IIGS
How can I use the "extra" keys on the Apple Extended Keyboard on my Apple IIGS®? What values do they return?
The following chart shows what the "extra" keys and other extended keys of the Apple Extended Keyboard return on the Apple IIGS. All of the keys turn on bit 4 of the Modifier Key register at $C025 (see page 124 of the Apple IIGS Hardware Reference) to distinguish these keys from the "regular" keys.
Key ASCII char Key ASCII char Key ASCII char
--- ---------- --- ---------- --- ----------
F1 z F8 d F15 q
F2 x F9 e help r
F3 c F10 m home s
F4 v F11 g page up t
F5 ` ($E0) F12 o page down u
F6 a F13 i end w
F7 b F14 k del |X> y
Devices & Hardware: Input Devices: Macintosh and multiple keyboard input
Is it possible to connect more than one keyboard into an ADB chain on a Macintosh II family computer?
Connecting multiple keyboards in parallel should work; however, a bug in many existing keyboards prevents them from distinguishing themselves at boot time. The result is that an application has no way of telling which keyboard has sent input. Parallel input from multiple keyboards doesn’t present a problem, but differentiating input from multiple keyboards often won’t work. This situation has improved with the Extended Keyboard II.
If you need to differentiate multiple keyboard input, use the Extended Keyboard II exclusively or mix your keyboards. Alternatively, the Macintosh can always distinguish a standard ADB keyboard from nonalike keyboards such as the Apple IIGS keyboard.
You can’t go wrong by trying, so hook them up and see if your needs are adequately served. If you don’t notice any problems, then great!
Devices & Hardware: Input Devices: Apple IIGS keyboard buffering: disabling and enabling
We need to turn off Apple IIGS keyboard buffering temporarily. Setting BParam $2B (keyboard buffering) and calling ToBRAMSetup ($E1/0094) works, but it’s invasive; a user’s Reset, for example, leaves the Control Panel in a “tampered with” state. Is there a way to do it without involving the Control Panel, like setting speed with the $C036 softswitch?
Keyboard buffering on the Apple IIGS occurs in the ADB microcontroller chip. While there’s no softswitch to control it, there is a way to disable keyboard buffering without modifying any battery RAM or permanent user setup stuff. To disable and re-enable keyboard buffering, use the Clear Modes and Set Modes ADB microcontroller commands, documented on page 189 of the Apple IIGS Firmware Reference. To “contact” the keyboard micro and communicate with it, you’ll need to use the Apple Desktop Bus Tool Set function SendInfo (Apple IIGS Toolbox Reference Volume 1, page 3-19). The background information in both these chapters, together with the code snippet below, will help you get up and running without keyboard buffering. Keep in mind that buffering does not affect the event queue, so when the VBL occurs and you are running an event driven application, the keyboard will still be polled and any keys put in the event queue.
mcopy 2/aInclude/m16.adb
copy 2/aInclude/e16.adb
longa on
longi on
KeyBufferOn Start ;called with jsl in full 16-bit mode
lda #$0001 ;dataLength = 1
pha
lda #^data ;dataPtr = pointer to data
pha
lda #data
pha
lda #setModes ;adbCommand = Set Modes
pha ;this will set the buffer keyboard mode
_SendInfo ;make ADB SendInfo call
rtl ;and return to caller
KeyBufferOff Entry ;called with jsl in full 16-bit mode
lda #$0001 ;dataLength = 1
pha
lda #^data ;dataPtr = pointer to data
pha
lda #data
pha
lda #clearModes ;adbCommand = Clear Modes
pha ;this will set the buffer keyboard mode
_SendInfo ;make ADB SendInfo call
rtl ;and return to caller
data dc b'00010000' ;bit 4 = Buffer keyboard mode.
End
Devices & Hardware: Input Devices: Using GetKeys to check Macintosh key status
Is there a way to test whether a particular key is down independently of the event record? My application needs to check the option key status before entering the main event loop.
The call GetKeys(VAR k:KeyMap) returns a keyMap of the current state of all the keys on the keyboard. The call is documented in Inside Macintosh Volume I on page 259, with the definition of keyMap on page 260. The option key will appear as the 58th bit (counting from zero) in the map. In MacsBug you can see this with a DM KeyMap which returns:
0000 0000 0000 0004 0000 0000 0000 0000
It is important to understand that the keyMap is an array of packed bits. You need to test if the option key BIT is 1 or 0. The key code 58 = $3A is the 58th bit of the keyMap. This number can be determined from the keyboard figure on page 251 of Inside Macintosh. (If in counting the above bits you get 61 instead of 58, remember that the bits within each byte counts right to left.)
With the above information you should be able to determine the status of any key on the keyboard within your program without waiting for an event.
Devices & Hardware: Input Devices: Mapping “Standard” Apple IIGS Option-key input to char table
How can we determine which physical Apple IIGS® key is pressed, when a user types Option-Keystroke? For example, if the user types Option-A, we want to determine the “A” key was pressed. When the keyboard translation is set to “None” this is not a problem, but when it is set to “Standard” the keystroke is translated to a high ASCII character that’s not simply “Key+$80.”
There is no way to get the physical keystroke when keyboard translation is turned on. There is an imperfect, gnarly way that might work though, explained below. However, it’s better to simply equate the standard dead keys with the characters they belong with inside your application, so that whether you receive an option-A or an option-å you perform the macro associated with A. This is probably the simplest but not the most foolproof method.
If you are willing to write a lot code, there is a way to reverse engineer thekeystroke that you receive in most cases. To de-translate a standard keystroke, you will first have to obtain the current keytrans table. Then take the keystroke returned to you and search for its ASCII value in the proper 128 bytes of the translation table. If the Option key is not down in the modifiers message, search the first 128 bytes of the table. If the option key is down, search the second 128 bytes. The offset into either of these two tables tells you the probable ASCII code for the real keystroke—”probable” because there is no rule that says two different physical keystrokes cannot return the same translated ASCII value. Fortunately you won’t have to worry about this with the standard translation much, assuming that you stick to Option-letter keystrokes. Dead key sequences will be much tougher, but since they require multi-key input, your users will probably not have a problem with them.
See the Event Manager chapter of Apple IIGS Toolbox Reference, Volume 3, for a complete description of how the data structure looks and how to determine the resource number of the keytrans table.
Devices & Hardware: Input Devices: Macintosh interfaces for Apple Scanner
Is there a set of Macintosh® C interfaces for the Apple Scanner driver?
The Apple Scanner Reference (APDA #M7078) comes with a disk that has interface files for assembly language, Pascal, and C. The C headers are in a file called ScIntf.j. Just #include this file and Link with the file called ScIntf.a.o (on that same disk), and you should be able to control the scanner from C.
Devices & Hardware: Input Devices: Macintosh LC and IIsi sound input hardware documentation
Where can we get documentation on the Macintosh® LC and IIsi sound input hardware?
You can find sound input information in the Macintosh LC and IIsi Developer Notes, which you should have received by now as part of Apple’s developer mailing. Developer Notes are available from APDA® if you don’t already have them. Additionally, may I suggest that you refer to the Sound Manager chapter of Inside Macintosh Volume VI.
Devices & Hardware: Input Devices: How the Macintosh mouse/cursor mechanism works
I’m writing a tablet (mouse, pointer, etc.) driver, and I need to be able to position the cursor and post mouseUp mouseDown events. How do I do it?
Here is an explanation of the Macintosh® mouse/cursor mechanism, which should provide the information necessary for you to place the cursor:
The mouse is a “relative” device, which means it does not return actual coordinates; it returns a “count” or amount of movement since the last report.
When the mouse has new information, it interrupts the Macintosh. The interrupt handler adds the horizontal and vertical counts to MTemp (a low-memory location), and sets crsrNew to tell the system that the coordinates are new. Some time later (but before normal VBLs are executed) the cursor VBL task is executed, and it compares MTemp with RawMouse (which has the last value), and figures out the delta (that is, the horizontal and vertical distance moved), and does the scaling trick depending on what the user has selected in the control panel. It also updates MTemp to reflect the new value. Then it draws the cursor.
Here are the names and locations of the relevant low-memory locations:
RawMouse equ $82C ;point
MTemp equ $828 ;point
CrsrNew equ $8CE ;byte
CrsrCouple equ $8CF ;byte
(NOTE: These may change in future CPUs.)
If you wish to place the cursor in an absolute location on the screen, you must set RawMouse, and MTemp to the same value, and set CrsrNew to the same value as CrsrCouple.
Keep in mind that moving the cursor from an application may violate the Human Interface Guidelines, possibly confusing and frustrating the user. Also keep in mind that the low-memory locations named above are not documented, and as such, are considered unsupported and volatile.
Posting mouse down/up events is a simple matter of keeping track of the last state of your device button, and when you detect a change, you post the appropriate event. If you wish to support the ToolBox Event Manager call Button, you must also update the low-memory global MBState. The high bit of MBState reflects the current state of the mouse button: 1 = button up, 0 = button down.
Unfortunately, the system mouse driver will change this value if it notices that the state of MBState is different from the state of the real mouse button. This means if there is a mouse connected to the Macintosh while your device is connected, it will override whatever you put in MBState. On systems equipped with ADB, this will happen only when the mouse moves, or the button is pressed. On earlier systems this happens all the time, since the button checking routine was a VBL task, and is always executed. One possible workaround is to patch Button, and return the state of your button, rather than MBState. The obvious problem is that you disable the real mouse from working with Button.
Devices & Hardware: Interrupt Handling: Use Time Manager instead of VIA2 timer T1
The Apple Macintosh Family Hardware Reference, first edition, (page 17-28) says VIA2 timer T1 can generate interrupts up to every 1.2766 microsecond. Is there any documentation for programming the timer to generate the interrupt at high speeds and installing the interrupt service routine? By the way, the Time Manager documented in Inside Macintosh Volume IV (page IV- 299) is capable of generating interrupts at the accuracy of only one millisecond.
Apple discourages direct use of the VIA2 because it’s not present on all Macintosh CPUs. It’s absent on the popular Macintosh IIci and IIfx models, for example.
Contrary to the outdated Inside Macintosh Volume IV Time Manager documentation, the Time Manager in System 6.0.3 and later has accuracy on the order of 1 microsecond. See Inside Macintosh Volume VI for details on new Time Manager features.
Devices & Hardware: Interrupt Handling: Macintosh Read calls at interrupt time
Read calls at interrupt time often result in a “hang,” waiting for the paramblock to show “done.” This occurs if the interrupt occurred during another Read call. I have tried checking the LowMem global FSBusy, and that decreases the occurance of this problem, but does not eliminate it. When it is safe to make the Read call?
The problem you are experiencing is a common one known as DEADLOCK. The good news is that you can ALWAYS make Read calls at interrupt time! The only requirement is that you must make them ASYNCHRONOUSLY and provide a completion routine, rather than loop, waiting for the ioResult field to indicate the call has completed. This will require that you use the lower-level PBRead call, rather than the high-level FSRead.
The low-memory global FSBusy is NOT a reliable indicator of the state of the File Manager. The File Manager’s implementation has changed over time, and new entities patch it, and use the hooks it offers to do strange and wonderful things. FileShare really turns it on its ear. The result is that when FSBusy is set, you can be sure the File Manager is busy, but when it is clear you can’t be sure it is free. Therefore, it would be best if you ignore its existence.
If you need to have the Read calls execute in a particular order, then you will have to chain them through their completion routine. The basic concept is that the completion routine for the first Read, initiates the next Read, and so on until you’re done Reading.
By the way, never make Synchronous calls at interrupt time (and contrary to the popular misconception, Deferred Tasks are still considered to be run at interrupt time) or from ioCompletion routines, which may get called at interrupt time.
Devices & Hardware: Interrupt Handling: Macintosh interrupt routines and I/O
Are there any dangers in doing a synchronous read at interrupt time? In particular, if an asynchronous write is executing and is interrupted by a synchronous read, can the re-entrancy into the Macintosh ROM read/write code cause problems?
The Macintosh ROMs are not re-entrant. For this and for timing considerations, you should do as little as possible within an interrupt routine. In any case, you should not be doing I/O of any kind from within your interrupt routines. You should simply use the interrupt to do the minimum possible to respond to the signaled condition and set indicators to your larger application to handle the larger context, like initiating additional I/O.
Devices & Hardware: Interrupt Handling: Macintosh disk drivers and slot interrupts
Macintosh disk drivers and slot interrupts
In the present-day implementation, Macintosh slot interrupts are always disabled for floppy disk access. The floppy driver disables the interrupts using code like this:
OR.W #HiIntMask, SR
where
HiIntMask EQU $0300
For hard drives, interrupts are enabled with SCSI transfers. They are disabled for very short periods of time during SCSI reset and when things are being put into and removed from queues.
Note that some day Apple might implement SCSI chip interrupts, which might defer slot interrupts if a card wanted to interrupt while a SCSI interrupt wasbeing serviced. To ensure future compatibility, please design variances in interrupt latency into your product.
Devices & Hardware: Interrupt Handling: VBL tasks under System 7 with virtual memory running
I use a VBL task to animate the cursor when my disk driver installer performs tasks such as media verification and low-level formatting. When a command such as Format Unit is sent to the drive, the Macintosh® does not gain control until the drive completes the command, which ranges from a few minutes to close to an hour. Under System 7.0 with virtual memory (VM) running, the cursor is never even set, much less animated. I’ve tried HoldMemory, and I’ve tried allocating a system heap pointer and installing the VBL task there. Any help would be appreciated.
The reason your cursor is not animating when VM is running is fairly straightforward to explain.
VBL tasks are deferred until a time when paging is safe if the VBL interrupt occurs at a time when paging is not safe. Paging is not safe when the VM backing store drive’s driver is busy, when a page fault is already being serviced, or when the SCSI bus is busy.
When you issue your Format Unit command, you call SCSIGet(), which makes the SCSI bus busy. It probably takes several minutes before this command completes and you are able to call SCSIComplete, which makes the SCSI bus free. All during this SCSI bus tenure, VM paging is unsafe and no VBL tasks may execute. Holding memory will not help this situation.
It would be nice if the Macintosh® SCSI Manager supported SCSI Disconnect/Reconnect, but this is not an option either.
The beach ball in Apple HD SC Setup does continue to rotate during Apple HD SC Setup disk formatting, even under VM. Apple HD SC Setup uses the standard RotateCursor call in the MPW® CursorCtl.h interfaces rather than a VBL, and apparently never loses control to the SCSI Manager. What Apple HD SC Setup does after SCSICmd returns is loop on SCSIStat until the SCSI bus enters status phase and then call SCSIComplete. This allows the cursor to rotate and a watchdog counter to time out the Format in case the drive dies. You’re probably going to need to do something similar. VBLs aren’t going to do you much good during a long format.
Devices & Hardware: Interrupt Handling: VBL tasks shouldn’t call Macintosh Memory Manager
What’s wrong with having VBL (vertical blanking) tasks make calls to the Macintosh® Memory Manager, either directly or indirectly?
The problem is that the Memory Manager could be moving memory around when an interrupt occurs. If the VBL task also moves memory, the heap could be destroyed.
VBL tasks are intended to provide a method of time-syncing to the video beam of the display. (On slotted Macintosh models you’d use SlotVInstall.) They’re also used to get periodic time for short tasks, although the Time Manager is better for this. VBL tasks should minimize execution time. The best use of a VBL task is to do a short condition check and set a flag for the main process to indicate that it’s now a good time to do something.
Devices & Hardware: Interrupt Handling: Eliminating Macintosh VBL animated cursor ghosts
What do I have to do to prevent an animated cursor from leaving ghosts on the Macintosh® screen?
Make sure the low-memory global CrsrBusy is FALSE before you try to change the cursor. MacApp® does this.
Devices & Hardware: Interrupt Handling: OK to set Apple IIGS TaskCnt to zero to prevent task execution
Is it possible to store a zero into the TaskCnt field to keep the Apple IIGS® system from ever executing a heartbeat task in the Heartbeat Task Queue? We are using the heartbeat task as a time-out, during which the routine may complete and the same task will need to be reinitialized immediately for the next routine’s time-out.
Yes, if you know where the count word is. You can then set it to zero to prevent it from being called. The system does not keep this information in a separate buffer; it checks the value in the queue header each pass through the heartbeat queue. So if you are at 200 one pass, and then 0 the next, the system is not bothered by that; it does not remember the previous value. And because the task is not executed unless the system itself decrements the count to zero, this is a fine way to prevent a task from executing.
Devices & Hardware: Interrupt Handling: Macintosh VBL documentation
Comments in the Technical Note #180 examples mention that A0 points to the VBL record when a VBL task is called, but we can’t find this documented in Inside Macintosh®. Is this really true? Is it going to change in 7.0?
Although we would like our documentation to be perfect, I must admit that sometimes it isn’t. We are always striving to improve the documentation. One method of making corrections to published volumes already in the hands of developers is to issue technical notes. So, although we will strive to have Inside Macintosh document that A0 points to the VBL record entry on when called, until it is published in a new volume we provided Technical Note #180 as additional update documentation. You can depend on A0’s contents as it is documented in Technical Note #180. It will not be changing in System 7.0.
Devices & Hardware: Interrupt Handling: Reset and NMI on a Macintosh IIsi or LC
The Macintosh® IIsi and LC computers don't come with programmer’s switches. How do I get reset and NMI on these machines?
Both machines have an ADB (Apple DeskTop Bus™) I/O processor which incorporate the reset and NMI functions through the keyboard. The functions are accessed as follows:
Reset on these Macintoshes is always available by simultaneously pressing the command (cloverleaf), control, and power-on keys.
To enable the NMI on the Macintosh IIsi or LC, you need MacsBug 6.2 or later. It's needed because the IIsi and LC start up with NMI disabled (if they didn't, nontechnical users might get into trouble with it), and the ADB controller must be programmed to enable it.
Once MacsBug is installed, NMI is activated by simultaneously pressing the command (cloverleaf) and power-on keys (like the Programmer's Key).
Under some circumstances you may have to hold the reset and NMI key combinations down for a little while (but no more than a second) to make sure the ADB processor sees them.
MacsBug 6.2 final is available in several places. You can buy the software and the manual from APDA® for $35.00 (if you don't have the MacsBug reference manual, we recommend it). The software can be downloaded from AppleLink. The path is:
Developer Support
Developer Services
Developer Technical Support
Macintosh Tools
MacsBug
In addition, various Beta versions of MacsBug are on the System 7 beta CD, the latest developer CD and the E.T.O. CD.
Devices & Hardware: Interrupt Handling: Macintosh interrupt handling saves and restores startup MMU mode
How does the Macintosh® system handle swapping MMU mode from 32 bit to 24 bit?
The system interrupt handler takes responsibility for the MMU mode. The first thing a low-level interrupt vector does is push the system’s startup MMU mode on the stack. It then sets the Macintosh to the 24-bit MMU mode. After the mouse vector is executed, the interrupt walks through the VBL queue, processing any tasks that are pending. Before the interrupt leaves interrupt land, by executing an RTE, it restores the MMU mode that was saved on the stack upon entry.
Devices & Hardware: Interrupt Handling: How to make sure inactive application VBL tasks always get time
Why is my Macintosh® VBL task (installed via SlotVBInstall in VBL queue) getting dumped after a few successful operations if I use a GetNextEvent or EventAvail call within the routine, but runs OK if I don’t?
One of the lesser-known mysteries of running in the world of MultiFinder® is that on either major or minor context switches (which both GetNextEvent and EventAvail allow), VBL tasks installed in the application heap will be unhooked until that application is the current application again.
If you wish for your VBL task to always get time install the VBLRecord in the system heap. One way to do this would be to use NewPtrSys(sizeof(VBLRecord)) and then to cast the resulting pointer as needed.
Devices & Hardware: Interrupt Handling: Macintosh LC SIntInstall & SLOTIRQ Interrupt Handling
How can we get our Macintosh® driver to talk with hardware using the SLOTIRQ provided on the bus?
To get SLOTIRQ to work correctly you need to use SIntInstall to add a slot interrupt queue element for slot $E. The interrupt service routine pointed to by the slot interrupt queue element must clear the interrupt line before returning. The slot interrupt enable bit in the V8 chip referred to by the Macintosh LC developer note (page 26 in the /SLOTIRQ signal description) is enabled during the boot process, so you don’t need to worry about it.
SIntInstall is described in Inside Macintosh Volume V on pages V-426 through V-428 and in Designing Cards and Drivers for the Macintosh Family on pages 161 through 163. Designing Cards and Drivers for the Macintosh Family also includes an example of a driver on pages 178 through 202.
Devices & Hardware: Interrupt Handling: System 6 “Faceless Background Driver” bug and workaround
We want to improve performance by getting frequent and consistent run times, but our Macintosh® driver seems to get run time only about every 0.5 sec under MultiFinder®, even when set to be awakened every tic. This current behavior degrades our performance noticeably when Finder™ is the active application and no other applications are running. Is there a way around this problem?
I successfully reproduced the result you reported. With only the Finder running, my driver got called on once every $1E (30) ticks.
It seems that the reason for this is considered a MultiFinder bug (called the “Faceless Background Driver” bug). What happens is that MultiFinder doesn’t call SystemTask when all applications are asleep. When Finder is the the only application, for example, it gets awakened once every 30 ticks. Otherwise, it’s asleep. When it’s asleep, MultiFinder just spins its gears, and fails to call SystemTask. If you run another application that has a much smaller sleep time (like AppleLink®), you’ll find that your driver gets called more frequently.
I talked with one of the other support guys here who was once in a situation almost identical to yours when he did a tape backup driver for a third party. What he did was write a VBL that would make a special Control call to the driver. The code that responded to the Control call would do whatever processing he wanted to do, taking care not to move or allocate any memory. Then, the next time he got an accRun message, he’d take care of any memory munging that he couldn’t do at VBL time. He says that it wasn’t hard to do, and that it all worked out very well.
Otherwise, I don’t know if there is much you can do. I understand that System 7.0 is supposed to fix the problem, but I haven’t double-checked that yet. It also doesn’t help all your System 6.0.x customers, so you might want to investigate the VBL solution.
Devices & Hardware: Interrupt Handling: International VBL timing on the Macintosh
Do VBL tasks execute at 50 Hz in Europe?
Televisions use AC line frequency to determine the vertical retrace interval. The Macintosh® does not. All Macintosh systems have their own internal 60.15 Hz clock for timing VBL tasks, regardless of whether that clock is actually connected to video circuitry. Tasks installed by _VInstall are always timed by this 60.15 Hz clock. Slotted Macintosh systems may have additional frequencies determined by the installed video card. Tasks installed by _SlotVInstall are timed by these card-specific clocks. In any case, VBL task frequency is not determined by the location of your power source.
Devices & Hardware: Interrupt Handling: What can I do and not do from a Macintosh interrupt routine?
What can I do and not do from a Macintosh® interrupt routine?
The most popular examples of interrupt code are I/O completion routines, VBLs, Time Manager tasks, and deferred tasks. Contrary to popular belief, the Deferred Task Manager will run your task at interrupt level. All code that runs at interrupt level must follow very strict rules. The most significant rule is that the code cannot allocate, move, or purge memory, nor can it call a Toolbox routine that would. This eliminates nearly, if not all, QuickDraw™ operations. For a more complete list of these toolbox routines, refer to the Inside Macintosh X-Ref.
Additionally, interrupt code must avoid accessing a low-memory global or calling a trap that would access one. While MultiFinder® is running, application’s low-memory globals are being swapped in and out. Because of this, the interrupt code cannot rely on which application’s globals are currently available. Even if CurApName is correct, the interrupt routine may be called while MultiFinder is in the process of swapping the application’s globals. This restriction is difficult to deal with because it isn’t documented as to which low-memory globals are swapped by MultiFinder, nor which globals are accessed by traps.
A typical example of this problem is interrupt routines that attempt to restore A5 by examining CurrentA5. This low-memory global is only valid while the current application is running at non-interrupt time. Thus, the MPW® routine SetCurrentA5 (or the obsolete SetupA5) cannot be used at interrupt level. It is necessary to place the application’s A5 somewhere it can find while in interrupt routine. This is documented in DTS’s Macintosh Technical Notes #180 and #208. In fact, the exact code you need is in #180.
It is best to avoid interrupt code if at all possible. Also, there are limitations while System 7.0 is running under virtual memory. Move the functionality of the interrupt code into the application. For example, if you do require a VBL, limit the code to an absolute minimum. Set a global flag for the application to check in its event loop.
Devices & Hardware: Interrupt Handling: How to set the Macintosh cursor at interrupt time
How do I set the Macintosh® cursor at interrupt time, such as a VBL task?
Changing the cursor at interrupt time is permissible as long as the cursor handle is locked in memory and the cursor routines are not busy. A test needs to be performed before changing the cursor. If you want to call SetCursor (with a cursor handle locked in memory), you must check CrsrBusy, a low-memory global defined in MPW® SysEqu. If CrsrBusy is true, then you cannot call SetCursor. Changing the cursor while CrsrBusy is true causes it to leave mouse bits, or trails, on the screen.
CrsrBusy EQU $8CD ; Cursor locked out? [byte]
Devices & Hardware: Interrupt Handling: Consistent application scrolling speed for all Macintosh systems
How can I keep the speed of my application’s scrolling consistent on all Macintosh® systems, including faster ones such as the Mac® II?
One method is to use TickCount. If a certain number of ticks has passed since the last increment of the scroll bar, then go on. If not, then loop until the desired number of ticks has passed before scrolling. It’s easy to include this test, but you’ll have to play with itawhile to find the right number of ticks for the desired delay. Also, consider that some Macintosh systems are faster than a Mac II, such as the SE/30 and Macintosh systems with third-party accelerator boards. It might be nice to let users set their preference for the scrolling speed.
Devices & Hardware: IOPs: Information on the IOP Manager not available
After reading the preliminary release notes for the Macintosh® IIfx, I found myself craving more information on the IOP interface and the IOP Manager. Where can I get more information about this new manager?
Apple will not be releasing IOP Manager information to developers because we plan on expanding the use of the IOPs in the future.
As the release notes stated, the IOP Manager can handle up to eight IOPs, but only two are currently used. The other six cannot be used by developers, because they are reserved by Apple for this future expansion.
Devices & Hardware: NuBus: Macintosh NuBus card development tools
Does a card exist with built-in circuits interfacing to NuBus that I can use to design my own custom part for my own interface card? Is there a chip set available to handle the NuBus protocol?
There are two levels of prebuilt NuBus support available to you, depending upon the level of control you wish to exercise over the interface of the design and how expandable and compatible you desire your card to be.
The first is to use the Macintosh Coprocessor Platform (MCP) prototyping kit available from APDA: Macintosh Coprocessor Platform Developers Kit (#M0793LL/B). The Macintosh Coprocessor Platform, together with A/ROSE, is a generic hardware and software foundation to help developers create add-on cards and software applications for NuBus-compatible Macintosh computers. The card helps the developer quickly build a NuBus coprocessor prototype and ultimately helps speed time-to-market. This product contains the Macintosh Coprocessor Platform, A/ROSE (Apple Real-Time Operating System Environment) software, and the Macintosh Coprocessor Platform Developer’s Guide. Its intent is to inform and assist the developer in creating an interface to the Macintosh II product family bus (NuBus).
The Macintosh Coprocessor Platform card is a prototyping card with over 26 square inches of space available for the developer to use. It has no input/output interface, but is a generic master/slave I/O processor. Affiliated I/O devices that the developer adds, such as RS232 ports or Token-Ring connectors, give the card access to the outside world. The Macintosh Coprocessor Platform includes a Motorola 68000 processor operating at 10 megahertz and has 512K of RAM. The NuBus interface provides a bus master interface to NuBus on the Macintosh II main logic board. The Macintosh Coprocessor Platform card acts as a slot device to the Macintosh II operating system, freeing the processor on the Macintosh II to perform other functions.
A/ROSE is a real-time multitasking operating system for smart cards and provides an intelligent peripheral-controller interface to NuBus on Macintosh II computers. It provides the operating system and core software services required by Macintosh Coprocessor Platform card by providing software services to smart card application programs. The code includes a collection of traps, interrupt handlers, and tasks that provide support for task naming, timing services, and inter- and intra-card communications via messages. The manual provides information about the Macintosh Coprocessor Platform and A/ROSE software. The manual also provides a general overview of the product as well as detailed information on both the hardware and software components of the product. In addition, there are sample programs and instructions on how to create applications using the services of the hardware and software. If you plan to redistribute any portion of the A/ROSE software, either within their own company or outside, you must sign a license agreement with Apple Software Licensing.
Note: Because of the card’s design, access to the 6800 requires direct wiring to the 68000 socket.
For development with the Macintosh Coprocessor Platform you need a Macintosh II computer (with NuBus) running Macintosh System Software v. 6.0.2 or later, A/ROSE software and the Macintosh Coprocessor Platform, MPW v.2.0 or later, MPW C and/or MPW Assembler, and a Macintosh Coprocessor Platform NuBus card.
The second option is to use two NuBus™ interface chips designed by Texas Instruments specifically to aid in interfacing to the Macintosh NuBus. These chips are MCP NuBus Interface Controller SN74ACT2441 and MCP NuBus Address/Data Registered Transceiver SN74BCT2425. These chips are described and documented in the Texas Instruments NuBus Interface Products Data Book available from Texas Instruments
Devices & Hardware: NuBus: Should similar Macintosh LC and NuBus cards have same ID?
We’re considering a Macintosh LC card with the same functionality as our NuBus card. In creating the declaration ROM for this card, should we be requesting a new card ID from you or should we use the same ID as we do in the NuBus version?
Whether you request a new board ID is up to you. We argued about it here in DTS a bit:
Pro-New-ID: “You may someday need to tell the difference between the two boards; any design shortcuts that depend on ID equality are probably bad.”
Con-New-ID: “If they’re basically the same board, they oughta have the same ID.”
It really came down to: they’re not *exactly* the same board, and since board IDs are plentiful and free, you might as well request a unique ID for the new board.
Devices & Hardware: NuBus: Macintosh IIsi MMU table bug fixed for System 7
Macintosh IIsi MMU table bug fixed for System 7
A bug in the Macintosh IIsi MMU tables, which has been fixed for System 7, caused slot 9 to be shadowed in slot B. This shouldn’t affect applications or drivers using the Slot Manager to look for their cards IF they scan starting from slot 0 up to E, because a card in 9 will get seen in 9 and all will work OK. But if someone scans from E down to 0, the Slot Manager would think it found the card in B. That’s bad because the driver would install the SIntInstall interrupt routine for slot B, and the card would really interrupt on 9, causing a crash. Fortunately every example DTS has seen publishes indexes from 0 to E.
Devices & Hardware: NuBus: NuBus 90 documentation
Where can we get NuBus 90 information?
NuBus 90 is specified in the following two ocuments published by the Institute of Electrical and Electronics Engineers (IEEE):
• IEEE Standard for a Simple 32-bit Backplane Bus: NuBus
• IEEE Std. R1196-R1990
You can obtain these documents by contacting IEEE at the following address:
IEEE Service Center
445 Hoes Lane
Piscataway, NJ 08854
201-981-0060
Devices & Hardware: NuBus: How to request advance NuBus product information from Apple
We develop NuBus products. How can we get advance information if Apple makes any NuBus changes?
Pre-release product information is managed by Apple’s Evangelism Group. To request advance information on future NuBus technology from Apple, please provide the following information either by AppleLink or letter addressed to MacDTS (the Hotline staff will forward your information to the appropriate Evangelist.):
• A detailed description of the product you intend to or are developing.
• Key distinguishing features of your product
• Resources you have to conduct the development including:
- a description of your company’s technical expertise
- development experience and how it relates to the product
- development you propose (include programming experience,
products you’ve developed, etc.)
• How and where you intend to sell and distribute your product.
• Why you think this product warrants seeding.
• What does your product do uniquely with a new technology.
Your request for advance information or pre-release product seeding will be reviewed carefully by Evangelism. Because of the limited quantities of seed units, not all requests can be granted, nor can Apple seed for compatibility issues alone. Approximately three weeks after Apple receives your information, Evangelism will inform you of the decision regarding your request.
Devices & Hardware: NuBus: Use DirectSetEntries for remapping individual color components
Use DirectSetEntries for remapping individual color components
You can use DirectSetEntries to remap each individual color component of a DAC instead of mapping 16 million colors to 16 million colors mapping in 24-bit mode. This works for Apple’s 24-bit video cards and others that support the DirectSetEntries call described in "Designing Cards and Drivers for the Macintosh Family," second edition, page 171. It can be used to change brightness and contrast, as well as for doing color correction.
The sample program called DirectSetEntries in the Snippets folder on AppleLink and the latest Developer CD Series disc demonstrates how to call DirectSetEntries.
Devices & Hardware: NuBus: Macintosh bus or resource locking for NuBus access
Is there a way to do Macintosh®-to-NuBus™ access with bus or resource locking but without the CAS CPU operation which uses a Read-Modify-Write cycle? Does a CPU Read-Modify-Write cycle do resource locking when the CPU accesses NuBus?
Macintosh II CPUs perform an Attention-Resource Lock cycle as a prelude to Read-Modify-Write cycles to NuBus addresses. There is no other way to initiate bus or resource locking from the Macintosh CPU. Macintosh CPUs do not support locking NuBus for longer tenures.
The only Read-Modify-Write instructions are TAS, CAS, and CAS2.
Use of these instructions is problematic, as they may introduce timing problems for certain CPUs (see Macintosh Technical Note #271), and the operand address must always be previously cached in the MMU address translation cache or else a bus error results. They must be used with extreme care.
Devices & Hardware: NuBus: Byte lanes and 8-bit NuBus data transfers
Can we use the Macintosh® SReadFHeader function and specify the appropriate byte lanes to send 8-bit data over the NuBus™ through QuickDraw?™
I don’t think it’s a great idea to be 8 bits wide. But I think you are confusing byte lanes with the Macintosh actually talking to the board.
Byte lanes values serve _only_ to show where the declaration ROM is, not anything at all about how the rest of the card is laid out or accessed. Reading the header to figure out the byte lanes values is only used to figure out how to access the declaration ROM. The driver or application that locates the card (via the Slot Manager) is presumed to know how to talk to the card and so will do so in the most efficient manner.
Most card developers use a byte-wide declaration ROM and design the rest of the card for whatever makes the most sense. For example, video cards need some registers and frame buffering RAM. It makes the most sense to have the frame buffer be 32 bits wide for performance reasons. Because QuickDraw and the operating system don’t need to access the video card’s declaration ROM much at all (mostly during startup), it’s quite OK and cost efficient to have the declaration ROM be byte-wide (you can put it on any lane you like in this case, such as B/L 0). The registers are mapped typically to byte locations as well.
One thing to note is that QuickDraw (always) talks _directly_ to the frame buffer RAM on the card by doing long word accesses. This is done for speed reasons, because video buffers can get big and if you have a lot of video activity, QuickDraw has to push a lot of data around.
So, if you want to respond with an 8-bit RAM frame buffer port, when QuickDraw is accessing the video buffer on your card, your card is going to see the NuBus TM lines from the Macintosh showing long word accesses, and you will have to (slowly) fetch, and latch and hold each of the 4 bytes of the long word until you fill that long access (that is, all 32 bits) before ACKing. For this reason, no one to my knowledge has ever produced a video board that did not have a 32-bit wide frame buffer. Also, QuickDraw does Bit Field Extract instructions to the buffer, so that may slow things down some more.
Devices & Hardware: NuBus: NuBus board sResources needn’t start with ID=1
Does the first item in the Macintosh® NuBus™ sResource directory have to be a board sResource with an ID of 1? Is a declaration ROM in error if this is not the case?
There’s no restriction that sResources must begin with a board sResource with an ID of 1. All our examples do start this way, but it’s not necessary. The sResource IDs do need to be organized in ascending order. A special case restriction is that video board functional sResource IDs must begin at 128 (for the default mode) and continue sequentially, covering the remaining operating modes. Beyond this restriction, the board sResource can have any ID value.
Devices & Hardware: NuBus: Where to find NuBus declaration ROM sample source code
Where can I find a source code sample for NuBus™ declaration ROM creation?
You can find sample code for a NuBus declaration ROM in issue 1 of develop and in the develop folder on the latest developer CD.
Devices & Hardware: NuBus: NuBus RAM can be used as RAM disk driver but not system memory
Can the Macintosh® use my NuBus™ board RAM as additional system memory or as a RAM disk?
There is no way that the Macintosh operating system can recognize NuBus RAM and use it for applications. If you want to use it as a RAM disk, you’ll need to write a RAM disk driver. (Refer to Inside Macintosh for more information about this.)
Devices & Hardware: NuBus: Where to get Macintosh IIsi NuBus expansion card specs
What are the exact physical specifications for NuBus™ expansion cards for the Macintosh® IIsi? I have heard that there were some slight differences from the physical specs published in Designing Cards and Drivers for the Macintosh Family.
Macintosh IIsi dimension restrictions for NuBus cards are documented in Macintosh Technical Note #234. (This was written before the Macintosh IIsi was released, but with the IIsi in mind.)
Devices & Hardware: NuBus: Test and board exchange for early Macintosh II/NuBus problem
I seem to remember that the first few months’ worth of Macintosh® II systems shipped had some sort of NuBus problems, which Apple acknowledged and even had a free motherboard swap offer. These problems were subsequently fixed on later revisions. What was the real problem with those early Macintosh II systems? Is the free (or any other) board swap still available, and how does an end user take advantage of it? What were the serial numbers of the affected Macintosh units? What should we be telling our customers and dealers?
The Rev A Macintosh II mother boards had a problem with 32-bit addressing of NuBus™ space. If you have a card which has its ROM mapped into the top of the 16 MB space, then the card would not be seen. The other problem was with cards which had more than 1 MB of RAM.
The swap is still available as far was we know. The way to get the swap is to go into any dealer and ask for it. It may take a week for the dealer to get the parts, but they should be able to help any user.
We give out a tool that will determine if the board is an old version or not. The tool, “NuBusTester,” is on the developer CD and you can give it to all of your users. The tool checks the machine and if the machine is one of the problem machines, then it will bring up a dialog which tells the user to see their dealer. If the machine is fine then the app does nothing. The tester application will tell the customer what to do.
Devices & Hardware: NuBus: Macintosh board IDs and sResource equate info not available
Can I get a list of all Macintosh® NuBus™ board IDs?
No, that information is confidential. We register board ID and functional sResource equates so developers don’t use equates that are already in use, but we can’t distribute the list because the database contains information on unreleased products.
However, even if the list could be distributed, any program that depended on the information in it would be obsolete as soon as a new board came out.
We recommend that you use the Slot Manager’s ability to find certain cards or functions. That way, you only need to write your code once, and it will work with newer boards. That’s why QuickDraw™ can find video cards years after it was frozen in ROM. It does so by calling the Slot Manager and looking for boards that perform the QuickDraw-compatible video function.
Devices & Hardware: NuBus: How to register a Macintosh NuBus board
How do I register a Macintosh® NuBus™ board?
You need to have Developer Technical Support assign ID values for the sRsrc_Type fields (Category, cType, DrvrSW, and DrvrSW) for sResources other than the board sResource (the sRsrc_Type fields for the board sResource are ALWAYS $0001, $0000, $0000, and $0000 for the Category, cType, DrvrSW, and DrvrSW fields respectively), as well as board IDs for the board sResource. AppleLink® or mail the following information to MacDTS:
- Company name
- Company address
- Person to contact (name, mailstop, phone number, and electronic
mail address)
- The official product name (or at least a code name for
the board)
- What the board will do
- If the board will have a software driver
- If the board will have a software driver, if it will be
in ROM
- If the board will have a software driver, if it will be
compatible with one that has already been defined
(for example, Apple's defined video driver)
We need this information to maintain our database of NuBus boards. The information you provide is kept confidential, and the database is not available outside of DTS.
Devices & Hardware: NuBus: NuBus test for early 1-MB Macintosh systems
My NuBus™ card needs more than 1 MB of memory. How do I determine if my card has been installed in a Macintosh® that can see more than 1 MB of memory?
Some early Macintosh II systems can’t use more than 1 MB of memory. There is an upgrade available for those machines.
“NuBus Tester,” available on AppleLink and on the current developer CD, tells you which version of Macintosh you are running on.
There are object files that you can link with so that you can call CheckNuBus from your own application. You can also just send out the application called “NuBus Tester,” which checks the Macintosh and alerts you if you need to upgrade.
Do not try to make your own version of CheckNuBus—the dialog was set up by Apple’s legal department.
Devices & Hardware: NuBus: Macintosh II NuBus slot numbers and addresses
What are the numbers and addresses of the NuBus™ slots in the Macintosh® II class of machines?
If viewed from the front of the machines, from left to right:
Macintosh II 1,2,3,4,5,6 ($9, $A, $B, $C, $D, $E)
Macintosh IIx 1,2,3,4,5,6 ($9, $A, $B, $C, $D, $E)
Macintosh IIfx 1,2,3,4,5,6 ($9, $A, $B, $C, $D, $E)
Macintosh IIcx 1,2,3 ($9, $A, $B)
Macintosh IIci 4,5,6 ($C, $D, $E)
Macintosh IIsi 1 ($9)
Software should not assume anything about slot numbers. Programs should call the Slot Manager and index through the slots using the range 0 through E.
(NuBus is a trademark of Texas Instruments.)
Devices & Hardware: NuBus: How to upgrade earlier EtherTalk cards for Mac IIcx and IIci
Why am I having problems with EtherTalk® and my Macintosh® IIcx/IIci?
Revisions J and earlier of the Apple® EtherTalk card have a timing problem with Macintosh IIcx and IIci units. Symptoms of the problem are intermittent and include system hangs on boot, serious system errors, and exceedingly poor network performance. Revisions K and later of the EtherTalk card have been modified so that they will not exhibit this problem.
This problem occurs because the capacitance of a six-slot NuBus was factored into the timing mechanism of the EtherTalk card. Consequently, the capacitance level in a three-slot NuBus is lower, thereby affecting adversely the EtherTalk card’s timing.
As additional NuBus cards are installed into a system, the capacitance level is raised on the NuBus. As a result, the problem is less likely to present itself. The most likely IIcx and IIci candidates for having the symptoms mentioned above are units with a single EtherTalk card installed and no other NuBus cards in the remaining two slots. This is a configuration that would be commonly used for routers, file servers, mail servers, and so on.
If you need to exchange your EtherTalk card for a newer revision, please see your local authorized Apple dealer. To find a dealer near you, call toll-free 800-538-9696. You will be asked for your zip code, and you’ll be given names and phone numbers of all dealers in your area.
Devices & Hardware: Processor Direct Slot: SE/30 expansion card form doesn‘t require square holes
SE/30 expansion card form doesn‘t require square holes
The small square holes at the top of the SE/30 expansion card depicted in Figure 15-9 of “Designing Cards and Drivers for the Macintosh Family,” Second Edition, are not necessary. Their appearance in the diagram is probably a legacy of either an abandoned design approach or some fluke in the construction of the sample card used by engineering on which the diagrams were based.
Devices & Hardware: Processor Direct Slot: Processor Direct Slot (PDS) adaptor card documentation
Processor Direct Slot (PDS) adaptor card documentation
Processor Direct Slot (PDS) adaptor card specifications for the Macintosh IIsi are documented on pages 49-71 of the Macintosh IIsi Developer Note, available on AppleLink and on the latest Developer CD Series disc.
Devices & Hardware: Processor Direct Slot: Dynamic bus sizing on the Macintosh IIfx PDS
Referring to pages 312-3 of the second edition of Designing Cards and Drivers for the Macintosh Family, it seems the Macintosh IIfx handles PDS Pseudo NuBus differently between read and write cycles, and therefore does not support true 68030-style dynamic bus sizing. Could you please explain?
To clarify Designing Cards and Drivers…, the paragraph with the wording about “cycles incoming to the Macintosh IIfx memory” on page 313 really refers to MASTER cycles incoming to the Macintosh IIfx memory. The memory controller will respond to masters reading IIfx memory with STERM (and only STERM) as a 32-bit port.
PDS slaves can use either DSACK or STERM—it’s your choice. DSACK is passed directly to the processor in this case. So the right thing should happen because the Macintosh IIfx circuitry is not altering your DSACK signals.
While there are buffers on the Macintosh IIfx connected to the PDS, they are only bi-directional buffers that flip one way or the other, depending on whether a read or write is happening. There is no byte-swapping.
The only differences between an Macintosh SE/30 card and the Macintosh IIfx are that the IIfx uses slot E and the PDS is a 20 MHz rather than a 16 MHz slot.
The only way to get on D0-D15 would be if a 16-bit cycle was made on a 32-bit port. Again, the Macintosh IIfx PDS doesn’t do anything funny with regard to slave accesses.
Devices & Hardware: Processor Direct Slot: Don’t exceed Macintosh LC expansion card size specifications
The Macintosh® LC expansion card specifications are clear, but I’m wondering why a larger expansion card cannot be developed. It seems that a card with an “L” shape could be used to increase the size of the board. There don’t seem to be any restrictive components other than a large electrolytic capacitor which could be avoided. Are the restrictions due to heat or power considerations? What would Apple think about a card that was larger than the specifications if it was within the power budget?
Making a larger or oddly-shaped expansion board for the Macintosh LC is not a viable alternative. Besides physical size limitations, blocking ventilation and air flow patterns, increasing the heat dissipation, and exceeding the power budget all become more acute because the Macintosh LC is designed with even less tolerance for “bending the rules” than any model before. Also, in designing upgrades to any Macintosh model, our engineers know not to violate the documented expansion space reserved for you. Likewise, your staying out of areas not defined for your use will eliminate conflicts with Apple’s upgrades.
The guidelines were set up to protect you and your product from an expensive exercise in incompatibility. Apple very much wants to see your product to be asuccess in the market place.
Devices & Hardware: Processor Direct Slot: Macintosh SE expansion card must be parallel to motherboard
The documentation for a Macintosh® SE expansion card shows the board mounted parallel to the motherboard, but the chassis of the Macintosh SE which I have is the same as the one used on the Macintosh SE/30, whose expansion cards are mounted perpendicular to the motherboard. Is it possible to design an expansion card for the Macintosh SE following Macintosh SE/30 guidelines?
When hardware guidelines are set up, such as expansion board dimensions, power budgets, heat dissipation, Apple goes to great lengths to ensure that if you stay within these parameters your board will fit into every unit of that specification. This should remain true regardless of any manufacturing change to the unit and with all configurations of options.
The Macintosh SE internal chassis was changed in mid-production life to be interchangeable with the Macintosh SE/30 chassis. Although this appears to allow you to use the Macintosh SE/30 form factor on your expansion board, this is not the case. First, your board would not physically fit in all Macintosh SE systems because many have the original chassis. Second, there is no way for a user to tell which chassis s/he has, short of opening up the case. Third, even though the newer chassis does not block a vertical version of the board, other components used at various times in manufacture WILL block a vertical board in a Macintosh SE. The maximum allowable specifications for each model’s expansion boards are detailed in Designing Cards and Drivers for the Macintosh Family, 2nd edition. If you design beyond these specifications, even if it seems to work in a specific Macintosh you own, it will not fit in all or even most of the other units within the same model. Mounting the card perpendicular to the motherboard on a Macintosh SE is not a viable option.
Devices & Hardware: Processor Direct Slot: /CPUCLK signal
What are the termination and fanout specifications for the /CPUCLK signal on pin A38 of the DIN connector?
There are no known problems with the /CPUCLK signal termination. The buffering available on the motherboard is rated for 1 TTL input. If you need more than you must provide the buffer yourself.
Devices & Hardware: Processor Direct Slot: /NUBUS signal
What is the function of the /NUBUS signal on the Macintosh® expansion connector?
The /NUBUS signal can be used to start decoding the address lines, but in general it is of very little use.
Devices & Hardware: Processor Direct Slot: Processor Direct Slot RAM access references
Please send us timing diagrams and any other useful information about accessing the RAM on the motherboard from the Processor Direct Slot (PDS) on the Macintosh® IIsi and LC.
You will find the information you need in the Macintosh IIsi and LC Developer Notes, which are available through APDA® (Apple Programmers and Developers Association). APDA is a membership organization for professional, advanced amateur programmers and developers who work on Apple® equipment. Membership is open to anyone needing advanced tools and information for use in the development of Apple-compatible products. Dues are $20.00 annually. Contact APDA for product information at 1-800-282-2732 or write
APDA
Apple Computer, Inc.
20525 Mariani Avenue, Mail Stop 33-G
Cupertino, CA 95014.
AppleLink®: APDA
You may also want to consult the 68020 and 68030 user’s manuals, which are available from Motorola.
Devices & Hardware: Processors: Identifying a unique system and why Apple doesn’t serialize ROMs
Is there any way to uniquely identify a Macintosh®? For example, if we have twenty Macintosh IIfx systems, can we tell which is which? Is the ROM unique?
The ROMs are all identical. The best you can do with software is to look at some combination of things, like the user name, internal disk name, something like that. 'STR ' -16413 (the Macintosh name entered at the Sharing Setup Control Panel) in the system file might be one way to ID a system. Or you could create files in the system folder that had unique serial numbers. Of course, the user could change any of this.
The last Apple machine to have serialized ROMs (in the video PALs on the CPU board) was the Lisa. When the software was installed, it copied the serial number on to the master disks and would only work on that machine. The serialized ROMs caused lots of problems. Making and tracking the ROMs was expensive in manufacturing, and when the user took a machine in for service, if the CPU board got exchanged, the service people had to remember to pull out the old PAL and put it in the new board. If the PAL was the thing that went bad, it got even worse, since only the factory could program them.
Devices & Hardware: Processors: Macintosh LC and MC68030 load limits
Can you explain the apparent differences between the information contained in the Macintosh® LC Developer Notes concerning the MC68030 load limits for A0-31 and D0-31 and page 13-2 of the MC68030 User’s Manual?
The loads listed on page 24 of the Macintosh LC Developer Notes are the total loads allowed on the TTL lines. The table on page 27 listing the lines and their loads has different values because they are the values of each line after considering the loads that are already on these lines. In other words, some of the lines already have loads on them (such as pull-up resistors) and these loads have been subtracted out of the total load allowed and then listed. The load values to follow are those listed on page 27 of the Developer Notes.
Devices & Hardware: Processors: Where to find list of “sad Macintosh” error codes & descriptions
Where can I find a list of “sad Macintosh®” startup error codes and descriptions?
A list of the “sad Macintosh” error codes and descriptions is on AppleLink® and on the current Developer CD.
Devices & Hardware: Processors: 68030/Macintosh LC notes
What do I need to know to replace the 68020 with a 68030 in my Macintosh® LC? We know we need to generate the /AVEC but can we ignore the other signals that are not in the Macintosh LC’s 68020 direct slot bus, or are they even used in the 020 design? Also, is the LC compatible with the 68030 implementation as per the book with regard to the no-cache instruction fetches mentioned in the Motorola guide?
A few signals are not in the Macintosh LC’s 020 direct slot bus—namely, /1PEND, /AVEC, /ECS, /OCS, /CDIS, and /DBEN. Also, since there is only a 16- bit bus to the LC processor from the main memory, there is some question as to how Apple handled the no-cache instruction fetches.
Pull up all signals other than the /AVEC. The /AVEC signal should be grounded. As long as you don’t try to support bursting, you shouldn’t have a problem with None Cachable instruction fetches.
There is one other problem, however, which will affect you. There seems to be a problem with the early test code in the ROM, which does not like the 68030. When you try to run a Macintosh LC with a 68030, you will get the chimes. Apple is looking into the problem.
Something else which you need to be very careful about is the power budget on the Macintosh LC PDS. The LC power supply is very minimal and will not allow cards to take more than they are allocated. So keep your power budget in mind while you are developing your card.
Devices & Hardware: Processors: Macintosh CAS2 instruction needs bus error trap handler
When we use the CAS2 instruction with the Apple’s 8•24 GC card, we get a bus error. Why?
The reason you get a bus error has to do with the way the NuBus™ interface works on the Macintosh® II. If an incoming NuBus cycle to the motherboard happens exactly at the same time a Read-Modify-Write (RMW) instruction such as CAS2 tries to go out over NuBus (something a card with bus master capability might do), the processor gets a bus error due to the bus conflict. What your software must do is set a bus error trap handler before the CAS2 instruction and eliminate the trap handler after the instruction. The trap handler needs only to do an RTE instruction to cause the CPU to retry the CAS2 instruction.
Devices & Hardware: RAM: Macintosh RAM addressability under System 7.0
Macintosh RAM addressability under System 7.0
Maximum
Addressable Classic II, IIx IIci,
RAM in: Plus, SE SE/30 IIcx IIfx IIsi LC Portable
----------- -------- ----- -------- ---- ---- ---- --------
24-bit mode 4 8 8 8 8 8^ 9/8*
24-bit mode N/A 13** 13** 13** 12^^ N/A N/A with VM
32-bit mode N/A 128t 128t 128 65tt 10^ N/A
32-bit mode N/A 1GB~ 1GB~ 1GB~ 1GB~ N/A N/A with VM
* The maximum addressable RAM on the original Macintosh® Portable is 9 MB; because of its memory controller, the backlit Protable is limited to only 8 MB of RAM.
** The original 24-bit mode memory map allocated 8 MB for RAM, 1 MB for ROM, 1 MB for I/O and 6 MB for NuBus™ (1 for each of 6 slots; if the slots were not occupied this memory could be used for RAM) for a total of 16 MB. On the Macitosh SE/30 and IIci, built-in video takes up 1 MB that was previously allocated for an expansion slot. On the Macintosh II, IIx, IIcx and IIfx, a video card is needed which also takes away 1MB. That means there is 16MB -1MB (I/O) - 1MB (ROM) - 1MB (video on board or on NuBus) =13MB maximum RAM memory available. On the Macintosh II, the 68851 PMMU chip is needed for VM.
^ The Macintosh LC uses its own contiguous memory scheme that gives a total of 8 MB accessible RAM in 24-bit mode and 10 MB RAM in 32-bit mode.
^^ The 24-bit memory map on the Macintosh IIsi is the same as for all other Mac II systems. It allocates 8 MB for RAM, 1 MB for ROM, 1 MB for I/O and 6 MB for expansion slots. However, because of the slot table, the on-board video takes up 2 slots rather than 1, which results in 2 MB allocated for on-board video. That means there is 16MB -1MB (I/O) - 1MB (ROM) - 2MB (on-board video) =12 MB maximum RAM available.
t - With either a 32-bit software patch (Connectix Mode32) or A/UX®. Also, Macintosh II and IIx systems can be upgraded to Macintosh IIfx systems; likewise, Macintosh IIcx systems can be upgraded to Mac IIci systems.
tt - The Macintosh IIsi has 1 MB soldered on the main logic board (Bank A) and 4 SIMMs (Bank B). A maximum of 64MB is addressable in Bank B, which gives a total of 1+64=65MB RAM.
~ Under the 32-bit memory map, 1 GB is allocated to RAM, 256 MB to ROM, 256 MB to I/O, and 2.5 GB to NuBus. VM in 32-bit mode only accesses the 1 GB RAM. Again, for the Macintosh SE/30, II, IIx and IIcx, it is necessary to have either a 32-bit software patch (Connectix Mode 32) or A/UX. Or, a Macintosh II or IIx can be upgraded to a Macintosh IIfx; likewise, a Macintosh IIcx can be upgraded to a Macintosh IIci. On the Macintosh II it is also necessary to have the 68851 PMMU.
Devices & Hardware: RAM: Macintosh LC Developer Note VRAM correction
Macintosh LC Developer Note VRAM correction
The VRAM memory map information in Table 1-1 on page 10 of the “Macintosh LC Developer Note” is incorrect. The line that currently reads:
Function 24-bit mode 32-bit mode
VRAM $FC 0000-$FF FFFF $50FC 0000-$50FF FFFF
should be corrected as follows:
Function 24-bit mode 32-bit mode
VRAM $F4 0000-$FB FFFF $50F4 0000-$50FB FFFF
Devices & Hardware: RAM: Apple IIGS text page 2 and shadowing
How can I force text-page-two shadowing on the Apple IIGS?®
Most uses for text-page-two shadowing come from older, 8-bit applications that use text page two. On the Apple IIGS, a Monitor ROM routine at $F962 (TEXT2COPY) toggles shadowing of text page two, through hardware on ROM 3 and through software on older machines. (A heartbeat task copies the bank $00 screen to the bank $E1 screen for software shadowing.)
TEXT2COPY is only a toggle—it can't tell you the current state of shadowing. To see if shadowing is currently enabled (the user may have enabled it manually with the Alternate Display Mode desk accessory), try storing a character in the bank $00 text-page-two screen, waiting more than 1/60th of a second and seeing if the character has been copied to bank $E1.
Devices & Hardware: RAM: Macintosh IIci DRAM specifications
What are the required specifications of the Macintosh® IIci DRAM?
Here are the Macintosh IIci memory specifications:
256K (made from 1 MB Fast Page Mode parts), 1 MB, 4 MB,
or 16 MB SIMMs
RAS: 80 ns
CAS: 20 ns
Access Type: Fast Page Mode
Refresh Type: CAS before RAS
Refresh Period: 15.6 µs
The SIMMs can be composed of the following sizes in each bank:
4 256K SIMMs (composed of 1 MB of fast page parts only)
4 1 MB SIMMs
4 4 MB SIMMs
If on-board video is going to be used, RAM must be installed in Bank A, since the frame buffer is maintained beginning at physical address $0000 0000. If two different sizes of RAM will be installed—that is, 5 MB comprised of 4 256K and 4 1 MB SIMMs—then install the 256K SIMMs in Bank A for best video performance.
Devices & Hardware: RAM: Macintosh IIfx SIMM specifications
I would like to make SIMMs for the Macintosh® IIfx. Where do I get the specification for the new SIMMs?
The information about the new SIMMs is in the Guide to the Macintosh Family Hardware, 2nd Edition, pages 210-211. The physical and electrical specifications are the same for LaserWriter II-compatible SIMMs; however, the Macintosh IIfx requires 80 ns or faster RAM. You can obtain this specification by writing Developer Technical Support and requesting a copy of the “Macintosh IIfx SIMM Physical Specification.”
Devices & Hardware: RAM: Applications should not change Macintosh parameter RAM settings
How can I change the Macintosh® parameter RAM settings?
Changing parameter RAM is not supported. Inside Macintosh documents portions of PRAM and a couple of calls that will modify it. The layout of the standard PRAM was detailed, but since then PRAM has changed and extended. PRAM is reserved for the system, and is set by the user via the control panel. As you may have noticed, changing the settings of PRAM does not necessarily mean the system will start using those settings.
The system examines the contents of PRAM at startup time, and build its low- memory global information based on it. If you change PRAM during run-time, you would also have to change all of the affected low-memory globals. This is exactly how the Mouse and the rest of the control panel items work. Also, there is no trap to change the RAM cache setting because it is considered a user function. The RAM cache will only go into effect at the next application’s launch. The only supported documentation regarding the cache is in Macintosh Technical Note #81 and Inside Macintosh.
Parameter RAM is under the control of the user, not the application. We do not condone, and can’t support, applications that attempt to modify the PRAM.
Devices & Hardware: ROM: Macintosh II “32-bit clean” upgrade
I want to upgrade my Macintosh II with new ROMs so that I can be 32-bit clean and address more than 14 MB of RAM. Will the SuperDrive upgrade with new ROMs provide the solution I am looking for? If not, then is there any way to be able to address RAM using 32 bits in the future on a Macintosh II or do I have to upgrade to a Macintosh IIfx? I would prefer to stay with my Macintosh II and would like an upgrade path of this nature.
Currently the only way to obtain 32-bit clean ROMs for a Macintosh II is to purchase the Macintosh IIfx logic board upgrade. There are no plans at this time to provide 32-bit clean ROMs for CPUs prior to the Macintosh IIci that would allow the extended 32-bit addressing supported by System 7.0.
Devices & Hardware: ROM: No 32-bit clean Macintosh II ROM upgrade
I have heard that there is a ROM upgrade available for the Macintosh® II which is necessary for it to be fully 32-bit clean or to be compatible with System 7.0. Please respond and let us know whether a ROM upgrade is necessary, and if so how it may be obtained, and if there is any cost for the upgrade.
We don’t have a 32-bit clean ROM upgrade kit for any of our Macintosh systems. All our newer Macintosh systems have 32-bit clean ROMs, but all our computer models prior to the Macintosh IIci don’t. You might be thinking of the PMMU chip upgrade.
This won’t stop you from using System 7, however. It just keeps you from using 32-bit addressing. You can still use Virtual Memory if you put a PMMU in your Macintosh II. Even with a PMMU, however, you won’t be able to access more than 14 megabytes of RAM (minus 1 megabyte for each NuBus slot you’re using). If you did have 32-bit clean ROMs and used 32-bit addressing, you could address up to 128 megabytes of physical RAM, and address over a gigabyte of Virtual Memory! Most people would not need to use even a fraction of that. So even if you did have 32-bit clean ROMs, it’s likely you wouldn’t need 32-bit addressing.
Devices & Hardware: SCC: Macintosh maximum sustainable serial baud rate
When my hardware device sends data to a Macintosh at 57.6 kilobaud, characters can get lost if LocalTalk is on and a file server is mounted. Does Apple know about the problem? Is there a solution?
The specification for the top speed of the serial port on a Macintosh is an absolute maximum given that no other processing or use of the SCC are present. Although the speed of the Macintosh IIfx has now allowed this ceiling to be reached in the presence of other processing, it is just not attainable on other models of the Macintosh except when the machine is dedicated to this purpose. While AppleTalk remains active there is no guarantee on serial port data transmissions over 2400 baud. The same processor must handle the OS, the Serial driver and the AppleTalk driver (with no advantage of DMA), so the overhead is considerable. Because of the AppleTalk driver’s considerations for incoming serial data, users can usually work at up to 9600 bps without any problems. All models in the current product line, except the Macintosh IIfx, are unable to sustain throughput with baud rates beyond 19.2 kbaud except when exclusively dedicated to that task.
There is essentially no way to guarantee 100% serial data acquisition when using AppleTalk. This is due to the fact that while the Macintosh is receiving an AppleTalk packet, interrupts are disabled for the duration of packet transmission. What this means in a “worst case” situation is that a 603-byte packet (the largest possible AppleTalk packet) sent to the serial port would take approximately 26 milliseconds to receive. Compare this with asynchronous serial data transmitted at 9600 bps which would only take 1 millisecond to receive. A very realistic situation arises in which 26 bits could be lost during a concurrent AppleTalk/Serial Device transmission. The possibility is further strengthened when there are routers on the network, which send out large RTMPs (Routing Table Maintenance Packets).
To alleviate possible data loss, the AppleTalk driver interrogates the serial port at key times that won’t interfere with packet reception. However, the checks are not at regular intervals; they are encoded in the driver as stated above. This means that these random checks may not coincide with the demands of the serial driver, and an occasional character is lost.
This same loss of characters may also occur in conjunction with the Sony driver. If a disk is inserted and it requires special attention (like formatting) then the odds of losing characters is increased. The Sony driver has built-in considerations like the AppleTalk driver (although not as frequent). So you can still lose data at high transfer rates if a disk is inserted during the transfer.
The character dropout also occurs on systems which are not currently running AppleTalk but are receiving serial transmissions from high-speed devices (57.6 kbaud) and are performing CPU tasks which require a high amount of memory access (such as a CPU like the Macintosh IIsi or IIci running on-board video in 8-bit mode, or a CPU using VM).
There is, however, a way to ensure reception of high-speed serial data without character loss—through the use of a Serial NuBus™ card or other third-party NuBus cards with a dedicated processor necessary to provide higher speeds The cards in essence operate as dedicated port-handling circuitry. They are able to perform necessary buffering while the processor is servicing other interrupts. This is the reason that network cards such as EtherTalk and TokenTalk can accomplish lossless transactions; they do at least some of their own buffering until being serviced to avoid interference with other operations like receiving serial data.
Alternatively, you may want to develop a custom card yourself that exactly fits the needs of your product. In this case you should look into the Macintosh Coprocessing Platform (MCP) and Apple / Real-time Operating System Environment (A/ROSE) as a basis of this line of development. Development packages for both these products are available from APDA.
Devices & Hardware: SCC: NuBus cards that monitor multiple serial ports simultaneously
What NuBus cards are on the market to monitor multiple serial ports simultaneously? Do any of these come with source?
You should be able to use the Apple Serial NB Card, along with the Macintosh Communications Toolbox. The board ships with the Serial NB tool, which is the best way to access the card.
You can also check the Redgate Product Registry on AppleLink for the Creative Solutions serial card and other third-party products that might be other options for you.
Devices & Hardware: SCC: Separate transmit & receive baud rates for Macintosh serial port
Separate transmit & receive baud rates for Macintosh serial port
The Serial Driver does not support separate baud rates for transmit and receive. This is due to limitations imposed by the Z8530 SCC.
The SCC supports separate transmit and receive clocks; each is independently configurable to use a clock from the RTxC pin, the TRxC pin, the internal baud rate generator, or the output of the onboard DPLL. The first two options provide only a very limited, fixed set of baud rates. The last is used primarily for synchronous protocols. For maximum baud rate flexibility, the Serial Driver uses the internal baud rate generator for both transmit and receive. In some scenarios, separate transmit and receive rates would require two baud rate generators per channel, but there is only one.
Also, because the input and output drivers for a particular serial channel share code and data structures, commands like SerReset and SerHShake operate on both channels, regardless of the input or output designation corresponding to the refNum. In spite of the historical admonitions to make these calls separately for each driver, it’s not necessary to do so.
There are essentially only two options for running separate transmit/receive baud rates: operate in a half-duplex mode and SerReset between sending and receiving (gross and disgusting), or reprogram the SCC (risky) to use the RTxC clock or some other clocking option for either the transmitter or receiver, and live with one of the limited baud rate options that offers you. Baud rate options are limited because the standard input clock you have to depend on is 3.672 MHz. You could divide this down by factors of 1, 16, 32, or 64, giving you a minimum baud rate of 57.375 kbaud—not very helpful if you need something like 2400 or 9600 baud. You could run an external clock, but this adds expense and complexity.
Devices & Hardware: SCC: How to keep power on the Macintosh Portable SCC
How do I tell the SCC on the Macintosh® Portable to stay on (powered)?
The Macintosh Portable has a second CPU known as the Power Manager. The Power Manager controls power to each subsystem of the Portable in order to best conserve power on those parts that are not currently in use. The Power Manager is documented in Inside Macintosh Volume VI as is a trap (_SerialPower) that can be used by a driver to turn on (and off when done) the SCC.
Devices & Hardware: SCC: Where to get detailed Zilog Z8530 SCC documentation
I need to find documentation for the Zilog Z8530 SCC beyond Inside Macintosh®. Do you how I can contact Zilog or another vendor for this documentation?
You can get documentation on the SCC from the following source:
Advanced Micro Devices (AMD Z8530)
901 Thompson Place
P.O. Box 3453
Sunnyvale, CA 94088
Devices & Hardware: SCC: Macintosh IIfx Serial Switch 'cdev' for SCC direct access
My application requires direct access to the SCC and I do not find the Macintosh® IIfx Serial Switch 'cdev' to be good solution. Is there a way for me to get the support I need from the Serial Driver, or do I need to continue breaking the rules?
The Serial Switch 'cdev' is a compromise between not allowing developers any solution or Apple redesigning the serial driver and waiting for developers to implement it. For the moment, this Serial Switch 'cdev' is the best solution available; however, Apple is working on improving the Serial Driver to solve this problem. Unfortunately, it was not possible to produce this improved Serial Driver in time for the Macintosh IIfx introduction.
Devices & Hardware: SCC: Macintosh Device Manager and IOP Serial Driver access
On the Macintosh® IIfx, does the Device Manager still use the same offsets into the Unit Table to access the IOP Serial Driver? Does this serial driver maintain the low-memory SCCASts and SCCBSts globals?
Yes, the Device Manager uses the same offsets. If you use the Serial Switch 'cdev' for compatibility mode, then the Serial Driver does maintain both SCCASts and SCCBSts.
Devices & Hardware: SCC: SCC and AppleTalk timing
The AppleTalk® spec claims a data rate of 230.4 kbaud, which should require a 3.6864 MHz input to the SCC, but RTxCB on the Macintosh® carries a 3.672 MHz clock. How does the AppleTalk driver reconcile this and what frequency should I use?
The SCC contains a phase-locked loop which is able to lock on and synchronize with AppleTalk transmissions whose clock rates are not exactly to specifications, so everything is fine as long as both ends of the communication are using approximately the same clock frequency. If you are designing your own AppleTalk hardware from scratch, it is easiest to use a 3.6864 MHz oscillator and a Z8530. This has been tested and works just fine.
Devices & Hardware: SCSI: Macintosh Quadra and SCSI termination
Macintosh Quadra and SCSI termination
Proper SCSI termination is critical for correct operation of the Macintosh Quadra computers, just as with all Macintosh computers. The Macintosh Quadra computers require external SCSI termination at the end of the device chain, either supplied by the last device in the chain, or using a standard Apple SCSI Cable Terminator (M0332LL/A). Note that this is the standard SCSI terminator, NOT the black terminator required by the Macintosh IIfx (although the black IIfx terminator may be used as well).
Termination is generally supplied at the factory for use with internal SCSI devices. Some early floppy-only Macintosh Quadra 700 units may not have internal termination, so users who attach external SCSI devices (without having added an internal SCSI device) may need to double terminate their external SCSI chain. Properly terminated floppy-only Macintosh Quadra 700 units will have a terminator inserted into the motherboard internal SCSI cable connector. Users of internal SCSI devices must, of course, remove this terminator before connecting their internal SCSI device.
The Macintosh Quadra 900 is the first Macintosh computer to provide a separate, internal SCSI bus. This bus is physically isolated from the external SCSI bus and must also be properly terminated. The cable provided with the machine includes all the termination necessary, so ALL internal devices must have SCSI termination removed before connecting to the internal Macintosh Quadra 900 SCSI cable. If extra termination is supplied it may cause intermittent hardware failures as well as physical damage to the device.
Developers who ship terminated SCSI devices for possible internal use in the Macintosh Quadra 900 must provide users with instructions for removing the termination.
Devices & Hardware: SCSI: Documentation describing VM/SCSI driver requirements
Are there any new rules regarding SCSI driving with Virtual Memory? My System 6 driver doesn’t work with System 7.
You need the following new documentation:
• Inside Macintosh Volume VI contains new information specific to Virtual Memory as it relates to drivers and especially SCSI.
• Technical Note #285, “Coping with VM and Memory Mappings”
• “VM Paper” from the System 7.0 developer CD in the VM Goodies folder.
These documents provide a good overview of what you need to do to revise a SCSI driver for VM compatibility.
Devices & Hardware: SCSI: Use Macintosh SCSI Manager for SCSI chip compatibility
Our SCSI driver asserts the SCSI bus protocol directly, according to the SCSI bus specs, using the low-memory global SCSIBase as the SCSI base address. Our code works fine on systems using the NCR 5380, but hangs with the new SCSI NCR 53C96. Do I need to add a NOP somewhere because the new chip is faster?
Although SCSIBase is exactly where a SCSI device driver should look to find the base address of a SCSI chip in the Macintosh, the NCR 53C96 is a physically different chip then the NCR 5380. Besides having its registers in different locations of the address map and a slightly different register set, the chip takes on much more of the burden (and control) of accessing the SCSI bus. The major difference is that with the 5380, the chip controller (drvr) needs to actively respond to the phases of the SCSI bus as the target changes them and to be ready to correctly react to any unexpected changes in state. For continued compatibility with the Macintosh product lines, your driver must use the SCSI Manager rather than to write directly to the chip. With the new chip (5396) the chip controller needs to set up all information for the entire command sequence (Arbitration thru Message In) and then tell the chip to execute it. The “controller” is not in direct control of the SCSI bus. (With the earlier chip, it’s really the Target that’s always in control, not your driver, but the 5380’s interaction model gives the IMPRESSION that your driver is in control.)
Your best course of action is to make sure your SCSI driver uses the SCSI Manager so that you will automatically work on all Macintosh platforms in the event that Apple changes chips in the future. If there is something odd about your SCSI device that it just cannot be accommodated by the SCSI Manager (this is rare!) then you will need to get the documentation for the NCR 5396 (from NCR) and rewrite your driver to use this new “setup and go” interaction model.
Devices & Hardware: SCSI: Macintosh SCSI reselection
How should we handle target reselection with the Macintosh SCSI Manager?
The Macintosh SCSI Manager does not support disconnection and reselection. After arbitration and selection, the target device should perform a SCSIMsgOut to identify the logical unit number and especially to see if disconnection and reselection is allowed (bit 6 of the Identify message). The Macintosh currently always sets bit 6 of the Identify message to 0, meaning disconnection is not allowed.
A target device should always assume that disconnection is not allowed unless it is specifically told otherwise by the Identify message. In this way, the target will do the right thing even if it does not follow protocol and issue a Message Out before requesting the Command.
Devices & Hardware: SCSI: Apple SCSI cable information
Where can we get specs for Apple’s SCSI cables, similar to Apple’s paint and finish standard, which allows us to match our hardware exactly to the Macintosh family? SCSI details we are concerned with are: single versus double shielding, contact types (such as gold), wire gage, and color.
The information you’ve requested is unavailable for distribution. Apple simply doesn’t supply specifications for any of its hardware to outside parties. However, you might try looking at the following SCSI specifications for more information:
Specification: Available from:
_____________ ___________
SCSI-1: ANSI X3.131-1986 American National Standards Institute
ISO DP 9316 1430 Broadway
ECMA-111 New York, NY 10018
CCS: X359.2/85-52,1986 (Rev 4.B) American National Standards Institute
(Common Command Set) 1430 Broadway
New York, NY 10018
SCSI-2: ANSI X3.131-1990 Global Engineering Documents
(Revision 10c) 2805 McGaw
Irvine, CA 92714
Tel: (800) 854-7179 or (714) 261-1455
These specifications discuss SCSI interface and, although they don’t tell you exactly how to build a SCSI cable, they give you a good benchmark for engineering one. Both of the above specs are available from:
Another alternative is to go out and buy one of Apple’s cables and reverse engineer it. Your local dealer might be the best location for this.
Devices & Hardware: SCSI: Transferring data from SCSI device to Macintosh
How can an external SCSI device interrupt the Macintosh system CPU? What’s the procedure for transferring data from my external SCSI device’s buffer to system RAM?
Transferring data from a SCSI device to a Macintosh is not a simple task. The Macintosh SCSI implementation does not support arbitration, so only the Macintosh can start a SCSI transaction. If someone else were to begin transferring data on the bus, and the Macintosh wanted to begin a transfer, it would not know how to deal with the situation.
This rules out your SCSI device being able to decide to send data to the Macintosh. The only way to accomplish what you need to do is to write a VBL or Time Manager task that periodically checks your device to see if it needs to be serviced, and if so, initiates a SCSI transfer to get the data from it. While this approach requires somewhat more care, because of its granularity, it should prove adequate.
Devices & Hardware: SCSI: SCSI hardware specifications
SCSI hardware specifications
SCSI 1 and Common Command Set (CCS) hardware specifications are published by the American National Standards Institute. You can request specifications from this organization by contacting them at:
American National Standards Institute
1430 Broadway
New York, NY 10018
SCSI 2 and most other SCSI documents are available from:
Global Engineering Documents
2805 McGaw
Irvine, CA 92714
Tel: (800) 854-7179 or (714) 261-1455
Devices & Hardware: SCSI: SCSI/NuBus card development tools and resources
Are there any new tools or resources for developing a SCSI/NuBus card? None of the slot tools available on AppleLink have been updated since September 1989.
We recommend you look at the application named Slots, on the latest Developer CD Series disc. It allows you to look at declaration ROM sResources and make your own calls to the Slot Manager. It was written in 1990 by an engineer working on the Slot Manager.
Devices & Hardware: SCSI: SCSI drivers and virtual memory
How can we disable virtual memory (VM) from a SCSI driver, for dequeuing partitions? How can our driver determine which volume the virtual swap file resides upon?
The use of virtual memory requires that at boot time the PMMU be programmed with the appropriate memory mapping tables and enabled. The virtual memory is then laid out in the “VM Storage” file and available “real” RAM begins to be used to implement those portions of the virtual memory that need to be resident. It is not possible to turn this on and off while the machine is running. Specifically, it cannot be disabled / re-enabled from within your SCSI driver. With VM running, you can dismount and remount any disk or partition EXCEPT the unit that contains the VM Storage file. Whenever the system boots with VM on, the Finder makes sure there is only one file of that name mounted anywhere and deletes any “extra” files it encounters.
Currently there is no interface for locating the VM Storage file. Since the file name is guaranteed to be unique, it should be sufficient to search each volume for that file name.
Devices & Hardware: SCSI: Currently A/UX is only OS to use Macintosh IIfx SCSI DMA chip
Does System 6.0.7 or 7.0 make use of the DMA portion of the Macintosh® IIfx hardware?
System 7.0, or any version of the Macintosh operating system at this point, does not utilize the SCSI DMA chip in the Macintosh IIfx. A/UX® is the only operating system on the Macintosh that does use this chip.
Devices & Hardware: SCSI: Using Macintosh SCSI Manager for direct disk access
I would like to read and write sectors directly on a SCSI disk. Do I need to access the SCSI chip directly or can I use the SCSI Manager for this?
The normal way to access a SCSI disk is to use the Macintosh® file system, which calls the SCSI Manager to access the SCSI bus and command the hard disk to read or write data in various blocks. You should be able to directly command the hard disk yourself and directly send and receive the sector buffers by calling the SCSI Manager to perform the SCSI communication for you.
Pseudo code to perform this kind of transaction would be:
• Prepare a command block for read or write, etc.
• Prepare your data buffer and a transfer instruction block (tib) containing instructions for data transfer. For example, a tib for transferring six 512-byte blocks of data from or to address $67B50 contains the following:
SCINC $67B50 512
SCLOOP -10 6
SCSTOP
• Call SCSIGet() to gain control of the buss
• Call SCSISelect(TargetId) to select the target device (your hard drive) and allow the target to command the bus.
• Call SCSICmd(CommandBlock,Length) to give the SCSI Manager the command you want it to transfer when the target requests the command.
• Call SCSIRead(tib) (or SCSIWrite) to tell the SCSI Manager where to put the bytes (or where to get them from on a write) when the target requests them.
• Call SCSIComplete(Status, message) to finish the transaction and receive the (potential) error code.
If what you intended to ask was how to write your own SCSI hardware driver, be aware that this is not an area that DTS normally supports. If you are developing for a unique SCSI device that cannot be interfaced to using the provided SCSI Manager, please let DTS know the details about your device and the problems you are encountering that will not allow its control via the SCSI Manager. Also, please note that the specific SCSI chip used in a specific Macintosh model may change in some future Macintosh model and will break your custom driver, requiring you to rev your driver if you want to continue to be compatible. For this reason we strongly suggest that you use the provided SCSI Manager if at all possible.
Devices & Hardware: SCSI: Macintosh System 7.0 SCSI function #14
What does the new Macintosh® SCSI function #14 do in System 7.0?
The new selector is called SCSIBusy or, more accurately, SCSIMgrBusy, selector #14 or $0E. It is a parameterless SCSI call to determine whether the SCSI Manager is busy or idle. A non-zero return value indicates that SCSI Manager is busy, meaning it is currently processing a SCSI transaction. It is important to note that return value does NOT reflect the busy/idle state of the SCSI bus. It is possible to get a return value of zero--SCSIMgr is idle--while the SCSI bus is busy.
The selector is intended to be used by Apple only, specifically by the file
system.
Devices & Hardware: SCSI: SetDefaultStartup sdRefNum should be real SCSI ID, not -33
If I’m doing a SetDefaultStartup for a SCSI device can I simply set sdRefNum to -33 for the SCSI ID? Do I have to set any other fields of the DefStartPtr? Will these other fields be ignored?
Don’t count on the unit table always staying the same. It would be better to use the real SCSI ID.
Devices & Hardware: SCSI: Macintosh/SCSI compatibility
Is there any reason that a SCSI device (scanner) would work on a Macintosh® IIfx but not work on a IIci?
Without a bit more information it is difficult to speculate what might be causing the problem. If you access the scanner through the SCSI Manager, there should be no problem. Usually it is the other way around (works on the Macintosh IIci but not on the IIfx). If any part of your driver does access hardware directly on the Macintosh IIci, it would likely have problems on the IIfx because its SCSI hardware is very different. It may simply be related to termination on the SCSI bus and not driver code on the IIci. The IIci is prone to termination problems if there is no internal HD or if it is not properly terminated externally. Check for that possibility by changing the arrangement of SCSI devices. There are also some specific bugs/quirks in the SCSI Manager documented in Macintosh Technical Notes #96, 212, and 258.
Devices & Hardware: SCSI: If Macintosh doesn’t boot with multiple SCSI devices
What would cause the system to refuse to boot up when I connect a third-party SCSI drive after the Apple CD-ROM drive?
Your problems with the CD SC and a third-party disk are probably related to noise on the SCSI bus. We use CD SCs here with as many as 5 other external SCSI devices without problems. However, any SCSI device’s performance can be affected by noise and is exacerbated as more devices are added to the SCSI chain. The most common causes of noise are improper termination, damaged or poor quality cables, and incorrectly designed SCSI devices. Because DTS successfully uses the CD with multiple devices (both Apple and third party), I suspect the third party drive is the source of the noise. If it uses any kind of internal termination, the terminator MUST be removed. Apple recommends that all SCSI device manufacturers not use internal termination, relying instead on the external terminators provided by Apple which can easily be rearranged or upgraded (as with the Macintosh IIfx). Also, try a different SCSI peripheral cable in case yours is damaged or not up to par. You may also be having problems if there is no internal hard drive in your system. This leaves the internal end of the SCSI bus unterminated. This is particularly a problem for the fast CPUs such as the Macintosh IIci and Macintosh IIfx, because they are more sensitive to noise. If this is the case, try installing an internal hard drive, or you can obtain an internal SCSI terminator from MicroNet (see the Macintosh Buyer’s Guide for a #/address). For more information, see Macintosh Technical Note #273.
Devices & Hardware: SCSI: Connecting two Macintosh systems via SCSI
How can I connect two Macintosh® systems together using the SCSI port so they can run in parallel?
For many reasons, connecting any two systems via SCSI port to SCSI port should not be attempted. The most important reason is that you would then have two devices (the CPUs, and probably the internal drive) on the bus with the same SCSI ID. Further, a straight-through cable would connect outputs to outputs and inputs to inputs, which would bring communications to a halt.
However, a SCSI-to-SCSI connection, like the type mentioned below, is possible between the Macintosh Portable and a desktop Macintosh using LapLink Macintosh III from Traveling Software. It works only on the Macintosh Portable since the SCSI ID of the Macintosh Portable can be changed from 7 to 6, avoiding the ID conflicts. Traveling Software also provides a special SCSI-SCSI cable, which is required for this connection. (This setup cannot connect two desktop Macintosh systems unless the drive ID can be changed. This is not possible with Apple’s internal drives but you may be able to do it with other internals. In any case, this is unsupported, so if you attempt this you do so at your own risk. You probably will void your warranty.)
LapLink Macintosh III
Traveling Software, Inc.
18702 North Creek Parkway
Bothell, WA 98011
206-483-8088
Devices & Hardware: SCSI: SCSI terminator specs
Please provide us with specs on Apple® Part No. M0332LL/A, and also information on what type of SCSI terminator can be used for Macintosh® IIfx.
Specs for Apple SCSI terminators (the original gray terminator and the special black Macintosh IIfx terminator) can be found in Macintosh Technical Note #273. The Macintosh IIfx requires the black terminator for external termination and either a properly terminated internal hard disk or the internal termination block and filter for internal termination. All Macintosh IIfx computers shipped without an internal hard disk include this internal terminator and filter plugged into the SCSI connector on the logic board.
Devices & Hardware: SCSI: Where to get Macintosh SCSI Manager sample code
Can you provide some sample code on using the Macintosh® SCSI Manager to access a SCSI device?
A SCSI Development Package is available from APDA® for around $20. You can contact APDA at (800) 282-2732.
Devices & Hardware: SCSI: Cannot make SCSI inquiries of CPU
Is there a way to get the SCSI information for the CPU (ID 7) using a SCSI call?
No, sorry. The SCSI protocol says that there is a SCSI bus Master and a SCSI target, and that the two will not be the same. Since the Macintosh® is always the master, there is no way you can make inquiries of it.
Devices & Hardware: SCSI: No new System 7.0 SCSI Manager yet
Where are the C header files for the new Macintosh® System 7.0 SCSI Manager?
There currently is no new SCSI Manager in use in System 7.0. This was announced a while back, but then it was also announced that it would not be implemented after all. I don’t know what the plans are for implementing a new manager, but the references you saw were probably left in there by mistake. As far as we know, there is no new SCSI manager and there aren’t any plans to place it in a system in the near future. If Apple does replace it, however, we will contact our developers so you shouldn’t worry about being left in the dark to guess when/if it does become reality. You should be able to use the same files as before since there isn’t any problem with incompatibility at this time.
Devices & Hardware: SCSI: Macintosh IIci SCSI power connector changes
What changes are there to the Macintosh® IIci SCSI power connector?
The IIci SCSI power connector is supplied by Molex. It is plug housing part number 39-01-2040 with four crimp pins (part number 39-00-0039) per housing needed. You can contact Molex sales representatives Dave Rios in San Jose, CA (408-946-4700) or Randy Kempf in Lisle, IL (312-969-4550) for these parts.
Figure as seen looking down at the IIci logic board:
+----------+ 1 +12V
| 3 1 | 2 ground
| | 3 ground
| 4 2 | 4 +5V
+----------+
Devices & Hardware: SCSI: Macintosh IIfx SCSI compatibility
My SCSI product is having problems working on the Macintosh® IIfx. What are the differences between the IIfx SCSI and SCSI on all the other SCSI-equipped Macintosh systems?
The SCSI chip on the IIfx is different from any of Apple’s previous machines. The new SCSI chip is an Apple ASIC which adds functionality to the 5380. The pinouts are identical, the cables are identical, but the terminator is different.
Every IIfx is shipped with the new terminator, so unless you have internal termination on your external SCSI device, there is no known reason for your product not working. The new terminator is black in color (instead of gray or platinum) and completely replaces the old terminator.
If your SCSI device is directly accessing the SCSI low-memory globals, then this is likely to cause your incompatibility problems, since the globals have changed in the IIfx and could change again in the future.
As stated in Technical Note #273, if you can give DTS detailed information on your compatibility problems with the IIfx and your SCSI device, we should be able to provide you with more information about the possible causes.
Devices & Hardware: SCSI: Can I have a device powered off and connected to the SCSI bus?
Can I have a device powered off and connected to the SCSI bus?
The SCSI specification does not define how a device is to behave while powered off. The best advice and the official line from Apple is not to have devices on the bus and powered off. It’s been found that having devices powered off and on the bus causes degradation to performance and the signals. This is the issue: electrical problems of termination and termination power. Some devices are NOT following the description of how Apple’s devices work, and following the guidelines of the Apple cable guide does not apply with non-Apple devices. The termination problem can cause hardware damage. Therefore, the rule is this: Do NOT have devices connected to the bus with their power off. Also, do not power on a device connected to the bus after booting and never connect one while the system is on.
Devices & Hardware: Serial Driver: Conditions degrading 57.6 Kbaud transmission
We are experiencing intermittent character dropout at 57.6 Kbaud on a Macintosh® IIsi in 256-color mode, but if we drop down to 16-color mode, everything works hunky dory. MultiFinder® on or off makes no difference. What’s the connection between the number of colors and the serial port?
It turns out that various additions to the system cause performance to degrade, such that serial operation at 57.6 Kbaud cannot reliably be maintained.
There are various factors here, including the video mode (which requires more memory accesses and wait states to produce the same video rate, thus incurring a higher processor overhead). VM, if turned on, exacts an additional performance penalty. These problems are not limited to the Macintosh IIsi; we’ve had reports that they can also occur on the Macintosh IIci when running the on-board video in 256-color mode without a cache card.
Devices & Hardware: Serial Driver: Macintosh serial driver doesn’t support synchronous communication
What Macintosh® system call should I use to use the modem port for synchronous communication?
Unfortunately, the Macintosh serial driver does not support synchronous communication. The only way to perform synchronous communication is to manipulate the hardware directly, which is unsupported. This means that if you directly manipulate the hardware, your product won’t work on Macintosh systems that don’t allow direct access to the SCC, such as the Macintosh IIfx.
Devices & Hardware: Serial Driver: Where to get “Sample Serial NuBus Driver Code” disk
How can I get a copy of the Macintosh® “Sample Serial NuBus™ Driver Code” disk mentioned on page vii of the Apple Serial NuBus Card Programmer’s Guide (APDA # M0941LL/A)?
After doing some rather extensive checking I have been informed that the Driver Code is available through APDA. The product quoted is the Serial NB Tool, Product Number M0950LL/A. The tool is available for $40.00 and includes a disk and documentation.
Devices & Hardware: Serial Driver: Serial driver DCE dCtlFlags and serial port arbitration
How do I tell which serial ports are available? DTS’s Macintosh® Technical Note #249 says not to check SPConfig, PortAUse or PortBUse. If I do an OpenDriver on both ports to see which ones return no error, I may have two serial ports open, and I’m not supposed to close them. When I set the handshaking options on the output port, am I also setting them on the input port?
Serial port arbitration… such a lofty goal. The Communications Toolbox sort of does it, and you can do it in about the same way if you simply look at bit 5 of the low-order byte of the dCtlFlags field of the Serial Driver’s DCE (Inside Macintosh, Volume II, p. 190).
If the driver is already open, assume someone else is using it. When you use it, be sure to close it when you’re done.
I’m not sure what you mean by you’re “not supposed to close them” unless you’re referring to the ancient serial driver documentation in Inside Macintosh, Volume II. You can simply call CloseDriver these days as long as you’re using a reasonably new serial driver (everything later than the 128K Macintosh Plus ROM).
If you want to be precise, you can call Status on the serial output driver with a csCode of 1 to get a handle to the driver’s DCE. If the return value in csParam is a valid handle, you can dereference it and check the byte at offset dCtlQueue+1 (=7) to get the driver version number. If it’s not zero, it’s OK to close the driver.
That in itself should help you a lot.
It’s not entirely obvious to what refNum one should address the SerHShake command, so you’ll have to trust me. Just call it once on the output driver and everything will be OK. The serial driver doesn’t support separate baud rates and handshaking protocols for each half of the duplex. (Ironically, I do recommend that you call SerReset on both halves. Don’t ask me why.)
Devices & Hardware: Serial Driver: Macintosh serial hardware handshaking
What is the method of asserting and then negating DTR with csCode=17 and csCode=18 respectively, in LightSpeed C on the Macintosh®?
Open the serial output driver and get its refNum followed by:
ctrlErr = Control(refNum, csCode, &csParam);
The results depends on what csCode is used. For the csCodes 17 and 18, csParam is not used and could probably even be NULL.
As an example, it is necessary to use csCode=14 instead of SerHShake() if you want to do full hardware handshaking. The code to do so is:
setHskErr = Control(gOutRefNum, kSerHShakeDTR, &hskFlags);
assuming that kSerHShakeDTR = 14 and hskFlags is a SerShk record.
Devices & Hardware: Serial Driver: Opening the Serial Driver more than once and the PortInUse error
Shouldn’t I get a PortInUse error if I open the Macintosh® Serial Driver twice?
Arbitration is only done on DIFFERENT types of drivers. Say you try to open the Macintosh ROM asynchronous driver; it will fail ONLY if the port is in use by a driver that is something other than async. If the port is in use by another asynchronous driver, you won’t get an error.
For example, if you try to open the async ROM driver while AppleTalk® (which is a different type of driver) is using it, you WILL get an error.
This unfortunately means users can open AppleLink®, SmartCom, Red Ryder, and so on, under MultiFinder®, and, because they all use the Macintosh async driver, get no errors. Of course, all programs can then merrily change the SCC like crazy. That is why it has to be documented that users can’t run multiple applications that use the Serial Driver under MultiFinder.
Devices & Hardware: Serial Driver: Specifying a specific Macintosh serial baud rate
How can I program the Macintosh® Serial Driver to use a baud rate of 38,400?
Use a baud rate constant of 1 for 38,400 baud. Note that you can specify a given baud rate by making the Serial Driver control call with a control code (csCode) of 13. The driver will return the closest baud rate that the Serial Driver will generate. Some trivia:
The formula for figuring out the SerConfig baud rate constants is
114709
Baud Rate Constant = ----------- 2.0
Baud Rate
For example, the baud rate constant for 9600 baud is
114709
Baud Rate Constant = ------ 2.0 = 11.949 - 2.0 = 9.949 = 10
9600
The 114709 figure comes from the SCC clock (3.670702 MHz) which comes from the system clock (15.6672 MHz), but doesn’t divide down evenly because of the timing PALs (in fact, 3.670702 = 15667200 /4 * 15/16, where the 15/16 is due to PAL timing). For the Mac XL (Lisa), use 115200 instead of 114709.
Similarly, you can do a reverse calculation and find the baud rate, given a constant. Reversing the formula, you get
114709
Baud Rate = --------------------------
Baud Rate Constant + 2.0
So, using the constant 10 (for 9600 baud), the formula gives
114709
Baud Rate = -------------------------= 9559.083
10 + 2.0
This isn’t exactly 9600 baud. In fact, the error percentage is
9559.083
1.0 -------------= 1.0 - 0.996 = 0.426%
9600
If you try this with 38400, you get
114709
Baud Rate Constant = --------- 2.0 = 2.987 - 2.0 = 0.987 = 1,
38400
a baud rate of
114709
Baud Rate = -------------------------- = 38236.333,
Baud Rate Constant + 2.0
and an error percentage of
38236.333
1.0 -------------= 1.0 - 0.996 = 0.426%
38400
Devices & Hardware: Slot Manager: How to tell if Slot Manager is implemented
How do you tell whether the Slot Manager is implemented?
The best way is to just check for the existence of one of the Slot Manager traps. You should be able to check the implementation of Trap $A06E and if it is there, then the Slot Manager will be there. Below is a piece of code which does this check:
#define SlotManager 0xA06E
#define NoTrap 0xA89F
main()
{
if ((GetTrapAddress(SlotManager) != GetTrapAddress(NoTrap)))
SysBeep(5); // if the Slot Manager is avail then beep
}
Devices & Hardware: Slot Manager: SGetCString and memory (de)allocation
Inside Macintosh Volume V (page V-445) states that SGetCString automatically allocates memory for holding the requested string. Does this mean that repeated calls to SGetCString will eventually exhaust memory and, if so, what is the correct way to release the memory?
The documentation doesn’t say so, but...
SGetCString automatically allocates memory (via NewPtr) for holding the requested string. It copies the string into that pointer and returns the pointer in spResult. You need to call DisposPtr on spResult to deallocate the pointer.
Devices & Hardware: Slot Manager: NuBus card prototype and declaration ROM development
Is it possible to convince the Slot Manager *after the boot process* that a NuBus card is now in a previously (apparently) empty slot?. Is there some standard declaration ROM to burn in order to have a “more generic” look to the system? We want to slam cards in and out of a system, and make all kinds of weird prototype boards without changing or making new declaration ROMs.
You’d have to hack the slot resource and slot info tables, which are undocumented. It probably would be doable, but not all that easy; just restarting would be easier and faster.
To do as much as you can running code from an application, pretending all the code that goes to the declaration ROM “works” would be easier, as you say. Then, only at the last, when you have everything working, put the driver in the ROM. You might make a very simple ROM that just lets the Slot Manager know a card is installed, run as much code as you can from the application level until it’s debugged, and then fold it into the ROM.
If you need code to a “generic” sort of ROM, why not take the skeleton from “Debugging Declaration ROMs” in the first issue of develop, available on the latest Developer CD Series disc. It would take very minor tweaking to work in your system.
Devices & Hardware: Slot Manager: Installing a Macintosh VBL task for on-board video
Installing a VBL task doesn’t seem to work on Macintosh systems with on-board video. I get the slot number for a video card by extracting the second nibble of the base address of the screen’s PixMap; however, on-board video computers report that the video card is in slot $B but the video card doesn’t seem to exist in any slot. Is there a better way to determine video card slot number? Is there any way to attach a VBL task to on-board video? How can I determine if the main monitor is using on-board video?
You should be getting the slot number for the video, not from the base address of the PixMap, but from the AuxDCE entry (IM V-424). You’ll need to get the gdRefNum for the desired monitor from the device list (IM V, Chapter 5).
For example, to install a VBL for the main screen, do something like this:
GDevHand := GetMainDevice;
IF GDevHand = NIL THEN BEGIN WriteLn(’no main device!’); HALT; END;
mainGDRefNum := GDevHand^^.gdRefNum;
DCEHand := AuxDCEHandle(GetDctlEntry(mainGDRefNum));
IF DCEHand = NIL THEN BEGIN WriteLn(’GetDctlEntry failed’); HALT; END;
retCode := SlotVInstall(@myVBLTask, DCEHand^^.dCtlSlot);
IF retCode <> noErr THEN WriteLn('SlotVInstall failed');
This should work regardless of the kind of video used.
Devices & Hardware: Slot Manager: Macintosh LC “Sad Mac” error code 0000000F 00000033
What is a Macintosh® LC “Sad Mac” error 0000000F 00000033?
This Macintosh LC error code means “unserviceable slot interrupt”—that is, a slot interrupt occurred but the Slot Manager was unable to find an interrupt service routine that would handle the interrupt. This might occur if the primary initialization (PrimaryInit) code for a card fails to establish an interrupt handler for the card but enables interrupts for the slot containing that card anyway.
Devices & Hardware: Slot Manager: Detecting a NuBus or PDS card in the Macintosh IIsi slot
Why does a call to gestaltNuBusConnectors return zero slots when there actually is a NuBus™ card or a PDS (Processor Direct Slot) card in the Macintosh® IIsi slot?
A call to gestaltNuBusConnectors returns zero slots because there’s no way to determine if there’s a NuBus card or a PDS card in the Macintosh IIsi slot. Gestalt can’t assume that there’s always a NuBus or PDS slot, so it just says there’s no slot. However, Apple recommends that you always use the Slot Manager instead of Gestalt to search for cards, after first checking to see that the Slot Manager trap is implemented. The Slot Manager will safely do all the necessary work for you whether a card with a valid declaration ROM is installed or not, and you can search for the card using a variety of criteria. This technique will allow you to locate NuBus cards, but has the added benefit of being able to find PDS cards that contain declaration ROMs.
The Macintosh SE/30, IIfx, and LC have the Slot Manager and PDS slots. It’s safe to assume the Slot Manager will be resident in all future machines that have either NuBus or PDS slot capability.
Devices & Hardware: Slot Manager: NuBus board configuration ROMs and IDs
I am making a NuBus board and I don’t think that I need a configuration ROM. Do I need to build a configuration ROM? If so, how do I get the SResource board ID? Why should board manufacturers have configuration ROMs?
Technically, you don’t need one, but if you don’t have at least a minimal configuration ROM (also known as a declaration ROM), you can’t use the library of Macintosh® Slot Manager calls.
Developer Technical Support assigns the board IDs (and sRsrc_Type IDs). These exist in order for your card to tell the world what functions your board can perform. In order for DTS to assign these values, you need to provide certain information about your board and your company. There is a HyperCard® stack published by DTS that allows you to enter the required information (it also has a tutorial that explains the Slot Manager and configuration ROM concepts in more detail).
A configuration ROM is desirable for flexibility. The combination of the Slot Manager and configuration ROM exists to locate and identify your expansion card and allow the computer and higher-level applications and drivers to communicate with it.
To better understand this, let’s look at the Slot Manager in more detail, and see why it is desirable for you, the developer, to take advantage of it.
The Slot Manager/configuration ROM architecture has two main functions. The first is to provide a mechanism to allow the user to insert a card in a slot and have the card be operational without having to set any switches, worry about which slot to put the card in, or install any special software.
The second is to free an application from being dependent on a particular type of hardware. That is, the goal is to allow an application to be insulated from the hardware by being able to locate underlying, intermediate driver software that will “know” about and talk to the specific hardware. This frees the application to be able to deal with higher-level functions without being tied to a given set of hardware. It allows for different revisions of a given card, or even cards made by different vendors to work with applications, without requiring a revision of the application each time a card changes (or a new one is introduced).
Both these goals are accomplished via the Slot Manager software and the firmware data structures contained in the configuration ROMs of each card. If a valid configuration ROM is present, system software as well as applications and drivers can take advantage of the Slot Manager library of routines to perform the two functions stated above.
Let’s examine the architecture and concepts further.
The specific functions of the Slot Manager are as follows:
Locate and list the cards with configuration ROMs (also known as
declaration ROMs); Impose a uniform structure on the information
in the declaration ROM and provide a set of library routines to
access the information. One major advantage of this is that once
certain sets of data structures are defined and made public, host
applications may use information contained in the structures on
any card regardless of vendor;
Provide routines to allow host applications to transparently access
information in the ROMs without regard to NuBus or byte lanes;
Provide a mechanism for cards to have initialization code run on the
host CPU during the host’s startup sequence;
Allow cards to have drivers in their declaration ROMs loaded into
the host CPU;
Initialize and manipulate the parameter RAM on the host CPU for the
card in the slot during startup.
Without a configuration ROM, most of this will be impossible. Locating the card will be difficult. You can’t ask the customer where it is, without violating the user-friendly interface of the Macintosh, and you can’t find it with software without the possibility of stepping on other cards’ registers, memory, and so on, not to mention having to deal with bus errors for empty slots. Configuration ROMs are well defined in terms of location in the slot address space and structure. Getting at stored nonvolatile data on the board will probably be different for each card. Having code and or drivers loaded and executed at startup time will not be possible.
In summary, you should make a configuration ROM, and use the Slot Manager. It will provide services to applications (and drivers) accessing the card, and will mean less maintenance for applications and drivers.
Devices & Hardware: Slot Manager: Ghost image when scanning Macintosh IIfx slots with the Slot Mgr
When I scan the Macintosh® IIfx slots with the Slot Manager I find a ghost image of a card in slot 1. Am I doing something wrong, or is this a bug?
This is a bug in the Macintosh IIfx Fast Memory Controller (FMC), but it should not cause you any problems.
Devices & Hardware: Storage Devices: Disk First Aid checks native HFS structures, not file contents
What does Disk First Aid check in the Macintosh System, desktop, and other files to determine that they are invalid? Does it check the resources, the resource map, or something else?
Disk First Aid doesn’t check the system or desktop files at all; it treats all files the same without examining their contents. The only things it does check are the native HFS structures, such as the catalog and extents b- trees, and the volume bitmap.
Devices & Hardware: Storage Devices: Macintosh csCode 100.
What is csCode 100? A control call with csCode 100 seems to come in to my block device driver whenever the Macintosh system fails to recognize the file system on my media. Should my driver specify valid non-HFS formats such as ISO 9660?
The csCode 100 you’re seeing is a ReadTOC command bound for what the operating system thinks is a CD-ROM drive. What’s happening here is that after deciding your device doesn’t contain a HFS partition, Foreign File Access (FFA) is attempting to identify the file system residing on that device; looking at the Table of Contents on a CD is one of the ways that it attempts to go about that. You can find this csCode documented in the CD SC Developer’s Guide which is currently available through APDA.
If you remove the Audio CD FST from your system folder, you’ll find that csCode no longer gets issued. The reason for this is that the ReadTOC call returns information about Audio CDs. Your driver need not even support this call; if FFA sees a paramErr (which you should return upon seeing an unrecognized csCode) it knows it can’t be looking at an audio CD.
You need not worry about adding any support to your driver for ISO 9660 or High Sierra. FFA’s File System Translators will just request certain blocks from your driver which contain information that identify the disk in question as ISO or HFS.
Devices & Hardware: Storage Devices: Apple IIGS and third-party SCSI disk drives
Do third-party generic SCSI drives work with the Apple IIGS® and the Apple II High-Speed SCSI Card? What sort of formatting/partitioning software do I need?
You should be able to hook up almost any SCSI device to the Apple IIGS® using the Apple II High-Speed SCSI Card. As long as it’s a standard SCSI device, it should work fine. As for disk utilities, you should use the Advanced Disk Utilities that come with the latest version of the IIGS system software. Before purchasing a particular third-party hard disk for your Apple IIGS, ask your distributor about compatibility.
Devices & Hardware: Storage Devices: Low-power hard drive requirements for Macintosh Portable
We can’t get some internal hard drives to work in the Macintosh® Portable.
We think this is a power draw problem. The Macintosh Portable drive needs to be a low-power drive. According to the “Macintosh Portable Developer Notes,” power requirements are as follows:
Voltage: 12 Vdc and 5 Vdc with ±5% tolerance
Voltage ripple to be ≤100 mv
Current (Amps): Currents drawn must be less than or equal to the values shown below.
DC Current: 5 Vdc 12 Vdc
Peak Max(rms) Typ(rms) Peak Max(rms) Typ(rms)
Startup (<5 sec) 1.5 1.1 1.0 .8 .56 .53
Seeking (<100 ms) 1.5 1.1 1.0 .44 .31 .28
Read/write TBD TBD .45 .65 .46 .42
Standby (spindle on) TBD TBD .25 .15 .11 .10
Autoshutdown
(spindle off) TBD TBD .16 TBD TBD .06
Note also that the Portable must have the battery installed; the adapter alone can’t spin a drive. Also the drive must be at SCSI ID 0 and the time-out value has to be sufficient to allow the drive to come up (you can look at the values and set them with GetTimeOut and SetTimeOut which are documented in Inside Macintosh Volume V, page 356). If this doesn’t solve the problem, then it’s possible there may be a SCSI termination problem.
Graphics, Imaging & Printing: Color Manager: Color Manager search and complement procedures
The AddComp complement procedure description in Inside Macintosh Volume V, pages 145-147, is vague. The last paragraph on page V-146 states, “Complement procedures work the same as search procedures,” but SearchProc is a function, CompProc is a procedure, and each have a different number of parameters. What else does CompProc need as input and on exit?
CompProc should be declared as a FUNCTION that returns a Boolean. The code performs a CLR.B for the return value of CompProc, so treat it like SearchProc. CompProc only uses one parameter since its one parameter is a VAR, which means it will be replaced with the correct complementary color. SearchProc returns an index in its second parameter, which is why it needs a second parameter.
Graphics, Imaging & Printing: Fonts: Apple IIGS FixFontMenu and NDAs
When I call FixFontMenu from my Apple IIGS new desk accessory (NDA), everything works fine, but if the current application has a font menu it stops working. What’s wrong?
FixFontMenu keeps only one correspondence between menu item IDs and font family numbers—if you call FixFontMenu from an NDA, you blow away the already existing correspondence that the application was using, maintained within the Font Manager. ItemID2FamNum then works only on item IDs corresponding to your NDA’s font menu, and these usually are unrelated to the values the application passes from its font menu. Worse, FamNum2ItemID will subsequently return menu item IDs for font family numbers that have nothing to do with the application’s menus; depending on how the application operates on the resulting item ID, this could be disastrous.
Fortunately, doing this yourself is fairly easy with the Font Manager’s help. CountFamilies tells you how many font families there are, and FindFamily returns the name of each of them. You can manipulate this information into a font menu in a fairly straightforward way, using standard Menu Manager calls. While you’re at it, you can also use FindFontStats to figure out what point sizes and styles are available for each font family, so you can indicate this in your Size and Style menus. You could even use the information to build your own font-choosing dialog, much as HyperCard IIGS does. Remember that your NDA should run in either 320 or 640 mode, so don’t make the dialog box too wide.
Graphics, Imaging & Printing: Fonts: FScaleDisable and Macintosh screen rendering
What is the current interface guideline on font scaling? Should we set FScaleDisable to true or false for screen rendering? I believe the old guideline was to set it to true (thus disabling font scaling) so that if you have a 23 pt screen font you will see 12 pt glyphs with 23 pt widths. We want performance on Apple’s low-end machines, and we don’t want to make this a user preference.
Most applications now set FScaleDisable to false all the time. If you are worried about the speed degradation in your application when running on slower Macintosh systems, you could have your software identify which Mac it is running on using Gestalt, SysEnvirons, etc., and then set FScaleDisable to true only on the slow machines. From the purely interface point of view, “what-you-see-is-what-you-get” is best, if processor speed allows it.
With TrueType there is no issue, since FScaleDisable doesn’t have any effect on an outline font.
Graphics, Imaging & Printing: Fonts: Remapped keys for System 7
Remapped keys for System 7
The System 7 keyboard map has changed for the following 11 keys:
Shift-Option-` Shift-Option-M Shift-Option-V
Shift-Option-E Shift-Option-N Shift-Option-X
Shift-Option-G Shift-Option-R Shift-Option-Z
Shift-Option-I Shift-Option-T
The remapping is not a bug; it’s the result of conscious decisions, taken with the consideration of the advantages and disadvantages of changing the 'KCHR' key-mapping resource (this is where the change did in fact occur). The opt- shift-e and opt-shift-u characters, for example, were changed to create the lone representations of their dead key equivalents, opt-e and opt-u or ´ and ¨. Opt-shift-` now returns the character marked on the key, `, rather than the bunny rabbit symbol you used to get (with Geneva, at least). These were deemed more logical mappings.
Your application shouldn’t attempt to depend on key-to-character mappings, because they can change from version to version and they definitely change from country to country.
X-Ref:
Inside Macintosh, Volume VI, page 14-97
Graphics, Imaging & Printing: Fonts: System 7 reserved fonts
Which are the reserved fonts for System 7 and international versions?
All Macintosh system software—including System 7 and international versions— contains four basic fonts, all of them bitmapped: Chicago (12 point), Geneva (9, 12), and Monaco (9). In fact, these fonts cannot even be removed with Font/DA Mover. All systems normally contain other font families, and international versions with multiple script systems contain special font sets. For example, Hebrew system software uses Elath and Hermon.
As of September 1991, System 7 ships in the United States with nine standard font families: Chicago, Courier, Geneva, Helvetica, Monaco, New York, Palatino, Symbol, and Times. Eight of these include TrueType versions: Chicago (plain), Courier (plain, bold), Geneva (plain), Helvetica (plain, bold), Monaco (plain), New York (plain), Symbol (plain), and Times (plain, bold, italic, bold-Italic). Of course, there is no guarantee that users will keep all these fonts in their systems.
X-Ref:
“Guide for Software Localization” beta draft (APDA #M1528LL/A)
Graphics, Imaging & Printing: Fonts: Creating fixed fractional width fonts with ResEdit
How do we create a “fixed fractional width” font using ResEdit 2.1. I tried setting FontInfo fields such as ascent and widMax with fractional numbers, but ResEdit refused all noninteger numbers.
ResEdit doesn’t know how to take fixed-point numbers as input, so it assumes the number you enter for a value like WidMax is the integer representation of the fixed-point number. In other words, ResEdit displays a 16-bit fixed-point number as an integer with 256 times the value of the fixed number actually used by the Font Manager.
To enter the numbers with ResEdit, you’ll need to do the conversion yourself. Take a 8.8 fixed number and multiply by 256 to get the integer to type in, or take a 4.12 fixed number and multiply by 4096 to get the integer.
This rigamarole occurs because ResEdit wasn’t really designed to build fonts from scratch. You may find that certain third-party tools, such as Fontographer (from Altsys) or FontStudio (from Letraset), which are specifically designed to this task, may be easier for you. The time you save in building your width table may be worth the cost of the program.
Graphics, Imaging & Printing: Fonts: Five font style-mapping table styles
Why is “47” the bounds of the indexes’ array in the StyleTable?
The style-mapping tables, which are used for mapping of a font style to a particular font for printing, have only five possible styles, unlike the six screen styles (underline is omitted, since a laser printer just explicitly draws a line under the string—it doesn’t need a special font for that). You can have any combination of these five styles, EXCEPT that you can’t have “Condense” and “Extend” at the same time (Condensed Extended wouldn’t make a whole lot of sense). Thus you get (combinatorics come back to haunt us) 48 possible unique styles to map to.
X-Ref:
Chapter 2, “Working with Fonts,” LaserWriter Reference (Addison-Wesley; APDA #M7073, $19.95).
Graphics, Imaging & Printing: Fonts: 'FOND' resource features subject to change
Which 'FOND' features are subject to change, and what parts can I rely on?
'FOND' features not documented in Inside Macintosh, Macintosh Technical Notes, or develop are subject to change. That’s the official word.
Graphics, Imaging & Printing: Fonts: System 7 and modified fonts
We ship modified versions of the Chicago and Geneva fonts and their fonds in our application’s resource fork. With System 6, when we ask for font 0 or font 3, we get our modified fonts in windows, buttons, menus and dialogs, but not with System 7. Is there a new way to tell System 7 to use my version of Chicago 12 to display all system related stuff?
What’s happened is that the system software is being much more strict about whose “Chicago” it uses for menus and dialogs. The Menu and Control Managers now only look at the system file for the Chicago they use.
There are a couple of ways to get around this: First, you can try patching DrawString right before calling MenuSelect in your program. The patch would select your Chicago and then jump to the standard DrawString. After MenuSelect, remove the patch. The disadvantage of this method is that, if a future system software release doesn’t use DrawString for drawing menus, the patch would cease to have any effect.
A better solution is to write your own menu and control definition code—in other words, your own custom MDEF and CDEFs. The way you typically do this is to get a copy of the standard Macintosh system’s MDEF or CDEF, and alter it to your specifications. In your case, this would be merely selecting your font instead of the system font. Name your font something other than Chicago and just select that font by name in the menu or control’s draw routine. The Control and Menu Manager chapters in Inside Macintosh Volume I have more information on writing custom definitions. There is only one problem with this right now: While the System 6 MDEF and CDEF are available on AppleLink, the System 7 versions are not available yet, although they will be soon.
A note on the use of Chicago in your application: As the June 1991 edition of Macintosh Technical Note #245 mentions, fonts are copyrighted material. Apple owns the Chicago font and typeface, so be sure you check into licensing issues before releasing any version, altered or unaltered, with your application.
Graphics, Imaging & Printing: Graphics Devices Manager: Determining video RAM size
How can we determine how much video memory is available to us to use on any given Macintosh? We need to determine how much memory is on plug-in video cards and how much memory is allocated for built-in screen video at system startup.
Video memory is not for your use! <grin> What you are asking is how to find the total physical memory on the board or allocated. There is no method to deterministically find this out. Each video board manufacture provides a driver that knows how to interact with QuickDraw and has its own special knowledge of how much memory is on board or how to test for how much is installed. Without this special knowledge you will not be able to tell where the memory starts (some start on other than even megabyte boundaries) or if the RAM image wraps over and over throughout the address space. Some areas of the memory may be set aside for other controlling data and your attempt to use this space will disable the proper functioning of the board. The same applies to built-in video.
Graphics, Imaging & Printing: Palette Manager: SetPalette cUpdates, NSetPalette, and window update events
When I pass false in the cUpdates parameter to SetPalette, I still get update events to that window when I modify its palette. What’s going on?
SetPalette’s cUpdates parameter controls whether color-table changes cause that window to get update events only if that window is NOT frontmost. If that window is frontmost, then any changes to its palette causes it to get an update event regardless of what the cUpdates parameter is. When you call SetEntryColor and then ActivatePalette for your front-most window, it gets an update event because it’s the front-most window even though you passed false in the cUpdates parameter. Another important point is that windows that don’t have palettes also get update events even when another window’s palette is activated.
Fortunately, system software version 6.0.2 introduced the NSetPalette routine, which you can find documented in Macintosh Technical Note #211, “Palette Manager Changes in System 6.0.2,” and on page 20-20 in the revamped Palette Manager chapter of Inside Macintosh Volume VI. This variation of SetPalette gives you a lot more flexibility in controlling whether your window gets an update event than SetPalette does. If you pass pmAllUpdates in the nCUpdates parameter, then that window gets an update event when either it or another window’s palette is activated. If you pass pmFgUpdates, then it gets an update event when a palette is activated only if it’s the front-most window (in effect, it only gets an update event if its own palette is activated). If you pass pmBkUpdates, then it gets an update event when a palette is activated only if it’s not the front-most window (in effect, it only gets an update event if another window’s palette is activated). If you pass pmNoUpdates, then that window never gets an update event from any window’s palette being activated, including that window itself.
Graphics, Imaging & Printing: Palette Manager: Restoring Finder desktop colors after using Palette Manager
After using the Macintosh Palette Manager, how do I restore the Finder’s desktop colors?
The Finder desktop’s colors are restored automatically on quitting applications that use the Palette Manager. Colors aren’t restored automatically when switching from your application to another, but if that application needs a certain set of colors and uses the Palette Manager to get them, then it’ll have them the moment it comes to the front. If you’re concerned about applications that don’t use the Palette Manager, you can use RestoreDeviceClut(gd:GDHandle), passing the handle to the GDevice of the screen you want to reset, or nil if you want to reset all of your devices. Passing nil to RestoreDeviceClut is your best bet, as it is very straightforward, and resets all of your monitors. You may not wish to do this, however, because RestoreDeviceClut is only available on machines with 32-bit color QuickDraw.
To reset a screen’s GDevice for machines without 32-bit color QuickDraw, you will need to keep track of the color table.When your application starts up, get the GDevice’s color table and save it—you’ll need it later. This value can be found at (**(**GDHandle).gdPMap).pmTable, where gdPMap is a PixMapHandle, and pmTable is a CTabHandle which tells you the absolute colors for this image. These data structures are found in Inside Macintosh Volume V, pages 52 and 119.
Build your application’s “world” using the Palette Manager, and avoid low- level methods of changing colors. When your application is about to quit and you want to restore the environment to its original state, get the color table you saved in the beginning. Convert this to a palette using CTab2Palette. Then set your window to this palette with SetPalette. This will cause the environment to update to the original color table that you initially got from the GDevice. If the application that is behind your application is Palette Manager friendly, then it will restore the environment to its palette. You may also want to do this procedure at the suspend event, as shown in the DTS sample MacApp program, FracApp. One of the problems that you won’t be able to solve this way involves multiple monitors. You won’t know which one to update. Only the monitor that has the window that you’ve called ActivatePalette on will update.
If your application changes the color environment with the Palette Manager, then RestoreDeviceClut is called automatically when your application quits. This means that you shouldn’t have to worry about restoring the palette if you don’t want to. There is a catch, however (there always is). When you use the SADE version of MultiFinder (6.1b9), it prevents this from automatically happening. Other versions of MultiFinder don’t have this side effect.
Graphics, Imaging & Printing: Palette Manager: RestoreDeviceClut and color flash when application quits
When my application, which uses a color palette, quits, there is momentary but distracting flash of weird colors in the Finder windows and the desktop temporarily appears in a weird color. Is there any way to get around this?
When you quit, RestoreDeviceClut is called to restore the color table and an update event is called to redraw the screen. It’s the delay between the change in the color table and the update event that causes the flash of incorrect colors to be displayed. This, unfortunately, is unavoidable.
Graphics, Imaging & Printing: Picture Utility Package: Spooling PixMaps to disk
Do you have sample code for spooling PixMaps to disk in PICT format? Should I write the PICT opcodes to the file myself?
Apple recommends that you do not try to write the PICT opcodes yourself. Instead, replace the PutPicProc bottleneck proc, as shown in the Color QuickDraw chapter of Inside Macintosh Volume V on page V-89.
Two additional samples can be found in the sample code contained in the Developer CDs. Look for: “Tools & Apps (Moof!): Graphics and Imaging: PICT Stuff.” One is a program and the other is an FKEY; both dump the main screen to disk as a PICT. The FKEY is a more complete sample in the sense that it works in black and white as well as Macintosh color computers, but the other is a smaller and simpler sample.
Graphics, Imaging & Printing: Printer Drivers: Changing printer driver settings without using the dialog
Changing printer driver settings without using the dialog
To change default printer driver settings without using the dialog, keep a copy of the print record with the various settings you want, and when you want to choose your settings, just use your special print record. The current Macintosh print architecture doesn’t allow procedural access to the print record, so you must call the dialogs once for yourself, choose your settings, and then save a copy of the print record that is produced. Some settings are job-dependent, but values that are retrieved from the print record can be changed using this technique. You can only save the settings in the Style dialog. Call PrValidate when retrieving a print record from the resource fork to make sure it is “good.”
See develop, issue #1, pages 58-65, for a complete discussion of changing default printer driver settings and sample code.
Graphics, Imaging & Printing: Printer Drivers: Printing 2-byte bitmap fonts on PostScript LaserWriters
Macintosh Technical Note #91 refers to using QuickDraw picComments to print rotated text, but this doesn’t work for 2-byte Japanese text. Is there a recommended workaround for this problem?
Two-byte characters don’t print when using the TextBegin, TextCenter, and TextEnd PicComments because of the structure of the data that is being sent in the comments. The LaserWriter driver uses these PicComments to rotate text, and it is not expecting the data to be in the 2-byte format. The 2- byte format is converted to bitmap data by the driver, so the data is ignored and nothing is printed. The driver is expecting the comments to contain “normal” text.
Since the data is in bitmap format, you can use the RotateBegin and RotateEnd PicComments to perform the rotation, as follows:
RotateBegin
DrawString (...); << To rotate your 2 byte Japanese characters
RotateEnd
The tricky part of the solution is that you only need to use this approach when you’re printing 2-byte Japanese bitmap fonts. Therefore, you’ll need to check the type of data that is to be printed, and send the appropriate PicComments.
You can also use the following PicComments to hide the QuickDraw representation of the rotated text, as shown below:
PostScriptBegin
CopyBits (...); << For the QuickDraw printers
PostScriptEnd
The PostScriptBegin and PostScriptEnd PicComments are used to hide the CopyBits calls from the LaserWriter driver in a device-independent manner. When you use PostScriptBegin, the LaserWriter driver doesn’t interpret any QuickDraw calls until it finds the PostScriptEnd PicComment. Since QuickDraw printer drivers do *not* understand the PostScriptBegin and PostScriptEnd PicComments, they ignore the PicComments, and the CopyBits call is used to perform the rotation of your text.
There is one problem with the previously mentioned solution: If you record the previous PicComments into a picture and print it, everything will print exactly as expected, but if you display the picture into a window, you’ll see the *unrotated* version of the text. This is definitely a bug, which has been reported, but it won’t be fixed in the very near future. So, what do you do in the meantime? You have the following two options:
1) Do not export pictures that contain this type of rotated data.
2) Export the picture with this problem, and explain the problem to your users.
Neither solution is ideal. Quite a few applications out in the market today have decided to use idea #2.
Graphics, Imaging & Printing: Printer Drivers: Use LaserWriter Driver srcCopy instead of srcOr transfer mode
I’m creating PICTs that are comprised of many lines drawn in srcOr mode. When using the LaserWriter 6.x or 7.x driver with the Color/Grayscale radio button selected, some lines fail to print. Why is this happening?
The problem is a bug in the LaserWriter driver. Sometimes, when using a CGrafPort, the driver doesn’t reproduce lines drawn in srcOr mode. (A CGrafPort is used when the Color/Grayscale print option is selected; in Black & White print mode, a regular grafPort is used.) A workaround is to use srcCopy instead of srcOr when drawing QuickDraw objects within your PICTs.
Graphics, Imaging & Printing: Printer Drivers: LaserWriter ignores ForeColor while filling smoothed polygon
When doing the FillRgn for drawing the fill of a smoothed polygon (as described in Macintosh Tech Note #91) the foreColor isn’t used on the LaserWriter. Any way to make it work?
You’ve discovered a design limitation of the LaserWriter driver. Things that have patterns associated with them are rendered by using the LaserWriter screen operators. This results in an assumption of the foreground color being black and the background color being white, which is what’s causing the problem you noticed. In short, it makes the driver ignore your foreground and background colors.
You can work around the problem by working in an offscreen GWorld first and then CopyBitsing everything to the printer port using srcCopy. There are a couple of problems with this approach: First, don’t do it with text or your text will be turned into a bitmap and you’ll get the “jaggies.” Second, you’ll probably want to increase the printer port’s resolution from its default of 72 dpi for better results. A value of 288 dpi works nicely since it’s an even multiple of QuickDraw’s native 72-dpi resolution. Also, make sure that the GWorld you create has the same bounds as the printer port’s rPage rectangle to avoid unnecessary scaling and clipping. After you’ve done all that, draw into it and CopyBits the result to the printer port. The nice thing about doing everything offscreen first is that then you can use some of the non-printer- friendly transfer modes like blend or dithered. Also, you can use ForeColor/BackColor and get the right thing this way.
If you don’t want to use this method for all printers, (since it can be quite a memory hog), you can check for the LaserWriter driver and use this method in just that case. For other drivers, you should just print as normal.
So, what do you need to do all this? Well, to set the resolution of the printer port, use PrGeneral as described in Inside Macintosh Volume V and develop #3.
To determine whether you have the LaserWriter driver or not, check the high byte of the wDev field in your print handle. This is described in Tech Note #72. While this method might break some day, it’s currently the best way to determine which driver you’re using, and Apple will have to let developers know before we break it.
If the high byte of the wDev is 3, then you either have the LaserWriter driver or a third-party driver impersonating the LaserWriter. Some PostScript drivers do that because many apps assume a wDev of 3 means a PostScript printer, and anything else doesn’t. By acting like Apple’s LaserWriter driver, they get preferential treatment from apps that “special case” for PostScript. That’s not really a problem in this situation.
Graphics, Imaging & Printing: Printer Drivers: Asynchronous LaserWriter driver no longer supported
What is causing incorrect characters to be printed on the Asynchronous LaserWriter driver we licensed from Apple for use with a non-Apple PostScript- equipped printer?
The printing of incorrect characters is probably due to an incompatibility between the async driver and the version of PostScript being used in the printer.
The reason for the incompatibility is that the driver is no longer supported and hasn’t been revised for quite some time. The driver was originally developed outside of Apple, and Apple licensed the driver for its use. The company subsequently went out of business and the driver hasn’t been revved since.
PostScript and Apple’s AppleTalk LaserWriter drivers have been updated and changed quite a bit since then, which is why the characters print correctly when using AppleTalk, but not when printing asynchronously. The old Async driver just doesn’t know how to handle the new PostScript versions and therefore prints “garbage” characters.
The SL Laser II driver is no longer supported by Apple, and at this time Apple has no plans to update this driver or write a new one. Since things work correctly with AppleTalk, you should confine usage to AppleTalk when printing PostScript to the LaserWriter. If this is unacceptable, you might check around with different clearinghouses to see if a third-party developer has a compatible, up-to-date Asynchronous LaserWriter driver that you can use.
Graphics, Imaging & Printing: Printer Drivers: LaserPrep 7.0 file & AppleShare Print Server
LaserPrep 7.0 file & AppleShare Print Server
The LaserPrep 7.0 file is included on the System 7 “Printing” disk and the System 7 Group Update CD for upgrading the AppleShare Print Server to support the LaserWriter 7.0 driver. The AppleShare Print Server has its own LaserWriter driver built in and all it needs to print is a LaserPrep file. In fact, the AppleShare Print Server completely ignores any LaserWriter driver installed in the System Folder of the server.
Page 49 of the “System 7 Group Upgrade Guide” states the following procedure for upgrading an AppleShare Print Server to support the System 7 LaserWriter drivers:
1. Shut down the print server software.
2. Install the printer driver update…
3. Drag the LaserPrep icon from the Printer Update folder to the Server Folder of the print server Macintosh®.
4. Restart the print server Macintosh and the AppleShare Print Server software.
Actually, step #2 in the “System 7 Group Upgrade Guide” is unnecessary. Installing the printer driver update has no effect on the AppleShare Print Server software.
Graphics, Imaging & Printing: Printer Drivers: LaserWriter 7.0 driver and LaserPrep dictionary
In the old LaserWriter drivers it was possible to create a PostScript file with or without the LaserPrep dictionary (“f” or “k” key). Is it possible to generate a file without the dictionary with the LaserWriter 7.0 driver?
In 7.0 printing, a LaserPrep dictionary is always sent with a print job. This is done to prevent constant reinitialization of the LaserWriter by conflicting printer drivers. You cannot prevent it from being sent. Fortunately the 7.0 version of the LaserPrep dictionary is much smaller (≈40K total) than its 6.x predecessors.
Graphics, Imaging & Printing: Printing: ImageWriter II 6.1 & 7.0 driver PrGeneral/PrStlDialog bug
ImageWriter II 6.1 & 7.0 driver PrGeneral/PrStlDialog bug
If an application uses PrGeneral to set draftBits mode on an ImageWriter II (using the 6.1 or 7.0 drivers) and then does a PrStlDialog, a fatal crash occurs. This happens with both the AppleTalk and non-AppleTalk drivers. This only happens on Macintosh systems with Color QuickDraw.
The problem is connected to the two 'dctb' resources which were added in the 6.1 driver. When the landscape icon is being grayed out (since it’s unsupported in draftBits mode), the driver is jamming the gray pen pattern directly into the GrafPort. While this brute-force method works fine with GrafPorts, the 'dctb' resources make the Dialog Manager use a CGrafPort now. Jamming the pattern into this CGrafPort as if it were a GrafPort makes a mess and causes a fatal crash, manifesting itself as a “division by zero” error, for example.
To work around the problem, check to see if you are printing to a 6.1 or 7.0 ImageWriter driver, and if so, do the style dialog before setting draftBits. The disadvantage of this is that setting draftBits before calling PrStlDialog causes the 50% reduction and landscape controls to be disabled, and this method doesn’t. Therefore, after the style dialog, you should check to see if the user selected landscape printing or 50% reduction by calling PrGeneral (getRotnOp) and checking bit 3 of the wDev field (See “Learning To Drive” on the Developer CDs for more about the wDev.) If the user selected either of those options, display a dialog warning them that those features will be ignored. Then, call PrGeneral to set draftBits and continue normally. PrGeneral will adjust the print record so that options not supported with draftBits are turned off. If a non 6.1/7.0 ImageWriter driver is used, the code should set draftBits as usual, before the PrStlDialog call.
This workaround is the better alternative to hacking the 'dctb's out of the driver or patching around the problem, although it doesn’t help 7.0 users running applications that already make use of the draftBits option. The following Pascal snippet demonstrates how to use the workaround:
(* Sample snippet that demonstrates how to work-around the
'dctb' bug in the ImageWriter II 6.1 and 7.0 drivers.
Bug causes a crash when doing a style dialog
after setting draftbits with PrGeneral.
*)
{
What's what in the code snippet that follows.
thePrRecHdl : THPrint;
rslData : TSetRslBlk;
draftData : TDftBitsBlk;
rotnData : TGetRotnBlk;
isBadImageWriter : Boolean;
isLandscape : Boolean;
isReduced : Boolean;
}
PrOpen;
IF (PrError = noErr) THEN
BEGIN
PrintDefault(thePrRecHdl);
IF (PrError = noErr) THEN
BEGIN
{See if we're using a version 6.1 or 7.0 ImageWriter driver.}
IF (thePrRecHdl^^.prStl.wDev DIV 256) = 1 THEN
isBadImageWriter := (PrDrvrVers = 61) OR (PrDrvrVers = 70)
ELSE
isBadImageWriter := FALSE;
IF NOT (isBadImageWriter) THEN
BEGIN
{Set draftBits mode now, if not our special case.}
draftData.iOpCode := draftBitsOp;
draftData.hPrint := thePrRecHdl;
PrGeneral(@draftData);
END;
{Do the style dialog.}
IF (PrStlDialog(thePrRecHdl)) THEN
IF (isBadImageWriter) THEN
BEGIN
{If so, see if they selected rotation or 50% reduction.}
rotnData.iOpCode := getRotnOp;
rotnData.hPrint := thePrRecHdl;
PrGeneral(@rotnData);
isLandscape := rotnData.fLandscape;
isReduced := BTst(thePrRecHdl^^.prStl.wDev, 3);
{If so, warn them that those things will be ignored.
Preferably use something other than DebugStr… }
IF (isLandscape) OR (isReduced) THEN
DebugStr('Bad ImageWriter; landscape and/or reduced.');
{Now, set draftBits mode, since we didn't before.}
draftData.iOpCode := draftBitsOp;
draftData.hPrint := thePrRecHdl;
PrGeneral(@draftData);
END;
IF (PrJobDialog(thePrRecHdl)) THEN
BEGIN
{Print}
END;
END;
END;
PrClose;
Graphics, Imaging & Printing: Printing: How to abort printing while PrPicFile is executing
Can I abort printing from within PrPicFile? My attempts haven’t been succesful.
The following Pascal procedure is *roughly* the same as the default idle procedure—the one the system supplies for you when you don’t supply one of your own:
procedure MyPIdleProcedure;
var
pIdleEventRecord: EventRecord;
begin
if GetNextEvent(keyDownMask, pIdleEventRecord) then
begin
if ((BitAnd(pIdleEventRecord.message, charCodeMask) =
longint('.')) and
(BitAnd(longint(pIdleEventRecord.modifiers), cmdKey) =
cmdKey)) then
PrSetError(iPrAbort);
end;
end;
(This is written in Think Pascal, but it should work fine under MPW Pascal if you change the “BitAnd” functions to “BAND”.)
As you can see, the system aborts when you press Command-period by using PrSetError to the constant iPrAbort, which is the same error returned when the user clicks “Cancel” in the style or job dialogs. If you set the error to iPrAbort, the system will take care of the rest. Your print loop will also gracefully cancel, provided you follow the guidelines in Macintosh Technical Note #161, “A Printing Loop That Cares.”
Graphics, Imaging & Printing: Printing: ImageWriter II 6.1 & 7.0 driver PrGeneral/PrStlDialog bug
ImageWriter II 6.1 & 7.0 driver PrGeneral/PrStlDialog bug
If an application uses PrGeneral to set draftBits mode on an ImageWriter II (using the 6.1 or 7.0 drivers) and then does a PrStlDialog, a fatal crash occurs. This happens with both the AppleTalk and non-AppleTalk drivers. This only happens on Macintosh systems with Color QuickDraw.
The problem is connected to the two 'dctb' resources which were added in the 6.1 driver. When the landscape icon is being grayed out (since it’s unsupported in draftBits mode), the driver is jamming the gray pen pattern directly into the GrafPort. While this brute-force method works fine with GrafPorts, the 'dctb' resources make the Dialog Manager use a CGrafPort now. Jamming the pattern into this CGrafPort as if it were a GrafPort makes a mess and causes a fatal crash, manifesting itself as a “division by zero” error, for example.
To work around the problem, check to see if you are printing to a 6.1 or 7.0 ImageWriter driver, and if so, do the style dialog before setting draftBits. The disadvantage of this is that setting draftBits before calling PrStlDialog causes the 50% reduction and landscape controls to be disabled, and this method doesn’t. Therefore, after the style dialog, you should check to see if the user selected landscape printing or 50% reduction by calling PrGeneral (getRotnOp) and checking bit 3 of the wDev field (See “Learning To Drive” on the Developer CDs for more about the wDev.) If the user selected either of those options, display a dialog warning them that those features will be ignored. Then, call PrGeneral to set draftBits and continue normally. PrGeneral will adjust the print record so that options not supported with draftBits are turned off. If a non 6.1/7.0 ImageWriter driver is used, the code should set draftBits as usual, before the PrStlDialog call.
This workaround is the better alternative to hacking the 'dctb's out of the driver or patching around the problem, although it doesn’t help 7.0 users running applications that already make use of the draftBits option. The following Pascal snippet demonstrates how to use the workaround:
(* Sample snippet that demonstrates how to work-around the
'dctb' bug in the ImageWriter II 6.1 and 7.0 drivers.
Bug causes a crash when doing a style dialog
after setting draftbits with PrGeneral.
*)
{
What's what in the code snippet that follows.
thePrRecHdl : THPrint;
rslData : TSetRslBlk;
draftData : TDftBitsBlk;
rotnData : TGetRotnBlk;
isBadImageWriter : Boolean;
isLandscape : Boolean;
isReduced : Boolean;
}
PrOpen;
IF (PrError = noErr) THEN
BEGIN
PrintDefault(thePrRecHdl);
IF (PrError = noErr) THEN
BEGIN
{See if we're using a version 6.1 or 7.0 ImageWriter driver.}
IF (thePrRecHdl^^.prStl.wDev DIV 256) = 1 THEN
isBadImageWriter := (PrDrvrVers = 61) OR (PrDrvrVers = 70)
ELSE
isBadImageWriter := FALSE;
IF NOT (isBadImageWriter) THEN
BEGIN
{Set draftBits mode now, if not our special case.}
draftData.iOpCode := draftBitsOp;
draftData.hPrint := thePrRecHdl;
PrGeneral(@draftData);
END;
{Do the style dialog.}
IF (PrStlDialog(thePrRecHdl)) THEN
IF (isBadImageWriter) THEN
BEGIN
{If so, see if they selected rotation or 50% reduction.}
rotnData.iOpCode := getRotnOp;
rotnData.hPrint := thePrRecHdl;
PrGeneral(@rotnData);
isLandscape := rotnData.fLandscape;
isReduced := BTst(thePrRecHdl^^.prStl.wDev, 3);
{If so, warn them that those things will be ignored.
Preferably use something other than DebugStr… }
IF (isLandscape) OR (isReduced) THEN
DebugStr('Bad ImageWriter; landscape
and/or reduced.');
{Now, set draftBits mode, since we didn't before.}
draftData.iOpCode := draftBitsOp;
draftData.hPrint := thePrRecHdl;
PrGeneral(@draftData);
END;
IF (PrJobDialog(thePrRecHdl)) THEN
BEGIN
{Print}
END;
END;
END;
PrClose;
Graphics, Imaging & Printing: Printing: Determining if printer supports color and/or grayscale printing
Is there any way to determine whether I’m printing to either a color printer or a printer simulating color, such as the LaserWriter set for Color/Grayscale?
Check the grafPort returned by your call to PrOpenDoc. If the rowBytes of the grafPort is less than 0, the Printing Manager has returned a color grafPort. You can then make Color QuickDraw calls into this grafPort. LaserWriter driver version 6.0 and later returns a color grafPort from the PrOpenDoc call, if the Color/Grayscale button has been set.
The following code fragment demonstrates this:
(* This function determines whether the port passed to it is a *)
(* color port. If so, it returns TRUE. *)
FUNCTION IsColorPort(portInQuestion: GrafPtr): BOOLEAN;
BEGIN
IF portInQuestion^.portBits.rowBytes < 0 THEN
IsColorPort := TRUE
ELSE
IsColorPort := FALSE;
END;
A third-party printer driver should return the type of grafPort that represents the abilities of its printer. Therefore, if the printer supports color and/or grayscale, and if Color QuickDraw is present, the application will receive a color grafPort after calling PrOpenDoc. Otherwise, if the Macintosh you’re running on does not support Color QuickDraw, you should return a black-and-white grafPort.
Graphics, Imaging & Printing: Printing: Apple IIGS ImageWriter driver page sizes
How do I specify custom page sizes to the Apple IIGS ImageWriter driver?
The Apple IIGS ImageWriter driver can’t handle paper sizes other than what’s built in, which is what shows up in the “Page size” pop-up menu. It means if the form isn’t listed, the ImageWriter Driver can’t print to it. (Please don’t confuse the Print Manager with the ImageWriter driver -- see the article in Develop #4 and Apple IIGS Technical Note #93 for more details, but the Print Manager isn’t doing *anything* other than making sure the ImageWriter driver is loaded and passing all the calls along to it.) Other drivers will behave differently, depending on how they were written. There’s no generic, works-on- all-drivers way to add new page sizes to a driver you want to print to. The 6.0 ImageWriter driver does not have this feature either.
Graphics, Imaging & Printing: Printing: GS/OS and text-only printing to a character device
What’s the best way to do text-only printing to a character device through GS/OS?
If you want to print text to GS/OS character device, here’s how you do it:
1. Look at all the devices online to find which are character devices. You can tell when a device is a character device by examining bit 7 of the “characteristics” word returned by DInfo--the bit is set for block devices and clear for character devices. You don’t have to hard-code a list of character device IDs.
2. Present the user with a list of device names followed by their location and generic type in parentheses. You can adjust the names of device types to reflect your use. For example, “.RPM (AppleTalk printer, port 1),” “.DEV2 (serial modem, port 2),” or “.DEV3 (generic character device, slot 5).” You can use bit 3 of the slot returned by DInfo to know whether to return “slot” or “port,” too.
3. When the user selects a device to print to, call Open on the device name (such as .RPM for an AppleTalk printer). Use Write to write the information, just like you would to a file, then call Close (you can call Flush if you like, but it shouldn’t be necessary). That’s all that’s necessary.
Remember not to embed ImageWriter or any other printer-specific codes in the output stream. With the exception of choosing a device and creating a file, this same code could be used to print to another device such as a disk, *any* text printer, or modem. You might give users a “text printing preferences” dialog where they can enter some codes if they like, and you might have built- in sets for ImageWriters and other common printers, but don’t make it too complicated. This is very generic and will work well on *any* setup, not just an ImageWriter II connected through the serial port.
Graphics, Imaging & Printing: Printing: Personal LaserWriter LS 1.1 driver is faster
My LaserWriter LS is very slow when printing from my Macintosh SE. Any suggestions?
Use the new LaserWriter LS driver version 1.1. It was released after System 7.0, and is available on AppleLink or from your dealer.
If you’re printing Word files, Microsoft’s TrueType INIT will help. It’s available from MicroSoft Technical Support or from commercial bulletin board services.
Graphics, Imaging & Printing: QuickDraw: System 7 QuickDraw DrawText performance
We’ve noticed that using DrawText is much slower in System 7, especially when drawing in color (anything other than black on white). What can be done to restore the drawing speed to System 6 levels?
A QuickDraw function like DrawString or DrawText will be slower under certain circumstances in System 7 than System 6. Specifically, if you are drawing in srcCopy mode and you colorize the text—that is, foreground color is not black and background color is not white (Inside Macintosh Volume VI, page 17-16)—then QuickDraw really slows down as you have noticed. SOMETIMES, the speed of drawing is 6 times as slow as System 6.
The cause of this slowness is a known System 7 bug. The bug has concerned the engineers greatly and will be responded to in an appropriate manner in the future.
There are a few workarounds: One, you can avoid using the srcCopy mode and use the default srcOr mode instead. However, this is not a real workaround, since you may have essential reasons to use srcCopy. The other option is to create an offscreen pixmap or GWorld and perform a DrawText with srcOr to this GWorld with colorization. Then, you can perform a CopyBits from the offscreen to the screen with srcCopy mode and no colorization. Using CopyBits will not cost you much time. Again, this is a workaround and is not ideal.
The srcOr is a bit slower than in System 6.0.x, but it does not have a bug; rather it is a side effect of system enhancements. The slow speed is a trade-off taken to receive the host of other benefits.
Graphics, Imaging & Printing: QuickDraw: No System 7 QuickDraw alpha channel support
How can I directly access the alpha channel (the unused 8 bits in a 32-bit direct pixel using QuickDraw) under System 7? Under System 6 it was easy, but under System 7’s CopyBits() the alpha channel works with srcXor but not with srcCopy.
With the System 7.0 QuickDraw rewrite, all “accidental” support for the unused byte was removed, because QuickDraw is not supposed to operate on the unused byte of each pixel. QuickDraw has never officially supported use of the extra byte for such purposes as an alpha channel. As stated in Inside Macintosh Volume VI, page 17-5, “8 bits in the pixel are not part of any component. These bits are unused: Color QuickDraw sets them to 0 in any image it creates. If presented with a 32-bit image—for example, in the Copybits procedure—it passes whatever bits are there.”
Therefore, you cannot rely on any QuickDraw procedure to preserve the contents of the unused byte, which in your case is the alpha channel. In fact, even CopyBits may alter the byte if stretching or dithering is involved in the copybits by setting them to zero. Therefore, the only possible workarounds for this problem are to not use the unused byte for alpha channel storage since the integrity of the data cannot be guaranteed; or, to not use QuickDraw drawing routines which can alter the unused byte.
Graphics, Imaging & Printing: QuickDraw: Macintosh PICT-to-PostScript conversion
How do I convert PICT format data to PostScript in my printer driver?
Converting PICT files to PostScript involves a detailed understanding of both bitmaps (or pixmaps) and the graphics state in PostScript, which is a data structure defining the context in which other graphic operators in PostScript execute. If you don’t know PostScript, the following manuals are a must:
• PostScript Language Tutorial and Cookbook (Addison-Wesley) is an introduction to PostScript.
• PostScript Language Reference Manual (Addison-Wesley).
• PostScript Language Program Design (Addison-Wesley) details designing efficient PostScript programs. It has a lot of useful sample programs on topics like writing a print spooler.
You need to convert all the QuickDraw operations in a PICT to corresponding PostScript operations. To get a feel for this conversion, you can analyze the PostScript dump from a LaserWriter to see how it converts a PICT to PostScript. Under System 6.x, a PostScript dump can be obtained by pressing Command-K while printing. Under System 7.0, you can get a dump by selecting the PostScript File option in the Print dialog.
Some areas of QuickDraw, such as transfer modes, do not have a correspondence in PostScript. The PostScript imaging model is designed so that all areas of a page affected by an image are marked as if with opaque paint. Using image masks can help. See the Graphics chapter in the PostScript reference manual.
PICT-to-PostScript conversion can be a long process, especially if one is unfamiliar with PostScript. Using the above books and the PostScript dump from the LaserWriter (but ONLY as a general guide) should help.
Graphics, Imaging & Printing: QuickDraw: OpenCPicture and PICTs other than 72 dpi
Can I use OpenCPicture to create PICTs with a higher resolution than 72 dots per inch (dpi)?
There’s good news and bad news: The good news is that you’re on top of the situation, which means the bad news is that there aren’t better ways to do what you want to do, mostly. Here’s the scoop:
You can use vRes and hRes in pictures opened with OpenCPicture to tell QuickDraw it’s not a 72-dpi picture, and as long as the application that receives the picture uses DrawPicture to image it, QuickDraw will Do The Right Thing—scaling it on the screen to 72 dpi instead of making it humongously large. Unfortunately, this way you lose hairlines; if you print such a picture to a 72 dpi grafPort (like the LaserWriter driver normally returns), you’ll get 1/72-inch lines instead of 1/300-inch lines as you probably want.
(This _can_ work correctly, but the receiving application has to notice your picture is bigger than 72 dpi and ask PrGeneral to increase the resolution of the printing grafPort accordingly, and this doesn’t always or often happen.)
Graphics, Imaging & Printing: QuickDraw: Highlighting ignored if foreground same as background color
Under System 7, but not System 6, HiliteColor is not used for InvertRect when the hilite bit is set and the background is exactly black (R=G=B=$0000). Also, HiliteColor doesn’t draw when a pen mode of XOR is used in a LineTo call.
The problem you encounter exists whenever the background and foreground color are the same when using highlight mode. If the foreground color is the same as the background color, highlighting is ignored. Therefore, when you set the foreground color to white, you should set the background color to something other than the default color of white.
Graphics, Imaging & Printing: QuickDraw: GetPixelsState is slow sometimes
Why do I sometimes see incredible slowdowns under System 7.0 when calling either GetPixelsState or LockPixels (I’m not sure which) for the PixMapHandle of a GWorld allocated in temporary memory?
GetPixelsState takes an arbitrary amount of time since it makes a call to RecoverHandle to get the handle pointing to the baseaddr. Therefore, the slowdown you see as actually due to the call to RecoverHandle, which is slow because it must traverse the heap to find the pointer to the baseaddr. LockPixels is not responsible for the slowdown because it does not make call to any traps which could take an extended amount of time.
Graphics, Imaging & Printing: QuickDraw: Using a Macintosh PICT file that‘s larger than available memory
How can I read a 2 MB PICT file into only 1 MB of memory?
You can’t read it in since you don’t have enough memory, but drawing the picture contained in the file using a technique called “spooling” increases your chances of using a 2 MB PICT file with 1 MB memory. Spooling is documented in the Color QuickDraw chapter of Inside Macintosh Volume V (pages 88-89).
Graphics, Imaging & Printing: QuickDraw: Getting a single scan line from a PICT file
Is there any way to obtain a particular scan line from a PICT file?
A PICT file may contain more than just pixmaps, so getting one scan line out of it is not possible. The file may also contain other elements that overlap, such as rects and arcs. The only way to obtain a single line is to draw it offscreen and then, once the whole image is in memory, you can go and study individual pixels.
Graphics, Imaging & Printing: QuickDraw: Determining pixel depth from PICT files
How do you find out the pixel size of a PICT file on the disk?
A picture is by nature independent of depth. For example, you can have a picture containing DrawRects and LineTos and therefore lacking of any info regarding depth.
On the other hand, if the picture you are looking at has pixmap opcodes in it, then each pixmap contains its own pixel size and in this case a picture can have a number of depths associated with it.
If you want to see the pixel size for each pixmap opcode in a picture, replace all the bottleneck routines and every time the bitsProc is called you can see the pixmap and get the info out. Since the picture is in a file, you can use the spooling technique described in the QuickDraw chapter in Inside Macintosh Volume V. Be ready to deal with multiple, possibly different, pixmaps as well as direct pixmaps if the picture was created under 32-bit QuickDraw.
”KnowsPICT,” on the Developer CD Series disc, extracts this kind of information. The System 7.0 Picture Utilities package gets this information too.
Graphics, Imaging & Printing: QuickDraw: Rendering color PICTs in a black-and-white environment
I want to be able to render a color PICT as a black-and-white image substituting patterns for colors. My images are pretty small and have under 16 colors. What do you suggest as the easiest way?
One easy way is to take advantage of 32-Bit QuickDraw and System 7.0’s ditherCopy transfer mode modifier or flag (documented in Inside Macintosh Volume VI, page 17-17). Call DrawPicture into an offscreen pixmap with the pixel depth of the original color PICT. Then call CopyBits to copy the pixmap to the screen, with srcCopy + ditherCopy as the transfer mode. This will result in a nicely dithered image on the black-and-white end.
Under System 6 without 32-Bit QuickDraw, the solution is not nearly so cut and dried. One way might be to take advantage of the fact that DrawPicture goes through the QuickDraw bottlenecks for drawing. For each grafproc in your PICT, you'd intercept StdBits during DrawPicture and call your own dithering routine to examine the foreground color and set the pen pattern or fill pattern so that it has about the same lightness as the original color.
Well, this came out as a great sales pitch for writing a System 7-savvy app!
Graphics, Imaging & Printing: TrueType: RealFont and TrueType
What is the story with RealFont and TrueType? I am finding that, of the standard System 7 fonts, only Symbol and Courier get a TRUE for 7 point.
You are absolutely correct with your observation of RealFont for size 7 and certain TrueType fonts. The explanation is hidden in “The TrueType Font Format Specification” (APDA M0825LL/A), page 227:
The “head” FontHeader table contains a field “lowestRecPPEM,” which indicates the “lowest recommended pixel number per Em,” or, in other words, the “smallest readable size in pixels.” As it turns out, the Font Manager in its wisdom uses this information for the value it returns from RealFont. Note that for higher resolution devices, a point size of 7 does *not* correspond to 7 pixels; but as the unit “point” is 1/72 inch, and the screen resolution is (approximately) 72 dpi, the result corresponds to reality in this case.
The value for lowestRecPPEM can be arbitrarily set by the Font designer. We all know that small point sizes on low-resolution devices never look “great,” and even less so for outline fonts. Courier and Symbol have lowestRecPPEM = 6, while the other outline fonts in the System have lowestRecPPEM = 9. This doesn’t really mean that Courier and Symbol in size 7 (TrueType) look better than Times or Helvetica under the same conditions. It means the font designer had higher standards (or was in a different mood) when he choose lowestRecPPEM = 9.
Graphics, Imaging & Printing: TrueType: RealFont and smaller-than-legible TrueType font sizes
RealFont and smaller-than-legible TrueType font sizes
RealFont returns a false on a TrueType font if the font’s point size is less than the minimum legible point size defined in the 'sfnt'. A scaled bitmap is created for smaller-than-legible point sizes. This is a small point (a lame font pun there), but you might want to know.
Graphics, Imaging & Printing: Color Manager: Macintosh Color Manager versus Palette Manager
When should the Macintosh® Color Manager be used and when should the Palette Manager be used?
The Palette Manager is by far the friendlier and more versatile of the two. It provides all the functionality you need to customize and animate the colors in your application. You shouldn’t ever need to use the Color Manager unless you require custom color search and complement functions. Unless you really understand the Color Manager in detail, you are likely to have problems getting the Color Manager to work in a clean fashion. When using the Palette Manager, applications following the rules will maintain their respective color environments safely as applications move back and forth from foreground to background, and from one screen to another. Accomplishing this with the Color Manager calls is not worth the effort. For additional information, see the Palette Manager article in this issue.
Graphics, Imaging & Printing: Fonts: Chicago Control-Q prints propeller or clover symbol
How do I get the character that represents the clover used for command-key equivalents in documents and in menus?
This key is documented in the Apple Style Guide, which is available on the latest Developer CD Series disc as well as from APDA. One little feature of Key Caps which is not widely known is the Control key (not the Command or Option keys). Pressing the Control key in Chicago shows that Control-Q in Chicago maps to the propeller symbol for which you search.
Graphics, Imaging & Printing: Fonts: Apple IIGS static text item font bug and workaround
When I ran my Apple IIGS® application on a single 3.5-inch drive, I found that some of my windows were displaying static text items in the Shaston font that were meant to be shown in Geneva. Because the program disk was in the drive when the window was displayed, the system defaulted to the system font instead of asking for the system disk to be inserted so it could load the font. It just defaulted to the system font. Is this a bug and is there a workaround?
The Apple IIGS Font Manager keeps its fonts in separate files that it opens only when the font is requested. Hence, when the system tries to load the font on a one-disk system, the Font Manager simply gets a file (or volume) not found message. In any case, since the file was not already open, the system does not call TLMountVolume, and the Font Manager doesn’t, so… The Font Manager simply reports that the font does not exist and you get the default system font. The solution? Not a very pretty one. You’ll have to call LoadFont or InstallFont yourself, and if you get a “volume not found” error, call TLMountVolume yourself.
Graphics, Imaging & Printing: Fonts: Macintosh double-byte character encoding
When will System 7 and TrueType™ be able to support a larger character encoding vector than the current 256 characters? Is this something I could do now?
System 7 does not have double-byte character encoding support now. In the future, Apple will use the two-byte UNICODE standard for its operating systems. However, such a change will be huge and therefore will not be available before the next major system revision.
Ever since 6.0.2, KanjiTalk™ has had double-byte encoding, so you can use the Japanese system at this time. The system which allows you to do this is called shift-JIS (Japanese Input System). The mappings are on the current Developer CD in the Kanji folder.
Graphics, Imaging & Printing: Fonts: Macintosh Font Manager FOND information
Can you help me figure out the setwidth tables in Macintosh® FOND resources?
Basically, each width table entry looks like this:
struct WidTableEntry {
word widStyle; /* Bit flags describing which style this
table measures. */
word widRec[numChars+2]; /* Width information for each
character. */
};
To get the width information for character number x in the width table, you just index by x into the widRec. The font widths are stored in 4.12 fixed- point format—four bits to the left of the decimal point, and twelve bits to the right. If you need to convert to floating point, probably the easiest way is to coerce the 4.12 16-bit fixed-point number to 16.16 32-bit fixed-point (this type, "Fixed,” is described in Inside Macintosh Volume I, page 79), and then use the Toolbox Utilities routine Fix2X (Inside Macintosh Volume IV, page 65) to convert to the 80-bit "Extended" floating-point format.
theFix16_16 = Fixed(longword(theFix4_12)<<4);
theExtended = Fix2X(theFix16_16);
If your application needs to do the calculations quickly, it might be useful to avoid floating-point altogether, keep the widths in Fixed format, and do all the calculations with the Toolbox Utilities fixed-point routines. Fixed- point math is much faster, and for your purposes a resolution of 2^-16 may be sufficient to avoid rounding error.
One last caveat: To maintain System 7.0 compatibility when digging into FONDs for bitmap fonts, it's really important to check that the FOND info you are checking/altering refers to 'FONT' or 'NFNT' resources, not to the new 'sfnt' resource used for outline fonts. The internal FOND structure is unsupported and subject to change.
Graphics, Imaging & Printing: Fonts: Determining PostScript font intrinsic styles
How can I determine the intrinsic styles that are supported by a particular PostScript® font?
To find the styles which are supported by a particular font, you need to access one of two tables. To find the screen fonts that are available, you can use the Font Association Table. This table is shown in Inside Macintosh® IV- 38. Each entry in the table contains the size and style of the font, as well as the resource ID. Each font in this table should be available for the screen.
When you print a font to a PostScript printer, the Font Manager uses the style mapping table in the family record to create a PostScript name for the font. The table has a list of strings, followed by an entry for each style supported by that particular font. A table for Helvetica® might look like this:
|__?ΩHelvetica
-
Bold
Italic
The first part ('|_____') is the prefix the LaserWriter® uses for fonts that it has coordinated. In the process of downloading a PostScript font, the LaserWriter driver has to change the encoding vector so that the special characters supported by the Macintosh will be usable on the printer. When the LaserWriter does this, it renames the font and prepends this prefix so it can distinguish it from the original version. The rest of the table is used to build the font name for a particular style. This is a little sick, so hang on. Let's look at the table again, and number each line:
1 |__?Ω2 Helvetica
3 -
4 Bold
5 Italic
6 1,2
7 1,2,3
8 1,2,4
9 1,2,3,4
So entry number 6 here, is the entry for plain Helvetica. It is built by using lines 1 and 2 creating the name '|_____Helvetica'. Entry number 9 is the entry for bolditalic. The name that gets built here is: '|_____Helvetica- BoldItalic'. The style-mapping table is not covered in the Font Manager chapter of Inside Macintosh since it is so specific to PostScript. Instead, this information is in the LaserWriter Reference (available from Addison- Wesley), pages 28-35. It's pretty hard to grasp without the preceding description.
Graphics, Imaging & Printing: Fonts: Don't put fonts into your Macintosh application
My Macintosh® application will not run. The problem seems to be my font that I keep in the application. The first time I call DrawString the machine hangs.
We don't recommend putting fonts into an application because the ID numbers may conflict with fonts in the System file.
Graphics, Imaging & Printing: Fonts: Preshifted FASTFONT increases Apple IIGS text drawing speed
What is "FASTFONT" on the Apple IIGS® and how can I use it?
FASTFONT is a new disk file for System Software 5.0. It contains a preshifted version of the ROM font, Shaston 8. QuickDraw™ will load FASTFONT from the Fonts directory at QDStartUp time (if present) and use it for greatly increased text drawing speed. Currently, the System does not support different or multiple FastFonts, and no special work is needed by the application to take advantage of the present capability.
Graphics, Imaging & Printing: Fonts: Fonts and Apple IIGS aspect ratio
Why do Apple IIGS® fonts look tall and skinny, as if they were made out of rubber and stretched too far in one direction. They look OK when I print using the "vertical condensed" option.
Nearly all the Apple IIGS fonts were originally designed for other systems, usually the Macintosh®. Font definitions for the Apple IIGS and other systems are nearly identical. Macintosh pixels are square; the width-to-height ratio of a pixel is 1:1. Apple IIGS pixels are much taller than they are wide. (The ratio for Apple IIGS 640 mode is about 5:12.) When a font designed for square pixels is displayed on a system with pixels of a different shape, the characters look stretched. This is what happens on the Apple IIGS.
Apple could have changed the font strike for a more pleasing look at Apple IIGS resolutions, but for legal reasons such a change would require renaming the fonts. Times wouldn't be Times anymore, Helvetica wouldn't be Helvetica, and so on. The fonts would look the same, but the names would have to be different. In the tradeoff between appearance and well-recognized font names, Apple chose to keep the familiar names and font strikes.
To compensate for the stretched fonts, all of Apple's printer drivers include a "vertically condensed" printer option. Selecting this option causes the printer drivers to print with double the screen's vertical resolution. Doubling the vertical resolution effectively makes the pixel aspect ratio about 10:12, or 5:6, which is close enough to square that the fonts look the way we expect them to.
Some fonts are designed for the Apple IIGS aspect ratio of 5:12. Such fonts are identified in their font family numbers by having the high bit set.
Graphics, Imaging & Printing: Fonts: Fonts shipped with Macintosh system software
What are the standard fonts shipped with Macintosh® system software?
Chicago 12
Courier 10,12
Geneva 9,10,12,14,18,20,24
Helvetica® 10,12
Monaco 9,12
New York 9,10,12,14,18,20,24
Times® 10,12
Venice 14
Graphics, Imaging & Printing: Fonts: Macintosh fractional font width problems
Why can’t I get Macintosh® fractional font widths (FFWs) to work correctly?
There are a number of problems with the current implementation of fractional font widths. Because of these problems, Apple discourages use of fractional font widths at this time. Here are some of the difficulties:
The most serious problem with the current implementation of fractional font widths involves the way QuickDraw™ uses them. When you draw a string on the screen with FFWs enabled, QuickDraw rounds the fractions into integers. Rather than adding this rounding error onto the end of the string, QuickDraw distributes it across certain characters in the string. Note that this error will only occur on the screen. If this string is printed on a high resolution device (like a LaserWriter®), it looks fine.
The distributed rounding error causes one more significant problem. If an application wants to redraw part of a string, the rounding error is distributed differently than if the entire string is drawn. One solution for this problem is not to redraw sections of a string, but that doesn’t solve the problem completely. For example, consider a word processing application that tries to determine where to place its insertion point. Unless it has drawn each character individually, there is no way for it to correctly calculate the position between characters. You can see this by using TextEdit with FFWs enabled.
Enabling FFWs disables the Font Substitution feature of the LaserWriter driver because there is no way to mix the widths of a screen font with those of a printer font. For example, if you are using Geneva with FFWs enabled and the LaserWriter substitutes Helvetica®, which widths should it use? If the driver uses Geneva widths with the Helvetica font, the What You See Is What You Get (WYSIWYG) correspondence between screen and printer is lost. To solve this problem, the driver disables Font Substitution and uses the Geneva widths with the Geneva font.
Another problem with FFWs concerns QuickDraw pictures. Unfortunately, the FractEnable flag is not recorded into pictures, so if you create a layout with text in a picture with FFWs enabled, then paste that picture into an application which has FFWs disabled, you lose your layout. This problem with pictures is especially bad for applications which generate forms, since the field names no longer fit correctly in the boxes which surround them. Applications which generate pictures should do so with FFWs disabled.
Graphics, Imaging & Printing: Graphics Devices Manager: Technique for Macintosh GC card GWorld access
How can a Macintosh® in 24-bit addressing mode read from disk into a GWorld? If the GC card is installed, sometimes the GWorld is a 32-bit one cached on the card. How do we ensure the GWorld will be in main memory?
When you create your GWorld, set the keepLocal flag in the flags field of the NewGWorld call. This ensures that the newly created GWorld will be in main memory where you can access it. Read your data into the GWorld and then clear the keepLocal flag with a call to SetPixelState. This will issue a “GWorld hasbeen updated” type of message, causing the GWorld to be cached off to the GC card, giving you the best performance. When you want to load another image, call SetPixelState again, setting the keepLocal flag to bring the GWorld back to main memory. Using this technique you’ll be able to load your GWorld and cache it too, and you won’t need to recreate the GWorld each time you want to load more data into it.
Graphics, Imaging & Printing: Graphics Devices Manager: Code snippet for getting Macintosh display information
In my Macintosh® system, I have two screens. The main screen in a 19" monochrome. The second screen, to the left of the main one, is color. How can my program know whether or not a color display is available, its depth, and its coordinates?
The following bit of code will show you basically how to walk the GDevice list and find the information you want from it. Most of this information can be found on pages 119 and 124 of Inside Macintosh Volume V.
count = 0;
GDevHand = GetDeviceList();
ScreenRect[count] = (*(*gDevHand)->gdPMap)->bounds;
ScreenDepth[count] = (*(*gDevHand)->gdPMap)->pixelSize;
ScreenColor[count] = TestDeviceAttribute (GDevHand, gdDevType);
While ((GDevHand = GetNextDevice(GDevHand)) != nil) {
++count;
ScreenRect[count] = (*(*gDevHand)->gdPMap)->bounds;
ScreenDepth[count] = (*(*gDevHand)->gdPMap)->pixelSize;
ScreenColor[count] = TestDeviceAttribute (GDevHand, gdDevType);
}
Graphics, Imaging & Printing: Palette Manager: Macintosh Palette Manager and off-screen graphics
Macintosh Palette Manager and off-screen graphics
The Macintosh Palette Manager does not work on off-screen graphics. It needs to have a Window record in order to work correctly.
You can work around this limitation. For example, use Index2Color and then RGBForeColor to get the color to be set for drawing, instead of using PMForeColor.
A remake of the GiMeDaPalette code sample, available on the latest Developer CD Series disc, does off-screen drawing in place of copying a PICT.
Graphics, Imaging & Printing: Palette Manager: Macintosh palette disposal
What is the method of disposing of palettes that are attached to a window?
Disposing of palettes takes some thought; it's not straightforward. If you call GetNewPalette or create a palette using NewPalette and SetPalette then you are responsible for disposing the palette when you dispose of the window. If you call GetPalette for a window then you are again responsible for disposing the palette when you're done with the window.
If there is an associated palette to a window (there was a pltt=0 or pltt=WIND ID resource available) and you don't touch the palette with GetPalette, or any of the other previously mentioned calls, then the palette is disposed of for you automatically.
One thing to remember, it's best to play it safe and dispose of the window first and the palette second. You'll need the handle for the palette so make sure you have it before disposing the window. Though it doesn't matter which one gets done first, it's always best to keep yourself covered and do the window first.
Graphics, Imaging & Printing: PostScript: LaserWriter Font Utility copies Postscript file to printer
Is there a utility that will send a PostScript file from disk to the LaserWriter?
The LaserWriter Font Utility handles this job and is part of the System 7 disk set. On the System 7 Golden Master CD, the path is System 7.0: System Software 7.0: Installer Version: Tidbits folder.
Graphics, Imaging & Printing: PostScript: Apple IIGS EmulatorFont
What is EmulatorFont in the the font catalog of my LaserWriter? There’s no sample text for it.
EmulatorFont is a PostScript font installed by the ImageWriter Emulator. It doesn’t have ASCII characters in the normal range—it only contains the MouseText special characters that IWEM can’t map to Courier or Times when printing text. If you want to get rid of the font, restart the printer and don’t re-download IWEM. If you want to see the font definition, just open IWEM off the current IIGS System Tools disk.
Graphics, Imaging & Printing: PostScript: PostScript setprintername doesn’t accept colons in string
Why can’t I use a colon with the PostScript command setprintername to change the Personal LaserWriter NT network name and type, but it works with the LaserWriter II?
The reason that the Personal LaserWriter NT is not accepting the PostScript you’re sending is not because of a bug, but rather a bug fix. Colons have never been acceptable in the string passed to setprintername. (See page 296 of Adobe’s “PostScript Language Reference Manual.”) The reason the call works in older LaserWriters but not the Personal LaserWriter NT is that the NT has a newer version of PostScript in it. Older versions of PostScript didn’t enforce Adobe’s printer naming conventions. The setprintername restrictions have been enforced in the new version, however. Therefore, colons are not allowed.
If you need to change the LaserWriter network type, it can be done with the AppleTalk-type parameter described on page 105 of Apple’s “LaserWriter Reference” manual. This method will work on the new printers as well as the old.
Graphics, Imaging & Printing: PostScript: Printing an Encapsulated PostScript (EPS) file
I want to be able to print any Encapsulated PostScript (EPS) file. How can I do this? Can I somehow tell the LaserWriter driver to grab the files and print them?
Unfortunately, the Laserwriter driver cannot handle this for you. There’s no easy way to do what you’re asking, because PostScript in the Macintosh world is different from standard PostScript. Even if a standard PostScript file were dumped to the printer using PostScriptHandle, the printer would not be able to resolve the differences in standard PostScript. The only way you could print such PostScript files through the LaserWriter driver would be to do preprocessing such as changing transformation matrices and changing pen transfer modes. To be completely compatible with these files, you’d need to parse completely through them and fix the problems as they appear. This is a major job, requiring in-depth knowledge of PostScript. As it stands, the LaserWriter driver cannot handle vanilla PostScript. A printer driver *could*be written to do this, but then every job would have to be parsed and every job would be slowed down because of it.
One of the problems is that Adobe’s document structuring conventions just went final a short while ago. There are many EPS files out there that don’t match the structuring conventions that Adobe has laid down, so the only way you can get the vitals of a PostScript file consistently is to parse it completely. Ideally, everyone would comment their EPSF correctly and printer drivers could decide what to do based on that. Unfortunately, we’re a long way away from that point today. The only way to do what you need to do is to get real deep into PostScript and devote a lot of time to the project. You have to weigh the time and resources required against the benefit of being compatible with non-Macintosh EPS files.
Graphics, Imaging & Printing: PostScript: PostScript documentation
PostScript documentation
Adobe Systems publishes three great manuals that can help you with PostScript commands: “PostScript Language Reference Manual,” “PostScript Language Tutorial,” and “PostScript Language Cookbook.” You can find these manuals at just about any bookstore, or you can order them through APDA by calling (800) 282-2732 or writing them at:
Apple Computer, Inc.
20525 Mariani Avenue, Mail Stop 33-G
Cupertino, CA 95014
Graphics, Imaging & Printing: PostScript: PostScript code for renaming LaserWriter
In checking a printer name to ensure an even number of characters, does the LaserWriter Namer append a space to the end if the total is odd?
In a nutshell, yes. The Namer does indeed append an extra space to odd-length printer names. The reasoning behind this is to be compatible with some of the old 68000 processors. The addressing scheme of these old processors requires that memory be accessed by even-numbered addresses. To get at a piece of memory located after an odd-length LaserWriter name, you would need to get an odd-numbered address (which is not directly possible). This obviously can be worked around, but the authors of the Namer felt it best to avoid this altogether by padding the name when necessary. It’s worth noting that the version 7.0 Namer does this too.
If you’d like to work around this, here’s an alternate method for renaming the printer:
The printer name is stored as a string in the persistent parameters of all LaserWriters. This string can be changed by the following PostScript program:
serverdict begin 0 exitserver
statusdict begin (NEWNAME) setprintername
Replace NEWNAME with the name you want for the printer. The name can be up to 31 characters and should consist entirely of printing characters--the “@” and “:” cannot be used. Note that parentheses are required.
This program can be downloaded to the LaserWriter in batch or interactive mode. In interactive mode you should type both command strings on the same line before pressing Enter, because exitserver disconnects you from the printer. When you reestablish your connection to the printer, the name will be changed.
Make sure you have selected the correct LaserWriter using the Chooser before downloading this program, so you don’t rename the wrong LaserWriter.
Graphics, Imaging & Printing: PostScript: SCSI drive format for LaserWriter II NTX with Rev. 3 ROMs
What could be causing intermittent PostScript® errors from a LaserWriter® II NTX with an SCSI hard disk mounted after installing the Rev 3 ROM upgrade?
The LaserWriter II NTX with Rev 3 ROMs does not work properly with a hard disk formatted with the LaserWriter Font Utility 1.x. You need to reformat the disk and copy the fonts back onto the hard disk using the LaserWriter Font Utility 2.0.2. Unfortunately, there is no way to make this procedure easier.
Graphics, Imaging & Printing: PostScript: Where to find Encapsulated PostScript file (EPSF) documentation
I am developing an application that creates pictures containing both QuickDraw™ and PostScript® (as picComments). How do I create an encapsulated PostScript file (EPSF)? Is the format explained anywhere, and is it possible to convert the QuickDraw into PostScript directly in the application?
Adobe’s EPSF format is documented in the new (2nd) edition of Adobe’s PostScript Language Reference Manual (Addison-Wesley) and in “Adobe Document Structuring Conventions,” available from Adobe Systems. Adobe’s references explain how to structure your comments in your PostScript file so that other applications know how to read it.
You probably don’t want to try to convert QuickDraw to PostScript directly in your application, although it is possible. Basically, it involves translating each QuickDraw command into PostScript, which is what the LaserWriter® Driver does. It’s a lot of work and makes you dependent on the QuickDraw features being used, which can be a problem when new features are added.
Graphics, Imaging & Printing: PostScript: How to inhibit LaserWriter test page
How do I inhibit the test page on a LaserWriter®?
Download the following PostScript commands:
serverdict begin 0 exitserver
statusdict begin
false setdostartpage
end
The above commands can be downloaded from your Macintosh® to the printer several ways:
1. You can use a PostScript utility like LaserTalk from
Emerald City Software.
2. The PostScript Language facility in Microsoft Word.
3. PSDump or PSsend
4. An Adobe downloader utility that they include with
their products.
5. Use the PostScript utilities in the Developer CD’s
PostScript Utilities folder.
6. Use the menu command in the LaserWriter Font Utility
that comes with System 7.0ßx.
When you issue the commands, your LaserWriter will probably crank and grind for a few seconds (it has to re-program the EPROM inside) then after the lights stop flashing, your LaserWriter will no longer spit out the start-up page.
For more information on the above subject I recommend the PostScript Language Reference Manual by Adobe Systems.
Graphics, Imaging & Printing: PostScript: Using PostScript to control LaserWriter serial I/O
Where can I find information on using PostScript to control a multi-tray sheet feeder by communicating through the LaserWriter® serial port?
You need to talk with Adobe on how they control the serial chip with PostScript. They use some undocumented PostScript calls to control the serial chip on the controller board of the LaserWriter. They can be reached at:
Adobe Systems, Inc.
1585 Charleston Road
Mountain View, CA 94039
- or -
AppleLink Address: ADOBE.SUPT (Tech Support)
Details about installing feeder resources for Macintosh® into the LaserWriter driver 7.0 dialogs are available on request from Apple’s Developer Technical Support group.
Graphics, Imaging & Printing: PostScript: How to send PostScript from the Macintosh to the LaserWriter
How do I send PostScript® from the Macintosh® to the LaserWriter®?
The best method for sending PostScript to the LaserWriter is to use the PostScriptHandle (kind = 192) PicComment documented in Tech Note #91. There are a few PicComments for sending PostScript to the LaserWriter, but the easiest to use and most problem free is the PostScriptHandle comment. One model is:
PrOpenPage(...)
{ Send some QuickDraw™ so that the Printing Manager gets a }
{ chance to define the clip region. }
MoveTo(-32000, -32000);
Line(0, 0);
PicComment(PostScriptBegin, 0, NIL);
{ QuickDraw representation of graphic. }
MoveTo(100, 100);
LineTo(200, 200);
{ PostScript representation of graphic. }
thePSHandle^^ := '100 100 moveto 200 200 lineto stroke';
PicComment(PostScriptHandle,GetHandleSize(thePSHandle),thePSHandle);
PicComment(PostScriptEnd, 0, NIL);
PrClosePage(...)
The described fragment prints a line on any type of printer, PostScript or not. The first MoveTo/Line combination is required to give the LaserWriter driver a chance to define a clipping region. The LaserWriter driver replaces the grafProcs record in the GrafPort returned from PrOpenDoc. In order for the LaserWriter driver to get execution time, you must execute a QuickDraw drawing routine that calls one of the grafProcs. In this case, the MoveTo/Line combination is sent firing the StdLine grafProc. When StdLine executes, it notices that the GrafPort has been reinitialized, and therefore initializes the clipping region for the port. Until the MoveTo/Line combination is executed, the clipping region for the port is set to (0,0,0,0). If PostScript code is sent via the PostScriptHandle PicComment before executing any QuickDraw routines, all PostScript operations will be clipped to (0,0,0,0). The next thing to do is send the PostScriptBegin PicComment. This comment is recognized only by PostScript printer drivers. When the driver receives this comment, it saves the current state of the PostScript device (by executing the PostScript gsave operator), then disables all QuickDraw drawing operations. This way, the QuickDraw representation of the Graphic will be ignored by PostScript devices. In the previous example, the MoveTo/LineTo combination is only executed on non-PostScript devices. The next comment is the PostScriptHandle PicComment. This tells the driver that the data in thePSHandle is to be sent to the device as PostScript code. The driver then passes this code unchanged to the PostScript device for execution. The PostScriptHandle PicComment is only recognized by PostScript printer drivers. The last PicComment, PostScriptEnd, tells the driver to restore the previous state of the device (via a PostScript grestore call), and to enable QuickDraw drawing operations. Since all PicComments are ignored by QuickDraw devices, only the QuickDraw representation is printed. Since PostScriptBegin tells PostScript drivers to ignore QuickDraw operations, only the PostScript representation is printed on PostScript devices. This is a truly device- independent method for providing both PostScript and QuickDraw representations of a document.
Graphics, Imaging & Printing: PostScript: PicComment TextIsPostScript versus PostScriptHandle
When using the Macintosh® TextIsPostScript picture comment, my PostScript code is also “printed” on the ImageWriter®. Why isn’t it ignored?
One of the comments, TextIsPostScript, allows the application to use the QuickDraw™ DrawString procedure to send the PostScript® code. This method is no longer recommended, as it is not device independent. If you use the TextIsPostScript comment when printing to a non-PostScript device, the PostScript code will be printed as text. On an ImageWriter, the entire PostScript program will be printed as one line on the page, because the TextIsPostScript PicComment is ignored by the ImageWriter drivers, and the DrawString calls are executed normally.
To avoid this problem, developers should use the PostScriptHandle comment. This comment accepts a handle as a parameter. The handle points to the PostScript code that you want to download. This comment is better for two reasons:
First, there is no QuickDraw/PostScript interaction. For example, early versions of the LaserWriter® driver sent the strings passed to DrawString as- is. The latest version of the driver appends carriage returns onto those strings. If your application is expecting the DrawString calls to work one way or another, you might get a surprise.
The other reason for using the PostScriptHandle comment involves device independence. When a non-PostScript driver sees the PostScriptHandle PicComment, it not only ignores the comment, but also ignores the PostScript data that was passed to the comment, so nothing prints if you use the PostScriptHandle comment on a non-PostScript driver.
Graphics, Imaging & Printing: PostScript: LaserWriter driver and PostScript showpage
When I print a PostScript® file, why do I get one blank page for every page printed?
Your PostScript file probably contains calls to the PostScript showpage operator. This operator is also called by the Macintosh® LaserWriter® driver when it receives the PrClosePage call. The solution to this problem is to strip showpage calls from the file before sending the file to the LaserWriter. If you send one QuickDraw™ graphic at the beginning of each page,
MoveTo(-32000, -32000);
Line(0, 0);
the LaserWriter driver will handle calling showpage for you. Versions of the LaserWriter driver before 5.2 do not send the showpage operator unless a QuickDraw drawing routine (that is, something other than PicComment) is sent. This is why you need to do the MoveTo/LineTo. Versions 5.2 and later will send the showpage operator whether any QuickDraw has been sent or not. Since you can’t be sure whether showpage will be sent for you or not, the best solution is to let the LaserWriter driver send it.
Graphics, Imaging & Printing: PostScript: Macintosh spooling should be device independent
How can I tell whether the chosen printer supports PostScript® or not?
There is no supported method for determining whether or not a device speaks PostScript. Apple engineering would like all Macintosh® applications to spool both PostScript and QuickDraw™ regardless of the chosen printer, so that the spool file is device-independent and can be redirected after spooling. Since engineering is strongly encouraging developers to spool both models, it is doubtful that Apple will be providing a query mechanism in the future. The best method is to assume PostScript is available, and format your document based on information returned by PrGeneral and the print record.
Graphics, Imaging & Printing: Printer Access Protocol (PAP): Monitoring PAP PostScript packets with AppleTalk Peek
Are there hardware or software tools for monitoring AppleTalk Printer Access Protocol (PAP) packets in some direct way?
A tool called “AppleTalk Peek” allows you to monitor packets that are being sent over AppleTalk. It is available on the AppleLink and on the latest Develope CD Series disc. You can find the tool via the following path: Storage and Communication Folder : Network Folder : AppleTalk Tools Folder. This tool might enable you to determine experimentally, PostScript handle sizes that work best for your application.
Graphics, Imaging & Printing: Printer Access Protocol (PAP): Using PAP & code for finding printer driver under System 7
Is there any documentation or sample code on the Printer Access Protocol (PAP), besides Inside AppleTalk® and MacTutor’s sample? Or is there a better way to shove 1 MB and larger files down the pipe to a PostScript® device?
The question that you ask has become a popular one these days; it seems that a lot of people are writing PAP programs. Unfortunately, there isn’t really a clean-cut answer. There are several options:
1) The code that appeared in MacTutor seems to work just fine. Of course, it is unsupported by Apple and it may very well break under a future system software release. It is definitely the quickest way to get a PAP-based program coded.
2) You could write your own PAP interfaces. This is a very time consuming operation, but it also most likely not to break under future systems. Other companies have done it, and it is fairly straightforward.
3) Through software licensing, you can license a library named papworkstation.o. It is a library only, with little or no documentation, and it is unsupported. It is, however, used by several third parties, and it works OK.
In case you do use the MacTutor code, the following example shows a method for finding the printer driver under System 7:
FUNCTION GetPAPDriver: BOOLEAN;
VAR
theResFile: INTEGER;
theWorld: SysEnvRec;
theError: OSErr;
DoinFolders: BOOLEAN;
myFeature: LONGINT;
sysVRefNum: INTEGER;
sysDirID: LONGINT;
gotDriver: BOOLEAN;
numStr: Str255;
BEGIN
gotDriver := TRUE;
DoinFolders := FALSE;
(*--------------------- The 7.0 Way! --------------------------*)
IF GestaltAvailable THEN BEGIN
theError := Gestalt(gestaltFindFolderAttr, myFeature);
IF theError = noErr THEN BEGIN
DoinFolders := BitTst(@myFeature,
31-gestaltFindFolderPresent);
IF DoinFolders THEN BEGIN
theError := FindFolder(kOnSystemDisk, kExtensionFolderType,
kDontCreateFolder, sysVRefNum, sysDirID);
IF theError <> noErr THEN BEGIN
DebugStr('FindFolder err');
gotDriver := FALSE;
END;
END;
END;
END;
(* If FindFolder was not available, use good ol' SysEnvirons (thanks Jim)*)
IF NOT DoinFolders THEN BEGIN
(* No FindFolder! Gotta do it the old way... *)
theError := SysEnvirons(1, theWorld);
IF theError = noErr THEN
sysVRefNum := theWorld.sysVRefNum
ELSE
gotDriver := FALSE;
END;
(*----------------------------------------------------------------*)
(* Okay, at this point we should have found the folder where the*)
(* drivers are. If we are running under System 7.0, this folder*)
(* will be the extensions folder in the System folder. If we are*)
(* pre-7.0,this will be the System folder. If FindFolder was *)
(* available, then we have to use HOpenResFile because *)
(* FindFolder uses dirIDs. If we just used SysEnvirons (ie. pre *)
(* 7.0), then we can use OpenRFPerm. *)
IF gotDriver THEN BEGIN
IF DoinFolders THEN
theResFile := HOpenResFile(sysVRefNum, sysDirID, driverName, fsRdPerm)
ELSE
theResFile := OpenRFPerm(driverName, sysVRefNum, fsRdPerm);
theError := ResError;
IF theError = noErr THEN BEGIN
driverCode := GetResource('PDEF', 10);
HNoPurge(driverCode);
DetachResource(driverCode);
IF ResError = noErr THEN BEGIN
LWName := StringHdl(GetResource('PAPA', -8192));
DetachResource(Handle(LWName));
CloseResFile(theResFile)
END ELSE
gotDriver := FALSE;
END ELSE BEGIN
NumToString(theError, numStr);
DebugStr(numStr);
gotDriver := FALSE;
END;
END ELSE
gotDriver := FALSE;
GetPAPDriver := gotDriver;
END; (* GetPAPDriver *)
Graphics, Imaging & Printing: Printer Drivers: Update Backgrounder if using LaserWriter 7.0 under System 6
When we use the LaserWriter® driver 7.0 with System 6.0, the Chooser’s Background Printing “On” button is always dimmed. Is there any way to enable background printing?
To get the LaserWriter 7.0 driver to work with System 6.0.x, update your Backgrounder file with the version on the Printing Tools Disk that’s used to install System 7.0.
In short, to use the 7.0 LaserWriter Driver, 7.0 PrintMonitor, and System 6.0.x, place these files from the System 7.0 Printing Tools installation disks into your System Folder. All three must be used together for printing to work correctly. After you’ve placed these files in the System Folder, you should find the Background Printing option enabled for your use.
There are no known incompatibilities with the 7.0 drivers and System 6.0.x, so everyone should use the latest drivers, even with a mixed environment. This will also get rid of “printer wars” that occur when users use more than one version of the LaserWriter driver to print to the same printer. (The printer must be reinitialized if the current user uses a different version of the driver than what was used by the previous user.)
Graphics, Imaging & Printing: Printer Drivers: LaserWriter 6.1 versus 7.0 (use new installer for both)
What is the difference between the LaserWriter® driver version 6.1 and 7.0?
The 6.1 driver is basically an early release of the 7.0 driver. A number of bugs were corrected in the final 7.0 release. In terms of functional differences, there aren’t any. Some features just function a little bit more like they’re supposed to in the 7.0 version.
Since the 7.0 driver can be used with 6.0.x systems, there’s really no reason to use the 6.1 driver anymore. If you decide to use the 7.0 driver with a 6.0.x system, be sure to install it with the 7.0 installer. Several system files must be removed or updated to work with the 7.0 driver and the installer correctly handles this.
Graphics, Imaging & Printing: Printer Drivers: Printing directly to a LaserWriter from an Apple II application
How can my 8-bit Apple® II application print bitmapped graphics directly to a LaserWriter®?
To print directly to a LaserWriter from an Apple II, you have a few choices. All of Apple’s system software support assumes you’re going to connect the LaserWriter through an AppleTalk network, so that’s how most of your help for doing this is structured.
When you choose a given LaserWriter (either through Chooser II from ProDOS® 8 or from the LaserWriter cdev under GS/OS®), you can make sure something called the “ImageWriter® Emulator” is installed. IwEm is a PostScript® program that works with the Remote Print Manager (AppleTalk® software in the Apple II) so that direct ImageWriter commands sent to the AppleTalk port (which looks like a serial port) work. This works even for bitmapped graphics, although only at ImageWriter resolutions. If you’re using networked LaserWriters, you might choose to tell your users to pretend the printer is an ImageWriter connected to the network slot. As long as they’ve properly chosen the printer and downloaded the ImageWriter emulator, this will work fine.
If you want to directly connect the LaserWriter, you have only a couple of choices. You can use the Diablo 630 emulation, or the HP LaserJet emulation on those printers that have it, but that requires physically flipping a dip switch in some cases. The only other option is to do what the Macintosh® and Apple IIGS® printer drivers do—drive the printer by sending it PostScript commands to image your page. This will produce the best output at the cost of being the most difficult to code.
Instructions for emulations and direct PostScript modes are in the LaserWriter Reference, available from Addison-Wesley. Instructions on PostScript are available from Addison-Wesley as well, in one of several Adobe technical books or non-Adobe PostScript books.
Graphics, Imaging & Printing: Printer Drivers: Save and restore long word if using $948 under System 7
Unless my Macintosh® application restores the contents of the long word at $948 after using that space for globals, the Finder™ draws icons incorrectly and my third-party LaserWriter® driver crashes. Is somebody now using $948 for other purposes?
This is a known System 7 icon drawing bug, and also a bug with the printer driver that you are using.
The icon drawing utilities are trying to determine if a print page is currently open, by looking at that variable ($948 is part of printvars). This turns out not to be such a good idea, and it will be fixed in the next release of the system software.
The printer driver bug that you are experiencing is that every printer driver must return the variable at $948 to -1 when they are done printing. Also, while printing, the driver should set it to <> -1.
Graphics, Imaging & Printing: Printer Drivers: Where to get documentation on writing a Macintosh printer driver
Where is documentation on how to write a Macintosh® printer driver equivalent to the ImageWriter® or LaserWriter® driver?. In particular, how are Print Manager and QuickDraw™ commands translated into calls to the print driver? I also need information on how to install the driver into the Slot Manager.
See the “Learning to Drive Information” document in MacDTS’s Interim Technical Documents folder in the Developer Service icon on Applelink. You should also take a look in Inside Macintosh and in the reference Designing Cards and Drivers for information on the Slot Manager.
Graphics, Imaging & Printing: Printer Drivers: Determining if a printer driver accepts Color QuickDraw calls
How do you find out if a printer driver accepts Macintosh® Color QuickDraw™ calls?
Check to see if the printer driver has returned a color GrafPort to your application after the call to PrOpenDoc (that is, the port that PrOpenDoc returns).
To determine if the GrafPort is color, you need to check to see if rowBytes from the GrafPort are less than 0. The following code fragment demonstrates this idea:
(* This function determines if the port passed to it
is a color port. If *)
(* so, it returns TRUE. *)
FUNCTION ColorPort(portInQuestion: GrafPtr): BOOLEAN;
BEGIN
IF portInQuestion^.portBits.rowBytes < 0 THEN
ColorPort := TRUE
ELSE
ColorPort := FALSE;
END;
Graphics, Imaging & Printing: Printer Drivers: Writing a Macintosh printer driver
I have a printer I would like to connect to the Macintosh®. Where can I find information on writing a printer driver?
A Macintosh printer driver is more than a standard device driver. A printer driver contains code to implement all of the standard Macintosh Printing Manager routines. The code includes routines like PrOpen/PrClose, and PrOpenDoc/PrCloseDoc. A Printing Resource File contains all of the resources (including code) to implement the Macintosh Printing Manager for a particular device. A driver works best with all Macintosh applications if it supports both the high and low-level Printing Manager interfaces, as well as the PrGeneral (IM V:410) routine and its associated opcodes.
Apple is not currently supporting the development of Chooser-selectable device drivers, at least not those that support printers. There are many reasons for this, and here are at least a few of them:
First, there are no documentation or examples available. Each of the Apple® printer drivers is unique. They are all written almost entirely in 68000 assembler, and consequently, are not very easy to read. Since each driver is different, the only real documentation for how the drivers work is the source code to the driver. There is some general interface information available, but important information, like how the driver manages its print record, is described only in the source code. This information could be extracted and distilled into some kind of document, but this brings up the next problem:
The Macintosh Printing Manager is currently being revised and enhanced. These revisions will require major changes to the architecture of the Printing Manager. It’s not clear what effect these changes will have on existing printer drivers, but it is very possible that the drivers that exist today will have to be revised significantly to run under the new Printing Manager.
Apple is designing and implementing the next generation Macintosh Printing Manager. Developers’ suggestions for features are being taken into account. One of the goals of the new architecture is to make writing drivers much simpler, and to allow the sharing of code between drivers. When this architecture becomes available, Apple will reconsider its position of driver development, and will probably end up with some kind of licensing agreement for developers that want to write drivers. Until then, the preceding reasons should be adequate justification for NOT attempting a Macintosh printer driver at this time.
If you still aren’t convinced, and want to write a driver despite the challenge, see the article in the December ‘88 issue of MacTutor magazine. There is an example printer driver written in C. It is just a skeleton driver, and does not handle any of the more difficult problems such as line layout, font substitution, graphics, or banding. But it is a start, and gives you a general idea of the structure of a driver. Since some developers began writing their drivers before Apple discontinued support, DTS is still answering questions concerning driver development. However, these questions are limited to those that can be answered by the DTS engineers. You should also be aware that some of the techniques used by Apple® printer drivers are considered proprietary. Information on methods used for line layout as well as certain aspects of font handling will not be disclosed.
Graphics, Imaging & Printing: Printer Drivers: Macintosh print record wDev field
What is the Macintosh® print record wDev value for the ImageWriter® LQ, LaserWriter® IISC, and AppleFax™ Modem?
Apple strongly discourages the use of the wDev field in the print record for several reasons. First, this field contains a unique ID for each printer driver on the Macintosh. Coding your application to use this ID makes it device dependent, and device dependence will cause many problems in the future as the Macintosh Printing Manager continues to evolve. Many applications currently check for wDev = 3 to determine whether or not to send PostScript®. Although the Apple® LaserWriter driver has a wDev of 3, third party printer drivers for PostScript devices do not, so if you’re application determines whether or not to send PostScript based on wDev alone, your application may incorrectly print with QuickDraw™ on third party PostScript devices. A second problem concerns spoolers and spool files. If a spooler is installed between an application and the printer driver that is going to do the printing, the application receives the wDev ID of the spooler instead of the target driver. If the application makes assumptions based on this ID, it probably gets unexpected results. In the future, it may also be possible to redirect spool files. This means that a file that was originally spooled for a PostScript printer may be redirected to a QuickDraw device. If the spool file contains only the PostScript representation of the document, it will be useless to the QuickDraw device. Despite these strong warnings, some developers are convinced they need the wDev values, and there may be some vertical applications where they’re needed. For those cases, here is the current list of wDev IDs for Apple printer drivers:
Device wDev (Hi Byte)
ImageWriter I/II: 1
LaserWriter,
LaserWriter Plus,
LaserWriter IINT,
LaserWriter IINTX: 3
LaserWriter IISC: 4
ImageWriter LQ: 5
AppleFax Modem: 10
DTS does not support the use of these constants. They are definitely subject to change.
Graphics, Imaging & Printing: Printer Drivers: FractEnable (TRUE) disables Font Substitution
Why does enabling Macintosh® fractional font widths (FFWs) with FractEnable(TRUE) disable Font Substitution?
When you call FractEnable(TRUE), you are telling the Printing Manager that you always want to use the fractional width information in the FOND resource of a font. This fractional information is specified for a 1 point font, and can be scaled for any desired size. When you tell the Printing Manager to use this width information, the normal font width information (stored in the ROM of the LaserWriter®) is ignored. Font Substitution provides the ability to substitute high quality PostScript® fonts for fonts that have no PostScript equivalent. For example, a document laid out in Geneva will be printed with Helvetica® if Font Substitution is enabled. When this substitution occurs, the Printing Manager makes adjustments to the intercharacter spacing of the line to make the printed Helvetica version match the width of the Geneva version displayed on the screen. When you enable fractional font widths for a document that uses Geneva, the Printing Manager is being told to print Helvetica characters on the printer using fractional widths from the Geneva screen font. If the Printing Manager placed the Helvetica characters using the fractional widths, formatting problems might occur. For example, some of the Helvetica characters may be wider than their Geneva equivalents, causing character collisions. To avoid this problem, the LaserWriter driver disables the Font Substitution option when fractional fonts are enabled, so that WYSIWYG is maintained. If you want to use fractional fonts, format your document using fonts that have PostScript versions available on the LaserWriter.
Graphics, Imaging & Printing: Printing: Getting Mac Page Setup dialog’s “Reduce or Enlarge” value
Is it safe to get the Macintosh Page Setup dialog’s “Reduce or Enlarge” value from the TPrint.prXInfo.iBandH record, or is there a better way to tell if it’s been changed?
You don’t want to rely on the value contained in TPrint.prXInfo.iBandH to determine if “Reduce or Enlarge” has been selected by the user if you want to avoid possible compatibility problems with other printer drivers. The best and cleanest approach to determining if “Reduce or Enlarge” has been selected is to check the value of rPage (Inside Macintosh Volume II, page II-150). rPage is the printable area for the currently selected printer.
For example, when the user does not change the value of “Reduce or Enlarge” (the field defaults to 100%), rPage is 0, 0, 730, 552. If 50% is selected, rPage changes to 0, 0, 1460, 1104, which is a factor of 2 greater than the 100% case, thereby printing your image at half its original size.
This method works without any difficulties until the user selects “landscape” printing. It still works, but you need to check for this condition. Let’s look at how the numbers change: If “landscape” is selected, and “Reduce or Enlarge” is 100%, rPage is set to 0, 0, 552, 730. Notice that the values for bottom and right have been swapped. Everything still works, but you need to make sure that you notice the change to use the correct values for calculating the “Reduce or Enlarge” factor.
You can check for this change to “landscape” printing by comparing the bottom and right values in rPage, or you can use PrGeneral’s GetRotn opcode to determine if “landscape” has been selected by the user. See the July issue of develop and Inside Macintosh Volume V, pages 410-415, for details about using PrGeneral and the GetRotn opcode.
Graphics, Imaging & Printing: Printing: Displaying document name in Print Monitor box
How do I include the name of the document in the Print Monitor window?
Macintosh Technical Note #149, “Document Names and the Printing Manager,” explains how to get the Print Manager to display the name of the document that you’re printing. Basically, this should already work, unless you don’t have a window open when printing or if the name of the window is something other than the name of the document you’re printing (like “Untitled”). The tech note also explains how to create the window with the appropriate title so that it appears invisible to the user in case you don’t want to show a window for some reason.
You also need to call PrValidate between PrClose and PrOpen for the next document if you want the name of the next document to correctly appear when it’s printed.
Graphics, Imaging & Printing: Printing: Troubleshooting 7.0bx/LaserWriter problems
My Macintosh® is bombing all over the place every time I try to print with the LaserWriter® (and the PrintMonitor isn't helping) with System 7.0bx. Please advise.
We are using 7.0bx in our department with no problems printing to a variety of LaserWriters from both 7.0 and 6.x systems. I suspect your problem is related to either an incompatibility with some specific product or that the system software is corrupted. Here are a couple of things to try: First, hold down the Shift key while booting to disable all system extensions (INITs), set addressing to 24 bit, turn off filesharing and VM. Try printing. If it works, then add things back in one at a time to find the incompatibility. If it still bombs, then trash the 7.0 system folder and reinstall from scratch. Try using only Apple hardware, no third-party devices or software drivers.
Graphics, Imaging & Printing: Printing: Choosing a printer from within an application
Is it possible to select a printer among several printers programmatically instead of having to go to the Macintosh® Chooser each time?
Unfortunately, the answer is no. It obviously violates lots of human interface guidelines, but beyond that it would almost require the writing of a single printer driver that could support all of those different printers (a tremendous undertaking).
A little background might help explain the problems. The type of the currently selected printer is stored in the System file in 'STR ' resource ID -8192. This will be the name of the driver selected, such as LaserWriter® or ImageWriter®. The name of the actual printer selected will be in the driver file (same name as the printer type chosen) in 'PAPA' resource ID -8192. Look at this resource with ResEdit™ to see what is in it.
In programs that support such a thing (for example, 4D), you could write an External procedure to modify the name of the actual printer. I guess you could also modify the name of the driver selected, but unless your system never changes, this would almost certainly cause you headaches (for example, better not try to select a driver that has changed its name).
In a nutshell: You can change the 'STR ' and 'PAPA' resources, but it may not work now or in the future. We do not recommend changing the system file or circumventing the Chooser. Further, any program that depends on these resources or tries to change the selected printer will almost certainly break with future releases of the system software.
The least objectionable solution I can think of is to set up a QuickKeys macro that automates changing between printers via the chooser.
Graphics, Imaging & Printing: Printing: Modifying PDEFs to have printer driver jump into dialog code
Could you please point me to the correct section in “Learning to Drive” (or send me an example) that we would need to modify the appropriate PDEF resource in order to have the driver jump to our dialog code?
Pages 15-18 discuss the contents of the various PDEFs. You will need patch the appropriate PDEF to get your required functionality. You should also realize that patching PDEFs is not an easy task, nor will it always survive “new” Macintosh® LaserWriter® driver releases. I want you to know that before you go too far down the PDEF patching road.
By the way, we do know of a couple of developers that have patched PDEFs successfully. The following paragraphs are a “high-level” look at patching a PDEF:
To patch a PDEF, you must write an installer application that lets users choose the printer driver they want to modify via Standard File. You can cause Standard File to display only printer drivers by telling it to display only files of type “PRER”. Once the user has selected a driver you need to scan the driver for the PDEF 0 and 1 resources. When you find one of these you read it in and modify it.
However, I'll give you a quick overview of what you need to do. PDEF 0 & 1 both start with jump tables (a table of JMP instructions followed by the PC relative address to jump to). The JMP to PrClosePage always begins at offset 12. So what your installer needs to do after it loads the resource is grab the eighth word in the resource. That is the offset to the actual start of the PrClosePage code. Then you have to resize the handle so that it is big enough to hold your patch and then BlockMove {IM II-44} your code into the end of the handle. The following illustration might help:
JMP $0486 << Note: some PDEF's have multiple
JMPs at the beginning of the
* - - - - - - - - - - - - - * code. The original offset to
* * PrClosePage was $0386.
* >> Original PDEF code << *
* *
$0386 --> PrClosePage << Note: most PDEF's have
* * multiple printing calls defined.
* *
* *
* - - - - - - - - - - - - - *
$0486 --> {{{ Your Code }}}
* * << You resize the resource
* * handle to this and blockmove
* * your code in here.
* *
* - - - - - - - - - - - - - *
JMP $0386 << At this point we jump into
the printer driver's original
code for PrClosePage.
Note: The previous illustration is not to scale nor completely accurate in regards to the addresses used. Please consult “Learning To drive” for the correct offsets for each PDEF.
Then replace the original offset to PrClosePage with the offset to your new code. Remember that this is PC relative so you would calculate it like this: If the original PrClosePage JMP was JMP 10(SP) and the size of the original PDEF was 50 bytes, then you need to replace the JMP 10(SP) with JMP 50-16(SP). In other words, you need to JMP to what was formerly the end of the PDEF resource but what is now the beginning of your code (subtract 16 because the offset table is 16 bytes long. Refer to “Learning to Drive” for more details). Then on the end of your code, add a JMP ((SizeOfJumpTable + originalOffset) – (sizeofOriginalPDEF + SizeOfYourCode))(SP). Your code will end with a JMP to a negative offset off the PC back to the original PrCloseRoutine.
If you are willing to support “Post 3.3” systems only (basically that means that you won’t be supporting Macintosh 512K and 512KE computers), you don’t have to deal with all the PDEF changing, and you can simply patch out the $A8FD trap and look for the proper selector on the stack. (Use SysEnvirons to be sure that you are on a Post 3.3 system.) This will work because the newer libraries (that is, any library that shipped since the Macintosh II shipped) first checks for the trap and jumps there if the trap exists so even if the application has linked in the printing library they still end up calling the trap on systems after Post 3.3.
Graphics, Imaging & Printing: Printing: Call Printing Mgr’s bottleneck to send StdText to printer driver
We need to use the Macintosh® toolbox call StdText instead of DrawChar, DrawString, and DrawText to accomplish horizontal scaling and fractional point sizes, but StdText does not work on the LaserWriter® IISC. Is there any workaround?
The problem is that you are calling the low-level bottleneck directly, and the Printing Manager has replaced the bottleneck completely with its own. So when you are actually printing, the print driver will not see your call to StdText. The work-around for this is to call the Print Manager’s bottleneck itself when you are printing. You can do this in the following way:
/* typedef the function */
typedef pascal void (*StdTextProcPtr)( short, Ptr, Point, Point );
void tstDrawStuff( pInfo, thePort, pageNum )
TPrint pInfo;
GrafPtr thePort;
unsigned short pageNum;
{
StdTextProcPtr Proc; /* declare a variable here */
/* do your clipping etc. */
/* TEST -- no good w/o PriMon */
/* do your moveto etc. */
/* Is there a replacement bottleneck ?*/
if ( thePort->grafProcs ) {
Proc = (StdTextProcPtr)thePort->grafProcs->textProc; /* yes, so
grab it */
(*Proc)( strlen("HELLO") , (Ptr) "HELLO", numer, denom );
}
/* else just call standard text */
}
This technique will work in both background and foreground printing. I have tested this solution on the Personal LaserWriter SC and the LaserWriter IINTX, and it prints fine.
Graphics, Imaging & Printing: Printing: System 6.0.x and Color Printer software compatibility
Which versions of Apple® Color Printer software work with which Macintosh® system software versions? Can Apple Color Printer software distributed with System 6.0.7 work with previous system software releases?
The software sent with System 6.0.7 will work with all other System 6.0.x systems. This should be the rule with most other LaserWriter® printer software, as well. There really isn’t any simple way (yet) to match up the version of the printer software with the version of the system software with which it is compatible. Starting with System 7.0, they are hoping to keep this type of system matching standard throughout. This is not a guarantee, just something that is being considered.
Graphics, Imaging & Printing: Printing: Apple IIGS Parallel.Card driver prints to first card found
How can I get the Apple IIGS® Print Manager to print to the parallel card I choose when more than one is in my system?
The port driver provided with the system (the file Parallel.Card) searches for a card with which it can communicate in the PrDevIsItSafe routine, as documented in Apple IIGS Technical Note #36. The search routine scans upward starting with slot one, stopping when it finds a suitable card. The driver will always print to the card in the lower-numbered slot; it has no facilities to let the user choose among all suitable interfaces.
Graphics, Imaging & Printing: Printing: Macintosh System 7 printing architecture is same as System 6
Is the Macintosh® printing architecture different for System 7?
No changes were made to the printing architecture for System 7. Printer drivers were revised for System 7 to support TrueType™, to be completely 32- bit clean, and to fix bugs, but the printing architecture remains the same for System 7.
Graphics, Imaging & Printing: Printing: Macintosh Printing Manager error -8133
What is Macintosh® Printing Manager error -8133?
Printing Manager error -8133 occurs when the PostScript® interpreter of the LaserWriter® (or any other PostScript printer) generates a PostScript error. A description of the PostScript command that caused the error is displayed in the status window. This error often occurs when an application sends PostScript directly to the printer, and that PostScript contains an error. To debug this problem, look at the PostScript generated by the driver. Hold down the Command-F key right after clicking okay in the Print dialog. A file named PostScript0 will be created in the current directory.
Graphics, Imaging & Printing: Printing: Customizing Macintosh printer page sizes
I am printing checks, labels, etc. and the page sizes provided by the Apple® Macintosh® printer driver are not sufficient. How can I customize these page sizes?
Most printer drivers (Apple as well as third-party) do not support customization of their page sizes by an application, because the page sizes provided are usually based on physical characteristics of the device. On some devices, printing outside of the imageable area of the page (specified by prInfo.rPage) can cause physical damage to the printer, so customization of page sizes is generally discouraged. However, there are some valid reasons for wanting to customize the page size of a driver, and there are applications available that provide this feature. Since this is one of the most requested features (by developers), expect to see some Printing Manager support for customizing page sizes in the future. Until then, there are two ways to go:
1. Pound the print record: Most applications that allow you to customize page sizes relay the custom page size information by storing into fields of the print record. When the print record is subsequently passed to PrValidate, the driver recalculates its internal buffers based on the information in the print record. There are a number of reasons, however, that DTS does not support this method. First, the print record is a device-dependent, private structure. Although most of the record is documented in Inside Macintosh, only a few fields are needed by the application at print time, such as rPage, iCopies, and bJDocLoop. There are only a few of these fields that applications need to modify: iCopies if application handles multiple copies, iFstPage/iLstPage if application handles page ranges, and others. Most of the fields in the record are global variables of the current printer driver. When an application starts writing to other fields in the print record, it has to make assumptions about the driver’s interpretation of these changes. Since the print record is “owned” by the printer driver, developers are free to change the format of the record as they require. Although important fields like rPage are likely to remain available for applications to read, writing to these fields may lead to undesirable/unpredictable results. Rather then taking this compatibility risk, DTS recommends that you either wait for a supported solution from engineering, or consider method 2 below.
2. Semi-supported solution: This solution is “semi-supported” because it only works on three of Apple’s devices; ImageWriter® I, II, and LQ. The default page sizes provided by the Apple printer drivers are stored in a resource of type 'PREC' with an ID of 3. The format of this resource is as follows:
PageSizeRecord = RECORD
numItems: INTEGER;
botRights: ARRAY [0..NumPageOptionsZB] OF Point;
titles: PACKED ARRAY [0..0] OF CHAR;
END;
numItems is the number of page sizes displayed in the dialog. The maximum number is six (since there is only room for six radio buttons in the Page Setup dialog). botRights is an array of points specifying the bottom right corner for each page. This corner is specified in 120ths of an inch, and it should define the physical size of the paper, not the imageable area. For example, U.S. Letter is specified as:
bottom = 1320(11"), right = 1020(8.5"). titles is a packed array of page size names. Each name begins with a length byte, followed by the number of characters specified by the length byte. The strings are packed, so
string1[LENGTH(string1)+1]
would reference the length byte of string2. To use this mechanism, your application should create a PREC resource with an ID = 4. You can do this very easily by copying PREC(3). Once you have a copy, you can modify the page sizes as you wish. When the printer driver is called to display the Page Setup dialog, it will first look for PREC(4). If found, it will use it to define the page sizes. If not found, the driver will use the standard sizes in PREC(3). This method is supported only by the Apple ImageWriter drivers. Other drivers (including the LaserWriter® and LaserWriter IISC) will ignore the resource. If you decide to implement this feature in your application, be sure to warn your users that custom page sizes may not be available on all devices. For a Pascal example of this method, send an AppleLink® message to DTS and ask for “PagePounder.”
Graphics, Imaging & Printing: Printing: Low-level Printing Manager interface changes
My Macintosh® application uses the low-level interface to print to the ImageWriter® just fine, but crashes when printing to the LaserWriter®. Why?
The original model documented in Volume II of Inside Macintosh (pages 163-164) for opening and closing the low-level Printing Manager interface looked like this:
PrDrvrOpen;
PrCtlCall(iPrDevCtl, lPrReset, 0, 0);
{ Image data sent here via other control calls... }
PrCtlCall(iPrDevCtl, lPrPageEnd, 0, 0);
PrDrvrClose;
This worked fine on all LaserWriter drivers up to version 5.0. Now in 5.0 and later versions of the driver, applications are required to follow this model (documented in Tech Note #192):
PrDrvrOpen;
PrCtlCall(iPrDevCtl, lPrDocOpen, 0, 0);
PrCtlCall(iPrDevCtl, lPrPageOpen, 0, 0);
{ Image data sent here via other control calls... }
PrCtlCall(iPrDevCtl, lPrPageClose, 0, 0);
PrCtlCall(iPrDevCtl, lPrDocClose, 0, 0);
PrDrvrClose;
This is because the newest LaserWriter driver is actually converting the low level calls into their high-level equivalents before executing them. This makes for a cleaner internal structure for the driver.
Graphics, Imaging & Printing: Printing: Macintosh color printing code sequence
I have an application running in Color on the Macintosh® II. What is the recommended method for printing in Color?
Your application should first call SysEnvirons to check for Color QuickDraw™. If Color QuickDraw is available, you should then check the portBits of the Printing Manager’s GrafPort (returned by PrOpenDoc).
IF printingPort.gPort.portBits.rowBytes < 0 THEN BEGIN
{ Printer driver supports color, use Color Quickdraw calls }
{ to image data. }
RGBForeColor(RGBred);
RGBBackColor(RGBgreen);
MoveTo(100, 100);
LineTo(200, 200);
END ELSE BEGIN
{ Printer driver does not support color, use }
{ Quickdraw color calls or PostScript®... }
PicComment(PostScriptBegin, 0, NIL);
{ Quickdraw representation for ImageWriter® and other }
{ non-PostScript printers. }
ForeColor(redColor);
BackColor(greenColor);
MoveTo(100, 100);
LineTo(200, 200);
{ PostScript representation for imaging with halftones. }
{ This should be used only when the driver for a device }
{ doesn’t support color. See the question, 'How do I }
{ use the PostScript image operator to print halftones?'}
thePSHandle^^ := '.75 setgray 100 100 moveto 200 200 lineto';
PicComment(PostScriptHandle,GetHandleSize(thePSHandle),thePSHandle);
PicComment(PostScriptEnd, 0, NIL);
END;
Graphics, Imaging & Printing: Printing: Update Macintosh color table if printing in color
I’m having trouble printing in color. When I copy a color image from a Macintosh® offscreen pixmap to the printer, I get a black piece of paper. If I draw directly it comes out fine. What am I doing wrong?
When you built your offscreen port and copied the color table from a GDevice, did you change the color table to reflect that the color table is now part of a pixmap? In a GDevice the color table’s value field is zero for all entries, but in a pixmap the value field represents the index value of each color in the table. If the color table has not been converted, printing won’t work properly.
Graphics, Imaging & Printing: Printing: Printing halftone images on the LaserWriter
How can I print halftone images on the LaserWriter®? How do I use the PostScript® “image” operator for printing halftones?
The PostScript “image” operator is similar to the Macintosh® QuickDraw™ CopyBits routine. It can be used by converting a QuickDraw bitmap/pixmap into an image call. This is only necessary if you are printing color information with a PostScript printer driver that doesn’t support Color QuickDraw. LaserWriter drivers up to 5.2 do NOT support Color QuickDraw. If you want to send color information to a LaserWriter with version 5.2 of the driver, you will have to convert your color images into image commands. Before doing this it is important to check the GrafPort returned by PrOpenDoc. If this port is a Color QuickDraw port (for example, portBits.rowBytes < 0) then you should use Color QuickDraw commands and let the driver handle the conversion to PostScript.
About image: The PostScript image operator is used to send bitmaps or pixmaps to the LaserWriter. The image operator can handle depths from one to eight bits per pixel. Our current LaserWriters can image only about 16 shades of gray, but the printed page will look like there’s more. Because the image operator is still a PostScript operator, it expects its data in the form of hexadecimal bytes. The bytes are represented by two ASCII characters(“0”-”9,” “A”-”F”) per byte. The image operator takes these parameters:
width height depth matrix image-data
The first three are the width, height, and depth of the image, and the matrix is the transformation matrix to be applied to the current matrix. See the PostScript Language Reference Manual for more information. The image data is where the actual hex data should go. Instead of inserting the data between the first parameters and the image operator itself, it is better to use a small PostScript procedure to read the data starting right after the image operator. For example:
640 480 8 [640 0 0 480 0 0] {currentfile picstr readhexstring pop} image FF 00 FF 00 FF 00 FF 00...
In the preceding example, the width of the image is 640, the height is 480, and the depth is 8. The matrix (enclosed in brackets) is set up to draw the image starting at QuickDraw’s 0,0(top left of page), and with no scaling. The PostScript code (enclosed in braces) is not executed. Instead, it is passed to the image operator, and the image operator calls it repeatedly until it has enough data to draw the image. In this case, it is expecting 640*480 bytes. When the image operator calls the procedure, it does the following:
1. Pushes the current file which in this case is the stream of data coming to the LaserWriter over AppleTalk®. This is the first parameter to the readhexstring operator.
2. Pushes picstr. picstr is a string variable defined to hold one row of hex data. The PostScript to create the picstr is:
/picstr 640 def
3. readhexstring is called to fill picstr with data from the current file. It begins reading bytes which are the characters following the image operator.
4. readhexstring leaves the string we want, and a boolean that we don’t want, on the stack, so we do one pop to kill off the boolean. Now the string is left behind for the image operator to use.
Using the above PostScript code you can easily print an image. Just fill in the width height and depth, and send the hex data immediately following the PostScript code.
Setting up for image: Most of the users of this technique are going to want to print a Color QuickDraw pixmap. Although the image command does a lot of the work for you, there are still a couple of tricks for performance:
Assume the maximum depth: Since the current version of the image operator has a maximum depth of eight bits/pixel, it is wise to convert the source image to the same depth before imaging. You can do this very simply by using an offscreen GrafPort that is set to eight bits/pixel, and then using CopyBits to do the depth conversion for you. This does a nice job of converting lower resolution images to 8 bits/pixel.
Build a color table: An eight bit deep image can use only 256 colors. Since the image that you are starting with is probably color, and the image you get will be grayscale, you need to convert the colors in the source color table into PostScript grayscale values. This is actually easy to do using the Color Manager. First create a table that can hold 512 bytes. This is two bytes for each color value from 0 to 255. Since PostScript wants the values in ASCII, you need two characters for each pixel. Now loop through the colors in the color table. Call Index2Color to get the real RGB color for that index, and then call RGB2HSL to convert the RGB color into a luminance value. This value is expressed as a SmallFract which can then be scaled into a value from 0 to 255. This value should then be converted to ASCII, and stored at the appropriate location in the table. When you are done, you should be able to use a pixel value as an index into your table of PostScript color values. For each pixel in the image, send two characters to the LaserWriter.
Sending the data: Once you have set up the color table, all that’s left to do is loop through all of the pixels, and send their PostScript representation to the LaserWriter. There are a couple of ways to do this. One is to use the low-level Print Manager interface and stream the PostScript using the stdBuf PrCtlCall. Although this seems like it would be the fastest way, the latest version of the LaserWriter driver (5.0) converts all low-level calls to their high level equivalent before executing them, so the low-level interface is no longer faster than the high level. Another way is to use the high-level Print Manager interface, and send the data via the PostScriptHandle PicComment. This enables you to buffer a large amount of data before actually sending it. Using this second technique, you should be able to image a Macintosh II screen in about 5 minutes on a LaserWriter Plus, and about 1.5 minutes on a LaserWriter II NTX.
Graphics, Imaging & Printing: Printing Resources: Animate! graphics file format
How can I access Brøderbund’s Animate! graphics files from my Apple® II application?
If you’re looking for documentation on the Animate! file format, you will haveto contact Brøderbund software. As the authors of that format, they would be able to give you more information about it.
Graphics, Imaging & Printing: Printing Resources: Identifying Macintosh’s currently selected printer
How can I find out which printer the user has selected with the Macintosh® Chooser? How can I change it without going through the Chooser?
The type of the currently selected printer is stored in the System file in 'STR ' resource ID -8192. This will be the name of the driver selected, such as LaserWriter® or ImageWriter®. The name of the actual printer selected will be in the driver file (same name as the printer type chosen) in 'PAPA' resource ID -8192. Look at this resource with ResEdit™ to see what is in it.
You can change the 'STR ' and 'PAPA' resources, but it may not work now or in the future. WE DO NOT RECOMMEND CHANGING THE SYSTEM FILE OR CIRCUMVENTING THE CHOOSER! The Chooser is a very complicated piece of software, and it has many dependencies. Implementing the chooser within your application would make your application dependent on a particular version of the system software. Like the Chooser, your application would then have to be revised each time a new system is released.
Graphics, Imaging & Printing: Printing Resources: How to save Macintosh Page Setup and Print dialog options
How do I save options set in the Macintosh® Page Setup and Print dialogs?
The only supported method to save the dialog options is to save the Print Record that was passed to the PrStlDialog/PrJobDialog calls. This print record contains the options chosen in the Page Setup and Print dialogs. Although these options are saved in the print record, they cannot be used as defaults for the Page Setup. For example, say the user chooses landscape printing in the page setup dialog, and sets the number of copies to 5 in the print dialog. If the print record is passed to PrStlDialog, the dialog shows that landscape printing was selected in the print record. However, if that print record is passed to PrJobDialog, number of copies is shown as 1, because options in the PrJobDialog are considered to be “job dependent,” as opposed to “document dependent.”
The best method for saving the print record is to save it as a resource in your document’s resource fork. Since the print record is already pointed to by a valid handle, creating a resource is easy. Here are the required steps:
1. Save the refNum returned by CurResFile;
2. Make sure the resource fork of the document file is opened using
OpenResFile (IM I:115).
3. Now that you have a place to put the resource, you must get the resource manager to create it for you. First, pick a type and ID for your resource. You can use the Unique ID function (IM I:121) to generate the ID. Next, call the AddResource procedure (IM I:124). This procedure takes four parameters:
Parameter Type What to Pass
--------------------------
theData Handle The handle to the currently valid print record.
theType ResType The four character resource type you have
chosen.
theID INTEGER The ID returned from the UniqueID function.
name Str255 The name for this resource or '' if none.
4. Call WriteResource (IM I:125), and UpdateResFile (IM I:125) to make sure the new resource gets saved into the file.
5. Reset the currently selected file back to whatever it was before you began the save using UseResFile (IM I:117).
The important things to keep in mind when doing this are:
1. Make your resource type something different than those used by the Print Manager. This prevents the Print Manager from getting confused and grabbing the wrong resource. Types to avoid include 'PREC', 'PDEF', and 'POST'.
2. Don’t make any assumptions about the size of the print record. If you really need to know the size, use GetHandleSize.so that if the record gets bigger in the future, your code will still work.
3. Be sure to pass the record that you get from your document to PrValidate before using it. This ensures that the record gets updated if any changes have been made to record structure or contents since the record was saved.
Graphics, Imaging & Printing: PrintMonitor: Workaround code if Print Monitor changes custom palette
When our application prints with Print Monitor active, Print Monitor changes our custom screen color lookup table (CLUT) created with the Palette Manager.
A solution to your problem, until this Print Monitor problem is fixed, is to save your custom palette and restore it if the Print Monitor changes it. The following code segment does the trick:
<<<< Initialize oldSeed >>>>
oldSeed = (*(*(*GetMainDevice ())-> gdPMap)->pmTable)-> ctSeed;
• • Additional code • •
case updateEvt:
if ((WindowPtr) myEvent.message == myWindow) {
if (oldSeed != (*(*(*GetMainDevice ())-> gdPMap)->pmTable)-> ctSeed)
{
oldSeed = (*(*(*GetMainDevice ())-> gdPMap)->pmTable)-> ctSeed;
ActivatePalette (myWindow);
}
BeginUpdate (myWindow)
• • Additional code • •
If you put this piece of code inside your event loop where you check for update events, it should work without any problems.
Graphics, Imaging & Printing: PrintMonitor: Location for spool files under System 7.0
Is there a recommended location for printer driver writers to put their own spool files?
Place it in the “PrintMonitor Documents” folder within a “personal spool” folder. PrintMonitor will ignore other folders and it will delete its spool file when it was done with it.
The biggest advantage with this approach is that all the spool files end up in the same location, which is probably the best solution for the native user.
There are a few cases when the folder might not be present (such as if the user has deleted it for some reason). Therefore, you should check to make sure that the folder is present before trying to add a file to it. If it is not present, be sure to create it with the exact name; otherwise, PrintMonitor will not be able to find it and will create a second folder with a different name, possibly confusing the native user. Folder management is relatively straightforward with the addition of the “Folder Manager” to System 7.0. The Finder™ chapter in Inside Macintosh Volume 6 contains the details about using it.
Graphics, Imaging & Printing: PrintMonitor: Background printing no longer affects color environment
Why does the color environment of our Macintosh® application get messed when I use background printing on the LaserWriter® II? We are using the Palette Manager. When I trace the code I notice that I am getting an update event for all the windows of the application when the printing completes. Calls to activate the palette (ActivatePalette) and set the windows palette (SetPalette) have no effect. As soon as a window is resized or moved the color environment is corrected.
The problems that you having been encountering with the Print Monitor affecting the color environment after the print job has been completed have been fixed in LaserWriter driver v7.0a12. The LaserWriter driver on the System 7.0 beta CD contains this fix.
This version of the driver will work on Systems 6 and 7, but it cannot be shipped with your application until System 7.0 is final.
Graphics, Imaging & Printing: PrintMonitor: Macintosh PicComments and background printing
My Macintosh® application prints fine when Background Printing is disabled, but doesn’t print or prints blank pages when Background Printing is enabled. Why?
The Printing Manager gets execution time by replacing the grafProcs of the
Printing Manager GrafPort (returned from the PrOpenDoc call). This GrafPort is created by the PrOpenDoc call, and is reinitialized by every call to PrOpenPage. On the LaserWriter® driver with Background Printing enabled, this reinitialization causes the clipping region of the port to be set to (0,0,0,0). On the next call to StdLine or StdText, for example, the Printing Manager notices the zeroed clipping region, and sets it to the rectangle specified by prInfo.rPage in the print record. If your application prints its documents with PostScript® using PicComments, the Printing Manager never gets a chance to define the clipping region. All of your PostScript code is sent to the LaserWriter and executed, but the results are clipped to (0,0,0,0). To work around this problem, you must call at least one Quickdraw™ drawing routine at the beginning of each page. The following is frequently used:
PrOpenPage(...);
MoveTo(-32000, -32000);
Line(0, 0);
{ PostScript code here }
PrClosePage(...);
The MoveTo is needed so that the line is drawn outside of the imageable area of the page, and thus is invisible. The Line call calls the Printing Manager’s version of the StdLine procedure, which defines the clipping region for the port. All subsequent PostScript code will be clipped correctly. Since PrOpenPage resets the clipping region, the MoveTo/Line combination must be done after each call to PrOpenPage.
Graphics, Imaging & Printing: PrintMonitor: SetOrigin and background printing
I have noticed PostScript® graphics printing in different locations depending on whether or not Background printing is enabled on the Macintosh®. What causes this?
In LaserWriter® 4.0 - 5.2, SetOrigin is handled differently when Background printing is enabled. The method used by these drivers is described below:
Background Printing DISABLED: The application calls SetOrigin, and QuickDraw™ responds to the call by adjusting the portRect of the Print Manager’s GrafPort. Since SetOrigin does not cause any grafProcs to run, the Printing Manager doesn’t see this change until the next QuickDraw drawing operation such as DrawString or LineTo. At that time, the Printing Manager notices the change in the portRect, and updates its internal origin. All QuickDraw graphics are now localized to the new origin. All PostScript graphics will also get the localization to the new origin.
Background Printing ENABLED: Because QuickDraw is playing back a picture that was spooled earlier, it handles calls to SetOrigin a little differently. When the SetOrigin call is encountered in a DrawPicture call, the portRect of the GrafPort is NOT updated. Instead, QuickDraw keeps the current origin cached, and offsets each graphic on the fly. Since the portRect was not modified, the Printing Manager does not see the SetOrigin call. Although all QuickDraw objects are still localized correctly (by QuickDraw), PostScript graphics do not move to the new origin. Instead, the application localizes the coordinates of its PostScript graphics. You could also use the technique documented in Technical Note #183.
The implementation of the SetOrigin (IM I:166) and ClipRect (IM I:167) calls has been revised in LaserWriter 6.0. This is a general description of those changes:
LaserWriter 6.0: Both QuickDraw and PostScript coordinates are offset with respect to the origin set by SetOrigin. The driver now inserts a picture comment into the spool file so that the Print Monitor knows that the origin was changed during spooling.
Since applications must support versions of the LaserWriter driver other than 6.0, they should still use the method described in Tech Note #183 to make sure their PostScript is position-independent.
Graphics, Imaging & Printing: PrintMonitor: Macintosh spool file formats aren’t available
What is file format of Macintosh® Printing Manager and LaserShare™ spool files?
Unfortunately, the formats for these files are not currently available, and it is doubtful that they will be made available in the future. Whenever new features are added to LaserShare, the Printing Manager, or other parts of the Macintosh toolbox, it’s not uncommon for these spool file formats to be affected. If the file format were published, and essentially frozen, it would be much harder for engineering to add features. On the bright side, many developers have asked for the format of these files. Rather then just publishing the current file format, engineering would be better off providing routines for reading these files regardless of the current format. This way, applications would have access to the information they need, without being dependent on the file format. If and when such routines become available, they will be documented via a technical note or system software release note.
Graphics, Imaging & Printing: QuickDraw: ditherCopy not supported on LaserWriter or ImageWriter
ditherCopy not supported on LaserWriter or ImageWriter
ditherCopy is not supported on LaserWriters or ImageWriters. On a LaserWriter, ditherCopy gets misinterpreted and inverts the image. On an ImageWriter it’s treated as a srcCopy. The ImageWriter driver doesn’t support color grafPorts, which is the only way to do the pixel image required for ditherCopy. Use srcCopy instead for both printers.
Graphics, Imaging & Printing: QuickDraw: Macintosh QuickDraw and pen characteristic routines
When generating pictures and then looking at the corresponding Macintosh PICT file, we notice that QuickDraw is optimizing PnMode, PnPat, and PnSize. Can you tell us how to stop QuickDraw from optimizing, and how to know when QuickDraw will optimize?
QuickDraw does not optimize away new pen characteristic routines, but it does insert them into pictures just before a drawing routine that uses the pen rather than place them where they are called. Therefore, you may not see your new pen characteristic routine until later in a picture when it is about to be used. Opcodes for pen characteristics are inserted into the picture when they are changed from the previous time they’re used.
Graphics, Imaging & Printing: QuickDraw: Macintosh animation samples
Do you have an example of flicker-free animation on the Macintosh?
We have some good stuff that’s written in MPW Pascal. It’s DTS Sample Code #16, OffSample, and this uses some routines defined in DTS Sample Code #15, OffScreen. Also, the System 7.0 CD sample code folder contains a smaller sample called “GMonde” that uses GWorlds.
Graphics, Imaging & Printing: QuickDraw: Save and restore document window grafPort at print time
DTS’s printing tech note should also probably recommend saving and restoring the document window grafport around printing, in case an error occurs during printing and the printing code leaves the current port set to some trashed value.
You’re right about saving and restoring the grafPort at print time. If you don’t, things could get ugly.
X-Ref:
Macintosh Technical Note #294, “Me and my PIdle Proc…”
Graphics, Imaging & Printing: QuickDraw: Install pIdle proc before calling PrOpenDoc
Macintosh Technical Note #294 says that “When installing your pIdle proc, it must be installed before the application calls PrOpenDoc.” Inside Macintosh Volume II, on the other hand, says, “If you designate a background procedure, you must set pIdleProc *after* presenting the dialogs, validating the print record, and initializing the printing grafPort: The routines that perform these operations reset pIdleProc to NIL,” (page 154), and “PrOpenDoc initializes a printing grafPort for using in printing a document...” (page 159). Who’s right?
The tech note is correct. If you do not install your pIdle proc before PrOpenDoc, you pIdle proc will NOT receive any time.
X-Ref:
Macintosh Technical Note #294, “Me and my PIdle Proc…”
Graphics, Imaging & Printing: QuickDraw: Version 2 PICTs on pre-Color QuickDraw models
Inside Macintosh Volume V says a System 4.1 (and later) patch ensures that version 2 PICTs are displayed correctly on earlier machines that don’t have Color QuickDraw, such as the Macintosh Plus and SE. However, my version 2 PICT, consisting primarily of a PixMap (opcode = $90 since rowbytes <8) displays correctly on a Macintosh IIfx but displays garbage on a Macintosh SE.
The PICT problem you reported is caused by a bug in 6.0.7 QuickDraw. The workaround for the time being is to:
• Use System 7.0, where it’s been fixed, or
• Don’t use opcode $90. Instead, use padding so that opcode $98 can be used. (Opcode $98 is the packed copybits version that works for rowbytes >= 8.) You can do this by creating the picture with a PixMap that’s wider than you actually need, and then use the clip region to clip out the part you don’t need.
Graphics, Imaging & Printing: QuickDraw: Detecting hidden application window or visRgn # portRect
We draw directly to the screen to gain the fastest possible animation speed, and when we need compatibility—such as when windows overlap or for multiple screens—we do use CopyBits. How do we tell whether the window is hidden or that the visible part is not rectangular?
If your window is hidden partially by another applications window or if your layer has been hidden by the process menu, the visRgn of your window’s grafport will not be the portRect anymore. (Keep in mind that if you scroll by modifying the portRect of the grafport, then you’ll have to do a more complex calculation...) Here is a small Pascal routine that returns this information:
Function UseCopyBits(thePort:grafptr):Boolean;
begin
UseCopyBits:= NOT( (thePort^.VisRgn^^.rgnSize=10) and
(thePort^.visRgn^^.RgnBBox=thePort^.PortRect) );
end;
Graphics, Imaging & Printing: QuickDraw: Using dithering and animation on the same Macintosh image
Using dithering and animation on the same Macintosh image
When setting up a dithered grayscale image for subsequent animation (to adjust brightness, for example), a conflict arises between the use of Palette animation and the ditherCopy CopyBits mode.This problem is demonstrated in the develop #5 GiMeDaPalette code sample: If you change srcCopy to ditherCopy in the CopyBits call, then run the program and selected Animate, the resulting image is pure black and white, with what appears to be an attempt to dither with just the black and white color table entries (that are not reserved for animation).
This happens because ditherCopy tries to use the inverse table to do color matching, but when the image is animated, the inverse table colors are limited to just black and white.
To work around the problem, you can jump into the bottlenecks and when you see the PICT hitting the opcode for CopyBits, change the PICT from a srcCopy to a ditherCopy. This way the dithering happens when you do the call to DrawPicture and not later on. This makes it possible to use dithering and animation on the same image.
Graphics, Imaging & Printing: QuickDraw: Gestalt 'qdrw' selector bug and workaround
Why does Gestalt tell me I have Color QuickDraw features on a non-Color QuickDraw machine?
The gestaltQuickdrawFeatures ('qdrw') selector, used for determining your system’s Color QuickDraw features, has a bug that causes it to tell you incorrectly that noncolor machines have color. The fix is quite simple: Gestalt has another selector, gestaltQuickdrawVersion ('qd '), which simply returns the QuickDraw version number. This version number is < gestalt8BitQD for classic QuickDraw and >= gestalt8BitQD for Color QuickDraw (see Inside Macintosh Volume VI, page 3-39, for more information). The trick is to ask Gestalt for the QuickDraw version first; once you’ve determined that you have Color QuickDraw, the 'qdrw' selector is OK to use to find out specifics.
Graphics, Imaging & Printing: QuickDraw: Sending PostScript via PostScriptHandle PicComment
If I use the PostScriptHandle PicComment to send PostScript code to the LaserWriter driver, do I need to open a picture and then draw the picture to the driver, or can I just use the PicComment with no picture open while drawing to the printer’s grafPort?
You don’t need to create a picture with your PicComment in it and draw the picture to the driver. The best method for sending PostScript code to the LaserWriter is to use the PostScriptHandle PicComment documented in Macintosh Technical Note #91, “Optimizing for the LaserWriter—Picture Comments,” as shown below.
PrOpenPage(...)
{ Send some QuickDraw so that the Printing Manager gets a }
{ chance to define the clipping region. }
PenSize(0,0);
MoveTo(0,0);
LineTo(0,0);
PenSize(1,1);
PicComment(PostScriptBegin, 0, NIL);
{ QuickDraw representation of graphic. }
MoveTo(100, 100);
LineTo(200, 200);
{ PostScript representation of graphic. }
thePSHandle^^ := '100 100 moveto 200 200 lineto stroke';
PicComment(PostScriptHandle, GetHandleSize(thePSHandle),
thePSHandl);
PicComment(PostScriptEnd, 0, NIL);
PrClosePage(...)
The above code prints a line on any type of printer, PostScript or not. The first MoveTo/LineTo combination is required to give the LaserWriter driver a chance to define a clipping region. The LaserWriter driver replaces the grafProcs record in the grafPort returned from PrOpenDoc. In order for the LaserWriter driver to get execution time, you must execute a QuickDraw drawing routine that calls one of the grafProcs. In this case, the MoveTo/LineTo combination calls the StdLine grafProc. When StdLine executes, it notices that the grafPort has been reinitialized, and therefore initializes the clipping region for the port. Until the MoveTo/LineTo combination is executed, the clipping region for the port is set to (0,0,0,0). If PostScript code is sent via the PostScriptHandle PicComment before executing any QuickDraw routines, all PostScript operations will be clipped to (0,0,0,0).
The next thing that’s done is to send the PostScriptBegin PicComment. This comment is recognized only by PostScript printer drivers. When the driver receives this comment, it saves the current state of the PostScript device (by executing the PostScript gsave operator), then disables all QuickDraw drawing operations. This way, the QuickDraw representation of the graphic will be ignored by PostScript devices. In the above example, the second MoveTo/LineTo combination is executed only on non-PostScript devices.
The next PicComment is PostScriptHandle, which tells the driver that the data in thePSHandle is to be sent to the device as PostScript code. The driver then passes this code unchanged to the PostScript device for execution. The PostScriptHandle comment is recognized only by PostScript printer drivers.
The last PicComment, PostScriptEnd, tells the driver to restore the previous state of the device (via a PostScript grestore call), and to enable QuickDraw drawing operations.
Since most PicComments are ignored by QuickDraw devices, only the QuickDraw representation is printed. Since PostScriptBegin tells PostScript drivers to ignore QuickDraw operations, only the PostScript representation is printed on PostScript devices. This is a truly device-independent method for providing both PostScript and QuickDraw representations of a document.
Graphics, Imaging & Printing: QuickDraw: Use srcOr instead of srcCopy for Macintosh text drawing
DrawText with srcCopy takes six times as long as with srcOr now that my Macintosh is running System 7. Why is this so slow? Is this a bug in System 7?
It’s true that srcCopy is slower than srcOr when handling text, especially in color mode. This loss in speed occurs because CopyBits is a lot smarter than it used to be. It can handle foreground and background colors a lot better, but that improvement came at the cost of speed. Our recommended method for drawing text is to erase before drawing, and use srcOr to draw, not srcCopy. Alternatively, you could draw colorized text in srcOr mode off screen and then use CopyBits to draw it on the screen in srcCopy mode without colorization.
Graphics, Imaging & Printing: QuickDraw: Dimming text in an Apple IIGS application
How can I “dim” text in my Apple IIGS application, similar to the way the Toolbox dims menu titles and menu options, and the way that HiliteControl dims a button name?
Dimming text is a piece of cake. Here’s how the Apple IIGS Menu Manager does it in both 640 and 320 mode. The same thing works great for both.
1. Calculate the bounding box of the text.
2. Fill it with the proper background color for the operation in question.
3. Draw the text.
4. Execute code that looks something like this:
pea dimmed>>16
pea dimmed
_SetPenMask ;Set the pen mask to "dimmed" mask
pea textRect>>16
pea textRect ;Push pointer to text boundary rect
lda backColor ;Get text's background color
and #$00FF ;Always solid
; Here you need to do something in your code to get the
; appropriate pattern for the text you're drawing. This will be
; one of the 16 patterns in the 512-byte table, starting with 16
; bytes of $00, 16 bytes of $11, and ending with 16 bytes of $FF.
; We leave the routine GetColorPtr for you to code, but our
; example assumes it returns the pointer we need in A (low word)
; and X (high word).
jsr GetColorPtr ;(see above)
phx ;high word
ph ;low word
_FillRect ;Fill will be dithered
pea nor_mask>>16 ;Reset drawing mask to normal solid
pea nor_mask
_SetPenMask
rts
textRect DC.B $00,00,00,00 ;Put your rectangle here
backColor DC.W $0000 ;Background color of text to dim
dimmed DC.B $55,$AA,$55,$AA,$55,$AA,$55,$AA
nor_mask DC.B $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
Yes, it’s really this easy!
Graphics, Imaging & Printing: QuickDraw: GetGWorldPixMap bug and workaround
Why does GetGWorldPixMap (when called on a Macintosh II, IIcx, or IIx running system software version 6.0.5 or 6.0.7 with 32-Bit QuickDraw 1.2) return a combination of the device field (two bytes) and the first two bytes of the portPixMap field? Is this a bug?
Your analysis of GetGWorldPixMap is exactly right: It doesn’t work correctly in system software version 6.0.5 and 6.0.7 with 32-Bit QuickDraw 1.2. It returns a value that’s two bytes before the value it’s supposed to return.
The solution is to use GWorldPtr->portPixMap instead of GetGWorldPixMap. It’s safe to do this, but you should use GetGWorldPixMap under System 7. Not only is the bug fixed there, but dereferencing the port is dangerous under System 7 because it may not be CGrafPort. Use Gestalt with the gestaltQuickdrawVersion selector to determine whether you can use GetGWorldPixMap. If Gestalt returns a value from gestalt8BitQD ($0100) through gestalt32BitQD12 ($0220), then GetGWorldPixMap either doesn’t exist or is the buggy version. If it returns gestalt32BitQD13 ($0230) or higher, then GetGWorldPixMap does exist and works correctly. Interestingly, GetGWorldPixMap can be called on a black-and-white QuickDraw machine under System 7. It returns a handle to a structure which should be treated as a BitMap structure, though there are some undocumented fields after the normal BitMap fields. To tell whether GetGWorldPixMap is available on a black-and-white QuickDraw machine, you must check the system software version by calling Gestalt with the gestaltSystemVersion selector. If it returns $0700 or higher, GetGWorldPixMap is available.
Graphics, Imaging & Printing: QuickDraw: Code for reversing Macintosh PICT images
Is there a simple way to put PICT images up in mirror image format, or is there sample code showing how to flip an offscreen bitmap?
There is no easy way to do this, nor do we have sample code showing how to flip an offscreen bitmap. Indeed, the best way to do what you want is to draw it to an offscreen pixel map and reverse it.
If you are using Color QuickDraw, always draw it to an 8-bit-per-pixel offscreen bitmap, and then the reverse is a very simple task. Here is some sample Pascal code that might roughly do what you want, with the following assumptions:
1. You are going to add error checking where appropriate.
2. Rowbytes correspond exactly to pixel width of the port.
3. The port is 8 bits deep.
4. You add the code to make this sketch work.
5. The origin of your offscreen port is (0,0).
Procedure FlipScanLine(theV:Integer; thePort:cGrafPtr);
{ Given any scan line number in the indicated port, this routine }
{ will flip that scan line horizontally. This routine assumes that } { you have made sure that scan line theV exists. }
type ScanLn=Packed Array [0..0] of Byte;
ScanPtr=^ScanLine;
var thePixMap:PixMapPtr;
Index,Size:Integer;
ThisScanLine:ScanPtr;
TempPixel:Byte;
Begin
thePixMap:=thePort^.PortPixMap^;
{ First create a pointer to the scan line we are currently }
{ reversing. }
ThisScanLine:=ScanPtr(thePixMap^.BaseAddr);
ThisScanLine:=ScanPtr(ord4(ThisScanLine)+(thePixMap^.RowBytes*theV));
{ Now simply reverse all the bytes. }
{ The scan line is simply an array [0..RowBytes] of Byte, and }
{ since this is 8 bits per pixel, each one is a single pixel.}
Size:=thePixMap^.RowBytes;
For Index:=0 to (Size div 2) do
begin
tempPixel:=ThisScanLine^[Index];
ThisScanLine^[Index]:=ThisScanLine[Size-Index-1];
ThisScanLine^[Index]:=tempPixel;
end;
end;
This same procedure can be used also to swap a 1-, 2- or 4-bit-per-pixel
pixmap if you add a function that accepts a byte and swaps the pixels in it.
Graphics, Imaging & Printing: QuickDraw: Macintosh picture (PICT) 90-degree rotation
Macintosh picture (PICT) 90-degree rotation
The trick for rotating a Macintosh QuickDraw picture 90 degrees is to intercept all bottlenecks and exchange the x and y coordinates. Then, call OpenPicture to receive the rotated picture, call DrawPicture(unrotatedPicture), and then call ClosePicture on the rotated picture. You’re done! QuickDraw spins out the DrawPicture call into its component parts, but runs each component through the bottlenecks first, so they get rotated (by YOUR bottleneck intercepts) and stuck into the new picture, already rotated.
Here‘s a bottleneck intercept for StdLine that rotates a PICT composed entirely of Line commands (which depend on the current pen position):
procedure MyLineProc(newPt: point);
var
tempV : integer;
begin
tempV := thePort^.pnLoc.v; { Swap current pen location
coordinates }
thePort^.pnLoc.v := thePort^.pnLoc.h;
thePort^.pnLoc.h := tempV;
tempV := newPt.v; { Swap destination pen location
coordinates }
newPt.v := newPt.h;
newPt.h := tempV;
StdLine(newPt);
tempV := thePort^.pnLoc.v; { Restore current pen location
coordinates }
thePort^.pnLoc.v := thePort^.pnLoc.h;
thePort^.pnLoc.h := tempV;
end;
Notice that the start coordinates as well as the destination coordinates must be swapped before calling StdLine. The resulting pen location is swapped back again after the operation, so the port looks like it should if unrotated drawing were performed. For things that don’t depend on the current pen location, things are simplified a little bit.
You’ll still need bitmap rotation code for the StdBits and StdText intercepts.You might do StdText by setting the port to an offscreen one you create earlier, calling QuickDraw’s StdText, and then calling your bitmap rotation code to copy it into the destination.
Graphics, Imaging & Printing: QuickDraw: System 7 TextMode problem and workaround
Our application uses the TextMode (blend + mask) as documented in Inside Macintosh® Volume V (blend is equal to the current ditherCopy constant) to make translucent text. Under System 7, this transfer mode causes garbage to appear when the text is drawn. Is there a way to work around the problem? Will there be a fix?
The problem you are seeing is due to the use of CopyDeepMask instead of the old-fashioned CopyBits to do the job. It is being studied now, and the hope is that it will work as advertised in a future release. One workaround is to render the text to an off-screen pixmap and then call CopyBits (using blendMode) to actually put it in the picture.
Graphics, Imaging & Printing: QuickDraw: CopyBits bug and workaround
Has anyone run across what I’m told is a bug in CopyBits? It works like this: In the deep, dark workings of CopyBits, some routine tries to read the two bytes preceding the baseAddress of the source PixMap. If the baseAddress is at the start of a card’s NuBus™ space and there isn’t a card filling the adjacentspace, this causes a bus error! Has anyone found a good workaround?
The short answer is: you’re right. QuickDraw™ inadvertently reads from memory below the base address of a pixmap. The workaround is to place the video base address 32 bytes into the RAM on the card; if the card you’re using doesn’t have this workaround, there’s nothing you can do other than making sure there’s a card in the next-lower slot.
Graphics, Imaging & Printing: QuickDraw: Construct a 'clut' instead of changing b/w palette entries
How can I change the first and last (white and black) entries in a Macintosh® palette?
The answer to your question about changing the black and white entries in a palette is a little strange. You can’t simply change the palette associated with an on-screen window, because too many portions of the Toolbox/OS assume that the first entry is white and the last entry is black.
However, what you _can_ do is create an off-screen GWorld and construct a 'clut' for it that does what you want. Creating the 'clut' is fairly straightforward:
/* Making a reversed gray-scale color table */
CTabHandle offColors;
offColors = (CTabHandle) NewHandleClear (sizeof (ColorTable) + 255 *
sizeof (ColorSpec));
(**offColors).ctSize = 255;
for (index = 0; index <= (**offColors).ctSize; index++)
{
(**offColors).ctTable [index].value = index;
(**offColors).ctTable [index].rgb.red = (index << 8) | index;
(**offColors).ctTable [index].rgb.green = (index << 8) | index;
(**offColors).ctTable [index].rgb.blue = (index << 8) | index;
}
(**offColors).ctFlags = 0;
(**offColors).ctSeed = GetCTSeed ();
Note that using this 'clut' with an off-screen GWorld will work fine _except_ if you attempt to draw text into the GWorld. Apparently drawing text off screen carries the same assumptions that all drawing does on screen.
Once you have done your off-screen drawing with the reversed 'clut' as described above, all that remains is to CopyBits from your off-screen GWorld to your on-screen window. Your on-screen window will need the appropriate palette. Fortunately, constructing that palette from the 'clut' is trivial:
/* Make a palette out of it */
aPalette = NewPalette (offColors, (**offColors).ctSize + 1, pmTolerant, 0);
Attaching this palette to the window will cause the correct remapping to occur when you CopyBits from the GWorld to the window, and everything should look just fine.
Graphics, Imaging & Printing: QuickDraw: Updating Macintosh cursor without mouse competition
How can I programmatically move the Macintosh® mouse without the real mouse interfering?
The real answer to your question is twofold: First, you can do exactly what you want to do with the sample included below. HOWEVER, this is not a good thing to do, it would be better if you took the solution used in Apple’s Guided Tour disks: Always hide the cursor and then decouple the cursor from the mouse. Then, instead of using the system’s cursor, simply draw your own “cursor” using QuickDraw and treat it as a little animated bitmap on the screen. This avoids all the problems that you have with the mouse competing. (Apple does update the mouse globals with the mouse position so that other things function correctly.)
Now, as promised, here is the way to do what you want using the real cursor. As you have discovered, setting the crsrCouple variable to false prohibits the mouse from affecting the cursor; unfortunately, it also prohibits the jcrsrTask routine from drawing the cursor. The solution to this is to set crsr couple to true, call the cursor drawing routine jCrsrTask yourself, and then set the crsrCouple variable to false, as shown below:
procedure callcrsr;
inline $2078 ,$08EE ,$4E90;
{ move.L jcrsrTask,A0
jsr (A0) }
Procedure FudgeMouse;
type PointPtr=^Point;
var RawMouse:PointPtr;
MTemp:PointPtr;
RandPt:Point;
CrsrNew:ptr;
CrsrCouple:ptr;
fred:Longint;
begin
RawMouse:=PointPtr($82C);
MTemp:=PointPtr($828);
CrsrNew:=ptr($8CE);
CrsrCouple:=ptr($8CF);
RandPt:=RawMouse^;
repeat
RandPt.h:=RandPt.h+1;
RandPt.V:=RandPt.v+1;
RawMouse^:=RandPt;
MTemp^:=RandPt;
CrsrNew^:=1;
CrsrCouple^:=1;
callCrsr;
crsrCouple^:=0;
repeat until fred<tickCount;
fred:=tickCount+3;
until Button;
crsrCouple^:=1;
end;
Graphics, Imaging & Printing: QuickDraw: Techniques for graying Macintosh text
How do I draw grayed-out text on the Macintosh®, like the text for disabled buttons or menu items?
There are currently two different kinds of grayed text: First, there’s “patterned” gray, where every other dot is missing. This really only looks good with Chicago or other heavy fonts and was always used for graying out menus and controls in system software through 6.0.x, and is still used in 7.0 when the screen is set to less than 4 bits deep. This is done by first drawing the text in a normal, srcCopy transfer mode. Then a gray rectangle is drawn over the text using the patBic mode. This “erases” half the bits in the text, and is rapid enough that there is very rarely any flicker.
The second kind of text is the actually gray text, which is used in System 7 on screens that are 4 bits deep or deeper for menus, controls, and other grayed text. To draw this text, just call GetGray (as documented on page 17-27 of Inside Macintosh, Volume VI) to get an appropriate gray. Then draw the text in that color.
Graphics, Imaging & Printing: QuickDraw: Use assembly to flip a 24-bit off-port color PixMap
What’s the best approach to horizontally flip a 24-bit off-port color PixMap?
Unfortunately, you won’t be able to use CopyBits for this kind of procedure; you’ll have to write your own routine to move each pixel. I’d suggest doing this in assembly language to squeeze the best possible performance out of your code.
Graphics, Imaging & Printing: QuickDraw: Drawing to off-screen bit maps allocated by 8*24 GC card
Can we use non-QuickDraw™ drawing routines in off-screen BitMaps allocated by the Macintosh® 8•24 GC accelerator card?
The 8•24 GC card is caching your GWorld onto the card so it can manipulate it as quickly as possible. As a result your GWorld could end up in 32-bit address space, and if you happen to be running in 24-bit mode you’ll be writing to the wrong address.
The solution is to get the address of the PixMap right before you write to it using GetPixMapAddr, swap over to 32-bit mode (call _SwapMMUMode), do your thing, and then swap back to the original mode so your machine doesn’t croak. The way to accomplish this is as follows:
baseAdd = GetPixBaseAddr(MyGWorld->portPixMap);
theMode = true326;
SwapMMUMode(&theMode); /* returns old mode and sets new */
…
Do_your_stuff();
…
SwapMMUMode(&theMode); /* leaves it the way it was */
Graphics, Imaging & Printing: QuickDraw: CopyBits maps source PixMap colors to GDevice inverse table
I’m trying to draw off screen so I made my own CGrafPort, PixMap, and color table, but when I draw into it, the colors come out all wrong. What’s going on here?
It’s a very common misconception that CopyBits maps the colors available in the source PixMap’s color table to the colors available in the destination PixMap’s color table.
What actually happens is that CopyBits maps the colors in the source PixMap to the colors available in the current GDevice’s inverse table. See Inside Macintosh, Volume V, pages 137 through 139 for a description of inverse tables. Inverse tables is a backwards color table. With a color table, you use a pixel value as an index into the table to return a color. With an inverse table, you use a color-like value as an index into the table to return a pixel value. When CopyBits maps colors from one pixel map to another, it takes a source pixel value, uses the source PixMap’s color table to get the corresponding color, and uses that color as an index into the current GDevice’s inverse table to get the pixel value of the closest color in the destination PixMap’s color table.
Generally speaking, every conceivable color table has exactly one conceivable inverse table. If you alter the contents of a color table, then the inverse table must likewise be altered. It’s just like numbers: for any number you give me, I can give you its negative. For any color table you give me, MakeITable can give you its inverse table. MakeITable is documented in Inside Macintosh, Volume V, page 142.
Think of the current GDevice as an implied parameter to CopyBits. If you don’t deal with GDevices at all, then the current GDevice is always the main screen’s GDevice as far as you’re concerned. Color QuickDraw often switches between different screens’ GDevices so that you can draw to multiple screens, but that’s all handled behind your back. If you create a PixMap, give it a color table, and CopyBits to it, then the main screen’s GDevice’s inverse table is used to map colors from the source PixMap. That’s OK as long as your destination PixMap’s color table is compatible with the main screen’s inverse table. If you change the depth and/or color table of the main screen, and then still CopyBits to this same PixMap with the same old depth and color table, then things won’t work correctly because the main screen’s GDevice’s inverse table changes, making it incompatible with your destination PixMap’s color table. This problem usually manifests itself as incorrect colors, but it can result in crashes.
To fix this, you’ll have to remove your reliance on the main screen’s GDevice. To do that you’ll have to make your own GDevice. There’s a routine called NewGDevice, but it always makes the GDevice in the system heap. Instead, you should just call NewHandle to allocate a GDevice record yourself. Here’s what the fields should hold:
gdRefNum - The GDevice has no driver, so set this to zero.
gdID - It doesn’t matter what this is set to — might as well set it to zero.
gdType - Set this to 2 if the off-screen uses direct colors (16 or 32 bits per pixel) or 0 if the off-screen uses a color table (1 through 8 bits per pixel).
gdITable - Allocate a small (maybe just a 2-byte) handle for this field. After you’re done setting up this GDevice and your off-screen PixMap, color table (if any) and CGrafPort, then set this GDevice as the current GDevice by calling SetGDevice. Then call MakeITable, passing it NIL for both the color table and inverse table parameters, and 0 for the preferred inverse table resolution.
gdResPref - I’d guess that more than 99.9% of all inverse tables out there have a resolution of 4. Unless you have some reason not to, I’d recommend the same here.
gdSearchProc - Set to NIL. Use AddSearch if you want to use a SearchProc.
gdCompProc - Set to NIL. Use AddComp if you want to use a CompProc.
gdFlags - Set to 0 initially, and then use SetDeviceAttribute after you’ve set up the rest of this GDevice.
gdPMap - Set this to be a handle to your off-screen PixMap.
gdRefCon - Set this to whatever you want.
gdNextGD - Set this to nil.
gdRect - Set this to be equal to your off-screen PixMap’s bounds.
gdMode - Set this to -1. This is intended for GDevices with drivers anyway.
gdCCBytes - Set to 0.
gdCCDepth - Set to 0.
gdCCXData - Set to 0.
gdCCXMask - Set to 0.
gdReserved - Set to 0.
For gdFlags, you should use SetDeviceAttribute to set the noDriver bit and the gDevType bit. You should set the gDevType bit to 1 even if you have a monochrome color table. The 0 setting was only used when monochrome mode was handled by the video driver, and 32-Bit QuickDraw eliminated that convention. Your GDevice doesn’t have a driver anyway.
Once this is done, the GDevice and the off-screen PixMap should be treated as inseparable. When you CopyBits or draws into the PixMap, first call SetGDevice to set its GDevice as the current GDevice. When that’s done, call SetGDevice to restore the previous GDevice. Doing this insulates you from changes in a screen’s GDevice.
If you alter your PixMap’s color table, you should make sure you update the ctSeed of that color table, either by assigning to it the result of GetCTSeed (documented on page 143 of Inside Macintosh, Volume V) or by passing a handle to the color table to CTabChanged. The next time that PixMap is drawn into, Color QuickDraw will update your GDevice’s inverse table automatically when it realizes that the ctSeed is different from the current GDevice (which had better be yours) inverse table’s iTabSeed.
GWorlds work this way on Color QuickDraw machines. Every GWorld comes with a PixMap and a GDevice. When you call SetGWorld, that sets both the GWorld and its GDevice as current.
Graphics, Imaging & Printing: QuickDraw: Why PlotCIcon requires GetCIcon instead of Get1Resource
Why do I have to use GetCIcon(resID) instead of Get1Resource('cicn',resID) for PlotCIcon to work correctly?
You apparently thought something that, at first, I thought also: that GetCIcon(resID) is just a utility routine that translates to Get1Resource('cicn',resID). However, this is not the case; GetCIcon not only gets the 'cicn' resource, but it also performs some minor surgery on the results, fills in some placeholder fields in the resource data, and the like. Basically, PlotCIcon can’t work without the things that GetCIcon does.
Graphics, Imaging & Printing: QuickDraw: Macintosh Color QuickDraw and packed PICTs
Does Macintosh® 32-Bit QuickDraw™ support packed PICTs? What’s the technique for saving packed PICT formats? What compression schemes are supported?
Color QuickDraw has always supported packed PICTs. See Inside Macintosh, Volume V, for details on how CLUT PixMaps are packed. Under 32-Bit QuickDraw, to pack direct RGB PixMaps in PICTs, call CopyBits with the packType field in the source PixMap set to one of the following constants that apply to direct RGB PixMaps:
0 - default packing (pixelSize 16 defaults to packType 3 and pixelSize 32 defaults to packType 4)
1 - no packing
2 - remove pad byte (32-bit pixels only)
3 - run-length encoding by pixel size chunks (16-bit pixels only)
4 - run-length encoding, all of one component at the time, one scan line at a time (24-bit pixels only)
Scheme 4 will store the alpha channel also if cmpCount is set to to four. PackSize is not used and should be set to zero for compatibility reasons. These are the only compression techniques supported at this time.
Graphics, Imaging & Printing: QuickDraw: Calling InitCursor instead of SetCursor
Is it legal to call InitCursor instead of SetCursor(arrow) when I want to set the cursor to an arrow (after my normal one-time program initialization code, in my UpdateCursor routine)? The only reason I'd want to do such a skanky thing is to save code. Calling a trap with no parameters is less code than one with parameters. What, exactly, if anything, does InitCursor do besides setting the cursor to an arrow and setting the cursor level to zero?
There's no problem at all with this, as long as you are aware that the hidden, busy, and obscured states are cleared when you call InitCursor, so if the cursor was hidden or obscured for good reason it'll suddenly reappear. It also gets the arrow from QuickDraw™, of course, but that's not a problem.
Graphics, Imaging & Printing: QuickDraw: PICT fontName opcode
Is there an up-to-date canonical source for PICT opcodes? In “Night of the Living Disc,” as far as I can see, the only list of PICT opcodes is in Macintosh® Tech Note #21, which does not mention opcode $2C. It appears that opcode $2C concerns font names. I recall seeing a patch for PictDetective named "fontnameop" or something like that. However I can't be sure that $2C is the only new opcode.
The fontName opcode is documented in Tech Note #275. Note also that since the introduction of 32-Bit QuickDraw™ there are two more bitmap opcodes for direct RGB PixMaps $009A (DirectBitsRect) and $009B (DirectBitsRgn). The QuickDraw section of Inside Macintosh Volume VI has all these opcodes listed in a single place, making it easier to get the necessary info. Here is the info on font names and pictures from Tech Note #275:
PICTs Contain Font Name Information
Every time you draw text inside of an _OpenPicture and _ClosePicture pair, QuickDraw stores the name of the current font and uses it when playing back the picture. The opcode used to save this information is $002C and its data is as follows:
PictFontInfo = Record
length : Integer; { length of data in bytes }
fontID : Integer; { ID in the source system }
fontName : Str255;
END;
QuickDraw saves this information only one time for each font used in a picture. When QuickDraw plays back a picture, it uses the fontID as a reference into the list of font names which are used to set the correct font on the target system.
For example, the following code:
GetFNum('Venice', theFontID); { Set a font before opening PICT}
TextFont(theFontID);
pHand2 := OpenPicture (pictRect);
MoveTo(20,20);
DrawString(' Better be Venice');
GetFNum('Geneva', theFontID);
TextFont(theFontID);
MoveTo(20,40);
DrawString('Geneva');
GetFNum('New York', theFontID);
TextFont(theFontID);
MoveTo(20,60);
DrawString('New York');
GetFNum('Geneva', theFontID);
TextFont(theFontID);
MoveTo(20,80);
DrawString('Geneva');
ClosePicture;
generates a picture containing font information like this:
OpCode 0x002C {9,
"0005 0656 656E 6963 65"} /* save current font */
TxFont 'venice'
DHDVText {20, 20, " Better be Venice"}
OpCode 0x002C {9, /* save next font name */
"0003 0647 656E 6576 61"}
TxFont 'geneva'
DVText {20, "Geneva"}
OpCode 0x002C {11, /* ditto */
"0002 084E 6577 2059 6F72 6B"}
TxFont 'newYork'
DVText {20, "New York"}
TxFont 'geneva' /* second Geneva does not
need another $002C guy */
DVText {20, "Geneva"}
This feature works regardless of the type of picture being saved, including old style PICTs in a black-and-white port. Using _OpenCPicture instead of _OpenPicture to start a recording session results in the same functionality.
Graphics, Imaging & Printing: QuickDraw: BitMapToRgn is available for nonColor QuickDraw Macintosh models
Is _BitmapToRegion available on any pre-System7 nonColor QuickDraw™ configurations such as the Macintosh® Classic, Plus, or SE? If not, is source or a library module available so that I don't have to take the time and compatibility risk of rolling my own?
BitMapToRegion works on pre-color Macintosh systems. You can license BitMapToRegion from
Software Licensing
Apple Computer, Inc.
20525 Mariani Ave. MS:38-I
Cupertino, CA 95014
AppleLink: SW.LICENSE
Phone:(408) 974-4667
Graphics, Imaging & Printing: QuickDraw: Macintosh OpenCPicture 72 dpi calculation bug
The 32-Bit QuickDraw™ _OpenCPicture call incorrectly calculates the 72 dpi frame width if the height of the native resolution srcRect exceeds 910 dots. To work around this problem, I calculate the 72 dpi frame independently, and store it in the PicHandle returned by _OpenCPicture.
It’s a known bug that under Macintosh® Systems 6.0.5 and 6.0.7 with 32-Bit QuickDraw 1.2, OpenCPicture doesn’t properly calculate the right coordinate of the 72 dpi picFrame if the height of the srcRect (native resolution rectangle) multiplied by 72 exceeds $0000FFFF. That works out to a maximum height of 910 pixels, just as you found. This bug is fixed in System 7.0, but gestaltQuickDrawVersion returns $0220 both under Systems 6.0.5 and 7.0, so you can’t tell whether the bug is fixed that way. Instead, you should use Gestalt with the gestaltSystemVersion selector. If the returned value is $0700 or greater, then let OpenCPicture handle the picFrame calculation; otherwise you should do the calculation yourself.
Graphics, Imaging & Printing: QuickDraw: Saving 32-bit Macintosh PICTs
I am using a packType=4 and have several questions about saving Macintosh® 32- bit images in a PICT format:
(1) What are the ramifications of using cmpCount=3 as opposed to cmpCount=4?
(2) How is the pixData actually stored? According to several references, each line is run-length encoded; that is, [byteCount][data]. If rowBytes>250 then byteCount is a word. After looking at several examples, I came to the conclusion that you are actually using packBits and that the term “run-length” encoded is a misnomer.
(1) The difference between using cmpCount=3 or cmpCount=4 is that in the first case only the R, G and B values are stored in the picture; in the second case QuickDraw stores in the picture the alpha channel plus R, G and B. cmpCount=4 can be used when it is important to also save the alpha channel (as when you have some flags stored there).
(2) Unless rowBytes is less than 8, the PixMap is compressed using PackBits, and the length is a word or a byte depending on rowBytes, but it always refers to the number of bytes comprising one scan line. My guess is that “run-length encoding” refers to the fact that pictures have data organized one row at a time.
To show how direct RGB PixMaps are stored inside a picture, I am including the decoding of a picture that I created to show how the different packing schemes change the resulting PixMap opcode data. First I created a direct RGB PixMap and drew three lines into it. The first line is 8 pixels long with a color of {0x1111,0xAAAA, 0x7777}, the third line is 8 pixels of {0xFFFF, 0x3333, 0xBBBB} and the line in between is two pixels of the first color then two pixels of the second color and so on until you make 8 pixels. Then I created a picture made of CopyBits calls copying the same lines but using different packing schemes. Finally I dumped the contents and the result is what you see here. I have put comments I think help make it clear how the packing scheme of choice changes the results.
I recommend that you have the Inside Macintosh Volume V QuickDraw™ chapter at hand to check the opcodes and data associated with them. If you had Inside Macintosh Volume VI then you wouldn't need to also check the 32-Bit QuickDraw docs for the direct RGB PixMap opcodes. Technical Note #171 gives details on how the packed data is arranged.
0256 0000 0000 0008 0008 /* size and rect */
0011 02FF 0C00 FFFF FFFF /* PICT2 Header */
0000 0000 0000 0000 0008
0000 0008 0000 0000 0000
001E /* Default hilite */
001A FFFF 3333 BBBB /* RGB Fore Color */
0001 000A 8001 8001 7FFF 7FFF /* ClipRgn */
009A /* direct pixels opcode; see IM VI QD
chapter for details */
0000 00FF 8020 0000 0000 0003 0008 0000 /* See IM V or VI
QuickDraw chapter */
0001 0000 0000 0048 0000 0048 0000 0010 /* packType 0001 = no
packing */
0020 0003 0008 0000 0000 006D A7DC 0000
0000 0000 0000 0003 0008 0000 0000 0003
0008 0000
0011 AA77 0011 AA77 0011 AA77 0011 AA77 /* line one xRGB after
xRGB */
0011 AA77 0011 AA77 0011 AA77 0011 AA77
0011 AA77 0011 AA77 00FF 33BB 00FF 33BB /* second line same */
0011 AA77 0011 AA77 00FF 33BB 00FF 33BB
00FF 33BB 00FF 33BB 00FF 33BB 00FF 33BB /* third line same */
00FF 33BB 00FF 33BB 00FF 33BB 00FF 33BB
009A /* same direct pixels
opcode */
0000 00FF 8020 0000 0000 0003 0008 0000
0002 0000 0000 0048 0000 0048 0000 0010 /* packType 2 = fourth
byte off*/
0020 0003 0008 0000 0000 006D A7DC 0000
0000 0000 0000 0003 0008 0003 0000 0006
0008 0000
11AA 7711 AA77 11AA 7711 AA77 /* one line of RGB
after RGB */
11AA 7711 AA77 11AA 7711 AA77 /* compare with
previous*/
11AA 7711 AA77 FF33 BBFF 33BB /* same here*/
11AA 7711 AA77 FF33 BBFF 33BB
FF33 BBFF 33BB FF33 BBFF 33BB /* and here */
FF33 BBFF 33BB FF33 BBFF 33BB
009A /* bits opcode */
0000 00FF 8020 0000 0000 0003 0008 0000
0004 0000 0000 0048 0000 0048 0000 0010 /* packType 4 =
pack */
0020 0003 0008 0000 0000 006D A7DC 0000 /* componentCount = 3 */
0000 0000 0000 0003 0008 0006 0000 0009 /* R,G and B separated */ 0008 0000
/* for details on packed data see
Tech Note #171 */
06 /* first line made of 6 bytes
including count */
F9 11F9 AAF9 77 /* -(-7)+1 of 11, -(-7)+1 of AA, and
-(-7)+1 of 77 -> 8 RGB triplets */
19 /* second row made of $19 bytes */
1711 11FF FF11 11FF FFAA AA33 33AA AA33 3377 77BB BB77 77BB BB
/* $17+1 unpacked values */
06 /* third line same as first */
F9FF F933 F9BB /* repeated R and B and G values */
009A /* bits opcode again */
0000 00FF 8020 0000 0000 0003 0008 0000
0004 0000 0000 0048 0000 0048 0000 0010 /* same packing = 4 but*/
0020 0004 0008 0000 0000 006D A7DC 0000 /* component count = 4*/
0000 0000 0000 0003 0008 0009 0000 000C /* alpha channel, R, G,
and B */
0008 0000
08 /* first line */
F9 00F9 11F9 AAF9 77
/* same as before but packing the high byte (00
value) also */
1B /* second line first has -(-7)+1 '00' and then
the same line as above */
F900 1711 11FF FF11 11FF FFAA AA33 33AA AA33 3377 77BB BB77 77BB BB
08 /* third line same as first */
F900 F9FF F933 F9BB
00FF /* end of PICT */
A section of the code that produces this picture follows:
RGBColor oneColor = {0x1111, 0xaaaa, 0x7777},
twoColor = {0xffff,0x3333,0xbbbb};
SetGWorld(GgwPtr, nil); /* set the offscreen GWorld */
if ( LockPixels(GgwPtr -> portPixMap) )
{
EraseRect(&(GgwPtr->portRect));
RGBForeColor(&oneColor);
MoveTo(0,0);
LineTo(7,0);
MoveTo(0,1);
LineTo(1,1);
RGBForeColor(&twoColor);
MoveTo(2,1);
LineTo(3,1);
RGBForeColor(&oneColor);
MoveTo(4,1);
LineTo(5,1);
RGBForeColor(&twoColor);
MoveTo(6,1);
LineTo(7,1);
MoveTo(0,2);
LineTo(7,2);
SetRect(&localR,0,0,8,3);
rr = localR;
p = OpenPicture(&(GgwPtr->portRect));
/* first no packing */
(*(GgwPtr -> portPixMap)) -> packType = 1;
CopyBits((*(GgwPtr -> portPixMap)),(*(GgwPtr -> portPixMap)),
&rr,&localR,srcCopy,nil);
/* second pack 2: remove alpha chanel */
OffsetRect(&localR,0,3);
(*(GgwPtr -> portPixMap)) -> packType = 2;
CopyBits((*(GgwPtr -> portPixMap)),(*(GgwPtr -> portPixMap)),
&rr,&localR,srcCopy,nil);
/* third pack 4: packing component by component */
OffsetRect(&localR,0,3);
(*(GgwPtr -> portPixMap)) -> packType = 4;
CopyBits((*(GgwPtr -> portPixMap)),(*(GgwPtr -> portPixMap)),
&rr,&localR,srcCopy,nil);
/* The last case is pack 4 but storing the alpha
channel also */
OffsetRect(&localR,0,3);
(*(GgwPtr -> portPixMap)) -> packType = 4;
(*(GgwPtr -> portPixMap)) -> cmpCount = 4;
CopyBits((*(GgwPtr -> portPixMap)),(*(GgwPtr -> portPixMap)),
&rr,&localR,srcCopy,nil);
ClosePicture();
UnlockPixels(GgwPtr -> portPixMap);
}
Graphics, Imaging & Printing: QuickDraw: Direct RGB PICT file compression
How are bits packed in direct RGB PICT files created by 32-Bit QuickDraw™? I looked at Macintosh® Technical Note #171, but this run-length encoded compression is clearly inefficient for cases where pixelSize is greater than 8 bits. I write software for machines other than Macintosh that decodes PICT files; therefore, I cannot issue any QuickDraw calls such as _unpackBits.
You’re quite right; compressing direct pixels using straight run-length encoding doesn’t work very well. Fortunately, direct pixel maps aren’t compressed this way. Compression schemes are discussed in Inside Macintosh Volume VI in the section titled “The New OpCodes: Expanded Format.”
In short, if the packType field holds the value 1, then no compression is done at all. The complete pixel image is saved in the PICT. If the packType field holds the value 2 and the pixel map is 32-bits per pixel, then all that’s done is that the alpha-channel byte is removed. So this:
00 FF FF FF 00 FF FF FF
is compressed to:
FF FF FF FF FF FF
If the packType field holds the value 3 and the pixel map is 16 bits per pixel, then run-length encoding is done, but not through PackBits. Instead, a run-length encoding algorithm private to QuickDraw is used. This algorithm is very similar to PackBits, but where PackBits compresses runs of bytes, this routine compresses runs of words. The format of the resulting data is exactly the same as described in Technical Note #171, but you’ll get words instead. To build on the example in Technical Note #171, lets say the 16-bit pixel image begins with these pixel values:
AAAA AAAA AAAA 8080 0000 2A2A AAAA AAAA AAAA AAAA 8080 0000
2A2A 2222 AAAA AAAA AAAA AAAA AAAA AAAA AAAA AAAA AAAA AAAA
After being packed by QuickDraw’s internal compression routine, this becomes:
FE AAAA
02 8080 0000 2A2A
FD AAAA
03 8080 0000 2A2A 2222
F7 AAAA
or
FEAA AA02 8080 0000 2A2A FDAA AA03 8080 0000 2A2A 2222 F7AA AA
* * * * *
where the asterisks mark the flag-counter bytes. Notice that you can’t assume that the pixel values are word-aligned. PackBits packs data 127 bytes at a time, though it will do this for up to 32,767 total bytes. Similarly, the internal compression routine packs data 127 words at a time.
If the packType field holds the value 4 and the pixel map is 32-bits per pixel, then run-length encoding via PackBits is done, but only after some preprocessing is done. QuickDraw first rearranges the color components of the pixels so that each color component of every pixel is consecutive. So the following four pixels (the row below the pixel values indicates a = alpha channel, r = red, g = green, b = blue, and the pixel offset):
00 FF FF FF 00 FF C0 00 00 FF 80 00 00 C0 80 00
a0 r0 g0 b0 a1 r1 g1 b1 a2 r2 g2 b2 a3 r3 g3 b3
is rearranged to become:
FF FF FF C0 FF C0 80 80 FF 00 00 00
r0 r1 r2 r3 g0 g1 g2 g3 b0 b1 b2 b3
The first four bytes are the red components of the four pixels, the next four bytes indicate the green components of the four pixels, and so on. The alpha channel isn’t included unless the cmpCount field contains 4 rather than the normal 3. If cmpCount contains 4, then all the alpha channel bytes are placed before the red bytes. Once this is done, then PackBits is called to compress the rearranged data.
Those are the only four compression schemes (including no compression) that are supported for direct pixel maps in PICTs. As always, reading PICTs yourself puts you in danger of not being able to read PICTs generated by future versions of QuickDraw. For compatibility reasons, these compression algorithms as I’ve described them probably can’t change in the future. It’s possible that new values for packType could be implemented though.
Graphics, Imaging & Printing: QuickDraw: Color and nonColor QuickDraw trap dispatch differences
Why does a call to RGBForeColor cause a corruption of the stack without resulting in an unimplemented trap error on nonColor QuickDraw™ Macintosh® systems?
The trap dispatcher on Color QuickDraw and nonColor QuickDraw machines are different. If you look at page 89 of Inside Macintosh Volume I, you’ll see the toolbox trap word format as it was in the days before Color QuickDraw. Bit 9 was “reserved for future use” and was ignored by the trap dispatcher, and so it was normally set to 0. That means that valid toolbox traps could either look like $A8XX or $A9XX as long as the auto-pop bit was turned off. Color QuickDraw machines have a trap dispatcher that uses that reserved bit to allow for more trap words, and therefore it has a much larger trap dispatch table. Color QuickDraw traps have that reserved bit set, so those traps look like $AAXX or $ABXX.
When a nonColor QuickDraw machine tests to see if a trap is implemented or not, it just checks the trap dispatch table to see if a routine is implemented for that trap or not. Because the reserved bit is ignored, trap words that look like $AAXX are treated as equivalent to $A8XX and trap words that look like $ABXX are treated as equivalent to $A9XX. The trap word for RGBForeColor is $AA14. If you call RGBForeColor on a nonColor QuickDraw machine, $AA14 is treated as $A814, which is the trap word for SetFractEnable. SetFractEnable is implemented on 128K ROM machines or greater, so no unimplemented trap error occurs.
If you look at recent DTS sample programs, such as the Utilities sample (SC.025.Utilities, which you can find on AppleLink® in Developer Support and on the current developer CD), you’ll see a routine in Utilities.c called TrapExists. It takes into account the size of the trap dispatch table so that you can tell in one call whether a routine is implemented or not regardless of whether it’s a Color QuickDraw trap or not and regardless of what kind of Macintosh you’re running on.
Under system software version 7.0, the trap dispatcher is modified on nonColor QuickDraw machines so that many Color QuickDraw traps are implemented and work as well as they can in black and white.
Graphics, Imaging & Printing: QuickDraw: CLUT should be black for video card startup
On a system restart, our PrimaryInit routine clears our video card’s memory before displaying grayscreen, but garbage appears on the Macintosh® LC screen. What should we do to fix this problem?
The problem you are having with your video card on the Macintosh LC sounds like a CLUT problem. We recommend that you start by setting your entire CLUT to black then do what you are already doing. Basically the problem is caused by the CLUT DAC coming in early. If the CLUT is set then it should not cause you any problems.
Graphics, Imaging & Printing: QuickDraw: Macintosh QuickDraw pixel map stack requirements
What are the guidelines for determining how much image can be copied to a Macintosh® pixel map at one time, given a particular set of characteristics for the source map and the destination map and given how much stack space is available. For example, we could say that we have an 8-bit deep PixMap to be copied to a 32-bit deep PixMap using the pmDithered mode and expanded by a factor of 4, and we have 45K of stack space.
Banding the image does not reduce the stack space requirement, though it does reduce your overall memory needs. The real stack requirement driver for QuickDraw™ is the width of each scan line (rowBytes). The rule of thumb is that you need at least as much stack as the widest rowBytes in your image (which can be huge with 32-bit QuickDraw) with the following additional modifiers: add an additional rowBytes for dithering; add an additional rowBytes for any stretching (source/dest rect != ); add an additional rowBytes for any color map changing; add an additional rowBytes for any aliasing. So, the rough maximum stack space you’d need is five times the rowBytes of your image. In general, you’ll be better off with processing narrower scan lines. Reducing the vertical size will not affect stack requirements. Narrow, tall bands (if you can use them) will reduce the stack.
Graphics, Imaging & Printing: QuickDraw: Using PicComments to rotate text
I have a PostScript® routine (using TextBegin/TextEnd) to generate bitmapped rotated text on the screen (which can be later printed on QuickDraw™ printers). Why do I get duplicate text? I get both bitmapped rotated text and PostScript rotated text when I print on the LaserWriter® II, and both bitmapped rotated text and horizontal text on the ImageWriter®. When I make a machine dependent check (check type of printer) and call the proper printing procedure, it works fine. Because of the speed and memory considerations of generating the rotated bitmapped text (especially at 300 dpi), is there a way to ensure that the printer will use the PostScript BEFORE generating the bitmap?
We will use the following Macintosh® PicComments to hide your QuickDraw calls from the LaserWriter, but the ImageWriter will use them:
PostScriptBegin
>> Put your CopyBits and QuickDraw calls to image your rotated
>> bitmapped text here....
PostScriptEnd
By wrapping your QuickDraw code within the PostScriptBegin and PostScriptEnd PicComments, the code will be ignored by the LaserWriter, but the ImageWriter will use the QuickDraw calls. Basically, the PostScriptBegin and PostScriptEnd PicComments tell the LaserWriter driver to turn “off” QuickDraw. In the ImageWriter case, the ImageWriter does not understand the PicComments. Therefore, it will use the QuickDraw calls to create and image your bitmapped text.
Now, we need to use the rotation PicComments to rotate the text on the LaserWriter, but have the ImageWriter ignore the code:
Rect zeroRect;
SetRect (&zeroRect, 0, 0, 0, 0);
TextBegin
TextCenter
ClipRect (&zeroRect);
>> Draw your text to be rotated on the LaserWriter....
ClipRect (&rPageRect);
TextEnd
Wrapping your text drawing call(s) between the ClipRect calls will ensure that the text is drawn only on the LaserWriter. Setting the ClipRect to zero tells the ImageWriter to ignore all QuickDraw calls until the ClipRect is reset to something “real” (actually, a zero ClipRect prevents QuickDraw from drawing anything). After we have completed drawing the rotated text, we reset the ClipRect to the dimensions of rPage (that is, rPage is the image-able area of the currently selected printer—see Inside Macintosh, Volume II, page 150). This will allow all of your normal drawing to continue on the ImageWriter and LaserWriter. If you did not reset the ClipRect after the TextEnd call, nothing would be drawn on the ImageWriter or LaserWriter.
Graphics, Imaging & Printing: QuickDraw: Using dithered drawing mode with QuickDraw
When I draw a 32-bit Macintosh® PICT image from a file to an 8-bit port via an offscreen GWorld, I use dither mode in the CopyBits call and the results are quite impressive. If there is not enough memory to allocate the GWorld, I draw the image directly to the port. But since there does not seem to be any way to tell QuickDraw™ to use dithered drawing mode, the image looks horrible.
Do you have any suggestions? I have installed bottleneck procs to allow DrawPicture to get its data from the file instead of the handle in memory. Is there a way, while in the bottlenecks, to find the CopyBits call that comes from the picture and force it to use dithered mode instead of source mode? I don’t want to try and parse the PICT myself, but I thought that maybe a QuickDraw global could be modified in my StdBits proc to force dithered drawing for that operation only?
You can install a StdBits or bitsProc bottleneck procedure to get all the CopyBits calls when the picture is being played back. One of the parameters to the StdBits call is the mode. You can install a procedure that saves the current mode, and then passes ditherMode to the original StdBits proc. This is all you should need to do. It’s been done here so we know it works, only not in any form that can be sent to you as sample code at this time.
Graphics, Imaging & Printing: QuickDraw: Why grafPort’s clipRgn should be changed before OpenPicture
On page 189 of Inside Macintosh®, Volume I, in the QuickDraw™ chapter’s description of OpenPicture, is the following warning:
“A grafPort's clipRgn is initialized to an arbitrarily large region. You should always change the clipRgn to a smaller region before calling OpenPicture, or no drawing may occur when you call DrawPicture.”
The “arbitrarily large” clipping region rectangle is set to -32767, -32767,32767,32767 (top, left, bottom, right) for new ports. This is the largest rectangle possible. If this is not a "valid" clipping rectangle for pictures, what is? Is there some specific limit to the size of the clipping rectangle? Does it depend on either available memory or the size of the picture?
Inside Macintosh ’s warning is based on truth but it’s incomplete. It didn’t actually say that this rectangle is invalid as a clipping region, because this is in fact a perfectly valid clipping region. But, you could run into problems if you use this as a clipping region when creating a QuickDraw picture. It’s not a matter of available memory or size; it’s a simple matter of 16-bit signed integer overflow and underflow.
When you open a picture, the current clip region is recorded in the picture (this wasn’t necessarily true in some early versions of QuickDraw). When you draw the resulting picture using the picture’s picFrame as the destination rectangle, there won’t be any problems. But if you use a destination rectangle that’s larger than the picFrame, QuickDraw scales everything in the picture proportionately, including the clip region. If you allowed the default clip region to be recorded into the picture, then its rgnBBox, already as large as possible, will be made even larger. That means that the -32767 coordinates might wrap around to the positive number range, and the 32767 coordinates might wrap around to the negative number range. This leaves you with an empty clip region. Nothing at all gets drawn when the current port’s clip region is empty.
If the destination rectangle is smaller than the picture’s picFrame, you won’t have any problems because the default clip region will be made smaller, and that’s no problem.
This is why Inside Macintosh suggests that you make the clip region smaller than the default clip region before opening a picture. By doing this, you’re almost guaranteed that the clip region won’t get scaled to the point that it turns inside out. What size should you make it? Small enough so that the risk of the clip region’s coordinates being scaled out of QuickDraw coordinate space is minimal. I usually just set the clip region to the picFrame of the picture. It’s hard to go wrong this way.
Graphics, Imaging & Printing: QuickDraw: Use Mac 8•24 GC card as video buffer only for now with 7.0ßx
Can I use my Macintosh® 8•24 GC card with System 7.0ßx? I was told the GC INIT misbehaves with any and all nonlinear address mapping, such as System 7.0 and A/UX®. Is this true? Can this be fixed with CODE/INIT patch? Is it scheduled to be fixed in the near future?
The 8•24 GC card INIT version 1.0 is not intended to run in any environment involving virtual memory management. A VM-compatible version of the GC INIT will be made available when System 7.0 is final. Until then, the card can be used as a video buffer, and System 7 preliminary software might run with VM switched off.
Graphics, Imaging & Printing: QuickDraw: Using Mac System 7 OpenCPicture for higher resolution
We want to use OpenCPicture for higher resolution, not for color per se. Can OpenCPicture in System 7 be used with non-Color as well as Color QuickDraw™ Macintosh® computers?
Yes, with System 7, OpenCPicture can be used to create extended PICT2 files from all Macintosh computers. Under System 6.0.7 or later, you must test for 32-Bit QuickDraw before using OpenCPicture. You can do this by calling Gestalt with the gestaltQuickDrawVersion selector. If it returns gestalt32BitQD or greater, then 32-Bit QuickDraw is installed.
Graphics, Imaging & Printing: QuickDraw: Macintosh QDError function under System 6 and System 7
Under what System 7 and System 6 conditions is it legal to call the Macintosh® QDError function?
Under System 7, QDError can be called from all Macintosh computers. (System 7 supports RGBForeColor, RGBBackColor, GetForeColor, and GetBackColor for all Macintosh computers as well.) On a non-Color QuickDraw™ Macintosh, QDError always returns a “no error.” Under System 6, QDError cannot be used for non-Color QuickDraw Macintosh systems.
Graphics, Imaging & Printing: QuickDraw: Macintosh CopyBits transfer modes changed for System 7
Why do some Macintosh® CopyBits transfer modes produce different results for System 7 than for System 6?
Under System 6, the srcOr, srcXor, srcBic, notSrcCopy, notSrcOr, notSrcXor, and notSrcBic transfer modes do not produce the same effect for a 16- or 32- bit (direct) pixel map as for an 8-bit or shallower (indexed) pixel map. With Color QuickDraw these classic transfer modes on direct pixel maps aren’t color based; they’re pixel value based. Color QuickDraw performs logical operations corresponding to the transfer mode on the source and destination pixel values to get the resulting pixel value.
For example, say that a multicolored source is being copied onto a black and white destination using the srcOr transfer mode, and both the source and destination are 8 bits per pixel. Except in unusual cases, the pixel value for black on an indexed pixel map has all its bits set, so an 8-bit black pixel has a pixel value of $FF. Similarly, the pixel value for white has all its bits clear, so an 8-bit white pixel has a pixel value of $00. CopyBits takes each pixel value of the source and performs a logical OR with the corresponding pixel value of the destination. Using OR to combine any value with 0 results in the original value, so using OR to combine any pixel value with the pixel value for white results in the original pixel value. Using OR to combine any value with 1 results in 1, so using OR to combine any pixel value with the pixel value for black results in the pixel value for black. The resulting image shows the original image in all areas where the destination image was white and shows black in all areas where the destination image was black.
Take the same example, but this time make the source and destination 32 bits per pixel. The direct-color pixel value for black is $00000000 and the direct- color pixel value for white is $00FFFFFF. CopyBits still performs a logical OR on the source and destination pixel values, but notice what happens in this case. Using OR to combine any source pixel value with the pixel value for white results in white, and using OR to combine any source pixel value with the pixel value for black results in the original color. The resulting image shows the original image in all areas where the destination image was black and shows white in all areas where the destination image was white—roughly the opposite of what you see on an indexed pixel map.
The newer transfer modes addOver, addPin, subOver, subPin, adMax, and adMin work consistently at all pixel depths, and often, though not always, correspond to the theoretical effect of the old transfer modes. For example, the adMin mode works similarly to the srcOr mode on both direct and indexed pixel maps. Also, 1-bit deep source pixel maps work consistently and predictably regardless of the pixel depth of the destination even with the old transfer modes.
Under System Software 7.0, the old transfer modes now perform by calculating with colors rather than pixel values. You’ll find that transfer modes like srcOr and srcBic work much more consistently even on direct pixel maps.
Graphics, Imaging & Printing: QuickDraw: System 7.0ß1 BitMapToRgn limitation
BitMapToRegion does not work as described in Macintosh® Tech Note #275, for a PixMap with baseAddr = (NuBus™ address). Which calls support PixMap 32-bit base addressing with pmVersion = 4?
As of System 7.0ß1, BitMapToRgn cannot handle a bitmap whose base address is in the NuBus address space or any bitmap that requires 32-bit addressing. The problem will be fixed for System 7’s final release. BitMapToRgn seems to be the only call that doesn’t yet support 32-bit addressed bitmaps.
Graphics, Imaging & Printing: QuickDraw: Macintosh QuickDraw region quirks
I’m working with regions, and I’m having problems with Macintosh® QuickDraw™ trashing the heap and crashing, even though my regions are under 32K.
There are some quirks in the current version of QuickDraw. Here are some the commonly-encountered problems:
1. When doing operations which use more than one region, sduch as UnionRgn, DiffRgn, XorRgn, or SectRgn, the sum of the sizes of the source regions MUST BE LESS THAN 32K, regardless of the size of the resulting region.
2. FrameRgn will fail if it tries to frame a region bigger than 16K.
3. If CloseRgn fails, the internal region data is already corrupt; there is nothing you can do to recover. CloseRgn will also fail if there isn’t at least a 32K block of free space available.
Here are some workarounds:
1. Keep regions small and not too complex. Keep track of the sizes of all regions so you can check the SUM of the sizes before calling a routine that has a 32K limit.
2. Keep 32K free, or allocate a 32K block and release it just before calling CloseRgn.
Apple is working on these problems and expects to fix them in future versions of QuickDraw.
Graphics, Imaging & Printing: QuickDraw: How to get Macintosh QuickDraw arc endpoints
Is there a way to obtain the endpoints of an arc drawn by the Macintosh® QuickDraw™ arc routines, such as FrameArc and PaintArc?
Given a rectangle R which frames the arc you wish to draw, convert your angles to an absolute coordinate system, where three o’clock is 0 degrees and 12 o’clock is 90 degrees.
Now, let:
x = .5 (+ or -) (R.right - R.left)
y = .5 (+ or -) (R.bottom - R.top)
The endpoint of the curve will be defined by:
EndPoint.h = x (+ or -) cos(ang);
EndPoint.v = y (+ or -) sin(ang);
h & v are relative to center of rectangle R
This calculates only the upper endpoint of the arc, but you can easily calculate the other endpoint using the same formula by calculating the absolute angle for the start point and applying the same formula.
Here is a subroutine which illustrates the algorithm, in LightSpeed Pascal:
{ DrawCurve: draw an arc from 0 degrees until the point defined }
{ by 'angle'. At that point draw a 4 by 4 crosshair. }
procedure DrawCurve (frame : Rect; angle : integer);
var
x, y : integer;
xr, yr : extended;
rad : extended;
begin
{ Convert angle to radians }
rad := (90 - angle) / 180 * 3.14159;
{ Find end point }
xr := (frame.right - frame.left) * cos(rad) / 2;
yr := (frame.bottom - frame.top) * sin(rad) / 2;
x := (frame.right + frame.left) / 2 + Num2Integer(xr);
y := (frame.bottom + frame.top) / 2 + Num2Integer(yr);
{ Draw crosshair }
MoveTo(x - 4, y);
LineTo(x + 4, y);
MoveTo(x, y - 4);
LineTo(x, y + 4);
{ Draw arc }
FrameArc(frame, 0, angle);
end;
Graphics, Imaging & Printing: QuickDraw: Mac PixMap is clipped to visRgn defined by screenBits.bounds
I’m drawing into a large offscreen bitmap (PixMap), but anything drawn outside the 640 by 480 pixel Macintosh® screen area doesn’t get written to the PixMap. Why not?
When you create a new port with OpenPort or OpenCPort the visRgn is initialized to the rectangular region defined by screenBits.bounds (IM I:163). If your port has a large portRect, any drawing will be clipped to the visRgn and you will lose any drawing outside of the screenBits.bounds rectangle.
To correct this set the visRgn of the port to coincide with your port’s portRect after creating the port.
Also note that OpenPort initializes the clipRgn to a wide-open rectangular region (-32768, -32768, 32767, 32767). Some operations, like OpenPicture, can fail with this setup, so try setting clipRgn to a smaller rectangle.
Graphics, Imaging & Printing: QuickDraw: How to identify 32-Bit QuickDraw version
How can my program find out which version of Macintosh® 32-Bit QuickDraw™ is running?
The following code snippet demonstrates how to use the Gestalt Manager to determine which version of 32-Bit QuickDraw is installed. There is no way to determine the version of 32-Bit QuickDraw before Gestalt. For 32-Bit QuickDraw version 1.2, Gestalt returns 2.2. IM VI describes the Gestalt Manager in detail.
#defineTRUE0xFF
#defineFALSE0
#define Gestalttest0xA1AD
#define NoTrap0xA89F
main()
{
OSErrerr;
longfeature;
if ((GetTrapAddress(Gestalttest) != GetTrapAddress(NoTrap))) {
err = Gestalt(gestaltQuickdrawVersion, &feature);
if (!err) {
if ((feature & 0x0f00) == 0x0000)
printf ("We have Original QuickDraw version 0.%x\n", (feature & 0x00ff));
else if ((feature & 0x0f00) == 0x0100)
printf ("We have 8 Bit QuickDraw version 1.%x\n", (feature & 0x00ff));
else if ((feature & 0x0f00) == 0x0200)
printf ("We have 32 Bit QuickDraw version 2.%x\n", (feature & 0x00ff));
else
printf ("We don't have QD\n");
}
else
printf ("Gestalt err = %i\n",err);
}
else
printf ("No Gestalt\n");
}
Graphics, Imaging & Printing: QuickDraw: Macintosh Color QuickDraw CalcCMask and SeedCFill clarified
I’m having trouble using CalcCMask and SeedCFill. What am I doing wrong?
There is some confusion regarding the use of the Macintosh® Color QuickDraw™ routines CalcCMask and SeedCFill, which are analogous to the older CalcMask and SeedFill. Much of the confusion was caused by early documentation errors. Be sure you have the release version of Volume 5 of Inside Macintosh and version 2.0 or later of the MPW® interface files.
The correct interface for CalcCMask is:
PROCEDURE CalcCMask(srcBits, dstBits: BitMap;
srcRect, dstRect: Rect;
seedRGB: RGBColor;
matchProc: ProcPtr;
matchData: LongInt);
The correct interface for SeedCFill is:
PROCEDURE SeedCFill(srcBits, dstBits: BitMap;
srcRect, dstRect: Rect;
seedH, seedV: INTEGER;
matchProc: Ptr;
matchData: LongInt);
Each routine calculates a one-bit deep BitMap representing either the mask or the fill area depending upon the routine. In both cases, the source BitMap may be either a BitMap or a pixmap, but the destination must be a BitMap, because it must have a depth of one-bit.
It is difficult to pass a pixmap for the source parameter because of Pascal’s type checking. To get around this difficulty, you can declare a new type:
BitMapPtr = ^BitMap
then use it to coerce the pixmap as follows:
SeedCFill(BitMapPtr(@myPixMap)^, ...);
If you have a PixMapHandle, do the following:
SeedCFill(BitMapPtr(myPixMapHandle^)^, ...);
If you are using a GrafPort (or a window), you can pass myWindow^.portBits and not have to worry about whether the port uses a BitMap or a PixMap.
Most of the other parameters are explained in detail in Inside Macintosh. To use the matchProc and the matchData parameters, though, you need more information.
As stated in Inside Macintosh, the matchProc parameter is a pointer to a routine that you would like to use as a custom SearchProc. To better understand how this is used, it is helpful to know how SeedCFill and CalcCMask actually work.
Both routines start by creating a temporary BitMap which, by definition, is one bit deep. The source PixMap (or BitMap) is then copied to the temporary BitMap using CopyBits. This copy causes the image to be converted to a depth of one-bit. Now with a normal black-and-white image, the standard CalcMask or SeedFill routine is used to generate the destination BitMap.
Most of the real work is done in the original call to CopyBits, which maps the PixMap image to a monochrome BitMap equivalent. For each color in the source PixMap, CopyBits will map it to either black or white. Which colors map to black and which ones to white is determined by the SearchProc.
SeedCFill installs a default SearchProc that maps all colors to black except for the color of the pixel at (seedH,seedV). SeedFill then calculates as usual the fill mask for the white bits .
The default SearchProc for CalcCMask maps all colors to white except the color passed in the seedRGB parameter. The seedRGB parameter, then, would be the color of the item that you wanted to “lasso.”
But suppose you want to fill over all colors that were shades of green, not just the particular shade of green at (seedH,seedV). Or maybe you want to fill over all colors that are lighter than 50% brightness. Or maybe you want to use dark colors as edge colors for CalcCMask. To do such things, you need to pass a pointer to your own SearchProc in the matchProc parameter.
Because your matchProc is just a custom search procedure for the Color Manager, it should be declared as one, but Volumes I-V of Inside Macintosh have documented this routine incorrectly. The correct declaration for a custom SearchProc is as follows:
FUNCTION SearchProc(VAR RGB: RGBColor;
VAR result: LongInt) : Boolean;
Normally, as each SearchProc is installed, it is added to the head of the SearchProc chain, so that it is called before all of the other ones which were already installed. When a SearchProc is installed, it can do one of three things:
1. Completely ignore the call by returning FALSE and not modifying any of the input parameters; 2. Completely handle the call by setting the result parameter to be the index into the color table that matches (according to your rules) the RGB parameter. In that case, the SearchProc returns TRUE; 3. Partially handle the call by modifying the RGB parameter, then returning FALSE.
In cases 1 and 3, the Color Manager continues down the SearchProc chain until it finds one that returns TRUE. If none of the custom routines handle the call, then the built-in default routine is used. In case 3, you can change the RGB color that is being matched. For example, if you want all shades of green to map to pure green, modify the RGB color, then return FALSE, letting the Color Manager find the index of that green in the color table.
In case 2, you return TRUE to indicate that you handled the call, and you return the color table index in the result parameter. The Color Manager then uses that index. For example, if you want to substitute white for all colors that can’t be matched exactly in the color table, then each time you get called you either return the index into the color table of the exact color, or 0 (which is the index for white) for all other colors.
A custom SearchProc for SeedCFill and CalcCMask should always return TRUE because the default Color Manager SearchProc usually doesn’t make sense. Because SeedCFill and CalcCMask are using CopyBits to copy to a 1-bit BitMap, you need to set the result to be either 0 or 1 (the only possible values in a 1-bit BitMap). A result of 0 is white, and a result of 1 is black.
All colors for SeedCFill that should be “filled over” would generate a result of 0 (white), and all colors that stop the fill generate a 1 (black). SeedFill is then called to fill the white area. All colors for CalcCMask that you want to form boundaries should generate results of 1 (black).
When your SearchProc gets called, the gdRefCon field of the current GDevice (theGDevice^^.gdRefCon) contains a pointer to the following record:
matchRec = RECORD
red: Integer;
green: Integer;
blue: Integer;
matchData: LongInt;
END;
The red, green, and blue parameters for SeedCFill are the values of the color of the pixel at (seedH,seedV). For CalcCMask, they are the fields from the seedRGB parameter. Your SearchProc can use this information to decide which colors are “fill-over” colors and which colors are “boundary” colors. For example, if you always set (seedH,seedV) to be the mouse point, your SearchProc then bases its decisions using the color of the pixel under the cursor. For example, the user clicks on a shade of green, so all shades of green get filled over.
The matchData field contains the value that you passed into the SeedCFill or CalcCMask routines in the matchData parameter. The use of this field is completely user-defined. For example, since your SearchProc routine may be a separate module, you might want to use this field to pass a handle to your variables. This field can contain a handle, a pointer, a long integer, or whatever; or you can just ignore this field altogether.
Warning: There are some features of CalcCMask and SeedCFill you should be aware of. To understand them, you should be familiar with the use of CalcMask and SeedFill, which are described in the QuickDraw chapter of IM IV.
CalcCMask and SeedCFill both use a parameter set that is very similar to the one used by CopyBits. CalcMask and SeedFill, however, are a different story. Instead of passing bitmaps and rectangles to SeedFill and CalcMask, these routines use an unusual set of parameters that describe the memory to be operated upon in terms of pointers, height, width, and offsets to the next row (rowBytes). Although these parameters are fairly easy to calculate, there are some limitations.
The most restrictive limitation is that the width of the rectangle used must be an even multiple of 16 bits. This limitation exists because the width of the rectangle is passed to SeedFill and CalcMask as a number of words (2 bytes). When calculating this parameter, SeedCFill and CalcCMask round down to an even word boundary. This rounding means that the rectangles you pass to CalcCMask and SeedCFill should be an even multiple of 16 pixels in width. If they are not, then the rightmost portion of the mask will be garbage.
To figure out the color of the pixel at (seedH,seedV), SeedCFill calls GetCPixel. GetCPixel finds the color of the pixel at (h,v) in the current port. Therefore, if you pass a PixMap which is not the PixMap of the current port you will get bizarre results. In other words, seedH and seedV are expressed in the local coordinates of the current port, not the coordinate of the source PixMap.
You have two methods to make it work. First, always pass the PixMap of the current port as the source parameter. If you are using an off-screen PixMap, it is a good idea to have an associated port for it, and then call SetPort, passing it a pointer your off-screen port, before you call SeedCFill.
The second method involves letting SeedCFill get some wrong value for the color at (seedH,seedV) then using your own custom SearchProc to do the real work. The default SearchProc for SeedCFill relies on getting the correct color, but your SearchProc doesn’t have to.
SeedCFill also makes the assumption that the seedH and seedV parameters are in the local coordinate system of the destination BitMap. This assumption comes into play when SeedCFill calculates the seedH and seedV parameters for SeedFill.
All this means that SeedCFill only works correctly if the source PixMap, destination PixMap, and current port all use the same coordinate system. Because of the above problem, this is almost automatic since the current port’s portRect and the bounds of the source PixMap have to be the same anyway.
The easiest way to make all this work is to have your main port be an even multiple of 16 pixels wide. Then, make sure that your source and destination structures (PixMap or BitMap) are all the same size and all have origins of (0,0).
Graphics, Imaging & Printing: TrueType: SetPreserveGlyph and font glyph preservation
The TrueType SetPreserveGlyph call works as described for Times and Helvetica, but it doesn’t appear to affect New York, Geneva, Monaco, or Chicago. The glyph size remains constant regardless of preserveGlyph’s state. Is this supposed to happen?
TrueType’s SetPreserveGlyph call with preserveGlyph set to “true” works as you’d expect for Times and Helvetica, but it has no effect on New York, Geneva, Monaco, or Chicago.
Why does SetPreserveGlyph work this way? Glyph preservation is a function of the font. It turns out that Times and Helvetica have glyphs that extend above the ascent line, thereby enabling SetPreserveGlyph to have an effect on a particular glyph. New York, Geneva, Monaco, and Chicago’s characters all fit between the ascent and descent lines, and so do not need to be compressed to fit if preserveGlyph is true. A font must have glyphs extending above or below the ascent or descent lines for SetPreserveGlyph to have an effect.
To see the ascent or descent lines for a particular glyph, use one of the new TrueType font tools. These tools allow you to see the glyph with the ascent and descent lines drawn.
Graphics, Imaging & Printing: TrueType: Getting Macintosh character outline data
Can you describe a procedure for extracting TrueType™ character outline data directly from the Macintosh® system software?
Future releases of Macintosh system software probably will include calls for accessing TrueType character outline data. In the meantime, sample code showing how to parse the 'sfnt' outline font resource is available on Volume VIII of the Developer CD Series disc and on AppleLink in the Developer Support:Developer Services:Developer Technical Support:Developer Essentials:Sample Code folder.
Graphics, Imaging & Printing: TrueType: Macintosh 6.0.7 and TrueType
Where can I find information on manipulating TrueType® fonts under System 6.0.7?
The System 6.0.7 TrueType INIT includes all the outline calls in System 7.0, so everything you need is in Inside Macintosh Volume VI. See also the article “Scoring Points With TrueType” in this issue. Use Gestalt’s gestaltFontMgrAttr selector (described in the “Compatibility Guidelines” chapter of Volume VI, and available in System 6.0.4 and later) to determine whether TrueType is available on the machine in question, and then use outline calls freely and with abandon. The latest MPW release has the header files, called OutlineCalls. Use version 4.1 of Font/DA Mover to move outline fonts under System 6.0.7. Both the TrueType INIT and Font/DA Mover 4.1 are available on AppleLink® and on the Developer CD Series disc, and you can license Font/DA Mover to include it with your product release by contacting Apple’s Software Licensing group.
Networking & Communications: Alternate AppleTalk: EtherTalk DriverClose function
My EtherTalk DriverClose function is never called by the system, so my VBL and interrupt service routines remain active, even though another network device is active. Any ideas or tips on what might be going on?
Your findings are as per design. Just because the user decides not to use EtherTalk doesn’t mean that the user no longer wants Ethernet services. For example, the user might be using MacTCP. MacTCP accesses the .ENET driver directly, bypassing the LAP Manager. Should the NetWork cdev close the .ENET driver when the user switches to LocalTalk or TokenTalk while MacTCP is still using the driver, a system crash would likely result.
Networking & Communications: Alternate AppleTalk: Apple Ethernet Cable System power requirements
Sections 3.1.2 and 3.1.3 of the “Apple Ethernet Cable System Product Family Overview and Interface Descriptions” state that pin 1 provides either 12 V/2.1W or 5 V/1.9 W, and that 5 volts will be made available on pins 7 and 8, if the host can supply greater than or equal to 1.9W @ 5 V. Which models do not have 5 V available on pins 7 and 8, which models have 12 V on pin 1, and which have 5 V on pin 1?
All known hosts will provide 5 V at pins 7 and 8. It is absolutely NOT recommended that a Multiple Access Unit (MAU) designer use Voltage Agile (pins 1 and 14) powering to power a 5 V-only MAU. It is anticipated that all friendlynet-compliant hosts will supply +5 V to pins 7 and 8. Third parties desiring a 5 V-only MAU should use these pins.
MAUs using pins 1 and 14 MUST have a DC-DC converter.
Apple doesn’t presently have a product that uses +12 V on pins 1 and 14 but may in the future. As this is an “open standard,” at least one clone maker and several third-party Apple printer and card manufacturers use this interface, and others are expected.
Networking & Communications: Alternate AppleTalk: IEEE assigns Ethernet card addresses
We need a range of Ethernet card addresses to uniquely identify each Ethernet card we manufacture. We received board IDs and equates from Apple, but not the range of Ethernet addresses.
You weren’t sent a range of Ethernet addresses because Apple does not assign them. IEEE is the governing body that you have to contact to get a range of numbers; Apple had to do the same thing to get the numbers for its boards. IEEE will assign you a block of numbers that includes a unique manufacturer’s ID allowing network sniffers to recognize your products.
Networking & Communications: Alternate AppleTalk: “Undefined entry” link errors when opening Ethernet Driver
When I try to open the EtherNet driver as described in Inside Macintosh Volume VI on pages 32-80 and 32-81, I get the following undefined entry error messages:
### Link: Error: Undefined entry, name: (Error 28) "DisplaySInfo"
Referenced from: Init_Enet in file: Mac_Raid.c.o
### Link: Error: Undefined entry, name: (Error 28) "SaveSInfo"
Referenced from: Init_Enet in file: Mac_Raid.c.o
### Link: Error: Undefined entry, name: (Error 28) "SGetTypeSRsrc"
Referenced from: Init_Enet in file: Mac_Raid.c.o
Any clue as to where these are?
The “DisplaySInfo” and “SaveSInfo” are bogus procs that the sample writer didn’t take out or comment out.
However, SGetTypeSRsrc is a legal Slot Manager trap, IF you are using the new version of the Slot Manager. The definitions from the latest interfaces (slots.p, slots.h) are as follows:
FUNCTION SGetTypeSRsrc(spBlkPtr: SpBlockPtr): OSErr;
INLINE $205F,$700C,$A06E,$3E80;
#pragma parameter __D0 SGetTypeSRsrc(__A0)
pascal OSErr SGetTypeSRsrc(SpBlockPtr spBlkPtr)
= {0x700C,0xA06E};
The Slot Manager is dispatched via D0 selectors; there is no glue.
Networking & Communications: Alternate AppleTalk: Use EtherTalk 2.5 with Macintosh LC only
Which Macintosh® systems does EtherTalk® 2.5 support?
EtherTalk 2.5 was developed to provide EtherTalk services on the Macintosh LC system, including the resources for installing AppleTalk version 55 on the Macintosh LC. This was the only platform on which version 55 was tested and the only platform that should be used with this software.
Networking & Communications: Alternate AppleTalk: Selecting alternate AppleTalk driver at system startup
I need to know how to set the Macintosh® parameter RAM field that controls which alternate AppleTalk® driver is used at system startup (for example, EtherTalk®).
We discourage directly setting the parameter RAM. The Network 'cdev' and the 'adev' device work together to handle this. Each type of AppleTalk connection (other than LocalTalk®) must have its own 'adev' file. The construction of the 'adev' file is similar to that of a 'cdev' file. For each type of AppleTalk connection, such as EtherTalk, the 'adev' file must contain the following resources:
'ICN#'
'STR '
'BNDL'
'FREF'
owner resource
'adev' code resource
'atlk' code resource
The 'adev' and 'atlk' resources are pieces of stand-alone code that reside in the adev file. The 'adev' resource is responsible for handling all control panel interactions with the Network 'cdev'. The 'atlk' resource contains the actual implementation code for the supported AppleTalk connection. When the user selects an AppleTalk connection from the Network control panel, the Network 'cdev ' updates parameter RAM with a value that represents the AppleTalk connection that is currently selected. This value remains in parameter RAM after the user turns off the Macintosh.
More information about this can be obtained from EtherTalk and Alternate AppleTalk Connections Reference, available from APDA®.
Networking & Communications: AppleShare: System 7 and AppleTalk Internet Router
We’ve tried to run the Apple Internet Router with our System 7 File Sharing servers. There does not appear to be support for multiple networks. Is there some solution to this?
The AppleTalk Internet Router and System 7 are compatible, with two exceptions: virtual memory and 32-bit addressing. You need to drag-install it instead of using the Installer. The Installer script on the router disk will put the parts of the router in the wrong place. Here are the steps to drag-install the router:
1) Drag the files Router, LocalTalk (Built-in), and LocalTalk (Modem) from the System Folder on the “AppleTalk Internet Router” disk to the closed System Folder on the disk where you want to install. System 7 will automatically put the Router file in the System Folder, and put the LocalTalk (Built-in) and LocalTalk (Modem) files in the Extensions folder in the System folder.
2) Under System 7, open the System file on the “AppleTalk Internet Router” disk (double-click on the System file). A window will open showing the desk accessories, fonts, and sounds that are part of that System file. Drag the “Router” desk accessory from that window to the closed System Folder on the disk where you want to install. System 7 will automatically put the “Router” desk accessory in the Apple Menu Items folder in the System folder.
3) Reboot.
That’s all there is to it.
X-Ref:
“System 7: Installing Internet Router 2.0,” AppleLink Tech Info Library
Networking & Communications: AppleShare: AppleShare open file limit
AppleShare open file limit
On an AppleShare 2.0 File Server platform, the only application that can access files outside of the Server Folder (i.e., the System Folder) is the file server application. AppleShare Foreground applications (described in Macintosh Tech Note #167) are the only other applications that should be running on a server and they can only access files inside the Server Folder. All file forks (referred to as files from here on) opened by remote AppleShare workstations are opened by the File Server application.
The File Server application will open a file only one time. All access to that file from any number of workstations will use the single access path the File Server has opened. Only when all workstations have closed the file does the File Server really close the file on the server. So, that means only one FCB is used on the server per open file, even if 50 users have shared access to that file.
The File Server application handles all access control to an open file using the AppleTalk Filing Protocol (AFP) deny-mode permission model. The only reason a user won’t be able to open an access path to a file on a server is if another user has opened that file with a deny-mode that conflicts with the second user’s request, or the user does not have the access rights needed to open files in the file’s parent directory or directory ancestors. The AFP deny-mode permission model is described briefly in Inside Macintosh Volume V, File Manager Extensions In a Shared Environment, and in detail in the AppleTalk Filing Protocol chapter of Inside AppleTalk.
As noted in Macintosh Tech Note #216, the maximum number of open file forks on an AppleShare 2.0 server is either 80 on a 1-MB MC68000 server platform, or 160 on an server platform with more than 1MB and a MC68020 or greater processor. That figure includes the number of files kept open by the system and the file server application. If an AppleShare Foreground application is running on the server (for example, the AppleShare Print Server), then any files it may have open count against the maximum, too. The same can be said for open desk accessories. Tech Note #216 currently doesn’t say anything about those files counting towards the limit. If the 160 (or 80) file limit is a problem, you can use the “Up Your FCBs” INIT to bump the number of available up to the maximum (342) allowed by the File Manager. “Up Your FCBs” can be found on AppleLink in the Developer Support:Developer Technical Support:Hacks folder.
Networking & Communications: AppleShare: TMGetTermEnvirons envVersTooBig error
A call made to TMGetTermEnvirons returns -5502 or envVersTooBig. The call is made with a good terminal handle started from your TTY tool. What’s wrong? How do I fix it?
When you call TMGetTermEnvirons, the TermEnvironRec that you hand it a pointer to must have initialized the version field with curTermEnvRecVers. The following will work properly:
void getTEnvirons(TermHandle aTerm)
{ ...
TermEnvironRec tEnv;
TMErr err;
...
tEnv.version = curTermEnvRecVers;
err = TMGetTermEnvirons(aTerm,&tEnv);
/* check for errors, do whatever... */
...
}
This is consistent with most other Macintosh “get environment” calls such as SysEnvirons, and is documented (somewhat unclearly) at the top of page 113 in “Inside the Macintosh Communications Toolbox.”
Networking & Communications: AppleShare: Macintosh AppleShare versus FileShare capabilities
We are using the FileShare capabilities of Macintosh® systems with System 7.0 to make them mini file servers. Where can information that details the features of both AppleShare® and FileShare be found? We are considering using only FileShare in the office if it is capable of providing most of what AppleShare provides.
Information on file sharing can be found in the System 7 Personal Upgrade Kit and in Inside Macintosh, Volume VI, on your Developer CD Series disc. The maximum number of concurrent connections allowed on a Macintosh using file sharing is 10. The performance of an AppleShare® file server (the standard kind of server) is approximately 25% better than a similar configuration of Macintosh computers acting as a file sharing server.
Networking & Communications: AppleShare: AppleShare Apple II Setup current version is 2.1.3
Is there a new version of Apple II Setup for AppleShare® to go with the Apple IIGS® 5.0.4 system, or is 2.1.3 the latest?
Apple II Setup version 2.1.3 is the correct version to use with Apple IIGS System 5.0.4.
Networking & Communications: AppleShare: Macintosh EOF in an AppleShare environment
I ran into the following when updating the logical end of file (EOF) of a shared file: Application A and Application B have access to a file under AppleShare®. Each is using fsRdWrShPerm. When Application A changes the logical EOF, Application B doesn’t seem to notice that EOF has changed until Application B calls GetEOF. Is there a better way to make Application B aware of the change of logical EOF?
You’ve made a correct assumption that the correct way to keep track of EOF in an AppleShare environment is to ask for it. When you open a file, the AppleShare workstation code translates the Macintosh operating system Open call to the AFP (AppleTalk Filing Protocol) FPOpenFork call, and sets the bits in the bitmap parameter to current length of the fork opened (in the case of Open, the data fork). It then uses THAT as the EOF for future operations unless it gets an update from the server. Because the server does not constantly update everyone who has the file open, you have to ask to find if another user (or application) has made a change. Just remember that using GetEOF will only get you the EOF at that instant in time. Someone else sharing the file could change EOF right after you check it.
The PBLockRange function can be used by an AppleShare aware application to prevent another user from appending data to a shared file while you are appending data. For example:
paramBlock.ioRefNum := myFileRef;
err := PBGetEOF(@paramBlock, FALSE); {get the current EOF}
{check for errors in a real application}
oldEOF := paramBlock.ioMisc; {save the current EOF}
paramBlock.ioReqCount := -1; {$FFFFFFFF}
paramBlock.ioPosMode := fsFromStart;
paramBlock.ioPosOffset := oldEOF; {start range lock at current EOF}
err := PCLockRange(@paramBlock, FALSE); {and lock the rest of
the fork}
{check for errors in a real application}
{now you can append data to the file}
paramBlock.ioRefNum := myFileRef;
paramBlock.ioReqCount := -1; {$FFFFFFFF}
paramBlock.ioPosMode := fsFromStart;
paramBlock.ioPosOffset := oldEOF;
err := PCUnlockRange(@paramBlock, FALSE); {unlock the locked range}
{check for errors in a real application}
PBLockRange can also be used when you need to truncate a shared file. Locking the portion of the file you're about to truncate prevents another user from using that portion during the truncation process. For example:
paramBlock.ioRefNum := myFileRef;
paramBlock.ioReqCount := -1; {$FFFFFFFF}
paramBlock.ioPosMode := fsFromStart;
paramBlock.ioPosOffset := theNewEOF; {start lock at truncation
point}
err := PCLockRange(@paramBlock, FALSE); {and lock the rest of the
fork}
{check for errors in a real application}
paramBlock.ioMisc:= theNewEOF;
err := PBSetEOF(@paramBlock, FALSE); {set the new EOF (truncate
the file)}
{check for errors in a real application}
paramBlock.ioReqCount := -1; {$FFFFFFFF}
paramBlock.ioPosMode := fsFromStart;
paramBlock.ioPosOffset := theNewEOF;
err := PCUnlockRange(@paramBlock, FALSE); {unlock the locked range}
{check for errors in a real application}
The entire fork can be locked with:
paramBlock.ioRefNum := myFileRef;
paramBlock.ioReqCount := -1; {$FFFFFFFF}
paramBlock.ioPosMode := fsFromStart;
paramBlock.ioPosOffset := 0; {lock from the beginning}
err := PCLockRange(@paramBlock, FALSE); {lock the whole fork}
{check for errors in a real application}
{do your thing}
paramBlock.ioRefNum := myFileRef;
paramBlock.ioReqCount := -1; {$FFFFFFFF}
paramBlock.ioPosMode := fsFromStart;
paramBlock.ioPosOffset := 0; {unlock from the beginning}
err := PCUnlockRange(@paramBlock, FALSE); {unlock the whole fork}
{check for errors in a real application}
Networking & Communications: AppleShare: Macintosh file system active ranges
How many active ranges can a Macintosh® application have on a shared file? If the answer is more than one, is the limit per application or per machine? If two ranges overlap, are they joined into one range? Can an application nest ranges? For example, if an application’s user performs an action that forces a record to be locked and later the application locks the full range of the file, does the initial record lock disappear?
The only way to determine the limit is to hit the limit and get a NoMoreLocks error. The number of range locks supported is a limit of the server platform, and that limit is shared by all users of the server (at least it is with Apple’s AppleShare® server software). With Apple’s server-based version of AppleShare, approximately 40 locks per user are allowed (for example, if the server allows 25 users, there are 1000 locked ranges total; if the server allows 50 users, there are 2000 locked ranges total; and with File Sharing running under System 7.0, approximately 20 locks are allowed per user). Other vendors may allow more or fewer locked ranges on their implementations of an AppleTalk® Filing Protocol (AFP) server. Notice that the numbers given are per user, not per application. It’s assumed that a user probably won’t need more than a few locks at a time on a single file.
You cannot have range locks that overlap. You’ll get a RangeOverlap error from AFP. All the rules for range locking can be found in the AFP chapter of Inside AppleTalk (page 13-56). Additional information on AppleShare limits is available in the Dev Tech Answers library on AppleLink and on the Developer CD Series disc.
The February 1991 revision of Macintosh Technical Note #186 covers several important details about PBLockRange and PBUnlockRange that are not in Inside Macintosh.
Networking & Communications: AppleShare: Purpose of AppleShare SP file
What is the file “AppleShare® SP” and what does it do? The AppleShare File Server seems to run without it, and it reduces the alert sound to just a beep even when the server is not running on that computer. Is the file really needed?
You do need the AppleShare SP INIT on your file server. The AppleShare SP (Small Patch) INIT is designed to correct a minor incompatibility between AppleShare 2.0x and the Sound Manager. The INIT forces the Macintosh® to use the “Simple Beep” sound at all times. System 7.0 file sharing and future versions of AppleShare do not need the INIT.
Networking & Communications: AppleShare: Software-selecting an AppleShare volume
Is there any source code available for mounting/unmounting AppleShare® volumes?
There are actually a couple of ways to select an AppleShare volume. You could use the ‘Choose’ tool in MPW® that accomplishes this, or you can do it with aliases under System 7. Other than the MPW tool, there is no other supported way of doing this under pre-7.0 systems; there are no current ‘hooks’ to allow easy mounting of AppleShare volumes programmatically. It gets pretty nasty trying to figure out everything that is necessary to accomplish this, which is why people here pretty much stay away from this as well. Also, some low-level stuff may be proprietary, which is why the tool is supplied for developers. ‘Choose’ is described in the MPW docs. It should be pretty straightforward to use.
Networking & Communications: AppleShare: Apple II Aristotle “Access Privileges” recommendations
What is the reason that when I try to log into AppleWorks 3.0 network through Aristotle on an Apple IIGS® I get the message “System error in Server/ Server.Setup / CDevInit See your Network Administrator”?
It sounds like the access privileges for the System folder (the one containing the Apple IIGS System files) are set wrong. I recommend that the System folder and all of the folders within it, and the Icons folder (the folder that contains the Apple IIGS icon files) be set to Bulletin Board (if you use an Apple IIGS to set the privileges) or See Folders = Everyone, See Files = Everyone, Make Changes = Owner, where the Owner is the system administrator.
Networking & Communications: AppleShare: Detecting AppleTalk being closed down by user
How do I detect that a user has closed down my AppleTalk® connection (by turning AppleTalk off from the Chooser or by changing network connections from the Network control panel)?
The AppleTalk Transition Queue provides a means to determine when the AppleTalk drivers change status or when they might be closed in the very near future. The Transition Queue informs its clients (everyone who has asked to be added to the queue) each time the state of the .MPP driver changes state (opened or closed) or is about to change state.
The AppleTalk Transition Queue is documented in Inside Macintosh VI, Chapter 32 (The AppleTalk Manager) and is also documented in the Macintosh® AppleTalk Connections Programmer’s Guide, Chapter 3 (“Calls to the LAP Manager”), available from APDA.®
Networking & Communications: AppleShare: How to tell if application’s running on a server
What is the best way to determine if a Macintosh® application is running on a server?
For 2.0.1 you can test the longword at $B50. If it is 0 or -1, the server is not running. If it isn’t—i.e., it’s a real address—then the server is either starting up, or is running. There might be a hook available in future versions of AppleShare which your process can hook into.
Networking & Communications: AppleShare: Server Move & Rename folder
A folder is created in the Server Folder called “…Move & Rename.” What is this and what are its contents? Should it be backed up? Are there any other temporary folders and files that might need to be backed up?
It’s the “$01$02$03Move & Rename” folder that AppleShare 2.0.1 and future versions create for the two-step process of moving and renaming a file or a folder, a feature that is not provided via HFS. It should be backed up, but in general will not contain anything. (It has something in it only for a brief instant and only if the server has IBM PCs or some other computer that uses this call. Macintosh systems don’t.) It needs to be backed up for 2.0.1 so that the folder is there if the server is restored. (Otherwise, Admin will have to be run to create a new one, a somewhat disconcerting action to perform after completely restoring a file server.)
Networking & Communications: AppleShare: 2.0.1 PBHGetDirAccess and PutDirAccess restrictions
If a volume is connected to an AppleShare server, but is not an AppleShare volume, will the PBHGetDirAccess (and PutDirAccess) function work on it? Can an INIT on the server make these calls?
For AppleShare 2.0.1, the INIT cannot make these calls on non-file server volumes. In future versions, the PBHGetDirAccess and PutDirAccess calls can safely be made on all volumes connected.
Networking & Communications: AppleShare: AppleShare user limit
What is the maximum number of users that can be logged in to any one AppleShare® file server? What can we do to increase the limit? Will upgrading to AppleTalk® Phase II help? Is there an upgrade to the AppleShare 2.0.1 software?
AppleShare currently has a limit of 50 simultaneous users. This is a limitation in the software and is not related to AppleTalk. Changing from AppleTalk Phase I to Phase II will not change anything. The next version of AppleShare might raise this limitation. We do not have any projected dates for a release of the next version of AppleShare. You may want to periodically check with APDA® for any update or new release.
Networking & Communications: AppleShare: Maximum number of users supported by AppleShare for each CPU
What is the maximum number of users supported by AppleShare®? Does this number change based on the type of CPU being used for the server?
The following chart lists some current AppleShare limits (AppleShare 1.1, 2.0, and 2.01) which are based upon the chosen server platform and memory configuration. The limits which otherwise might be present on a workstation are still in effect, and are not affected by the workstation being logged into an AppleShare server. These limits will change in the future.
Server machine is Macintosh Plus, SE, or II with one MB:
Number of users: 25
Number of locked ranges: 1000
Number of open files: 80
Number of volumes: 16
Server machine is Macintosh II with more than one MB:
Number of users: 50
Number of locked ranges: 2000
Number of open files: 160
Number of volumes: 16
Networking & Communications: AppleShare: Accessing the Server Folder on the AppleShare file server
I am trying to access the Server Folder on AppleShare® file server from my program. I have tried AFP (AppleTalk Filing Protocol) calls OpenDir and EnumerateCatalog, but they cannot access the Server Folder. Is there another method to access a Server Folder?
No. Access to the Server Folder of an AppleShare server is not possible except during local maintenance of the AppleShare server. It is then only accessible through the Finder™ while the AppleShare server application is not running.
Networking & Communications: AppleShare PC: AppleShare PC 2.0 changes
What are the new changes to AppleShare® PC 2.0?
AppleShare PC 2.0 was designed to affect developers in a MINIMAL way, so there were some very MINOR changes to the way programmers interact with AppleShare PC 2.0.
• The Int60 mechanism no longer exists; now far calls to the code are made.
• DS:BX no longer contains the parameter block pointer; ES:BX does.
• Commands 4, 5, 6, and 7 are no longer supported.
• The Open Data-Link Interface (ODI) was used and adhered to in the design of AppleShare PC 2.0.
• Compat.com was created and included to make all previous applications useable and compatible with AppleShare PC 2.0.
If your application uses any of these older methods (as outlined in the “LocalTalk® PC Card and Driver Preliminary Notes”), compat.com “translates” the interface to one which AppleShare 2.0 is able to use (that is, put DS:BX into ES:BX, make a far call to the code, and call different commands which replace commands 4,5,6 and 7).
ODI, which was co-developed with Novell, makes it possible for many different cards with different drivers to be usable by different upper-layer protocols. If there are ODI drivers for a given TokenRing/Ethernet/LocalTalk card, AppleShare PC 2.0 will work over TokenTalk/EtherTalk/LocalTalk. Currently, there are several drivers provided with AppleShare PC 2.0: IBM TokenRing drivers (IBM TokenRing cards—short, long and MCA), two Ethernet drivers (EtherLink MC Adapter card, and EtherLink II card), and the LocalTalk PC card driver. For more information about ODI, and/or becoming an ODI developer, contact Scott Lemon at Novell.
To use the AppleTalk® protocol stack (included as part of AppleShare PC 2.0), you need to reference the “LocalTalk PC Card and Driver Preliminary Notes” (August 3, 1987). These notes detail the AppleTalk stack and the PC interfaces to the stack. The “LocalTalk PC Card and Driver Preliminary Notes” document is available through APDA® (Order #M7055).
Networking & Communications: AppleShare PC: AppleShare PC 2.0 supports EtherTalk and TokenTalk
Does AppleShare® PC support EtherTalk®? TokenTalk®?
AppleShare PC v2.0 supports both EtherTalk and TokenTalk. Cards that work
include:
• 3Com’s EtherLink and EtherLink/MC Ethernet cards
• IBM’s TokenRing cards (long, short and MCA)
• DayStar Digital’s LocalTalk® board
Networking & Communications: AppleTalk: How to get the User and Computer names used by AppleTalk
I’d like to use the same names that the system uses to identify itself on the AppleTalk network in my program. Where can I find those names?
The names used by the system for network services are stored in two 'STR ' resources in the System file. Your program can retrieve those names with the Resource Manager’s GetString function.
Only one of the names is available in systems before System 7; the name set by the Chooser desk accessory. That name is stored in 'STR ' resource ID - 16096. Under System 7, the Sharing Setup control panel lets the user assign two names for network services: the Owner name and the Computer name.
The Owner name is the name stored in 'STR ' resource ID -16096 and it identifies the user of the Macintosh. The Owner name is used by System 7 for two primary purposes: to identify the owner of the system when accessing the system remotely through System 7 File Sharing or the user identity dialog used by the PPC Toolbox (and Apple Event Manager), and as the default user name when logging on to other file servers with the Chooser.
The Computer name (also known as “Flagship name”) is the name stored in 'STR ' resource ID -16413 and used to identify the Macintosh. The Computer name is the name used by system network services to identify themselves on the AppleTalk network. For example, if your system’s Computer name were "PizzaBox", the PPC Toolbox registers the name “PizzaBox:PPCToolBox@*” when you start Program Linking and File Sharing registers the name “PizzaBox:AFPServer@*” when you start File Sharing.
Networking & Communications: AppleTalk: Which AppleTalk routines can & can’t be called at interrupt time
Can any AppleTalk routines be called at interrupt time? Inside Macintosh says that DDPWrite and DDPRead can’t be called from interrupts. If all higher-level AppleTalk protocols are based on DDP, it seems that they all would not work.
The AppleTalk routines you can’t call at interrupt time are the original AppleTalk Pascal Interfaces listed in Inside Macintosh Volume II; these are also known as the “Alternate Interface” AppleTalk routines, or ABPasIntf.
The Alternate Interface routines cannot be called at interrupt time because they allocate the memory structures needed to make the equivalent assembly language AppleTalk call. For example, when the NBPLookup routine is called, it’s passed a handle to an ABusRecord. NBPLookup then has to allocate an MPPParamBlock and move the parameters from the ABusRecord into the newly allocated MPPParamBlock. Then NBPLookup makes a LookupName call, passing it the MPPParamBlock. When LookupName completes, NBPLookup must move results into the ABusRecord and release the memory used by the MPPParamBlock. Since memory is allocated and released within the routine, it cannot be called at interrupt time.
With that out of the way, the calls you can make at interrupt time (with some restrictions listed below) are what Apple calls the “Preferred Interface” AppleTalk routines. Most of the Preferred Interface routines are listed on page 562 of Inside Macintosh Volume V. There are a few additional calls that were added after the publication of Inside Macintosh Volume V; they’re documented in the AppleTalk chapter of Inside Macintosh Volume VI.
The Preferred Interface AppleTalk routines can be made at interrupt time as long as:
• You make them asynchronously with a completion routine (that is, the asynch parameter must be TRUE and you must provide a pointer to the completion routine in the ioCompletion field of the call’s parameter block). Making a call asynchronously and polling ioResult immediately afterward within the same interrupt-time code (which is basically the same as making the call synchronously) is not the same as using a completion routine.
• They are not listed as routines that may move or purge memory. The Preferred Interface routines do not allocate or dispose of any memory, since they’re just high-level ways to make the assembly language AppleTalk calls and are not built upon the old Alternate Interface routines.
X-Ref:
Macintosh Technical Note #121, “Using the High-Level AppleTalk Routines”
Macintosh Technical Note #132, “AppleTalk Interface Update”
Macintosh Technical Note #142, “Avoid Use of Network Events”
Networking & Communications: AppleTalk Data Stream Protocol (ADSP): PPC Toolbox and its use of AppleTalk protocol layers
Can I use the PPC Toolbox’s program linking dialog interface via the PPCBrowser function with AppleTalk protocols such as ADSP, ATP, and DDP? If not, can I access the ADSP data structures used by the PPC Toolbox?
The PPCBrowser function is for use by applications that use the PPC Toolbox, high-level events, or Apple events (high-level events and Apple events depend on the services of the PPC Toolbox). The PPCBrowser uses the functions GetZoneList, PLookupName, and IPCListPorts to fill the AppleTalk Zones, Macintoshes, and Programs lists in the program linking dialog. Since the IPCListPorts function returns a list of PPCPorts at a particular location, it isn’t useful for AppleTalk protocols and thus, makes the PPCBrowser function unsuitable for use with AppleTalk protocols which don’t have PPCPorts associated with them. It’s fairly easy for an application to create a browsing dialog for AppleTalk protocols that has two lists, one for zones found with GetZoneList and one for entity names found with PLookupName. See the “dmz” example on the Macintosh System Software 7 Golden Master CD for example code that builds two such lists.
Although the PPC Toolbox currently uses ADSP as the transport mechanism to communicate with other Macintosh systems, the ADSP structures used by the PPC Toolbox aren’t accessible for good reason: The transport mechanism used by the PPC Toolbox could change in the future to support other transport mechanisms besides ADSP. (On the local machine, PPC transfers the data directly, circumventing ADSP.) If you really need to use ADSP in a way that the PPC Toolbox does not, then you should skip the PPC Toolbox and use ADSP directly.
Networking & Communications: AppleTalk Data Stream Protocol (ADSP): ADSP dspAttention and attention retransmit timer interval
I’m having problems with the AppleTalk Data Stream Protocol (ADSP) call dspAttention. Sometimes it takes several minutes for dspAttention to complete. I’ve tried using ADSP 1.5.1 with System 6.0.7 and ADSP 56, which ships as part of System 7.
ADSP 1.5.1 (and ADSP 56) no longer uses the attnInterval field in the DSPParamBlock for the attention retransmit timer interval. Instead, the attention retransmit timer interval is based on the round-trip time of ADSP data packets. When a connection end is established, the attention retransmit acknowledged, the attention retransmit timer interval is adjusted for the connection speed. This mechanism works well when a connection end is established, an ADSP connection is opened, the connection is used, the connection is closed, and then the connection is eliminated.
A problem in this mechanism can surface when a connection end is established and is reused over and over for several ADSP connections. When a connection is closed and then a new connection is opened using the same connection end, the attention retransmit timer interval is not reset to the default starting value (the problem). Instead, some garbage value in memory is used. If the first ADSP attention packet or the acknowledgment packet returned for that attention packet is lost on the network, ADSP will use the “garbage” value for the attention retransmit timer interval and it could take several minutes for ADSP to retry sending the attention packet.
This has been fixed for versions of ADSP greater than version 56 and will be available soon (maybe by the time you read this message). Until then, the only workaround is to use a new connection end for every new ADSP connection requiring ADSP’s attention mechanism.
Networking & Communications: AppleTalk Data Stream Protocol (ADSP): ADSP closes connections on eClosed or eTearDown events
When I receive an eClosed or eTearDown ADSP connection event, do I have to close my end of the connection, or does ADSP close it automatically?
When you get a eClosed unsolicited event, it means the other (remote) side of the ADSP connection sent a Close Connection Advice control packet and ADSP has closed the connection. It is purely advisory and does not require you to take any action. The Close Connection Advice control packet allows ADSP to close connections faster than just waiting for the connection to time-out due to the open timer expiring.
When you get a eTearDown unsolicited event, it means the network connection with other side of the ADSP connection was lost (the open timer expired) and ADSP has closed the connection. Again, it is purely advisory and does not require you to take any action.
The ADSP chapter of Inside AppleTalk® (Chapter 12) might help other questions you have about ADSP in the future since it explains how ADSP works beneath the Macintosh® implementation documented in Inside Macintosh® Volume VI.
Networking & Communications: AppleTalk Data Stream Protocol (ADSP): AppleTalk Data Stream Protocol references
Where are the AppleTalk® Data Stream Protocol (ADSP) calls documented?
APDA® has a product called “ADSP: AppleTalk Data Stream Protocol Development Kit” that gives you ADSP and the ADSP call descriptions. ADSP and ADSP interfaces can be found on the Developer CD and can be used for your development purposes. However, you’ll need to license ADSP through Apple Software Licensing (AppleLink®: SW.LICENSE) before you ship your product.
If you want to use ADSP, then you should read ALL of the documentation. There are various tips and explanations that may be vital to your implementation of ADSP in your product. It is useful for transferring data between machines and provides built-in error checking to ensure that you do receive the data at the other end. For these reasons, you should read Inside AppleTalk, Chapter 12, Apple Data Stream Protocol, to make sure you utilize it to its fullest.
Networking & Communications: AppleTalk Data Stream Protocol (ADSP): Sending broadcast packets to transmit data to multiple clients
How do I broadcast information over AppleTalk® using the Communications Toolbox (CTB) and the AppleTalk Data Stream Protocol Development (ADSP) Tool or multiple access? I cannot find any significant information regarding broadcast or multiple access transmissions.
There is no supported method to send broadcast packets to transmit data to multiple clients. The reason is that this method does not ensure the data was received by every client. It is possible to lose a packet on a network before it reaches a client even though it may reach the others. If this is the case then the data is lost forever for this client unless you resend the packet. This is highly inefficient and unreliable.
If you want to have multiple clients, then you’ll need to write your own server software that can handle multiple clients logged on simultaneously. The server will then need to keep a record of every connection and its corresponding transaction ID even though you will be sending the same information to each client; this is to ensure that each client receives the data. Following the ADSP protocol should be enough for you to implement this server/client connection and ensure that the data is reliably transmitted to each node.
Networking & Communications: AppleTalk Data Stream Protocol (ADSP): Using ADSP with AppleTalk for Apple’s VMS
I am trying to create a simple program to try ADSP (AppleTalk® Data Stream Protocol) with AppleTalk for Apple’s VMS (version 2). I started the bridge process but got an access violation on the first call.
You need to make three calls before you can call any other functions with AppleTalk for VMS. These calls are:
ATK$INIT_ATALK
ATK$INIT_PORT
ATK$OPEN_PORT
Then you can use the other routines.
Networking & Communications: AppleTalk Filing Protocol (AFP): How an AFP volume’s allocation block size is calculated
The AppleTalk Filing Protocol (AFP) doesn’t appear provide a way to learn about the allocation block size of a server volume. So, how is the allocation block size determined on AFP server volumes? I noticed that the Macintosh® Finder™ seems to calculate “size on disk” erratically for files on some AFP server volumes. Is that a related problem?
All the workstation can get from an AFP server is the Bytes Total and Bytes Free (returned by FPGetVolParms and FPOpenVol), so the AFP workstation code estimates the value it uses in the allocation block size field (vcbAlBlkSiz) of the volume control block (VCB). The workstation code comes up with a value for vcbAlBlkSiz from the Bytes Total value returned to FPOpenVol when the volume is opened. The calculation used is:
vcbAlBlkSiz := round((BytesTotal / (512 * 65536)) + 0.5) * 512;
This is the same value a local HFS volume would use. If an AFP server is not running on a Macintosh (and then, probably not using HFS), then this value may not be what the server platform is actually using. And yes, the Finder uses the allocation block size in its calculations to decide how much space is used by a file, so the “size on disk” may not exactly reflect the amount of disk space actually used.
Networking & Communications: AppleTalk Filing Protocol (AFP): AFP 2.0 FPRead NewLine Mask change
I’m confused about the changes to FPRead in AFP (AppleTalk® Filing Protocol) version 2.0. How do I use the NewLine Mask?
The difference between AFP 1.1 and AFP 2.0 as far as the NewLine Mask is concerned is that, in AFP 1.1, the only legal values of NewLine Mask are $00 and $FF, whereas in AFP 2.0, all values of NewLine Mask are allowed. The NewLine Mask is logically ANDed with a copy of each byte read. If the result matches the NewLine character, the read terminates. The NewLine character is returned as the last byte of data that was read from the fork.
Networking & Communications: AppleTalk Session Protocol (ASP): ASPOpenSession error -17 bug fixed for next System 7 beta
Why does an attempt to open a remote database file that is hosted under both Macintosh® System 6.0.x and 7.0ß1 cause the AppleTalk® ASPOpenSession routine to always returns the error code -17 (I/O control error)?
This is a known bug with System Software 7.0ß1 and has been fixed, so the next release of 7.0 that you get should work again. I checked to see if there was a work-around that you might be able to patch into your application for 7.0ß1 but there isn’t.
Networking & Communications: AppleTalk Session Protocol (ASP): Server side of AppleTalk Session Protocol
I have the client side of the AppleTalk® Session Protocol (ASP), but not the server side. How do I get the server side of the protocol?
Apple only provides the interfaces and the driver for the workstation side of the ASP. We do not provide interfaces or the driver for the server side.
Depending upon your project, you can either use Apple’s implementation of an ASP/AFP server (AppleShare®) or write your own ASP server side of the protocol.
Networking & Communications: AppleTalk Tools: AppleTalk Peek and Poke tools
Is there an update for the Apple tool called Poke?
The following versions of Peek and Poke are current:
AppleTalk Peek 3.1
AppleTalk Peek 3.2d5
AppleTalk Poke 3.1
You’ll find them on Lord of the Files, the latest Developer CD Series disc, in Tools & Apps:Networking & Communications:AppleTalk Tools.
Networking & Communications: AppleTalk Transaction Protocol (ATP): Responder protocol documentation not available
Can you please point us to the note that describes the Responder protocol? I recall seeing it documented somewhere.
If you have seen any Responder documentation around, it must be bootleg documentation. After talking with the AppleTalk® engineers, I was assured that this documentation is not available. Some people wanted it available; others didn’t. Guess who won.
Anyway, the Responder uses ATP (AppleTalk Transaction Protocol) as well as AEP (AppleTalk Echo Protocol) to send/receive data from one machine to another. If you have a copy of Peek and Inter•Poll you can check this out on the network to better understand it. It’s a pretty straightforward implementation. AEP and ATP are documented in Inside AppleTalk. These, coupled with Gestalt or SysEnvirons, to get any machine-specific information you may wish to send, should be all you need to understand how the Responder works.
Networking & Communications: Connection Manager (CTB): Systems 6 & 7 Macintosh Comm Toolbox (CTB) installation
How do users install the Macintosh Communications Toolbox (CTB)?
The Communications Toolbox consists of two parts: the CTB managers and the CTB tools. The installation procedure for CTB tools is different between System 6 and System 7. Under System 6 the CTB tools are dragged from the Basic Connectivity Set disk to the Communications Folder in the System Folder on the hard disk. Under System 7 the CTB tools are dragged from the Basic Connectivity Set disk to the Extensions folder in the System Folder on the hard disk. Of course, because of the way System 7 works, CTB tools can simply be dragged to the System Folder and the Finder will automatically move them to the Extensions folder where they belong.
No installation of the CTB managers is required under System 7, since System 7 includes the Communications Toolbox as part of the system. Users running System 6.0.5 should use the Installer and Install script on the Communications 1 disk to install the CTB managers and other resources onto their hard disks. Users running System 6.0.7 should use the Installer and Install script on the Network Products Installer disk, which is part of the System 6.0.7 set users receive with their Macintosh systems. The Network Products Installer disk does not contain the CTB managers and other resources, but it prompts the user to insert the Communications 1 disk during the installation procedure.
The Basic Connectivity Set and Communications 1 disks should be shipped with your CTB-aware product. Contact Apple’s Software Licensing group (AppleLink SW.LICENSE) for a licensing agreement to ship the disks.
Networking & Communications: Connection Manager (CTB): Macintosh CTB CRMSerialRecord documentation correction
Macintosh CTB CRMSerialRecord documentation correction
On page 183 of Inside the Macintosh Communications Toolbox, the CRMSerialRecord data structure contains two fields, inputDriverName and outputDriverName, declared as type StringHandle. These two fields are erroneously described as “pointer to Pascal string” in the documentation further down the page. The correct declaration is type StringHandle.
Networking & Communications: Connection Manager (CTB): Macintosh Communications Toolbox resource ID conflicts
Macintosh Communications Toolbox resource ID conflicts
MPW’s Simple I/O Window (SIOW) package is incompatible with certain Macintosh Communications Toolbox (CTB) Tools because of difficulties with CMGetConfig and CMChoose. The CTB and Tools do a somewhat imperfect job of looking in the correct resource map for string components used in CMGetConfig; the application-defined 'STR ' IDs override the correct Tool defined IDs. CMChoose has a similar problem with 'CNTL' resource conflicts.
This problem is not confined to SIOW; it can happen for any application. In the case of SIOW, it is particularly frustrating since SIOW is a precompiled library and you can’t simply change resource IDs to ones that don’t conflict. Also, you cannot be certain that you won’t ever conflict in this manner for any arbitrary Tool and application.
There is a workaround to this situation which should be used for all applications, not just SIOW-based apps. The CTB makes sure that resource maps for Tools are searched after the system resource map—that is, instead of the resource chain looking like this:
ROM (resource lookup progresses from the bottom up)
System
Application
Document
Tool
it looks like this:
ROM
Tool
System
Application
Document.
The workaround is to save the current resource file reference, set the current resource file to the System file, and return to the proper resource file after completing CMGetConfig or CMChoose. Here is a C code fragment illustrating this technique:
{ ...
short saveResFile;
Point displayPt;
Ptr cfgString;
...
// save the current resource file
saveResFile = CurResFile();
// set resource file to the System file
UseResFile(0);
// call CMChoose to configure the Tool
err = CMChoose(&connectionHdl,displayPt,NULL);
// call CMGetConfig to get the configuration string
cfgString = CMGetConfig(connectionHdl);
// restore proper resource file
UseResFile(saveResFile);
...
}
and again in Pascal:
VAR
...
saveResFile : INTEGER;
displayPt : Point;
cfgString : Ptr;
BEGIN
...
{save the current resource file}
saveResFile := CurResFile;
{set resource file to the System file}
UseResFile(0);
{call CMChoose to configure the Tool}
err := CMChoose(connectionHdl,displayPt,NIL);
{call CMGetConfig to get the configuration string}
cfgString := CMGetConfig(connectionHdl);
{restore proper resource file}
UseResFile(saveResFile);
...
END;
Networking & Communications: Connection Manager (CTB): Mac Communications Toolbox (CTB) theEnvirons initialization
Mac Communications Toolbox (CTB) theEnvirons initialization
The Macintosh Communications Toolbox (CTB) Connection Manager and Terminal Manager each support a “get environment” function in order that the application can obtain the current environment of the connection or terminal record. They are declared as follows in the Pascal interface files:
FUNCTION CMGetConnEnvirons(hConn: ConnHandle;
VAR theEnvirons: ConnEnvironRec): CMErr;
FUNCTION TMGetTermEnvirons(hTerm: TermHandle;
VAR theEnvirons: TermEnvironRec): TMErr;
and in the C header files:
pascal CMErr CMGetConnEnvirons(ConnHandle hConn,
ConnEnvironRec *theEnvirons);
pascal TMErr TMGetTermEnvirons(TermHandle hTerm,
TermEnvironRec *theEnvirons);.
“Inside the Macintosh Communications Toolbox” does not make it clear that the respective theEnvirons parameter blocks used for these two functions require initialization for the functions to operate correctly. For CMGetConnEnvirons, theEnvirons.version should be initialized with the constant curConnEnvRecVers; similarly, TMGetTermEnvirons needs theEnvirons.version initialized with the constant curTermEnvRecVers. These constants are defined in Connections.p and Terminals.p (Connections.h and Terminals.h for C).
Initializing theEnvirons properly will prevent error result codes envBadVers or envVersTooBig. On return with cmNoErr or tmNoErr results, CMGetConnEnvirons and TMGetTermEnvirons will have filled in theEnvirons correctly for the version you specified and will update theEnvirons.version with the current revision level of the environment function call.
Networking & Communications: Connection Manager (CTB): Macintosh Communications ToolBox (CTB) initialization
Is there a way to tell if Macintosh Communications ToolBox (CTB) is already initialized? The CTB documentation says to make initialization calls once and only once.
The CTB documentation isn’t really true in that regard. It was originally thought that you couldn’t re-initialize the CTB, but that was changed, and it is safe to do so.
Networking & Communications: Connection Manager (CTB): Installer 3.2 and Macintosh Communications Toolbox
How do we make the Macintosh Communications Toolbox (CTB) installation script work with Installer 3.2 for users running System 6.x?
The current installer script for the CTB is not compatible with Installer 3.2, nor will it be in the near future. Installer 3.2 was designed to be compatible with System 7.0. Because the CTB is included with System 7.0, and Systems 6.0.5 and 6.0.7 come with the installation disk necessary to install the CTB, there’s no need to update the script. There isn’t really any Apple-approved way to make the script Installer 3.2-compatible.
Your users who are still using System 6.0.7 (or earlier) need to install the CTB separately from your product. They should have the installation disks necessary to install the CTB on their system. For System 6.0.5, they’ll need to use the Installer and Install script on the Communications 1 disk to install the CTB managers and other resources onto their hard disks. Users running System 6.0.7 should use the Installer and Install script on the Network Products Installer disk, which is part of the System 6.0.7 set users receive with their Macintosh systems. The Network Products Installer disk does not contain the CTB managers and other resources, but it prompts the user to insert the Communications 1 disk during the installation procedure.
The Basic Connectivity Set and Communications 1 disks should be shipped with your CTB-aware product. Contact Apple’s Software Licensing group (SW.LICENSE on AppleLink) for a licensing agreement to ship the disks. This will also help ensure that the users are using the version of the tool(s) that is most compatible with your product.
Remember to use Gestalt to make sure that you have the Communications ToolBox available, and check to make sure that the tools you need are available as well. For specific information on using Gestalt, please refer to Inside Macintosh Volume VI and Macintosh Technical Note #129, “_Gestalt and _SysEnvirons-A Never Ending Story.”
Networking & Communications: Connection Manager (CTB): Macintosh Communications ToolBox documentation
Can you point me to documentation on the Macintosh Communications Toolbox?
Inside the Macintosh Communications Toolbox (Addison-Wesley, APDA #M1215LL/A, $24.95) is a nice, comprehensive manual, detailing how to write programs that use the Communications Toolbox. In addition, the documents for the newly updated Macintosh Communications Toolbox 1.1 APDA packages are useful supplements to the Addison-Wesley reference.
Networking & Communications: Connection Manager (CTB): Customizing a modem’s initialization string
How do you customize the intialization string of a modem?
If the user holds down the option key while clicking on the Modem Type Popup menu in the lower left corner of the “Apple Modem Tool” dialog box, then an additional menu item appears. This item is called “custom,” and when selected, it brings up another dialog that contains the initialization string of whichever modem type (such as Hayes or Apple Personal) was LAST selected. You can then customize the intialization string to whatever you want it to be. In other words, select the modem, use the option-select method to get to custom, and then edit the init string.
Networking & Communications: Connection Manager (CTB): Connection Manager and connection records
When my application quits after using the Connection Manager to create a connection record but before the record is disposed, I can no longer create a connection record. Even if I exit the application and re-launch, it still does not work unless I re-boot. Is this a bug?
The behavior you describe is normal for Communications ToolBox 1.0. This has to do with how the CTB manages mapping shareable resources, heap zones, Resource Manager interactions, and all that. If you have a ConnectionHandle in a heap zone which is opened and you then dispose of the heap zone without closing it, the Connection Manager will be confused about life in general until you restart the Macintosh.
Networking & Communications: Connection Manager (CTB): Macintosh Communications Toolbox manual init correction
Macintosh Communications Toolbox manual init correction
The latest Macintosh Communications Toolbox manual says InitCTBUtilities should be called after InitCRM (page 192), but it should be the other way around. Call InitCTBUtilities before InitCRM, as do SurferPlus and Sessions.
System 7 initializes all appropriate CTB utilities itself, so it shouldn’t matter which order you call these routines if you’re using System 7, but it does matter for earlier versions of the operating system.
Networking & Communications: Connection Manager (CTB): Use Gestalt to check for Macintosh Connection Manager support
My driver uses the Macintosh® Communications Toolbox. How can I check to make sure the system software version supports CTB?
The solution to this sort of problem is to use the Gestalt mechanism to find out precisely what services/features are available. Full information on using Gestalt is available in Inside Macintosh Volume VI, on your System 7.0 CD. Gestalt can be called at interrupt time so drivers can use it, although there is a caveat included in the documentation. Also, using MPW 3.2 or later, you can call glue code that will let you use Gestalt even if it is not in ROM or in the System file, which is handy. This should provide exactly what you need for your driver.
Networking & Communications: Connection Manager (CTB): Trapping the “connect” message returned to CTB AMT by a network
When I use the Macintosh® Communications Toolbox (CTB) Apple Modem Tool (AMT) to dial and connect to Telenet or CompuServe, I never see the “connect” message returned by the network. Does the tool remove the “connect” message? If so, how can I trap on the “connect” message?
The Communications ToolBox (CTB) Apple Modem Tool traps the keywords, such as “Connect,” and does not pass this information on to the application. You’ll need to set a search stream using CMAddSearch.
Networking & Communications: Connection Manager (CTB): Macintosh Communications Toolbox Reference changes
Is the new Addison-Wesley Macintosh® Communications Toolbox Reference significantly different from the MacintoshCommunications Toolbox 1.0 reference manual that’s been available from APDA® for a while?
The Addison-Wesley manual has more information regarding extensions to the File Transfer Manager. It also has a description of the scripting interface to the tools and the Basic Connectivity Set, as well as having some of the text reworked. If you’re unsure about buying it, try taking a look at it first at a computer bookstore.
Networking & Communications: Connection Manager (CTB): How to obtain Macintosh Communication Toolbox
Does System 7.0 ship with the Macintosh® Communications Toolbox?
Though the Communications Toolbox is a part of System 7.0, the Communications Tools are not. They are, however, available from APDA® as the following products:
• Macintosh Communications Tools Basic Connectivity Set, Version 1.0 (part # M0379LL/B)
• LAT: Local Access Transport Connection Tool, Version 1.0 (M0800LL/A)
• Serial NuBus™ Tool, Version 1.0F11 (M0950LL/A)
• VT320 Terminal Emulation Tool, Version 1.0 (M0801LL/A)
You can license the above tools through Software Licensing. If you need the Communications Tools (or any other connection tool) to run a third-party product, the software probably is provided as part of the third-party product. The specific tools you need depend on the third-party product.
Networking & Communications: Connection Manager (CTB): Macintosh CTB initialization calls from nonapplications
What are the effects of InitCM, InitCRM, InitCRMUtilities, and similar calls to the Macintosh® Communications Tools by nonapplications such as INITs or background processes? What effect do multiple INIT calls have on Communications Tools operations and any existing connections? What do these calls do, and when (and how many times) is it safe to call them?
All these initialization calls deal with the process of loading the 'cmtb' resource into the system heap, putting entries into the Communications Toolbox (CTB) dispatch table with references to the current heap zone, and setting up various things having to do with resource management for the operation of the CTB. You can call them over and over again without damaging existing information.
With the perspective provided by that information, you can see that a synergy exists between operations of the CTB and the Resource Manager. The CTB needs to be in the appropriate heap zone when a ConnHandle is generated or referenced for it to operate as desired. If you’re writing a background process that maintains its own persistent heap zone, you shouldn’t have any difficulties using the CTB.
If you’re writing an INIT, matters are more complex. You must SetZone(SystemZone) while performing all CTB operations (including initialization, CMGetProcID, and CMNew) to be sure the heap zone will persist after the INIT has completed. Possibly the reason for doing this at INIT time is to create ConnHandles that will persist for CTB access at a later time. It seems reasonable that ConnHandles thus created require a SetZone(SystemZone) by any routine that needs to access them for Read/Write/Status/Delete operations.
Networking & Communications: Connection Manager (CTB): How to “de-install” Communications Toolbox under System 6.0.x
I have installed the Macintosh® Communications Toolbox (CTB) under System 6.0.7. What do I need to do to “de-install” it?
As you launch the Comm Toolbox Installer, hold down the option key. When the installer window comes up, you can toggle back and forth between the install and remove options using the option key.
Networking & Communications: Connection Manager (CTB): OK to use Communications Toolbox in DRVRs, cdevs, and INITs
Can the Macintosh® Communication Toolbox (CTB) be used in a DA? InitCM has to be called and the manual says to only call it one time (implies a crash if it is called twice). Is there any way to know if CM has already been INITed?
Yes, it is all right to call CTB Initialization routines from CODE Resources. This includes DRVR, cdev, and INIT. The CTB Reference Manual was not clear about this.
Networking & Communications: Datagram Delivery Protocol (DDP): AppleTalk and 'INIT's
Does AppleTalk work the same with an 'INIT' as with an application? I’m using only Name Binding Protocol (NBP) and Datagram Delivery Protocol (DDP) stuff.
Yes! Responder is an example of an 'INIT' that utilizes the NBP to register a Macintosh on the network. NBP requires DDP, so it is also present. AppleTalk is loaded before any 'INIT's, which makes it available to them.
Networking & Communications: Datagram Delivery Protocol (DDP): Datagram Delivery Protocol (DDP) header checksum field
Does the Macintosh® client pay attention to and validate Datagram Delivery Protocol (DDP) checksums within long DDP packets received?
DDP is a client of the AppleTalk Transaction Protocol (ATP), which is a client of the AppleTalk Session Protocol (ASP) and AppleTalk Filing Protocol (AFP). DDP is told by the entity for whom it is a client whether it should use checksumming. For performance reasons, our version of ATP does not specify that DDP use the checksum. Both AppleShare® and the AppleShare client are out of the loop; neither can specify whether or not to use the DDP checksum.
The LAP layer performs checksumming, ensuring no on-the-wire corruption. The only benefit of DDP checksumming is end-to-end corruption detection when the packet has travelled over a malicious router that has validly received a DDP packet on one net, changed the packet, re-computed the LAP checksum, and sent it out on another cable. Because of the performance hit of DDP checksumming and the rarity of such a malicious router, it was decided not to request DDP checksumming.
Networking & Communications: Datagram Delivery Protocol (DDP): Communication between players in a game on an AppleTalk network
How can I use the broadcast mode in an AppleTalk® DataGram Delivery Protocol (DDP) layer to communicate with the other players of a game that is on a network and not interfere with other network users?
The broadcast mode may seem like a solution, but Apple doesn’t recommend using broadcast mode. Applications like games generally end up sending LOTS of update packets to other players of the games. If your program broadcasts those packets, then all nodes on your network will be interrupted for every packet sent and that can cause performance problems on every machine on a network. In Apple supplied software, broadcast mode is only used when packets need to be sent to every node on a network. For example, Name Binding Protocol (NBP) Lookup packets are broadcast because the network address is unknown.
The following suggestions should help implement communications between players.
The DDP protocol layer does not guarantee delivery of packets (the disadvantage), but has very little overhead (the advantage). If you require delivery of all packets and can take a small additional performance hit, you should use the AppleTalk Transaction Protocol (ATP) layer.
The DDP type you use must be in the range of $10-$FF. The DDP type you choose to use (in that range) probably won’t make a lot of difference unless you define multiple clients to DDP within your socket listener. Packets addressed to your socket will get sent to your socket listener. How you use the type is up to you (as long as you stay out of the reserved range).
You should open a dynamic socket (i.e., use 0 for the socket number and use the socket number in the range $80-$FE that is returned) with the OpenSocket call and then register a name on the network for that socket with the RegisterName call. If all copies of the game register with the same NBP type, then you can use the LookupName call to find other players on the network. Once you’ve found other players and decided who you’re going to play against, you just address each DDP packet to the internet address(es) of the other player(s) socket(s). Several multi-player network games I’ve seen on the Macintosh do just that. (Hint: If you limit games to players on a single network, DDP will use short header packets which are slightly faster to send (8 bytes less per packet).)
If you build a table (array) of network addresses from those playing a game, you can use this algorithm to send a packet to each player.
BEGIN
{ put data into buffer for DDP and set the common parameter
block fields: }
{ Async Flag, Command, Checksum Flag, Source Socket, DDP Type,
BDS Pointer }
{ and Destination Network (if limiting play to a single
network). }
buildPacket;
FOR Player := 1 to NumberOfPlayers DO
BEGIN
{ Set the Destination Node and Destination Socket fields
of the }
{ parameter block to the network address of a player.
That address }
{ would be in an array of network addresses (one for each
player). }
setAddress(Player);
{ Send the datagram to a player using SendDatagram call. }
doSendDatagram;
END;
END;
Networking & Communications: Link Access Protocol (LAP): AppleTalk AOpen and AClose codes 7 & 8
What are AppleTalk messages 7 and 8? They’re documented in lapequ.a as:
AOpen EQU 7 ; Open an ATlk
AClose EQU 8 ; Close an ATlk
but what should the adev do with them and what parameters are passed?
The AOpen and AClose messages are sent when the .MPP driver is opened and closed, respectively. When the AppleTalk driver is closed, a shutdown message is not sent. Instead, the LAP Manager determines whether an adev is version 3 or greater and, if true, assumes that the adev can respond to the AClose message and sends the message. Conversely, when the .MPP driver is re-opened while the adev is active, the AOpen message is sent to the adev (assuming that the adev is version 3 or greater).
An important note on this matter is that if you modify your adev to version 3, additional selectors must be supported. These new selectors will be documented in a forthcoming Tech Note.
Networking & Communications: Link Access Protocol (LAP): Use transition queue to make sure AppleTalk isn’t turned off
How do I check if the user has turned off AppleTalk after I have already started using it?
The best way to determine this information is to submit an AppleTalk transition queue element so that whenever changes to the active state of AppleTalk occur, your program is notified. Check out Inside Macintosh Volume VI, page 32-17, Macintosh Technical Note #250, which discuss this topic. A simple description of the process is as follows.
First, define a transition handler function, which has the following form:
/*
* AppleTalk Transition Queue Sample
*
* Macintosh Developer Technical Support
* ©1990 Apple Computer, Inc.
*
* 10/31/90 pvh
*/
#include <AppleTalk.h>
/*
* Transition queue routines are designed with C calling
* conventions in mind. They are passed parameters with a C style
* stack and return values are expected to be in register D0.
*/
/* defined in IM VI, pgs 32-21&22, and MPW AppleTalk.h and
* AppleTalk.a Includes
*/
#define ATOpenEvent 0 /* MPP just opened */
#define ATCloseEvent 2 /* MPP is closing */
#define ATClosePrepEvent 3 /* OK for .MPP to close? */
#define ATCancelCloseEvent 4 /* MPP close was cancelled */
long main(long selector, ATQEntry *q, void *p)
{
long returnVal = 0;
/*
* This is the dispatch part of the routine. We’ll check
* the selector passed into the task; its location is 4 bytes
* off the stack (selector).
*/
switch(selector) {
case ATOpenEvent:
/*
* Someone has opened the .MPP driver. This is where
* one would reset the application to its usual network
* state (i.e., you could register your NBP name here).
* Always return 0.
*/
break;
case ATCloseEvent:
/*
* When this routine is called .MPP is going to shut
* down no matter what we do. Handle that type of
* situation here (i.e., one could remove an NBP name
* and close down all sessions) p will be nil.
* Return 0 to indicate no error.
*/
break;
case ATClosePrepEvent: {
/*
* This event gives us the chance to deny the closing
* of AppleTalk if we want. Returning a value of
* 0 means it’s OK to close, non-zero indicates we’d
* rather not close at this time. With this event,
* the parameter "p" actually means something.
* p in this event is a pointer to an address which
* can hold a pointer to a string of our choosing.
* This string indicates to the user which task would
* rather not close. If you don’t want
* AppleTalk to close, but you don’t have a name to
* stick in there, you MUST place a nil value in there
* instead. (We’re doing this all locally to this case
* because it’s C and we can, so there.)
*/
char **t;
/*
* Get a new reference to the address we were passed
* (in a form we can use)
*/
t = (char **) p;
/*
* Place the address of our string into the address
* we were passed
*/
*t = "\pBanana Mail"; /* this will either be an
* Ax reference or PC relative,
* depending on compiler
* and options
*/
/*
* Return a nonzero value so AppleTalk knows we’d
* rather not close.
*/
returnVal = 1;
break;
}
case ATCancelCloseEvent:
/*
* Just kidding, we didn’t really want to cancel
* that AppleTalk closing after all. Reset all you
* network activites that you have disabled here
* (if any). In our case, we'll just fall through.
* p will be nil.
*/
break;
default:
/*
* For future transition queue events (and yes,
* Virginia, there will be more)
*/
break;
} /* end of switch */
/*
* return value in register D0
*/
return returnVal;
}
OK, the next thing to do is to use the LAPAddATQ function, passing along the address of the handler, for insertion of the handler into the transition queue. See Inside Macintosh Volume VI, page 32-18, and Tech Note #250 for details. After that, your handler will be called every time some transition event takes place, even if it’s one which you initiated—“like closing down AppleTalk,” for example.
When the application is finished, remember to call LAPRmvATQ to remove the ATQ element; otherwise, AppleTalk will continue to send trans queue messages to a code resource which has since gone away. Oops.
X-Ref:
Macintosh Technical Note #250, “AppleTalk Phase 2 on the Macintosh”
Inside Macintosh Volume VI, Chapter 32, “AppleTalk Manager”
Networking & Communications: MacTCP: MacTCP and SLIP
Does MacTCP actually support SLIP? If not, does Apple plan to provide SLIP support in the future. Does anyone know of any company that does a SLIP for the Macintosh?
SLIP is an asynchronous, serial line protocol developed for running TCP/IP over serial communications lines in a point-to-point configuration. SLIP was developed to transmit IP packets over low-speed, sometimes noisy, asynchronous communications lines where error recovery and an efficient line protocol are needed. The SLIP protocol is now being replaced with a new serial line protocol named “PPP,” which uses a more efficient means of establishing a point-to-point IP connection.
MacTCP includes hooks that let you write different link-layer modules. This makes possible the development of interfaces to SLIP, PPP, and to any other link layer that someone may need, like broadband, X.25, and FDDI. Apple does not currently provide support in MacTCP for SLIP or any other serial line protocol.
Networking & Communications: MacTCP: Terminating a MacTCP asynchronous read operation
After having set up an ASYNC read operation (with a long or infinite timeout), is there any way to cause it to terminate sooner than the timeout, or to abort the read without aborting the connection? Would it work to change the timeout value in the parameter block to a small value?
Unfortunately, PBKillIO isn’t implemented in the MacTCP driver, so you can’t kill the pending operation by the standard Device Manager method.
Changing the value of the timeout or ioResult field is not really a good idea, since the result of doing so isn’t really defined for the Device Manager. Even if this works now, there’s really no way to guarantee that it would work in the future.
The best solution for the least hassle.is to make your timeout smaller, possibly setting it to the value that you would wait before aborting the call in your method. If you want to try the receive again, you can simply re-issue the call from your completion routine without a problem.
If you want to abort a MacTCP call while releasing the stream the call is being performed on, you can issue a TCPRelease. This will kill any outstanding calls on the stream, close the connection (if present), and release the stream. Of course, you said you don’t want to close the connection, so I would still recommend the re-issuing from completion described above.
Networking & Communications: MacTCP: Using MacTCP to communicate different processes on the same Mac
Is it possible to have both the source and the destination application on the same machine if they are using MacTCP sockets to communicate? If so, what should I do to make sure both applications share the processor so this works properly?
It is possible to use MacTCP to communicate to different processes on the same Macintosh computer. Unlike PPC, MacTCP does not bypass the network for same-machine connections, so there is still some “network traffic” involved.
As far as “sharing” the processor goes, this is VERY important in what you are doing. Here’s a brief outline of what you need to do:
• Make asynchronous MacTCP driver calls;
• Completion routines aren’t really necessary; instead, poll until ioResult < 1;
• Call WaitNextEvent or EventAvail while waiting for driver calls to complete (this gives time to the other MacTCP applications);
• Or, instead of calling WaitNextEvent in an “idle” procedure, make your application multi-threaded and yield time while waiting for driver calls to complete.
For a good reference on using “idle procs” to give time to background applications when using MacTCP, refer to the article, “MacTCP Cookbook” in develop magazine, Issue 6 and get the “NewsWatcher” source code from the Developer CD Series. For a reference on using threads to achieve better process time management, you can read the article, “Threads on the Macintosh,” also in develop magazine, Issue 6.
Networking & Communications: MacTCP: MacTCP name server resolver
I am trying to create a TCP/IP server socket and I get the error message from dnr.o “Failed to load name server resolver code -23004.” What is a name server resolver and where should its code be located?
The name server resolver is the piece of code residing in the 'dnrp' resource in MacTCP, which is called to translate a machine name (like apple.com) into an IP address or vice versa. For compatibility with pre-MacTPC 1.1 applications, MacTCP creates a file called MacTCP DNR that the glue code looks for and then executes; you don’t have to worry about creating it.
Networking & Communications: MacTCP: MacTCP hardware requirements
To use MacTCP, do I need just the software or do I need to have any extra hardware on the Macintosh, like an Ethernet card? Can I use MacTCP to set up a socket connection fromLocalTalk to LocalTalk or I need to have some sort of an IP gateway between two Macintosh systems?
You have three choices: First, you can run MacTCP with an Ethernet card and directly connect to any other machine running TCP (including other Macintosh systems). Another choice is to use your LocalTalk port. This requires an additional piece of hardware to do DDP-to-UDP encapsulation (also called KIP encapsulation). One example of this is the Cayman Gatorbox. You can’t do LocalTalk to LocalTalk without the hardware. Your third choice is to use EtherTalk in combination with a KIP gateway such as Fastpath or Gatorbox.
Networking & Communications: MacTCP: MacTCP 1.1 header file incompatibilities and fixes
MacTCP 1.1 header file incompatibilities and fixes
MacTCP 1.1, Apple’s System 7-compatible version of MacTCP, fixes several problems in earlier releases, but doesn’t address several header file incompatibilities. This short note outlines the MacTCP 1.1 header file problems, but it does not include the fixes. Patches in the form of MPW “compare” output are available on Apple’s latest Developer CD Series disc. The new headers are available as part of the “MacTCP Developers’ Kit,” available from APDA (part #M0704/C).
Each header problem is described below, organized by file(s) containing the problem and classified as a general bug or shortcoming, a Think C incompatibility, or a C++ incompatibility. NOTE: The changes have not been thoroughly tested, so use them cautiously.
Problems affecting all header files:
• General problem: Each header file is missing the
#ifdef __cplusplus
extern "C" {
#endif
and
#ifdef __cplusplus
extern "C" {
#endif
which are necessary for C++ unmangling.
• General problem: There are no #ifdefs to prevent including a file multiple times, as in other Apple headers. This was fixed by adding the following to each of the header files:
#ifndef __MACTCPCOMMONTYPES__
#define __MACTCPCOMMONTYPES__
...
#endif
where “MACTCPCOMMONTYPES” is replaced by the name of the header file.
• Think C problem: Think C before 5.0 does not support pascal typedefs, which MacTCP makes use of, so #ifdef THINK_C was added in several instances to declare these pascal typedef functions as type ProcPtr. This fixes the problem.
GetMyIPAddr.h problem:
• General problem: ParamBlockHeader is used as a #define here, conflicting with its use in <Files.h>. The solution is to change the name of the #define to IPParamBlockHeader.
MiscIPPB.h problems:
• General problem: ParamBlockHeader is used as a #define here, conflicting with its use in <Files.h>. The solution is to change the name of the #define to GetIPParamBlockHeader.
• General problem: The structure IPParamBlock is defined in this file with a different definition from the one in GetMyIPAddr.h. The solution is to change the name of the struct.
• General problem: AppleTalk.h is required for successful compilation. Code was added to include this if it has not already been included.
• General problem: icmpEchoTimeoutErr is defined in MacTCPCommonTypes in addition to being defined in MiscIPPB.h. Solution is to remove its definition here.
AddressXLation.h problems:
Think C incompatibility: The “int” type is used within the “hostInfo” structure definition. The default size of an int is different from Think to MPW. In all cases, int in the MacTCP headers should be changed to long.
• Think C incompatibility: The returnRec struct uses an int. Fix is to change to a long as above.
• Think C incompatibility: The CloseResolver() prototype is defined with an empty parameter list, not with a void parameter list. Think C requires the void to consider the definition a prototype. The fix is to add the void keyword as the function parameter list.
• C++ incompatibility: The cacheEntryRecord struct uses a variable named “class”. This causes major problems with C++ compilers, since the class keyword takes on a different meaning in this instance. The fix is to change this to “cacheClass.”
dnr.c problems:
• General/Think C problem: The typedef for OSErrProcPtr was incomplete, causing ambiguity for argument casting. This was changed to "typedef OSErr (*OSErrProcPtr)(long,...);" to make sure the first parameter to the name resolver calls is passed as a long.
• Think C incompatibility: Defines in Think default to short, not long, so all name resolver calls are made incorrectly. This is fixed by the typedef in above, but Think 4.0.5 does not recognize partial prototypes correctly. The fix is to add a “L” to the end of each of the name resolver command #defines.
• Think C incompatibility: The MXInfo() procedure has an extra semicolon after the trailing brace “};” which causes a syntax error with the Think C compiler. The semicolon was removed to fix the problem.
Networking & Communications: MacTCP: AdminTCP “obtain address” options
Under AdminTCP, what is the significance of the “obtain address” options, with respect to (1) manually, (2) server, and (3) dynamically?
According to the MacTCP 1.0 Documentation Kit (APDA #M0217LL/A), “obtain address” means the following:
• Manually: You will need to fill in some or all of the fields in the IP Address box;
• Server: The Internet Protocol (IP) address for the user Macintosh is automatically obtained from a server every time the user Macintosh boots up. This option requires - a Reverse Address Resolution Protocol (RARP) or Bootstrap Protocol (BootP) server on an Ethernet, or - a Datagram Delivery Protocol–to–Internet Protocol (DDP-IP) gateway on an AppleTalk network that’s compatible with the Kinetics Internet Protocol (KIP) developed at Stanford (also called “IPTalk”), such as the Shiva Fastpath or Cayman Gatorbox
• Dynamically: The node portion of the IP address for the user Macintosh is set dynamically every time the user Macintosh boots up. With this option you still need to set some of the fields in the IP Address Box. All these processes are described in further detail in the MacTCP documentation.
Networking & Communications: MacTCP: MacTCP resolver code is in domain name resolver
Is the MacTCP resolver code contained in the domain name resolver (DNR)?
According to the MacTCP 1.0 Documentation Kit (APDA #M0217LL/A), the resolver code is contained in the MacTCP DNR. The DNR code is stored as a resource file in the System folder and is read into memory as necessary in order to convert host names into addresses. It is used in conjunction with a domain name server or with the local hosts file.
Networking & Communications: MacTCP: MacTCP Hosts file location and function
Where should the MacTCP Hosts file be located, and who looks for that file?
According to the MacTCP 1.0 Documentation Kit (APDA #M0217LL/A), the Hosts file should be located in the user’s System Folder. The file maps machine names to internet addresses, providing the same service as the domain name server. The Hosts file can be used if you have no domain server on your network. It is also suggested that this file be used for frequently used name- to-address mappings. Instructions on setting up the file are included in the MacTCP documentation.
Networking & Communications: MacTCP: How to tell how many of StrToAddr’s network addresses are valid
How to tell how many of StrToAddr’s network addresses are valid
Using StrToAddr, you can receive up to four IP network addresses returned by the service for the host requested, but the MacTCP Programmer’s Guide does not say how to tell how many of the addresses are valid. According to the name resolver code, MacTCP zeros out 4 long words before the StrToAddr lookup and then fills in the addresses it finds. This means that the array contains *at most* 4 addresses, and is terminated by a zero address (0.0.0.0) if fewer than four addresses are returned.
Networking & Communications: MacTCP: System 7 and MacTCP
Is there a special version of MacTCP® for System 7.0?. If not, how can I get the current MacTCP (v 1.0.1) to work under System 7.0?
Currently there is no MacTCP version for System 7.0. To get version 1.0.1 to work with System 7.0, (1) make sure virtual memory is turned off, and (2) install MacTCP at the root level of your System Folder and not in the Control Panels folder.
Networking & Communications: MacTCP: Current MacTCP doesn’t run on TokenRing network
Does MacTCP® run on top of a TokenRing environment?
MacTCP does not run on a Macintosh TokenRing environment presently. This is being investigated by Apple N&C Engineering, however.
Networking & Communications: MacTCP: MacTCP gateway address and subnet mask fields
What are the MacTCP® Gateway Address and Subnet Mask fields used for?
In the TCP/IP protocol, there are a couple of provisions for simplifying the addressing scheme for smaller local networks. One of these is the subnet mask. It allows the sender to identify the destination machine by a shorter address,which is long enough to distinguish all the machines on the local network. This mask is made up of four octets, and is used as a bitwise mask to show how many bits are being used to specify the network number, subnet number, and node. The gateway address field specifies the IP address of the local network’s router. Packets destined for another network are sent to this router, which then transmits the packets to other networks.
Networking & Communications: MacTCP: Use AppleTalk to print from Macintosh A/UX to a LaserWriter
To print from a Macintosh® running A/UX to a LaserWriter®, would I use AppleTalk® or TCP/IP?
To print from an A/UX machine to a LaserWriter, you need to use AppleTalk. If you use your LocalTalk® port as your AppleTalk connection, you will require no further hardware (other than your LocalTalk network). If you use your Ethernet as your AppleTalk connection, you will need some kind of router to translate these packets from Ethernet to LocalTalk, as LaserWriters are available only with LocalTalk connections.
Networking & Communications: MacTCP: Porting a TCP/IP application to the Macintosh
We need the following to port our mainframe front-end application to the Macintosh®:
• a C++ compiler compatible with AT&T 2.0 (and ANSI C)
• a TCP/IP library with an Application Programming Interface (API) similar to sockets
• an Ethernet card
MPW® C++ is based on AT&T CFront 2.0. For information about CFront 2.0, please refer to the UNIX System V AT&T C++ Language System Release 2.0 Product Reference Manual.
Sockets is the general UNIX (Berkeley) API for TCP/IP programming. Apple currently offers some libraries that allow you to work with MacTCP but not APIs similar to sockets. Third-party socket libraries for MacTCP are available, however. Also, universities such as the University of Toronto provide public domain socket wrappers for MacTCP.
Ethernet cards are available from a number of sources, including some new Ethernet cards Apple introduced last month.
Networking & Communications: MacTCP: How to cancel transactions under MacTCP
How do I cancel transactions (specifically connect requests) under MacTCP? I know that I can specify a timeout; however, I would like the user to be able to hit ‘Command-.’ if the transaction’s tired of waiting. I tried KillIO but that seems to crash.
You should use Abort and Release. Abort terminates the pumping of data, and Release releases the driver. If there’s no release, the driver still believes there’s a process that it is working with, and it hangs when it tries to read data from a memory location that does not have anything.
Networking & Communications: MacTCP: A/UX® 2.0 doesn’t support IP encapsulation inside DDP packets
Can I get A/UX 2.0 to talk TCP/IP over the LocalTalk® network? MacTCP seems to support this but I can’t pummel A/UX into doing it.
IP encapsulation inside LocalTalk DDP packets is not supported under the current A/UX 2.0.
Networking & Communications: MacWorkStation: Using TextEdit for MacWorkstation “WYSIWYG” Exec
I am developing a MacWorkstation EXEC that will support a WYSIWYG display of a mainframe word processing document. Can I use TextEdit for display and editing?
You can use TextEdit, but you should know about some of its limitations. The latest TextEdit supports styles like bold, italic, and underlining, but does not support strike-thru (which can be done with QuickDraw™).
The TextEdit package may give the impression that there is a full featured word processing system built in the ROM, but unfortunately, TextEdit is not up to the job of being a word processor, for several reasons. First, TextEdit is limited to 32,767 characters per record (the TELength is defined as an integer). A second more subtle limit is the drawing limit of the rectangles surrounding the text. The destRect and viewRect both surround the complete TextEdit record. Using some rather rough approximations, there is an upper limit of about 40 pages of text that can be supported in the QuickDraw rectangle. This is quite a lot for some applications, but not very many considering the job typically required of a word processor.
Another programmatic limitation is performance. TextEdit will become quite sluggish with large blocks of data. After 2,000-4,000 characters are stored in a TextEdit record, performance slows to an unacceptable level. It is notable that the lineStarts array is a linear array of offsets into the edit record. If the data towards the end of the data record (high in the record) changes, the offsets must be changed. This can involve updating thousands of integer offsets for every character typed. If the different font, size and style information is tacked on top of all that, the performance can be expected to suffer with large blocks of text. This is especially true in a MacWorkStation Exec. TextEdit was not designed to handle large documents. It was designed as a simple field editor for the Dialog Manager, and extended from there. It was never intended to handle the large jobs expected of a word processor.
In order to perform the operations required of a word processor it is necessary to use QuickDraw extensively. The expected Macintosh selection approach with autoscrolling, typing over selected text, cut/copy/paste, and so on are best implemented using QuickDraw directly. How the text is stored internally is the primary determining factor on how the word processor will perform.
Networking & Communications: MacWorkStation: Customizing MacWorkstation documents
Where should I put resources—in the MacWorkstation document or the MacWorkstation application file?
To maintain the generic nature of MacWorkstation, it is important that you do all customization is on MWS documents and not on the MWS application. Any resource added to an MWS application may produce incompatibility with other applications that use MWS. Also, future versions of MWS may support multiple sessions. Here are some of the things that go into MWS documents:
• Communication module code resources
• Host application’s menu and dialog resources
• Any other host-specific resources such as icons, pictures, and data-strings
• Exec modules are stored in MWS documents as resources of type 'MWSX', along with a resource ID number for each module. The host program can load the module using either its resource ID number or its name.
Networking & Communications: MacWorkStation: How to make CCL “Debug” & “Matchstr” commands work correctly
The “Debug” and “Matchstr” commands in the Communication Command Language (CCL) don’t work as documented.
MacWorkstation does not attempt to read from the communications module at any time other than during the “Wait” command, so if a script does not have the “Wait” command, neither the “Debug” nor the “Matchstr” command will work. Add the “Wait” command and it all works.
Networking & Communications: MacWorkStation: Restricting access permissions for the Macintosh host
Is there some way to restrict the access permissions for the host?
Currently there is no easy way to restrict access permissions for the host. The host can access any file on the Macintosh® and create resources in the MacWorkstation documents. It would be possible, however, to write an EXEC which would prohibit certain commands from working under MWS, such as all file transfer commands.
Networking & Communications: MacWorkStation: Filtering out non-printing characters on the MacWorkstation end
How can I filter out non-printing characters on the Macintosh® end of the connection?
No checking is done on the MacWorkStation (MWS) side to filter out non- printing characters. If you want to filter them out, you must write your own communication module. This could also be a function of the host application.
Networking & Communications: MPP Driver: RAM-based AppleTalk driver fixes Mac Plus PNSendRequest error
I get an odd address error when using PNSendRequest on the Macintosh® Plus. The Mac® Plus has version 19 of the .MPP driver. Is there is an INIT or something that patches the older Macintosh models with the newer drivers?
Inside Macintosh suggests checking the .MPP driver version to see if the new driver is available (version >= 48).
You need the RAM-based AppleTalk drivers on the older Macintosh models to use the calls documented in Inside Macintosh Volume V. The RAM-based AppleTalk driver is available as an AppleTalk System file, and you need to place it in the System Folder of your Mac Plus.
Networking & Communications: Name Binding Protocol (NBP): AppleTalk 56 NBP reply packet entity field checks
AppleTalk 56 NBP reply packet entity field checks
As stated in Inside AppleTalk, each entity field in an NBP reply packet can be a maximum of 32 characters. In previous versions of AppleTalk, no range checking was done on entity field lengths, and often names that were too long were used, which eventually caused a crash somewhere else in the protocol stack.
Likewise, a null character in the object field of an entity has never been OK; it just happened to work because no range checking was done. (The only place that a null can legally be used in an NBP tuple is in the zone name field of an NBP LkUp, FwdReq, or BrRq packet; see page 7-17 of Inside Appletalk for more information.)
Now, under Appletalk 56, a range check is done on each entity field to ensure that the length is legal (1<=length<=32). When it finds a packet that contains a “corrupt” entity name, that packet is discarded.
Networking & Communications: Name Binding Protocol (NBP): Name Binding Protocol (NBP) interval and count fields
Is there a limit on the values set in the Name Binding Protocol (NBP) interval and count fields when used with PLookUpName and PConfirmName calls? How does the interval and count work? If a device is not on the network and I send a PLookUpName with intervals = 20 and count = 20, will I wait 400 seconds before PLookUpName return?
Since the interval and count parameters for NBP calls are both 1-byte, the values used are limited to the range of 0-255 ($00-$ff). Here’s what the values do:
interval = retransmit interval in 8-tick units. This value is used to set up
a VBL task. A value of 0 should not be used because that would
mean the VBL task would never be executed and would be removed
from the VBL queue.
count = total number of transmit attempts. Each time the interval timer
expires, this value is decremented by one. When it reaches 0, the
NBP call completes. So, if a value of 0 is used, the packet will
be retransmitted 255 times (or transmitted 256 times).
Three things can happen to make the LookupName, RegisterName or ConfirmName calls complete:
1) PKillBNP can be called to abort one of the calls (see Inside Macintosh, Volume V, page 519).
2) maxToGet matches are returned or the return buffer is filled. Here’s how this works: Each time a NBP lookup reply packet (LkUp-Reply) is received, an attempt is made to add all the NBP tuples found in that LkUp-Reply packet to the return buffer. If all of the tuples cannot be added to the buffer because there isn’t enough room, then the call completes with as many tuples as could fit and the numGotten field will contain the number of matches in the buffer. If all of the tuples from the LkUp-Reply packet are added to the buffer, then numGotten (the number of matches in the buffer) is compared to the value passed in the maxToGet field. If numGotten is greater than or equal to maxToGet, then the call completes and the numGotten field will contain the number of matches in the buffer. Since the buffer can fill before maxToGet matches are received and since LkUp-Reply packets can return multiple tuples, you may get more or less matches than you asked for with maxToGet.
3) The count is decremented to 0. You can use this equation to determine how long the call would take to complete this way:
IF count = 0
then count := 256;
TimeToCompleteInTicks := count * interval * 8;
The RegisterName and ConfirmName calls always complete after they receive the first LkUp-Reply packet packet to their request, so you could look at them as always having a maxToGet of 1 (maxToGet is NOT one of the parameters for those two calls).
Networking & Communications: Name Binding Protocol (NBP): Where to find AppleTalk Name Binding Protocol code sample
Do you have AppleTalk® sample code that uses NBP (Name Binding Protocol) to check for a name and type on the network and, if not found, register the name and type on the network?
The sample you’ve requested is available on the Macintosh® System 7.0 beta CD.
Networking & Communications: Name Binding Protocol (NBP): Version tests before using AppleTalk NBP’s RemoveName under A/UX
When I was running my program under A/UX® 2.0, the AppleTalk® NBP (Name Binding Protocol” routine RemoveName seems to do nothing. Beta manuals hint that LaserWriter® printing works but other parts of AppleTalk are absent or iffy. Am I right in assuming that RegisterName works but RemoveName doesn’t? Is it safe to check for AppleTalk version 0 for this purpose? When will RemoveName work under A/UX?
We recommend checking the A/UX version instead of the AppleTalk version. Good recommendations about how to do that are found in Macintosh Technical Note #283. If you use Gestalt you could also check if the release level is 2.0. Now that this problem is fixed in 2.0.1, you can check for release level and enable your functionality.
Networking & Communications: Name Binding Protocol (NBP): Macintosh NBPLookup badUnitErr conditions
Why am I getting a badUnitErr as a result code from NBPLookup? This error is not listed as a result code for NBPLookup, nor anywhere in the AppleTalk® Manager.
You’re probably getting the badUnitErr result because you don’t have the AppleTalk drivers open. Since AppleTalk calls are made to a device driver (the AppleTalk driver), you can get back general operating system errors from the driver.
See Macintosh® Technical Note #224 “Opening AppleTalk” for a description of how to open the AppleTalk drivers.
Networking & Communications: Name Binding Protocol (NBP): Don’t access the MPW NBP EntityName field directly
When I fill in the fields of MPW®’s Name Binding Protocol (NBP) EntityName structure, AppleTalk® doesn’t recognize the entity, even though I know it’s out there. What’s going on?
The real definition of EntityName is 3 PACKED strings of any length (32 is an example). No offsets for Asm are specified since each string address must be calculated by adding the length byte to the last string pointer. In Pascal, String(32) will be 34 bytes long since fields never start on an odd byte unless they are only one byte long, so this will generate correct-looking interfaces for Pascal and C, but the interfaces will not be the same. This is OK since they are not used.
The point is that you should never try to access the fields of the EntityName field directly. The only reason the type is defined at all is so that you can allocate EntityName variables that will hold the largest possible EntityName. To fill in an EntityName record, you call the NBPSetEntity routine.
Networking & Communications: Routing Table Maintenance Protocol (RTMP): Receiving RTMP packets from a generic router
I’m trying to receive the periodic Routing Table Maintenance Protocol (RTMP) packets sent out from a generic router. The only solution so far is to close down the Link Access Protocol (LAP) handlers and install my own. However, when I’m finished, I must restart AppleTalk® when my program exits. Is there an alternative solution?
You’ve hit upon a side effect of the AppleTalk architecture. It’s understandable that being only a listener, that you would simply want to attach yourself into the LAP chain without shutting down AppleTalk. Your findings are correct though—you would need to shut down the LAP handler and install one of your own. This would require restarting AppleTalk when your program exits.
You’d find that EtherPeek, a commercially available software sniffer works similarly. This has the ramifications of complicating the process by restarting AppleTalk with the desired connection method. It also limits compatibility with Apple cards and those from other vendors you select to support.
Networking & Communications: Token Ring: TokenTalk LLCBadList and LLCTruncated
When a list-directed receive is queued to TokenTalk’s implementation of Logical Link Control (LLC) with a total data size less than the active frame size, LLCBadList is returned when the receive completes. If a nonlist-directed receive is used, and the buffer size is less than a frame size, LLCTruncated is returned. Why aren’t the same error codes (LLCTruncated) returned as the condition is the same?
The LLCBadList error results because of an undocumented limitation imposed on the number of lists allowed in a list-directed receive. It’s likely that you’ve specified a list array with greater than eight elements. When the list is passed to LLCReceive, a check is made on the list array if one is used. If more than eight elements are in the list, the LLCBadList error is returned immediately with no processing of the incoming data.
On the other hand, if a nonlist-directed receive is used, the LLCReceive call is queued into the task list. The present TokenTalk LLC implementation doesn’t support partial reads of large data frames, so if it turns out that the buffer size is smaller than the frame size, only the information that fits into the buffer is returned. The remaining information is discarded. The error condition LLCTruncated is returned to indicate that this event occurred.
Networking & Communications: X.25 & X.400: How to increase Macintosh X.25 user list size
How do we go beyond the Macintosh® X.25 user list entry limit of 256?
The size of the X.25 user list can be modified by modifying the 'Maxu' resource in the X.25 Admin program using ResEdit™. If you’re using the latest revision of ResEdit v2.1, a template for the 'Maxu' resource exists to assist with this modification. The other recommended change is to increase the program partition size of X.25 Admin by 32 bytes for each additional user to ensure that there is enough memory to hold all of the names. Note that this change does not increase the number of simultaneous connections.
Networking & Communications: X.25 & X.400: Feasibility of MacX25 AppleTalk internet routers
What’s the feasibility of developing internet routers for AppleTalk® networks over MacX25?
This has been done at Apple, and tested between Cupertino and Paris. The problem is ITMP packets are a burden on the X.25 network. Too much bandwidth is used by AppleTalk® router protocol. The throughput goes way down, and the monetary cost of these undesirable packets is high. Efforts are underway to improve throughput. In other words, it is feasible but not practical to do this until modifications are rolled into the AppleTalk and router protocols.
Networking & Communications: X.25 & X.400: Providing general “listeners” on MacX25 servers
Is it feasible to develop general “listeners” on the MacX25 servers? This would allow users to connect to MacX25 servers and request specific services to be provided. Other non-Macintosh systems could also communicate with such “listeners.”
MacX25 does indeed provide a listener agent. Please refer to the MacX25 product documentation. If, however, you want to develop your own listener, one could be provided via access to A/ROSE®.
Networking & Communications: X.25 & X.400: Where to find X.400 & X.500 references
Where can I find documentation on the X.400 and X.500 electronic mail standard?
There are a few interesting articles about X.400 in the Technical Information Library on AppleLink®. One of them mentions that Apple has a forthcoming X.400 solution which is an X.400-compliant MTA (Message Transfer Agent) that runs on any modular Macintosh under System 7. It includes the seven layers of the OSI model. It works either over X.25 (on top of the MacX25 product) or over 802.3. (This is the most used link in the U.S.) It lets Macintosh users gain access to public X.400 networks or to connect to their private X.400 backbone.
For standards and specifications on X.400 and X.500, I would check with your local library for an IEEE periodical index. IEEE documents this type of stuff fairly regularly.
Networking & Communications: X.25 & X.400: Translating 8-bit Macintosh text to 7-bit ASCII
Is there an Apple-recommended method for converting 8-bit Apple text characters to that which can be sent over 7-bit mediums while observing X.400 rules, and only submit 7-bit text into the x.400 IA5Text body parts?
There is no Apple-recommended method to translate 8-bit characters to 7-bit characters. You’ll need to check around and see if someone has implemented this already. This would save you some time trying to figure out a formula for this. Unfortunately, there are some differences between the IBM-based environment and the Macintosh® environment that are extremely hard to overcome and this is one of them.
The following are some possible methods:
1. Strip the 8th bit off and send the character in 7-bit mode. Doing this will cause you to lose half of the normal 8-bit ASCII code, but there is still enough for people to work with. Most of the missing characters are special ones which usually require the option key to obtain them.
This limitation should not be restrictive for most users, except for those writing in foreign languages that may require such characters. This is another area that requires some thought. How do you handle foreign languages? If they are using 8-bit ASCII to get their special characters then they are out of luck. If they use the Script Manager they may be able to get what they need in the first 128 characters. You would have to check in the Script Manager of Inside Macintosh to know for sure if this is the case.
2. Just transfer 7 bits at a time. Break after every 7th character and then put the characters back together again at the other end. This might require a Macintosh-to-Macintosh connection, but it will provide you with the method of retaining the entire 8 bit ASCII character set and still get the file transferred.
Finally, You might want to check with user groups and bulletin boards to see if someone has done anything that is suitable to your needs.
Operating System: Alias Manager: Special Macintosh alias file types
Why does the alias of a font suitcase created in System 7.0 have a type of 'drop' instead of 'FFIL'? Should applications that open 'FFIL' files also try to open 'drop' files?
While it is true that an alias file generally has the same type and creator asthe file it points to, certain special Finder™ objects are given their own type, such as aliases to server volumes. An alias file of type 'drop' is an alias to a container object—that is, one that can contain other files like fonts. The complete list of special alias types is in the Finder Interface chapter of Inside Macintosh Volume VI and is defined in Finder.h.
You asked why the Finder needs to create this special type. The user is allowed to drag objects around the desktop, and if an object is dragged over something it can be dropped on or into, such as a folder, that object is immediately highlighted so the user knows this is a cool thing to do. Since the actual object an alias file points to may not even be currently accessible—for example, if it’s on a server volume—the Finder can’t resolve itimmediately to know if it’s cool to highlight the object, so alias files of type 'drop' are a catchall type that tells the Finder dropping is cool.
You should not assume an alias file of this type always points to a font file.It can also point to a desk accessory, for example. If you want to handle thistype properly in a standard file dialog, you need to filter on type 'drop', then have a filter proc which attempts to resolve the alias file. DTS recommends you use MatchAlias with kARMnoUI set in the rulesMask to see quickly if the alias file can be resolved with no user intervention required.
Alternatively, you can allow the user to select the file for opening and then if it doesn’t resolve to the correct type, inform the user via a dialog that the file isn’t of the appropriate type.
Operating System: Backgrounder: Valid resource handles for Notification Manager nmIcon field
Why can’t I pass a handle to an 'ICN#' as the Notification Manager nmIcon under System 7?
The Notification Manager chapter of Inside Macintosh Volume VI describes the nmIcon field as follows:
nmIcon: Contains a handle to a small icon that is to appear periodically in the menu bar...
The nmIcon field holds a handle to the icon that flashes in the process menu. Since 'ICN#' are not small (16x16), they will not work for this purpose. You need to pass a 'SICN' handle in the parameter block. Changing the icon that appears in the notification alert dialog box is not supported.
Operating System: DAs: System 7.0 DAs and 'vers' resources
Why does System 7.0 get rid of my 'vers' resources in my desk accessories when dropped into the System Folder icon?
The System 7 DA mover takes over some of the job of the old Font/DA Mover program. The Font/DA Mover took great pains to keep all resources owned by the DA together with the driver resource. This is mentioned in Macintosh Technical Note #6, “Shortcut for Owned Resources.”
Under System 7, the 'vers' resource used for Finder information is not owned by the desk accessory, so when the Finder copies the desk accessory it skips the resources extraneous to the DA—including the 'vers' resource.
The simplest thing to do is to provide a System 7-ready version of your desk accessory. The Finder will not strip off resources if the file type is already 'dfil' when the DA is dragged to the System folder. You can also provide a version of the DA in a suitcase for System 6, or you can instruct System 6 users to hold down Option while clicking Open in Font/DA Mover if they want to install your DA.
Operating System: DAs: Macintosh DA with custom 'WDEF'
Is it acceptable to write an installation program for a DA that uses a custom 'WDEF'? The Font/DA Mover won’t install a 'WDEF' because the 'WDEF' cannot be an owned resource.
Although the owned resource mechanism and the 'WDEF' ID with variation code are directly incompatible with each other, it is a simple matter to work around this problem with just a little code.
First, number your 'WDEF' resource as an owned resource, following the instructions on page 109 of Inside Macintosh Volume I. This will allow your users to simply use the DA/Font Mover to install/deinstall your DA and eliminate the need for you to do a custom installer with all the problems that involves.
Next, when you open a window that needs your custom 'WDEF', open it “invisible” and with a standard built-in 'WDEF' procedure ID; GetResource the 'WDEF' resource handle yourself and store the handle into the windowDefProc field of the window record. Its “owned” resource ID is calculated from the DA’s installed driver unit number, dCtlRefNum. Note: a refNum of -4 is a unit number of 3. See Inside Macintosh Volume II, page 191, for details.
Finally, show your window and it should be drawn using the custom 'WDEF'.
Operating System: DAs: DAs cannot call UnmountVol trap under System 7.0
DAs cannot call UnmountVol trap under System 7.0
Under System 7.0 a DA can no longer call the UnmountVol trap to unmount a volume, as it can under earlier systems.
The only known workaround is to build your product as an application and not a DA. Since System 7.0 will place any application into the Apple Menu, you don’t really need to make it a DA to have it easily accessible to the user.
Operating System: DAs: How to build a System 6 suitcase allowing for System 7 'ICN#'
Is there a way to build a file that is recognized by Font/DA Mover as a suitcase for System 6 that also allows the DA to have an 'ICN#' for System 7?
Yes, this is possible. You need to add a 'BNDL' resource to the DA, and mark it (in ResEdit’s “Info on <filename>“ window) as having a bundle. Make sure all the 'BNLD' components, such as 'BNDL', 'FREF', and 'ICN#', are owned resources of the DA.
All you need to do is add a 'BNDL' to your DA suitcase with your creator and a filetype for the icon of 'dfil'. Then, when the user drags the DA out of the suitcase (or drops it into the System file) in System 7 the Mover should associate that icon with that “naked” DA.
This works reasonably well; however, occasionally the Finder™ will “forget” the custom icon and default to the left-hand DA icon. Rebuilding the desktop usually fixes this.
So, it does work, but you (and your users) make occasionally experience a loss of the icon, but rebuilding the desktop will fix them.
Operating System: DAs: Increasing heap space for Macintosh DAs
I am writing a Macintosh desk accessory (DA) that opens large PICT files and makes offscreen pixel maps for them. Is there a way for a DA to ask for more space when it opens up, or should we be modern about this and make it an application instead of a DA?
A DA, like any application, can ask for available MultiFinder® temporary memory, as documented in “Programmer’s Guide to MultiFinder” (APDA #M7044) for running under System 6.0.x and in Inside Macintosh Volume VI for running under 7.0. You can also set the current heap to the system heap so that memory allocation will take place there until you set it back to the current heap. If you do this, you open up the can of worms of “how much space is left in the system heap?” Under Finder™ there’s a fixed amount of space, set by the boot blocks. Under MultiFinder (and System 7.0) the system heap adjusts itself to keep about 16K free, but if you allocate all 16K you will not know when it will resize larger or when the system might crash because all of its heap space has been used up.
DAs, however, were never intended to use large amounts of memory. For all but the most trivial (and small) functionality, it is better to implement as an application than as a DA, especially under System 7.0 where an application has all the advantages of a DA with none of the restrictions.
Operating System: DAs: DAs in background under under System 7.0 lack UnitTable entries
Under System 6 my driver, which runs all the time, can send a control call to my open DA (because it too is a driver). Under System 7.0 I get badUnitErr errors (-21) because evidently my DA resides in a different process that is inaccessible to my system-resident driver. How can I get around this?
DAs in System 7.0 do not actually have UnitEntries unless they are currently running, so your driver cannot call your DA unless the DA is frontmost. What you might consider instead is having the DA perodically issue a call to the driver, asking if there is anything for it at the moment. If you have an entity that hands data to your resident driver, and the DA then requests the data from the resident driver from time to time, you should have a very robustmechanism, albeit a slightly slower one with greater latency.
Operating System: DAs: How an Apple IIGS New Desk Accessory obtains its ID
How does an Apple IIGS® New Desk Accessory (NDA) obtain its ID?
Each Apple IIGS NDA has two IDs: a Memory Manager ID and a Menu ID. If you want the Memory Manager ID, simply call MMStartup from your DA. The NDA ID for the OpenNDA call can easily be obtained from your menu string. The Desk Manager replaces the ** of your \H** at the end of your menu string with your Menu ID, which is also your NDA number. A note of caution: Please be sure you’re running in the 16-bit environment before using the NDA ID to call OpenNDA. If you try this while ProDOS 8 is running, nothing good comes of it!
Operating System: DAs: Using 'dast' resource to display “About…” DA under System 7.0
I’m upgrading my desk accessory to be more compatible with Macintosh® System 7.0, but I’m unable to get anything to display in “About…” using the Alarm Clock’s 'dast' resource. What do I need to change?
The 'dast' resource will be used only if the system thinks your DA is System 7.0-friendly. The way to convince it of this is to add a BNDL and FREF resource into your DA file, along with the appropriate signature string (just like an application would have done). You then make sure that all of these resources are owned by the DRVR. This can be done in the GetInfo window of ResEdit™. The only resource that should be special is the signature resource which should still have a resource ID of 1. Once all of this is done, set the Bundle flag, and clear the INITed flag (also using ResEdit) to get the Finder™ to notice the changes. At this point, your DA should have the correct icons, and should also display the dast string in your about box. To make it easy, just copy all of the resources including the ICN# and icXX resources out of the Alarm Clock file, and then make them owned by your driver. If your DRVR resource has the same ID as the Alarm Clock, all you have to do is copy them over. Once the system starts using them, you can simply use ResEdit to edit the icons. This way you will have the appropriate icon in the Apple Menu as well as the About box.
Operating System: DAs: Zero non-input fields before calling Apple IIGS TaskMasterDA
How do I use the Apple IIGS® TaskMasterDA call?
TaskMasterDA is a call provided in Apple IIGS System Software 5.0 and later so that new desk accessory authors may use the features of TaskMaster even when the current application doesn’t use TaskMaster. The Desk Manager will pass an event record to the NDA, which should then copy it into an extended task record. TaskMasterDA will return values in the extended task record and will use values passed in that record, so be sure that the non-input fields are zeroed before your first call to TaskMasterDA. The parameters to the call are listed in Volume 3 of the Apple IIGS Toolbox Reference.
Operating System: DAs: Apple IIGS DAs can have resource forks
Can my Apple IIGS® DA have a resource fork?
A new desk accessory may use the Resource Manager if it requires System Software 5.0 or later, as the Resource Manager will always be present. However, New Desk Accessory (NDA) authors must be aware that any application doing a Close with reference number zero will close the NDA’s resource fork. The IIGS Finder™ can do this under some circumstances. Changing the file level will not solve this problem, as the level belongs to the current application and should not be permanently changed by desk accessories.
This means that your NDA can’t open its resource fork at DAInit time and expect it to always be open. You can use resources in an NDA by opening the resource fork when your DA is opened and closing it when your DA is closed. Although an application could still close your resource fork while your DA window is open but not active, this is not likely.
Classic Desk Accessories may also have resource forks. The same warnings apply, and the author must also be aware that the Resource Manager is not available to the CDA when the current operating system is ProDOS® 8.
For important details, refer to the Apple IIGS Technical Notes, especially Tech Note #71.
Operating System: Disk Cache: Tail-patching the Macintosh Write trap
How do I make Macintosh® Control Panel RAM cache a “write-through” cache?
The Write trap is not being patched by Apple. This makes sense, as Write isn’t called much from within the system software itself, and even when it is, it’s not a likely candidate for a come-from patch. The upshot of this is that you can probably safely tail-patch it. Here’s a suggested implementation:
TST.W ioFRefNum(A0) ;Is this _Write for a file?
BMI.S JumpToROM ;Go if not
BSET #5,ioPosMode(A0) ;One-shot disable for caching
PEA FollowUp ;Put new return address on stack
JumpToROM JMP <OldWrite> ;Jump to ROM address
FollowUp MOVE.W D0,-(SP) ;Save OSErr
BCLR #5,ioPosMode(A0) ;Restore ioPosMode
MOVE.W (SP)+,D0 ;Restore OSErr; also sets conditions!
The above takes care of a few not-necessarily-obvious things:
1) By testing ioFRefNum(A0), it determines whether it even needs to worry about the cache; that is, it determines whether this is a File Manager _Write or a Device Manager _Write.
2) The tail portion of my example clears bit 5 of ioPosMode while taking great care to ensure that the condition flags aren’t screwed up in the process.
Operating System: File System: PBGetUGEntry documentation fix
When I call the PBGetUGEntry function (documented in Macintosh Technical Note #305, “PBShare, PBUnshare, and PBGetUGEntry,” October 1991), it always returns a fnfErr error. I know there are users and groups on the system. Does the PBGetUGEntry function really work?
Get out your pencil and make this change on page 7 of Technical Note #305 (October 1991 version only):
ioObjType Word input value: Determines the type of object to be
returned, as follows:
$0000 return next user
$FFFF return next group
There is no value of ioObjType that will return both the next user and the next group.
Operating System: File System: Unlocking a Macintosh volume
PBSetVInfo failed to reset a software lock bit that had been set using PBSetVInfo, because the volume was, of course, locked. How do you allow a volume to be unlocked?
DTS discourages developers from locking and unlocking volumes through software because it’s not readily apparent to users. Many users are aware only of the physical reasons that they would be prevented from modifying a disk. For example, it’s easy to identify CD-ROMs and locked floppies as unchangeable.
Additionally, the Finder caches the contents of its windows, so a change in the locked status of a volume may not be reflected immediately. An unlocked volume may still show a lock icon in its window, misleading users into thinking that the particular volume is still protected. For these reasons, we recommend that volumes not be locked by software.
If you need to software lock a volume, be sure it’s done only after explicitly warning the user that the disk will be locked and providing an opportunity to cancel the operation.
Locking a volume is done by calling PBSetVInfo with bit 15 of the ioVAtrb field set. However, this creates a Catch-22 in that you can’t make the call to unlock the disk. To override the locked status for the volume and unlock it, you must walk the volume-control-block queue in memory and clear the lock bit for the drive, as shown in the following code:
USES Files, Errors;
FUNCTION SoftwareVolumeUnlock(targetVRefNum: INTEGER): OSErr;
TYPE VCBPtr = ^VCB;
VAR
theVCBQHdrPtr: QHdrPtr;
myVCBPtr: VCBPtr;
BEGIN
theVCBQHdrPtr := GetVCBQHdr;
myVCBPtr := VCBPtr(theVCBQHdrPtr^.qHead);
WHILE (myVCBPtr <> NIL) AND
(myVCBPtr^.vcbVRefNum <> targetVRefNum) DO
myVCBPtr := VCBPtr(myVCBPtr^.qLink);
IF myVCBPtr^.vcbVRefNum = targetVRefNum THEN
BEGIN
{ clear locked bit }
myVCBPtr^.vcbAtrb := BAND(myVCBPtr^.vcbAtrb, $7FFF);
{ write change to disk }
SoftwareVolumeUnlock := FlushVol(NIL, targetVRefNum)
END
ELSE SoftwareVolumeUnlock := nsvErr { volume not found }
END;
The VCB queue and volume attributes are discussed under “Volume Control Blocks” in the File Manager chapter of Inside Macintosh Volume IV.
Operating System: File System: Simulating PBExchangeFiles for System 6
Simulating PBExchangeFiles for System 6
Here’s how to do the equivalent of PBExchangeFiles (new in System 7) for System 6:
Create a new file. Copy the old files to the new one, do a PBHGetFileInfo on the old and and new, and copy the Finder and creation date from the old to the new. Then do a PBHSetFileInfo, renaming the new and deleting the old. The File Manager implements PBExchangeFiles as shown below:
Catmove file 1 to file 2’s directory
Catmove file 2 to file 1’s directory
rename file 2 to 1
rename file 1 to 2
Renaming and deleting require the file names instead of refnums. The file name may have been changed by the user since the file was opened because the Fnder doesn’t disallow changing names and moving files that are open. To get around this problem, use GetFCBInfo to recover the filename, DirID and VRefNum of an open file. In the case of files, the FCB’s ioFCBParID field is the ioDirID of the file, and ioFCBVRefNum is the ioVRefNum.
You may need to do an intermediate rename if there is file already exists with the name of the moved file in the destination directory. The File Manager is able to pull this procedure off a little more gracefully because it manipulates the B-Tree entries instead of going through the APIs.
Operating System: File System: Booting a write-protected disk under System 7
How do I boot a write-protected disk under System 7? It seems that the Macintosh operating system tries to write/modify the desktop file and I get an error message telling me to write-enable the disk.
Every Macintosh has been equipped with the ability for users to boot from both write-protected as well as writeable disks, all the way back to the first machine introduced in 1984. This didn’t change with System 7; in fact, the operating system has only an indirect impact on this capability. The only thing you can’t do from a write-protected boot disk is use the Chooser because the O/S needs to be able to write back the preferences for whatever you do in the Chooser.
You might be encountering the error you described because of desktop changes: Since the desktop file was obsoleted in System 7, which now uses the Desktop Manager instead, diskettes that are mastered on a System 7 machine then inserted into another machine running 6.0.x must have a desktop file created. (This does not apply to diskettes that you’re trying to boot from; rather, when you insert the disk into a machine already running 6.0.x.) When this situation is encountered, the user is presented with the now familiar dialog to the effect that the disk needs minor repairs (in fact, it needs a desktop file). If you say OK to this dialog, the desktop file will be created and all will be well. All this leads up to how (not) to treat diskettes mastered under System 7: If you drag a series of files to a floppy disk (from a System 7 machine), immediately eject and lock it, then try to boot from it, the machine will try to update the directory information on the diskette as the machine is booting up. The way around this is to either A) eject the floppy after copying your files then reinsert it (or simply open and close the main window) to allow the directory information to be updated or B) use the installer to place files on the floppy as the installer automatically updates the directory information.
Another possible explanation for the anomolous behavior you’re seeing is that you’ve got an INIT or application of some sort (such as a virus checker perhaps) on the floppy that wants to update itself after the system has finished starting up.
Operating System: File System: Code for detecting PBCatSearch support
Our code for volume searching using PBCatSearch doesn’t work for AppleShare volumes. Do know how we can make it work?
PBCatSearch only works on volumes that support it. If you attempt to use PBCatSearch on a volume that doesn’t support it, you’ll get a wrgVolTypErr (-123). (This isn’t documented in Inside Macintosh Volume VI.)
AppleShare 2.0 volumes (AppleShare 2.0 is an AFP 2.0 server) and volumes supported by some other external file systems do not support PBCatSearch, so you’ll have to resort to recursively searching the catalog using a routine similar to the one shown in Macintosh Technical Note #68 on those volumes. PBCatSearch is supported by AppleShare volumes on System 7 File Sharing servers because File Sharing supports AFP version 2.1 which includes CatSearch as a supported command.
You can use the File Manager call PBHGetVolParms to check a volume for most volume-specific features, including support for PBCatSearch. Here’s a short function that shows how to do that:
FUNCTION CatSearchable (vRefNum: Integer): Boolean;
{See if PBCatSearch is supported on the volume specified by vRefNum}
VAR
pb: HParamBlockRec;
infoBuffer: GetVolParmsInfoBuffer;
err: OSErr;
BEGIN
WITH pb DO
BEGIN
ioNamePtr := NIL;
ioVRefNum := vRefNum;
ioBuffer := @infoBuffer;
ioReqCount := SizeOf(infoBuffer);
END;
err := PBHGetVolParms(@pb, FALSE);
IF err = noErr THEN
IF BTst(infoBuffer.vMAttrib, bHasCatSearch) THEN
CatSearchable := TRUE
ELSE
CatSearchable := FALSE
ELSE
CatSearchable := FALSE;
END;
Operating System: File System: Changing a file’s fork without changing last-modified date
Inside Macintosh Volume VI, page 2-22, recommends updating the window positions in a file without changing the last modification date and time on the file. How do I alter a file without automatically changing the timestamp?
To modify the contents of a file’s data or resource fork without changing the last modified date, get the modified date before performing any save operations on the file and restore it when you’re done. You can use the PBHGetFInfo and PBHSetFInfo calls to do this. A short Pascal snippet that modifies the contents of a known file’s resource fork without modifying its modification date is included in the Snippets folder on this issue’s Developer CD Series disc. The code shows how the parameter block is filled in with the file’s information at the start of the routine with a PBHGetFInfo call, and the same data is then used without modification to set the file information at the end of the routine with a PBHSetFInfo. Inside Macintosh Volume IV, page 150, tells you which fields can be changed with PBHSetFInfo.
Procedure DummyResource;
var a:stringHandle;
b:Integer;
fred:str255;
theBlock:HParamBlockRec;
anErr:OSErr;
begin
{Set up the parameter block}
fred:='anIcon';
theBlock.ioCompletion:=nil;
theBlock.ioNamePtr:=@Fred;
theBlock.ioVRefNum:=0;
theBlock.ioFDirIndex:=0;
theBlock.ioDirID:=0;
{Recover the files info to save the mod date}
anErr:=PBHGetFInfo(@theBlock,false);
{modify the resource fork}
b:=OpenResFile('anIcon');
a:=StringHandle(GetResource('STR ',128));
a^^[1]:=char(ord(a^^[1])+1);
ChangedResource(Handle(a));
UpdateResFile(b);
CloseResFile(b);
{Now restore the original last mod date in the files
directory entry.}
theBlock.ioCompletion:=nil;
theBlock.ioNamePtr:=@Fred;
theBlock.ioVRefNum:=0;
theBlock.ioFDirIndex:=0;
theBlock.ioDirID:=0;
anErr:=PBHSetFInfo(@theBlock,false);
end;
Operating System: File System: System 7 Finder and file duplication time
Duplicating a large file under the System 7 Finder took four times as long as under System 6. How can I make System 7 copy more blocks and larger sizes, to reduce duplication time?
Duplicating a file in the Finder is slower in System 7.0 than in previous systems because the new system allows you to switch out of the Finder to another application for those really big file duplications. This is a feature that was installed into the Finder. The Finder is constantly checking to see if it should be switched out and this takes time. Since you can’t get something for nothing, even in the Macintosh world, there is a speed loss when copying files in the Finder.
This speed change will not happen from within an application. In fact, you may notice a small increase in the speed at which applications can duplicate files. Try using the “duplicate” command in MPW and you’ll see that it’s considerably faster than the Finder.
Operating System: File System: Copying a file or folder dragged to Macintosh application
What do I need to do to have my Macintosh application copy any folder or file that is dragged to it?
One method is to create an application and have it reside on the desktop. The user can then just drag files to that application, which will in turn receive an open event on the file and duplicate the file. This is possible because when a document’s icon is dragged on top of an application’s icon, the Finder will tell the application to open the file if the application knows about the file.. The only catch is that you’ll need to use the special 'FREF' type that will enable the Finder to send you an 'odoc' for ANY file. The key 'FREF's you’ll need are:
**** -- any file,
fold -- any folder,
disk -- any disk.
The characters should be all lowercase letters. This should allow your application to receive an open for anything that’s dragged to it. It will be up to your application to handle possible error conditions such as not enough disk space.
Operating System: File System: FSSpec and SFReply information blocks
How can I make FSSpec file information comply with what was a SFReply information block? Is there a way to convert FSSpec information—as passed, for example, via an Open Documents Apple event—to a vRefNum as understood by an SFReply record? We want to keep our tried-and-true non-System 7 file management logic and convert from FSSpec to SFReply-type format.
Not wanting to obsolete a good bit of file system code is understandable; however you would be better off investing in a redesign of all code that is dependent upon SFReply data structures. While it’s unlikely that Apple will dispense with support for old SFGet/PutFile functions in the near future, the use of SFReply-style data structures in internal calls has no development future.
The vRefNum field of the SFReply record was originally (Inside Macintosh Volume II days) a volume reference number; later, with the creation of HFS in 1986, it became a working directory reference number for purposes of backward compatibility. In HFS, a file or directory entity on a volume is specified with a volume reference number, a directory ID and a name. An FSSpec contains this latter information.
To convert from FSSpec to SFReply requires that your application manage the manipulation of working directory entities, which has disadvantages from the point of view of the system and compatibility.
There are several difficulties with working directory references:
• There is a system-wide limit on their number;
• If you have a working directory reference to which no file buffers are open and some other application closes that working directory without your knowledge of it, the internally stored reference number in your application is invalid and you have no way of knowing about it;
• The documentation about where/when/how to close a working directory is ambiguous and confusing…
• An FSSpec can refer to either a file or a directory while an SFReply can only refer to a file.
DTS urges you to take the time to remove dependencies upon SFReply data structures as soon as is feasible.
Operating System: File System: ioVAtrb bit 7 and bit 15 locked volume bits
I want to determine if a disk is locked before trying to open it. Examining bit 15 of ioVAtrb using PBGetVInfo, as suggested on page 104 of Inside Macintosh Volume II, bit 15 is clear for a locked volume such as a CD-ROM, but bit 7 is set. Why is this happening?
The reason for your observed discrepancy is that bit 15 is set for a software lock and bit 7 is set for a hardware lock. In the case of the CD-ROM there is no software lock but only a hardware lock, so bit 7 is set and bit 15 is clear. Volumes II and IV of Inside Macintosh both say that “only bit 15 can be changed” and should be set if the volume is locked. The fact that you can set it with PBSetVol means that it is a software lock. What the documentation fails to mention is that using PBGetVInfo you can also check bit 7 of ioVAtrb to see if there is a hardware lock. The recommended procedure is to first check the hardware lock (bit 7 of ioVAtrb) and then check the software lock (bit 15 of IOVAtrb).
Operating System: File System: How to search only nonserver mounted volumes
If I don’t want to search any AppleShare or File Sharing volumes, how can I tell which mounted volume to search?
You should be able to use the field vMServerAdr in the GetVolParmsInfo attributes buffer of PBHGetVolParms to determine whether to search a volume. Since the vMServerAdr field specifies the internet address of the server that manages an AppleTalk server volume, checking for a zero internet address before searching the volume would seem the way to go for you.
X-Ref:
Inside Macintosh Volume VI, pages 25-37 to 25-40
Operating System: File System: Apple IIGS Integer Math Frac numbers
The Apple IIGS Integer Math tool set has a square root function for Frac numbers. I’m not familiar with these Fracs; the Apple IIGS Toolbox Reference defines them as 32-bit signed with 30 bits of fraction. It would seem to me that this leaves 1 bit for the whole number. How can I use this call to extract the square root of 32-bit signed numbers with 6 bits of fraction (as found in TrueType point values)? Or is there a better alternative?
Fracs are 32-bit signed with 30 bits of fraction; this leaves 2 bits for the whole number portion, not 1. (Fracs represent numbers from -2 to 2 $80000000=- 2 and $7FFFFFFF=2.) The source of this information? Inside Macintosh Volume IV! Well, at least we did write it down…
You cannot, as you guessed, easily use this to get the square root of 32-bit
signed 6 bit decimal number, unless you consider the following information:
sqrt(x)=sqrt(x/100)*10
or
sqrt(x)=sqrt(x/10000)*100
or
procedure FixSqrt(theFix:Fixed):Fixed;
{ Take the square root of a fixed point number which has }
{ 16 bits of whole number and 16 bits of fraction. }
{ NOTE: This routine assumes the FixInput if between }
{ 20000 and -20000 }
var theFrac:Frac;
tempFix,anotherFixed:Fixed;
aLong:Longint;
begin
aLong:=10000;
tempFix:=Long2Fix(aLong);
tempFix:=FixDiv(theFix,tempFix);
theFrac:=Fix2Frac(tempFix);
theFrac:=FracSqrt(theFrac);
tempFix:=Frac2Fix(theFrac);
aLong:=100;
anotherFixed:=Long2Fix(aLong);
FixSqrt:=FixMul(tempFix,AnotherFixed);
end;
Of course, this could be simplified even further by hard-coding the constants for fix(100) and fix(10000), then recoding in assembly language to allow faster and looser type coercions.
Operating System: File System: Where to get Macintosh third-party file formats
How can I get the file format details on the likes of MacWrite, MacWrite II, and Microsoft Word?
Macintosh file formats are not published like Apple II file formats. You must contact the developers of the Macintosh software in order to obtain their file formats.
Operating System: File System: Macintosh open file maximums & how to alter
Macintosh open file maximums & how to alter
There’s a limit on the maximum number of files that you can have open on the Macintosh at one time. This varies between System 7 and earlier versions of the Macintosh operating system.
System 7 is basically limited in this area only by the amount of RAM that you have available. It dynamically allocates more memory for the file control blocks, depending on the number of files that you desire to open. So this typically is not a problem under System 7.
System 6, however, defaults to 10 open files at once. This is most easily altered by the use of an init called “Up Your FCBs,” available on the current Developer CD Series disc. Please note that you shouldn’t try to use this init with System 7; it isn’t necessary and most likely will cause you problems. Alternatively, you can change this value yourself by modifying your SystemStartup boot block information. This is fairly easy to do, but it should be noted that Apple doesn’t support modifications to your boot blocks.
The SystemStartup information (for a Macintosh system or a file server), is stored in logical blocks 0 and 1 of an HFS startup disk. It contains the maximum number of files that can be open simultaneously, with a default of 10. The location for this parameter is $7A of logical block 0 on an HFS disk. The number at $7A (default is $000A or decimal 10) serves as the parameter for files open at one time.
The number $000A (or decimal 10), for instance, is proper for 128K and 512K systems. If the Macintosh is equipped with 1 MB or more of memory, the system multiplies the number at $7A by four (that is, it becomes decimal 40) and uses the new number as the new file limiter.
You can use a disk editor, like FEdit, to change this number. The file control block buffer and system heap size will be calculated with the changed files open parameter upon restarting. If you must raise this number, do it in small increments. Raising the number in location $7A, as some users have done, can force the system to set aside too much memory. This causes a system error, which, because it is unexpected, the system cannot handle. The result is a system lockup.
The MPW linker tends to stretch the open file maximum. If you’re running into problems trying to link too many files at once, you might consider using the lib utility to combine some of these files, thus requiring fewer file control blocks to be open at once during the link process.
Operating System: File System: Code for reading from a nonMacintosh-formatted floppy disk
My Macintosh® application needs to recognize, list the files of, and read files from a DOS disk in a Macintosh application, while running under either System 6 or 7. Something akin to the way Apple File Exchange works would be fine—starting the application and then having the application recognize the DOS disk and listing its contents.
Assuming you want to start from scratch and write your own, instead of using a third-party software package such as DosMounter, you’ll probably need to check out technical references on DOS floppy formats. Here’s some code for the hard part—reading an arbitrary floppy in non-Macintosh format:
/* pass driver name, e.g. ".Sony" */
/* returns driver Reference Number */
OSErr
Open(fn, RefNum)
StringPtr fn;
short *RefNum;
{
OSErr result;
ParamBlockRec pb;
pb.ioParam.ioNamePtr = fn;
pb.ioParam.ioCompletion = 0;
pb.ioParam.ioPermssn = fsRdPerm;
result = PBOpen(&pb, false);
*RefNum = pb.ioParam.ioRefNum;
return result;
}
/* pass refNum gotten from Open */
/* pointer to destination */
/* bytes to read */
/* offset from byte 0 of disk */
OSErr
Read(refNum, dest, count, offset)
short refNum;
Ptr dest;
long count;
long offset;
{
OSErr result;
ParamBlockRec io;
io.ioParam.ioCompletion = NULL;
io.ioParam.ioVRefNum = 1;
io.ioParam.ioRefNum = refNum;
io.ioParam.ioBuffer = dest;
io.ioParam.ioReqCount = count;
io.ioParam.ioPosMode = fsFromStart;
io.ioParam.ioPosOffset = offset;
result = PBRead(&io, false);
if (result != noErr)
printf("PBRead failed. ioActCount = %d\n", io.ioParam.ioActCount);
return result;
}
Operating System: File System: Technique for maintaining up-to-date list of Macintosh volumes
How can my Macintosh® application maintain an up-to-date list of active volumes? Is there a way to detect if a volume is ejected?
No event is posted, and no other notification is available for when a volume is ejected. The best way of keeping your list of volumes up to date is to index periodically through all mounted volumes with PBHGetVInfo or PBGetVInfo and cross-check them against your program’s most up-to-date list of volumes.
It’s probably best to do this check also on every resume event, in case the user ejects a disk while in the Finder. The periodic check is still necessary, however, in case a Desk Accessory in your own heap ejects a disk or the user hits command-shift-1 or 2. Since you probably don’t want to check every call through WaitNextEvent, just keep track of the last time you updated the volume list and compare it to TickCount.
Operating System: File System: Changing the volume control block modification date
How can I change the modification date of my Macintosh® external file system driver’s volume control block? I’ve tried different values in both the vcbLsMod field of the volume control block and the ioVLsMod field of the HParamBlock without success.
Some of the volume information is getting magically cached somewhere, and that in order to update it, you must first put the volume offline! I know, it sounds weird, but I’ve seen the source code to disk copy utilities that do this in order to change that kind of information. So try putting the volume offline before writing the volume info out to it, and then call FlushVol on the volume.
Operating System: File System: Copying a file from application folder to System folder
My installer application should automatically copy known files from either a floppy or a folder in the same directory or folder as the application. How can I determine a reference number for the source file in the directory without using the Standard File Package SFGetFile?
Regarding your question as to how best to go about copying some files from the same folder as your application to the System folder, here are a few thoughts:
For any File Manager call that expects only a vRefNum—that is, it isn’t one of the HFS-specific calls—passing a vRefNum of zero (0) will refer to the same folder as the application. So, for example, you could pass zero to PBOpen to read the data fork of the file, and you could pass zero to read the resource fork. Note that in both cases, you should pass the name of the file as well, and specify read permission only, since your intent is to copy the file, not to write to it.
You should use the PB calls because they allow you to specify access privileges to the files, which is a particularly good idea in a shared environment, such as MultiFinder or a file server. If you do use the PB calls to open the file forks, you should also use them for reading and writing, as mixing and matching high- and low-level File Manager calls tends to give the Operating System indigestion, to say nothing of what it would do to the programmer.
Don’t forget to get the File Info from the source file and set the File Info of the copy! But in the process, don’t forget not to copy the INITed bit.
So, in summary: use a vRefNum of zero to refer to the same folder as the
application, refer to the files by name, and watch out for the above points,
and everything should go smoothly.
Operating System: File System: How to get the directory ID of a folder based on the path name
Is there any Macintosh® routine that gets the directory ID of a folder based on the path name?
You can call PBGetCatInfo with ioFDirIndex set to zero to get the directory ID of a folder based on the path name.
Operating System: File System: Code for identifying vRefNum and DirID of MAC System Folder
I need to identify the startup volume as I index through all volumes with PBHGetVInfo, but GetVol and SysEnvirons are returning WDIDs. How can I get the true vRefNum from these calls?
The code below is general purpose code to identify the vRefNum and DirID of the System Folder. It is System 7.0 friendly in that it will use FindFolder ifpresent; otherwise, it falls back to SysEnvirons and converts the wdRefNum into a vRefNum and DirID.
#define BTstQ(arg, bitnbr) (arg & (1 << bitnbr))
/* FindSysFolder returns the (real) vRefNum, and the DirID of
the current system folder. It uses the Folder Manager if
present, otherwise it falls back to SysEnvirons. It returns
zero on success, otherwise a standard system error. */
OSErr FindSysFolder(short *foundVRefNum, long *foundDirID)
{
long gesResponse;
SysEnvRec envRec;
WDPBRec myWDPB;
unsigned char volName[34];
OSErr err;
*foundVRefNum = 0;
*foundDirID = 0;
if (!Gestalt (gestaltFindFolderAttr, &gesResponse) &&
BTstQ (gesResponse, gestaltFindFolderPresent)) {
/* Does Folder Manager exist? */
err = FindFolder (kOnSystemDisk, kSystemFolderType,
kDontCreateFolder,
foundVRefNum, foundDirID);
} else {
/* Gestalt can't give us the answer, so we resort to
SysEnvirons */
if (!(err = SysEnvirons (curSysEnvVers, &envRec))) {
myWDPB.ioVRefNum = envRec.sysVRefNum;
volName[0] = '\000'; /* Zero volume
name */
myWDPB.ioNamePtr = volName;
myWDPB.ioWDIndex = 0;
myWDPB.ioWDProcID = 0;
if (!(err = PBGetWDInfo (&myWDPB, 0))) {
*foundVRefNum = myWDPB.ioWDVRefNum;
*foundDirID = myWDPB.ioWDDirID;
}
}
}
return (err);
}
Operating System: File System: System 7 UnmountVol and Eject calls return positive drive number
Why is my Macintosh® driver receiving a positive drive number under System 7.0 upon notification of an _Eject call?
When the “driver wants a call on eject” bit is set in the flag bytes preceding a drive queue element, _Eject will issue a _Control call with a csCode of 7 to the driver. This _Control call is supposed to inform the driver which disk the OS is attempting to eject, by passing the drive number in the ioVRefNum field of the parameter block.
However, there’s a bug in the ROM that only mainfests itself when _Eject is given a volume reference number for a disk that has both the “nonejectable” and “driver wants a call on eject” bits set in the drive flag bytes. This bug causes the driver to receive the negative of the drive number, rather than the positive drive number.
The System 7.0 Finder™ has reversed the order of its calls to _UnmountVol and _Eject, causing it to pass the drive number to _Eject, which then passes it on to the driver correctly. Unfortunately, under previous systems, the Finder passed the volume reference number to _Eject, forcing developers to work around the bug by accepting negative drive numbers; however, a problem could occur now under System 7.0 if positive drive numbers weren’t accepted as well.
A number of driver writers have notified us of this problem, but few (so far) have been adversely affected. As it has always been possible for utilities or applications to make _Eject calls with either a volume reference number or a drive number, the proper workaround is to handle both positive and negative drive numbers.
Operating System: File System: Apple II ProDOS file system cache
How can I turn off the GS/OS® file system cache, or keep it from writing to a disk while my file system optimizer is running?
Altering volumes at the block level will confuse GS/OS, because the ProDOS® File System Translator (FST) keeps copies of file system structures that aren’t in the cache. You need to use DWrite, although using DWrite instead of WRITE_BLOCK risks destroying the integrity of any open files on disk, such as the system resource file. If you use WRITE_BLOCK, you must close any open files, including the system resource file if you optimize the boot disk.
Once you start optimizing, don’t make any calls that could directly or indirectly result in operating system calls—no DA access, no Font Manager calls, no loading tools, nothing. When you’re done, GS/OS’s internal volume control records (VCRs) will be completely invalid and you’ll have to call OSShutDown.
Operating System: File System: Macintosh filename cannot start with a period (.)
Why do I get a bomb when I create a Macintosh® filename starting with a period (.)?
Macintosh filenames are not allowed to begin with a period, to avoid possible confusion with driver names, which must begin with a period. (This restriction does not apply to folder names.) Ideally, the Finder® should catch this possible error and require the file to be renamed, but it doesn’t. Future versions of the Finder should catch this potential problem, but until then users must remember not to begin a filename with a period. See Macintosh Technical Note #102, HFS Elucidations, for details.
Operating System: File System: Macintosh file reference number (refNum) range
Can the refNum returned by FSOpen ever be 1? What is the range or format of legal refNums?
Macintosh® file reference numbers (refNums) are currently positive and that means any positive number, including 1. This doesn’t mean that they won’t change in the future, however. To maintain system compatibility, use refNums only as they’re intended to be used.
Operating System: File System: PBHCopyFile and Macintosh file copying
I was just about to write a Macintosh® file copying function when I decided to look up a definition in HFS.h (THINK C 4.0.2) and stumbled across the following definition:
typedef struct {
STANDARD_PBHEADER
int ioDstVRefNum;
int filler8;
Ptr ioNewName;
Ptr ioCopyName;
longioNewDirID;
longfiller14;
longfiller15;
longioDirID;
} CopyParam;
Isn’t this a PB for a file copying function?
The ParamBlock structure that you found is indeed for the PBHCopyFile call. PBHCopyFile is documented in Inside Macintosh, Volume V, the File Manager chapter. The hitch is that it is an optional call for AppleShare® file servers, and it works only intra-server (but can work across volumes that are on the same server). You can determine whether a particular volume supports PBHCopyFile by calling PBHGetVolParms on that volume and checking the bHasCopyFile flag (bit 14) of the VMAttrib field. Also, you can determine whether two volumes are on the same server by calling PBHGetVolParms on them and comparing their internet addresses. If they are the same, then they are on the same server.
Unfortunately, if what you are looking for is a single call to copy a file on the Macintosh, there isn’t one (oddly enough). To handle the general case of copying a file on the Macintosh, you still have to copy the file’s data fork, resource fork, and Finder Info flags, except for the INITed bit.
Operating System: File System: Space & pointer needed for ioNamePtr name string to be returned
I am trying to convert from a Macintosh® working directory reference number, as returned by SFGetFile, to a directory ID (DirID) and volume reference number (vRefNum). I also require the volume name (ioNamePtr). My code successfully returns the former two items but repeatedly returns ioNamePtr as a NIL.
The File Manager calls that return a string always require you, the caller, to allocate space for that string and to pass the pointer to that memory in ioNamePtr. If the File Manager sees that ioNamePtr is NIL, it won’t bother returning the name string.
Operating System: File System: Determining the amount of free space on a Macintosh disk
How can I determine the amount of free space on my Macintosh® disk?
This is determined from information obtained from a pbHGetVInfo call. Determine the free space by multiplying the number of free blocks on the disk by the size of each of these blocks. Here’s an example in MPW® Pascal:
TwoIntsMakesALong = RECORD
{ Necessary trick to take into account that ioVFrBlk is unsigned }
CASE Integer OF
1: (long: LongInt);
2: (ints: ARRAY [0..1] OF Integer);
END; {TwoIntsMakesALong}
VAR
myHPB : HParamBlockRec;
convert : TwoIntsMakesALong;
BEGIN
WITH myHPB DO BEGIN { set up the block for the
PBHGetVInfo call}
ioNamePtr := NIL; { we don’t care about the name}
ioVRefNum := yourVRefNum;
ioVolIndex := 0; { use ioVRefNum only}
END; {with}
err := PBHGetVInfo(@myHPB,FALSE);
convert.ints[0] := 0;
convert.ints[1] := myHPB.ioVFrBlk;
FreeSpace := convert.long * myHPB.ioVAlBlkSiz;
END;
In MPW C, it looks something like this:
HParamBlockRec myHPB;
longint FreeSpace
myHPB.volumeParam.ioNamePtr = nil; /* don't care about
the name */
myHPB.volumeParam.ioVRefNum = yourVRefNum;
myHPB.volumeParam.ioVolIndex = 0; /* use ioVRefNum only */
err = PBHGetVInfo(&myHPB,false);
FreeSpace = (long)myHPB.volumeParam.ioVFrBlk * myHPB.volumeParam.ioVAlBlkSiz;
Operating System: File System: Opening and reading Macintosh files during I/O completion time
I have created a Macintosh® INIT that will communicate over the net asynchronously using ADSP (AppleTalk® Data Stream Protocol). I would like to be able to open and read files during IO completion time. File Manager calls like FSOpen would not work if an application were accessing the disk when the ioCompletion occurred. I am considering using ASYNC device driver calls, but PBOpen has the possibility of moving memory. Is there a way around this?
Hmmmmmm… in real life, PBOpen won’t move memory as long as you use the preallocated volume buffer that the system provides by default.
The File Manager isn’t reentrant, either, but there are a couple of things to try that might do the job for you:
1) Use the asynchronous versions of the calls. The problem here is that the SCSI Manager actually doesn’t support asynchronous SCSI I/O, but the effect that you’re really looking for—postponing the file operation until it’s safe— might be the end result anyway.
2) You might wish to block on the value of the low-RAM global FSBusy. If it’s TRUE, then a file operation is already in progress and you’ll have to wait.
A caveat: The FCB queue in System 7.0 is dynamically resized, which means that System 7.0 will no longer suffer from the “how many files can I have open at once” problem, but it also means that opening files will no longer be safe at times when it isn’t safe to call the Memory Manager (such as at interrupt/ioCompletion time).
Operating System: File System: How a new Macintosh directory ID is determined
Our Macintosh® application moves files between directories on a file system; the directories determine certain actions and are seldom changed; thus, the application keeps a persistent reference to the directories. The current form of this reference is <volume name, path from root>. According to a System 7 lecture, the preferred form for a persistent file reference is <volume name, directory ID, filename>, which reduces to <volume name, directory ID>, the preferred form for a persistent directory reference. The process of throwing folders away and creating new ones could result in a directory ID being reused on an HFS volume. Is this truly a threat, or has the directory allocation scheme been designed to require many transactions before reusing an ID?
You are correct in your assumption that many transactions need to take place before a directory ID gets reused. The system does not start with dir ID = 0 and search the hard disk until it finds an ID that’s not used. Instead, the ID of the last created folder in a “last created ID” field on the disk. When the system creates a new folder, it searches with that “last value” + 1. Since these are 32-bit values, you’d have to create over 4 billion folders before you wrap around again to zero.
Operating System: File System: No file limit within Macintosh HFS directory
Is there a limit to the number of Macintosh® files that can be put into a single directory under HFS?
There really isn’t a limit to the number of files that can be placed in a single directory under HFS. The only limit is disk space. The Finder™ may have some performance problems (for example, it may take a long time for the window to update), but there shouldn’t be any major problems.
Operating System: File System: _CatMove vs _HReName
When using the Macintosh® _CatMove trap, can I pass the ioNewName field and leave the ioNewDirID field nil? When tracing through a few calls to this trap, it seems that _CatMove works just fine when the reverse is true (ioNewName is nil).
It sounds like you are trying to get _CatMove to behave like _HRename. Leaving the ioNewName field nil is reasonable if you are just changing the position of the file in the directory structure without effecting its name. In the case of filling in ioNewName and leaving ioNewDirID blank (if it were allowed), this would be like saying “change the name and leave the directory unchanged.” This is definitely a job for _HRename.
Operating System: File System: Distinguishing between Macintosh vRefNums and WDRefNums
How do I find the real Macintosh® vRefNum and real dirID? If I pass a working directory to PBHGetFInfo, will the ioDirID field return a real dirID? Will the ioVRefNum field contain the working directory I passed in or the real vRefNum? Also, if I pass a real vRefNum to GetWDInfo, will it do nothing and yet return no error?
Here’s the way to tell the difference between vRefNums and WDRefNums (copied from Macintosh Technical Note #77):
A vRefNum is a small negative word (e.g. $FFFE).
A WDRefNum is a large negative word (e.g. $8033).
A dirID is a long word (for example, 38). The root directory
of an HFS volume always has a dirID of 2.
When you pass a real vRefNum into GetWDInfo, it will look at the ioWDIndex field in the WDPBPtr and return information about the corresponding working directory on that volume (Inside Macintosh, Volume IV, page 159). You can also specify an ioWDProcID and GetWDInfo will only index through Working Directories on the specified volume with the specified proc ID.
PBHGetFInfo will not return a valid dirID and vRefNum if you pass it a working directory; if you want that information you should pass the WDRefNum to PBGetWDInfo in ioVRefNum (making sure you set ioWDIndex to zero).
Remember that working directories are provided simply to facilitate compatibility between HFS and programs that were written under MFS. You should be converting working directories to their corresponding VRefNum and dirID pairs before using them with your PBH variant calls.
Operating System: File System: Working directories and WDRefNum
How do I get the directory ID when using HCreateResFile (as described in Macintosh® Technical Note #214). Also, what exactly are working directories, and do I need to be concerned with them, or are they a thing of the past?
The directory ID comes indirectly from the Standard File dialogue that the user uses to select an output or input file. Standard File returns a working directory reference number in the ioVRefNum. Use the PBGetWDInfo call to break that up into an ioVRefNum and ioDirID pair.
Working directories are a compatibility item to allow programs written for MFS to run under HFS. Since MFS didn’t support directories in any true sense, HFS needed to be able to encode both volume and directory information in the same place. The vRefNum was the most logical spot to do that, and hence the WDRefNum was born. The first and last thing you should do with a WDRefNum is convert it to a vRefNum and DirID pair. For more information on the PBGetWDInfo call, please refer to Inside Macintosh, Volume IV, page 159.
Operating System: File System: PBHDelete insights and code snippet
Using a synchronous call to delete an empty Macintosh® directory using PBHDelete returns a fBsyErr.
I don’t know exactly what is causing the fBsyErr on your machine, but here’s my best guess: The reason you are experiencing this problem is that something has set a working directory to the one you’re trying to delete. I was able to get this to happen by setting the current directory in MPW to “foo:temp:” and then trying to delete it. The bad news is that you can’t close another process’s working directory. There will be cases where your application won’t be able to delete the directory until the user resets the default directory in the offending application. Such are the perils of working in a multi-tasking environment....
Also, I would suggest using a routine like the one included below. It ensures that the specified file is in fact a directory, and supplies a vRefNum and DirID to PBHDelete, which I feel is safer than just giving a full pathname.
/*
**
** DirDelete.c
**
** An MPW tool to delete a directory.
** Gets the target file from the command line.
**
** Neil Day
** MacDTS
** Apple Computer, Inc.
** 11/29/90
**
*/
#include <Stdio.h> /* compiler interfaces */
#include <Files.h>
#include <Memory.h>
#include <Strings.h>
#define DIR_BIT 4
OSErr DirDelete (char *dirName); /* function prototypes */
main (argc,argv)
int argc;
char **argv;
{
int argCounter;
OSErr err;
if (argc < 2) {
printf ("Format : DirDelete <file1> [<file2> ... <fileN>]\n");
return;
}
for (argCounter = 1; argCounter < argc; argCounter++) {
printf ("%s\n",argv[argCounter]);
err = DirDelete (argv[argCounter]);
if (err)
printf ("DirDelete : got error %d while trying to remove %s\n",
err,argv[argCounter]);
}
}
/*
** DirDelete
** Deletes a directory given the full pathname to the directory.
**
** Uses PBGetCatInfo to retrieve the vRefNum and DirID
** of the directory and its status flags. Checks to see that
** the specified file is in a directory, and deletes
** it if it is...
**
*/
OSErr DirDelete (dirName)
char *dirName;
{
OSErr err;
CInfoPBPtr Info;
HParmBlkPtr delete_me;
err = noErr;
Info = (CInfoPBPtr) NewPtrClear (sizeof(CInfoPBRec));
Info->hFileInfo.ioNamePtr = c2pstr(dirName);
delete_me = (HParmBlkPtr) NewPtrClear (sizeof (HParamBlockRec));
err = PBGetCatInfo (Info,false);
if ((!err) && ((Info->hFileInfo.ioFlAttrib>>DIR_BIT) & 0x01)) {
delete_me->fileParam.ioVRefNum = Info->hFileInfo.ioVRefNum;
delete_me->fileParam.ioDirID = Info->hFileInfo.ioDirID;
err = PBHDelete (delete_me,false);
}
DisposPtr ((Ptr)Info);
DisposPtr ((Ptr)delete_me);
return err;
Operating System: File System: How to get the correct size of a Macintosh file
How do I determine the size of a Macintosh® file? I want to get exactly what the Finder™ reports when you do Get Info on a selected file. How do I use the FileParam fields, ioFlLgLen, ioFlPyLen, ioFlRLgLen and ioFlRPyLen to find out the size of a disk file after a call to PBGetFInfo?
To get the correct size of a Macintosh file one needs to sum the physical sizes of the resource and data forks. So, you’ll need to add the fields ioFlPyLen and ioFlRPylen returned in the parameter block.
Operating System: File System: Macintosh verified read error produces dataVerErr (-68)
If I call _Read with “44-ioPosMode” ORed with $40 for a Macintosh® verify, what error code is returned if the verify is not successful?
An error in a verified read should produce an dataVerErr (-68).
Operating System: File System: ioNamePtr needs value for PBGetWDInfo
Why does a call to PBGetWDInfo (without using the ioNamePtr) cause a bus error in the trap _HFSDispatch that is called from the XFCN glue?
DTS Macintosh Tech Note #179 says that you should always set ioNamePtr to some value (NIL if you don’t want a name returned to you).
Operating System: File System: Steps for duplicating a Macintosh file
Is there a routine in the Macintosh® operating system to duplicate a file? (Something that is similar to doing “File - Duplicate” or dragging a file from one disk to another.) We tried PBHCopyFile but, as Inside Macintosh V implied, it did not work.
Unfortunately there isn’t a routine in the Macintosh OS to duplicate a file. The only way to duplicate a file is by doing the following:
1) Create a new file,
2) Open the old file,
3) Open the new file,
4) Check to see how long the old file is,
5) Read the old file,
6) Write everything you read to the new file, then
7) Close both files.
Operating System: File System: Getting HFS directories from full pathnames
How can I determine Macintosh® HFS directories from the full pathnames without going through SFGetFile or opening files?
Apple recommends not using full pathnames. They’re unwieldy, they take up lots of space, the File Manager doesn’t deal with names longer than 255 characters, and they’re unnecessary.
However, if you are working with a piece of software other than your own, it may be unavoidable. If so, there are two methods depending on the size of the full pathname:
1. If the full pathname is less than 255 characters, simply get the dirID of the directory by calling PBGetCatInfo.
VAR
pbc: CInfoPBRec;
BEGIN
name := 'Chinese Junk:Test:VMCalls:';
WITH pbc DO BEGIN
ioCompletion := NIL;
ioNamePtr := @name;
ioVRefNum := 0;
ioFDirIndex := 0;
ioDrDirID := 0;
END;
err := PBGetCatInfo(@pbc, FALSE);
This will return to you the dirID of the folder in ioDrDirID.
2. If the full pathname is longer than 255 characters, you will have to break up the name into smaller parts and get information incrementally. This is shown below. Note that this example is not quite realistic since I store the original full pathname in a Pascal string, which will always be smaller than 255 characters.
VAR
pbc: CInfoPBRec;
pbh: HParamBlockRec;
name: Str255;
tempname: Str255;
vRefNum: Integer;
dirID: LONGINT;
done: Boolean;
lastPos: Integer;
curPos: Integer;
BEGIN
name := 'Chinese Junk:Test:VMCalls:';
tempname := name; {PBHGetVInfo modified ioNamePtr
string, so copy it}
WITH pbh DO BEGIN
ioCompletion := NIL;
ioNamePtr := @tempname;
ioVRefNum := 0;
ioVolIndex := 0;
END;
err := PBHGetVInfo(@pbh, FALSE);
vRefNum := pbh.ioVRefNum; {get vRefNum for PBGetCatInfo
calls}
dirID := 0; {init dirID to zero}
done := FALSE;
lastPos := 1;
REPEAT
curPos := lastPos; {look for the next chunk
surrounded by colons}
REPEAT
curPos := curPos + 1;
done := curPos >= LENGTH(name);
UNTIL (name[curPos] = ':') | (done);
tempname := Copy(name, lastPos, curPos - lastPos + 1);
lastPos := curPos;
WITH pbc DO BEGIN
ioCompletion := NIL;
ioNamePtr := @tempname;
ioVRefNum := vRefNum;
ioFDirIndex := 0;
ioDirID := dirID;
END;
err := PBGetCatInfo(@pbc, FALSE);
dirID := pbc.ioDrDirID; {get this dirID to use a
parent for next chunk}
Writeln('err = ', err);
Writeln('tempName = ', tempname);
Writeln('ioVRefNum = ', pbc.ioVRefNum);
Writeln('ioDrDirID = ', pbc.ioDrDirID);
Writeln('ioDrParID = ', pbc.ioDrParID);
UNTIL done;
END.
This will give you the following output:
err = 0
tempName = Chinese Junk:
ioVRefNum = -2
ioDrDirID = 2
ioDrParID = 2
err = 0
tempName = :Test:
ioVRefNum = -2
ioDrDirID = 271
ioDrParID = 2
err = 0
tempName = :VMCalls:
ioVRefNum = -2 <--- this is the vRefNum you want
ioDrDirID = 26399 <--- this is the dirID you want
ioDrParID = 271
Operating System: File System: How to display mounted volumes in a dialog box
In a MacApp® Pascal program, how can I display all mounted volumes in a dialog box including each volume’s icon and name (similar to the way the Finder™ displays volumes)? I cannot get the resource ID of the icons.
Inside Macintosh® IV-223 and V-469 describe how to read a volume’s ICON. “The Disc Driver” discusses csCode=21, which you can use to make special control calls that will work for all drives to get icon and other information. Tech Note #272, “What Your Sony Drives for You,” describes how to make floppy calls if necessary. The csCode control call should work for you. For an AppleShare® volume, Inside AppleTalk®’’s AppleTalk Filing Protocol (AFP) chapter, pages 13-91 to 13-94, describes a couple of helpful icon-related calls as well.
Operating System: File System: Where to find DirCreate documentation
How do I use DirCreate to create directories?
DirCreate (PBDirCreate) is documented in Inside Macintosh®, Volume IV, page 146. This should give you all the information you need to correctly create a directory with this call. You should also be able to find it listed in the index at the end of that volume for future reference.
Operating System: File System: Apple IIGS System 5 supports File Type Descriptor strings
I noticed the Apple IIGS® Finder™ is now using application-specific strings for the “kind” of a file. How can I use this capability?
The Finder on System Software 5.0 uses a new data structure known as a File Type Descriptor to allow a string to be matched with a particular file type and auxiliary type. Like icon files, multiple File Type Descriptor files may be used, so strings may be “added” to the Finder’s vocabulary. Details on the data structure and the Finder’s implementation are in Apple II File Type Note for File Type $42.
Operating System: File System: Where can I find more information about HFS structures?
Where can I find more information about HFS structures other than in Inside Macintosh®?
Another source of information besides Inside Macintosh® is the MPW® FSPrivate.a file, which contains some private equates used when building the system. None of the information found or used in this file, however, is supported. Don’t ask MacDTS questions regarding any of this information. Using the information is very risky, and will certainly lead to compatibility problems. Proceed at your own risk!
Operating System: File System: How to determine if a Mac file or resource file is already open
How can I tell if a Macintosh® file or a resource file is already open?
Use the File Manager routines PBGetFInfo (IM IV: 148), PBHGetFInfo (IM IV: 149), and PBGetCatInfo (IM IV: 155) to determine if a file is open, and which forks (resource and data) of the file are open. All these routines return ioFlAttrib in the parameter block, which has bits set or cleared to indicate if the file is locked, open, or a directory, and which forks are open (IM IV: 125).
OpenResFile will then call the File Manager to open the resource fork of a file. The refNum returned by OpenResFile is a File Manager reference number. To find out if a resource file is already open (so you don’t accidently close it, for example), just check if the resource fork of the file is open (before you call OpenResFile). If it is, call OpenResFile to get the refNum, but don’t call CloseResFile.
Here’s a fragment in C:
/* uses a full pathname rather than vRefNum/dirId */
HFileInfo fParams;
...
fParams.ioCompletion = NIL;
fParams.ioVRefNum = 0;
fParams.ioFDirIndex = 0;
fParams.ioDirID = 0L;
fParams.ioNamePtr := "\pVolume:Folder:Filename"; /* Pascal string */
err = PBGetCatInfo(fParams, FALSE);
if (fParams.ioFlAttrib & 0x10)
/* pathname is a directory */
else if (fParams.ioFlAttrib & 0x04)
/* resource fork is open */
else ...
Operating System: File System: How can I set the Protect bit of a Macintosh file?
How can I set the Protect bit of a Macintosh® file?
The Protect bit is neither documented nor supported. PBSetCatInfo and PBSetFInfo cannot set this bit. In fact, there is no system call that will modify this bit. Additionally, attempting to change the Lock bit also fails with either of these calls. SetFLock trap must be used to set the Lock bit of the file’s attribute. The Protect bit was an early method of copy protection. If the Finder sees this bit set, it will not allow the user to copy, move, delete or rename the file. It is important to note that ONLY the Finder is paying any attention to this Protect bit, so it would be possible to use any file utility to copy the file even if it is “protected.”
Operating System: File System: How to determine if a Macintosh file is on a locked disk
How do I determine whether a Macintosh® file is on a locked disk?
Call the function PBGetVInfo and check ioVAtrb, which it passes back in the parameter block. If the volume has a software lock, then bit 15 of ioVatrb will be set. If there is a hardware lock (such as the CD-ROM), bit 7 is set.
Operating System: File System: How do I tell if a Macintosh volume is MFS or HFS?
How do I tell if a Macintsoh® volume is MFS or HFS?
To determine whether a volume is HFS or MFS, call PBHGetVInfo. In the field ioVSigWord, the two values you want are $42$44 (HFS) or $D2$D7 (MFS).
Remember, there may be other types of volumes besides these two, such as High Sierra, ISO 9660, or MS-DOS. Don’t assume just two values.
Operating System: File System: How do I find the size of a Macintosh volume?
How do I find the size of a Macintosh® volume?
To find the size of a volume, call PBHGetVInfo. The size is the product of the number of allocation blocks and the allocation block size. (ioVNmAlBlks * ioVAlBlkSiz) It is important to remember—especially in Pascal—that ioVNmAlBlks is an UNSIGNED quantity. If you don’t take that into account, you may get negative results. See pages 123-4 and 130 of Inside Macintosh Volume IV for more details.
Operating System: File System: How do I tell if a volume is a floppy or hard disk, or removable
How do I tell if a Macintosh® volume is a floppy or hard disk?
What you probably want to know is whether a device in the drive queue is removable. Do this by examining the four bytes of flags proceeding the drive queue entry for the device. See pages 181-2 of Inside Macintosh Volume IV for details. C source is:
/* we assume that you get the drive number from some appropriate
place, such as doing a PBHGetVInfo for the volume or looking
directly in the vcb (ackk!)
*/
Boolean
IsEjectable(driveNumber)
short driveNumber
{
DrvQElPtr d;
QHdrPtr queueHeader;
Ptr p;
queueHeader = GetDrvQHdr();
d = (DrvQElPtr)queueHeader->qHead;
while (d != nil) /* find the appropriate drive # */
{
if (d->dQDrive == driveNumber) /* is this the drive
we want? */
{
p = (Ptr)d;
p -= 3; /* to get to the byte with eject info */
if (*p == 8)
return false; /* non ejectable disk
in drive */
else
return true;
}
d = (DrvQElPtr)d->qLink;
}
return false; /* you specified an invalid drive number */
}
If you actually want to know if a volume is a floppy or not, use PBHGetVInfo, and multiply the ioVNmAlBlks (remember, it’s unsigned!) times ioVAlBlkSiz. Currently valid sizes include 400K, 800K, 720K, 1440K.
How will you handle other sizes in the future? Nasty. That’s why I hope you are really asking to detect removable media.
Operating System: File System: How can I tell which directory my Macintosh application is in?
How can I tell which directory my Macintosh® application is in?
When an application is started, the default volume is set to the directory that contains the application. GetVol returns the default volume. If the application calls GetVol before changing the default volume, it will have the directory for the folder containing the application.
Operating System: File System: Forcing the Macintosh system to switch-launch
How can I get my Macintosh® application to force the system to switch to the application’s disk when the user launches it, like Installer does?
This is called switch-launching. You can do what Installer does, setting a Finder™ flag which tells Finder to switch-launch to the new volume. Set this flag with ResEdit™ by selecting the application, selecting “Get Info” from the File menu, then setting the appropriate check box. You can also set this with the MPW® command:
SetFile -a A foo
Note that forcing a switch-launch in this way NEVER works if any of the following conditions are true:
• The new volume is not bootable—that is, has no system
or Finder or is a volume like an AppleShare® volume;
• MultiFinder® is running;
• Either the system or Finder on the new volume is an
older version than the one currently in use.
If any of these conditions are true and you try to force a switch-launch, the user will get a dialog stating why switch-launching is not possible, and asking if the user wants to proceed with the launch (without the switch) or cancel it.
Because of these limitations, if you plan for your application to be used by others and you depend on this capability, you need to think carefully about the consequences of forcing switch-launching. For example, a user may (and probably will) choose to run MultiFinder. There is no way for you to know if MultiFinder is running, and if you are depending on the switch, strange things may happen. Switch-launching may be even more restricted in the future.
Operating System: Finder: Macintosh Finder’s 'fmnu' menu resource TMPL
A variety of homebrew TMPLs for the Finder’s 'fmnu' menu resources have been “thrown over the transom” on AppleLink and other bulletin boards, but I don’t recall anything official. Has Apple publicly documented this Finder resource?
Apple doesn’t have an official TMPL for the Finder’s 'fmnu' menu resources. It hasn’t been publicly documented, because (to some extent) it’s private to the Finder.
The Finder team agreed that there’d be no harm in releasing the Rez template they use, because users might want to mess with command keys, menu titles, etc, for their own use. However, they declined to release the definitions of the flag bits (marked below with three asterii); these should be left alone (they have to do with how the Finder decides to enable items and certain actions to be generically performed when an item is chosen). So, here’s the template, with the caveat that it could change anytime:
type 'fmnu'
{
integer; /* flags *** */
integer = $$CountOf(ItemArray); /* number of items */
array ItemArray
{
longint; /* command id */
integer; /* item flags *** */
string[1]; /* key equivalent */
align word;
pstring; /* menu title */
align word;
};
};
Operating System: Finder: Creating a Finder alias
How can I get my program to create a Finder alias?
Finder aliases are one aspect of the Macintosh human interface considered “reserved for users.” The format is intentionally undefined because it is subject to change, and because alias files should be neither created nor altered by applications. The Finder is the user’s domain, and aliases are a user convenience. If you are inclined to create an alias file, rethink your application design. Would clear instructions to users on how to make the aliases be adequate? Are the files your application needs too scattered?
If some demon still drives you to make alias files, the safest way to do it is by issuing Apple events to the Finder. The particular Finder event for making an alias is 'FNDR' 'sali'; it is documented in the Apple Event registry. Since this Finder event does not return either the name of or an alias to the new alias file, nor is there a Finder event for identifying the currently selected icons, moving the alias file elsewhere will be problematic.
The unsafe way to make an alias file is to create the file yourself. The format of alias files is undocumented; there is no guarantee that any alias files created by your application will always work. At present, you can construct an alias to a document by getting a handle to an alias with a NewAlias call, creating a resource file with the same creator and file type as the original file, adding the alias as a resource of type 'alis' and ID 0, and setting bit 15 of the file’s Finder flags. Aliases to applications have the file type 'adrp'; folder, volume, and system file aliases use other special file types. Finally, alias files should have the same custom icons as their targets.
Once again, DTS urges that you not create alias files from within an application.
Operating System: Finder: Macintosh Finder extensions aren’t supported
Please tell me how to write a Macintosh® Finder™ extension.
Sorry, but Finder extensions are not supported. They are not documented, and facilities for them have not been adequately tested. It is doubtful that there is enough free space in the Finder to reliably add any extensions which are not a standard part of the system.
This situation may change in the future, but for now, DTS has nothing to offer to help you in trying to write your own Finder Extension except assistance in finding an appropriate alternative.
Operating System: Finder: Updating Macintosh window to show new application icon
When I create an application from within my Macintosh® application and put it into an open folder, the new application’s icon does not show up. How come?
Have you made sure not to set the file’s “inited” bit? If this bit is not set,the Finder™ will eventually go check out the file and update the desktop with the bundle accordingly (then it sets the inited bit). This typically can take up to ten seconds to happen, but it should happen.
Unfortunately, there is no direct way to tell the Finder to update the desktop. The Finder will synchronize the desktop file’s appearance after it detects that a change has been made for a volume. This is triggered when the volume’s modification date changes. This occurs when you create or delete a file, for example, or move it to another folder. When a change occurs, HFS will change the modification date of the volume and that folder. When the Finder notices that the volume’s modification date has changed, it begins scanning for changes in all of the open folders. This scanning process takes place about once every 10 seconds, as mentioned above.
Changing the file’s FndrInfo or renaming the file does not change the modification date. As a suggestion for you, you might initially create a temporary file, and then, once all the files are moved around, delete the temporary file. Deleting the temporary file as a last step will cause the Finder’s window to be updated. This is pretty bogus, but it should work.
Keep in mind that the Finder may cache a windows directory and may not know about icon changes unless the folder’s modification date is updated. The update is not controlled by an interrupt, so an application that is not calling WaitNextEvent often enough will vary the period of updates.
Operating System: Finder: Macintosh Finder desktop updates
How does the Macintosh® Finder™ update its windows?
The Finder synchronizes the desktop file’s appearance after it detects that a change has been made for a volume. This is triggered when the volume’s modification date changes. This occurs when you create or delete a file, for example, or move it to another folder. When a change occurs, HFS changes the modification date of the volume and that folder. When the Finder notices that the volume’s modification date has changed, it begins scanning for changes in all of the open folders. This scanning process takes place about once every 10 seconds.
Changing the file’s FndrInfo or renaming the file does not change the modification date.
Keep in mind that the Finder may cache a window’s directory and may not know about icon changes unless the folder’s modification date is updated. The update is not controlled by an interrupt, so an application that is not calling WaitNextEvent often enough will vary the period of updates.
I’ve heard of other developers who changed the affected volume’s VCB lsMod time to the current time. This apparently forces the Finder to update, but it also apparently doesn’t work with floppy disks.
When the Finder is running without MultiFinder®, it is the only program running so it usually does not have to contend with its file system being manipulated under its nose. The major exception to this is when a driver or Desk Accessory adds, changes, or deletes a file. In this case the Finder is using a copy of the folder’s directory and does not know the contents have changed unless the modification date of the folder has changed.
Under MultiFinder the Finder is aware that other applications can be changing the file system under its nose and approximately every 5 seconds, as allowed by the foreground application calling WaitNextEvent, updates any windows that it knows have changed. The Finder still caches the windows directory and may not know about icon changes unless the folder’s modification date is updated. The update is not controlled by an interrupt; an application that is not calling WaitNextEvent often enough will vary the period of updates.
Operating System: Finder: Determining if Macintosh Desktop Manager is present
How does one determine if the Macintosh® Desktop Manager is available? I know under System 7.0 it’s always available, but how about under 6.0?
The best method for determining whether the Desktop Manager is available or not is to use PBGetVolParms on your boot volume and check one of the flags that’s returned, which indicates whether that volume has the new desktop.
Operating System: Finder: Saving as stationery for both Systems 6.0.x and 7.0
How should my application implement saving as stationery to be compatible with System 6.0.x as well as System 7.0?
When the user saves a document as stationery, your application should write it out with the appropriate stationery file type so both System 6.0.x and System 7.0 Finder vesions will display the file’s icon correctly. Also, set the file’s isStationery bit, which you’ll use to identify the file when the user opens it, under either system version. Of course, along with the regular document’s file type, you’ll need to register the stationery file type with DTS.
Operating System: Finder: Reason for Finder “trash can’t be emptied” alert in MultiFinder®
Why does the Macintosh® Finder™ sometimes display the alert “The trash could not be emptied (a file was busy or a folder was not empty)” when the trash contains only an emptied folder?
This is the behavior that you get from the Finder when another application is running (presumably the one that owns the documents that were trashed) that has the folder open as a working directory. Unfortunately, some applications that open working directories aren’t as careful as they should be about closing them, and the result is that the working directory doesn’t go away until the application has quit. Once it does go away, however, the folder can be trashed with impunity.
Operating System: Finder: Types of unsupported Macintosh Finder window manipulation
How can we access the Macintosh® Finder™’s desktop data structure to accomplish the following:
• Place a file or folder from any mounted volume on the desktop at (x,y)
• Determine what files and folders are on the desktop and where and what disks, directory they belong to.
• Open or close a finder window for a volume or folder
• Put away a file or folder that is on the desktop
under both System 6 and System 7?
Apple doesn’t support Finder window manipulation such as what you’ve described. There is a lot involved in this type of manipulation, and it requires knowledge in areas that also are not supported by Apple. If you really want to pursue this you can try to hack it out on your own, but we can’t guarantee that the techniques you come up with will continue to be compatible with future Finder versions.
Operating System: Finder: 7.0 Finder intercepts Control Panel command key menu events
Under System 7, Macintosh® command key menu events no longer are passed to a Control Panel’s main window and instead intercepted as Finder™ command key menu equivalents. Can I get around this?
Under System 7, all command-key equivalents refer to the menu bar. The problem lies in the fact that, if the Control Panel handles a command-keystroke, there is no way for the Finder to realize it. Although it’s not really recommended, you could conceivably patch KeyTrans and, upon finding that your Control Panel is up and that a command-keystroke is being pressed, queue those in your own private queue that the Control Panel could then search in addition to the normal event queue. This is probably much more trouble than it is worth.
Operating System: Finder: Applications shouldn’t position Macintosh Finder icons
In our installation program, how do we set the Macintosh® Finder™ location of folders that we create during the installation process? The method we’ve tried seems to work in positioning the folder in its parent, but causes the view state of the folder to be inconsistent in System 6—files in the folder appear by name, but the view icon has “by Small Icon” checked. Changing the view state from the View menu seems to work and has no further side effects.
The “right” to position icons in the Finder and to set the default view for new folders is reserved for the user. You create the files and folders, and let the Finder position them. In addition to being closer to what the user expects, you won’t have to worry about positioning conflicts with existing items in the folder (although if you’re creating the parent folder, this doesn’t matter as much). Even more significantly, you won’t have to worry about subtle changes between the 6.x and 7.0 Finders’ positioning and view algorithms.
Operating System: Finder: Macintosh desktop refresh rate
I have observed the Macintosh® desktop is refreshed every 10/20/30 ticks. What is the actual refresh period? Is it a constant or depends on an interrupt? Also is there a way that I can force a refresh? Is it the same under both Finder™ and MultiFinder®?
When the Finder is running without MultiFinder, it the only application running so it usually does not have to contend with its file system being manipulated under its nose. The major exception to this is when a driver or Desk Accessory adds/changes/deletes a file. In this case the Finder is using a copy of the folder’s directory and does not know the contents have changed unless the modification date of the folder has changed.
Under MultiFinder the Finder is aware that other applications can be changing the file system under its nose and approximately every 5 seconds, as allowed by the foreground application calling WaitNextEvent, updates any windows that it knows have changed. The Finder still caches the windows directory and may not know about icon changes unless the folder’s modification date is updated. The update is not controlled by an interrupt; an application that is not calling WaitNextEvent often enough will vary the period of updates.
Operating System: Finder: Controlling which application version is launched by Finder
We have several versions of a Macintosh® application (standard, demonstration, student, and so on) and they all share the same type ('APPL') and creator bytes. When we have all of the versions on a hard disk, double-clicking on a document launches the demonstration version rather than the full version. Is the system’s application choice based on its date of creation, name, or other attribute? How can a user specify which of several versions s/he wishes to launch when double-clicking on a document? Alternatively, what can we as developers do to designate the standard version as the one to be launched if there are other versions on the disk?
The Desktop file maintains a list called the Application List that is all the files of type APPL in order of their entry into the Desktop database. In deciding which one of several versions of the same application to launch, the Finder™ searches this list and launches the first app in the list with the matching creator ID. Applications in the list are ordered based on any event that would update their entry in the Desktop database. The last one copied to the volume is thus at the top of the list. To change the order, you must delete the one you want to be launched, rebuild the desktop and then copy the app back onto the disk. This puts it at the top of the list, and double- clicking any related document will now launch this version of the app.
Operating System: Finder: Apple IIGS 5.0.3 Finder bugs
In using Apple IIGS® System 5.0.3 and a 44 MB third-party removable hard drive, I have the following problems with the system disk: (1) In a disk-to- disk copy from a 32 MB partition to a removable cartridge, the progress bar does not reflect the actual time it takes to copy the partition (it moves too quickly) -- the actual copy DOES work. (2) If a cartridge is not in the drive at startup, a dialog appears stating that the disk is unreadable and asks if it is OK to reformat it.
What you’re seeing are Finder™ bugs. The Finder was not changed for System 5.0.3, but these bugs should be fixed in a future system software release.
Operating System: Finder: Macintosh System 6.0.x Finder rules for emptying trash
When does the Macintosh® 6.0.x Finder™ empty the trash?
According to the Finder source code, here are the conditions under which the trash will be emptied:
• Whenever a copy is done, both the source and destination
disk’s trash will be emptied
• Whenever a disk goes off line
• Whenever a disk is ejected
• Whenever a disk is formatted, the trash will be emptied
before the formatting begins.
• Whenever the user selects empty trash from the “Special” menu
• Whenever an application is launched
• Whenever the system is shut down.
(I determined this by searching the source for all occurrences of the trap _Delete. Then I looked at each of the routines to see if they pertained to trash management. If they did, I searched the source for all occurrences of those routines, looked at each of those and figured out what the enclosing routine did. Since all this was done by examination, it is possible that I missed something.)
Operating System: Finder: Where to find System 7 color icon documentation
How do you get color icons for your applications to show up on the desktop on Macintosh® II computers with color monitors?
Color icons are actually a System 7 feature and therefore unsupported in Systems 6.0.x or earlier. If you would like additional information on this, refer to Inside Macintosh, Volume VI, Chapter 9, “The Finder™ Interface.” This should give you all the information that you’ll need to get this to work under System 7.
Operating System: Finder: Apple IIGS Finder data file format is not available
What is the format of the Apple IIGS® Finder™ data files? There is no File Type Note describing the format.
The format of Finder data files is internal to the Finder. It is version- dependent and the information in the files can’t be reliably used at this point, so the file format is not available.
Operating System: Finder: Forcing the Macintosh Finder to update the desktop
How do I force the Macintosh® Finder™ to update its windows after my application has changed a file’s FndrInfo?
There is no direct way to tell the Finder to update the desktop. The Finder will synchronize the desktop file’s appearance after it detects that a change has been made for a volume. This is triggered when the volume’s modification date changes, which occurs when you create or delete a file, for example, or move it to another folder. When a change occurs, HFS will change the modification date of the volume and that folder. When the Finder notices that the volume’s modification date has changed, it begins scanning for changes in all of the open folders. This scanning process takes place about once every 10 seconds.
Changing the file’s FndrInfo or renaming the file does not change the modification date. As a suggestion for an installer program, you could initially create a temporary file, and then, once all the files are installed, delete the temporary file. Deleting the temporary file as a last step will cause the Finder’s window to be updated.
Operating System: Finder: What do all the bits in the Mac Finder’s 'LAYO' resource mean?
What do all the bits in the Macintosh® Finder’s 'LAYO' resource mean?
The following is probably the only documentation to be found on the 'LAYO' resource. It describes only the settings, not their values. You can use ResEdit to look at and change the values, but you do so at your own risk.
Font ID and size:
These change the font and size of most text displayed by the Finder™, including the icon titles, the window top margin text, all the text in the text views, and the printed text generated by “Print Catalog.” If, after changing font ID or size, you later change the System fonts or use the Finder with a different System file, the font you specified may be missing. In that case the default font will be used. If the size you specify is not available, a scaled size will be used.
Window rect:
This is the rectangle that controls the position and size of new windows created by the Finder. Windows of new folders are given the same view as the “parent” window, has regardless of the window rect.
Tab stops 1-7 and column justification:
You can adjust the column spacing used to display in the text views. The Finder truncates any text that is too wide for the column, so make sure the size, date, time and other columns are wide enough. You cannot change the ordering of the columns or eliminate any of them. Each column can be left or right justified.
Icon spacing options:
You can adjust the grid spacing by dragging the light gray icon, and the grid offset by dragging the dark gray icon. The grid offset vertically staggers the icons, allowing you to space the icons a bit closer together but still read the document titles. The grid you specify will be used when you do a “clean up” or grid drag, or when a new icon is created in a “by icon” format window.
Text view date:
The format of the date can be set to short (12/25/87), medium (Thu Dec 25, 1987) or long (Thursday, December 25, 1987).
Use zoom rects:
This is normally set TRUE, which means that the usual zooming effect takes place when the Finder opens a window or an application. If you set this to FALSE, the Finder does not use the zooming effect.
Skip trash warnings:
DISABLING THIS OPTION IS POTENTIALLY DANGEROUS. If you set this TRUE, the Finder will skip the usual warning that is given whenever you throw an application or system file into the trash.
Always grid drags:
This option is normally not set, which means you can position icons freely on the desktop. If you set this TRUE, whenever you drag an icon, the icon will snap into position on the grid automatically without having to do a “clean up.”
Sort style:
This option adjusts the style of the column heading by which the view is sorted. See the previous section on “text views” for more information. The column in which entries in the text view are sorted (“name in view” by name, “kind in view” by kind) is displayed according to the setting of the sort style.
Watch thresh:
This allows you to adjust length of time before the Finder will display a wristwatch cursor with animated hands during such lengthy operations as file copying. Older Finders don’t use the watch thresh option, so it is disabled and cannot be selected. The time is expressed in 60ths of a second. If you set length of time too short, the cursor will jitter and change shape too often.
Use phys icon:
This forces the system to display the floppy disk icon instead of an icon with an arrow pointing to a disk drive.
Title click:
This option is normally set FALSE. If it is set TRUE, a feature in the Finder is enabled, allowing you to double-click the title bar of a window so that window’s “parent window” opens or comes to the front if already open. The “parent window” is the one that contains the folder the original window represents.
Copy inherit and new folder inherit:
These options are for AppleShare folder privileges. They only affect folders created on an AppleShare server.
Color style:
Normally, folders and file icons are displayed with a color outline. Color style causes these icons to be filled in with color.
Max # of windows:
This allows you to set the maximum number of windows the Finder can open at one time. Increasing the number of windows causes the Finder to need more memory. Under MultiFinder, you may have to increase the memory allocation for the Finder.
Operating System: Finder: How often the Macintosh Finder updates its internal information
The Macintosh® Finder™ doesn’t always show changes my program makes to file sizes and attributes until I close and reopen the window.
The Finder updates its internal information every 10 seconds, and/or whenever a folder is opened. It may not notice some changes unless the folder’s modification date is changed.
Operating System: Folder Manager: Identifying a Macintosh folder correctly with FindFolder information
When I use the name and vRefNum returned from FindFolder, I always get a fnfErr from OpenRFPerm. Why?
FindFolder returns both a vRefNum and a DirID, and they both must be used to identify the folder. Instead of using OpenRFPerm (which only takes a vRefNum), try HOpenResFile. Avoid using PBHSetVol! (See Macintosh® Tech Note #140 for more information.)
Operating System: GS/OS: GS/OS GetFileInfo error conditions
Why does GetFileInfo return errors on some Apple IIGS device names but not others?
GetFileInfo is supposed to return an error because a device name is not a file. GetFileInfo returns information on the volume directory for online block devices, error $2F (device offline) for offline block devices, and error $45 (volume not found) for character devices. This makes sense when you realize that GS/OS is internally expanding all pathnames before trying to decide what to do with them. Device names in pathnames (to files) get converted to volume names before anything else is done with them.
Operating System: GS/OS: GS/OS newline mode and caching with ReadGS
I’m using GS/OS’s newline mode to let ReadGS only grab a record at a time from my file of variable-sized records, each separated by a null byte. Should I use caching in the Read call? If not, does GS/OS re-read the block for the next call to ReadGS?
Although “GS/OS caching” is only done at the driver level, other things can be cached as well. Most FSTs keep a copy of the block around the current mark in the file control record (FCR), just like they keep some key volume blocks in the volume control record (VCR), so usually caching isn’t necessary. However, the worst it can hurt you is the cost of the cache memory and the performance penalty of caching the entire file (which you will eventually do as you read in all the records), kicking out more useful blocks in the cache.
So, realistically, it probably won’t help. Try compiling with and without the cachePriority set to one and timing your code’s execution; you probablywon’t see see a speed increase.
Operating System: GS/OS: GS/OS Loaders “file number” parameter not used
What is the “file number” parameter used by calls to the GS/OS® Loaders such as LGetPathname2?
The file number parameter was intended for a multiple-file Object Module Format (OMF) facility that never quite made it, one way or the other. Unless future documentation says otherwise, always pass $0001 for the file number.
Operating System: GS/OS: GS/OS system service calls
When is it legal to make Apple IIGS® system service calls? I’d like to make calls such as MOVE_INFO from a driver that’s executing asynchronously.
It’s legal to make system service calls in response to a GS/OS® request, for example. Most of them require the OS environment, such as GS/OS’s direct page, but MOVE_INFO, SET_SYS_SPEED, DYN_SLOT_ARBITER, and SIGNAL do not.
When you’re not in the GS/OS environment, make sure the proper language card bank of bank 1 is swapped in. Just JSLing there will put you into something that’s not a system service call. You can either use the bank $E1 equivalents of MOVE_INFO, SET_SYS_SPEED, and DYN_SLOT_ARBITER, or you can make sure that the right $01 language card bank is enabled:
short
lda >$E0C068
pha
lda >$E0C08B
lda >$E0C08B
longmx
; Set up the registers and make your
; JSL My_Favorite_SysSrv_Call
short
lda >$E0C083
lda >$E0C083
pla
sta >$E0C068
longmx
Operating System: GS/OS: Recognizing SCSI partitions from GS/OS
Where can I find documentation on how to recognize SCSI partitions, such as MS DOS partitions, from GS/OS®?
The documents you’ll need are the GS/OS Reference (Addison-Wesley) and the GS/OS Device Driver Reference (APDA®). You can recognize SCSI hard disk partitions programmatically by looking for a SCSI Hard Drive device type ($0005) and a forwardLink or headLink that’s nonzero. This will give you all SCSI hard disk partitions, but it won’t give you non-SCSI partitions, which have a different device type.
Bit 13 of the Device Characteristics word is for “Linked devices” like partitions, but the GS/OS Device Driver Reference says that bit applies to removable media, so not all third-party GS/OS drivers may set that bit for partitions (even though Apple’s SCSI hard disk driver does).
Remember that GS/OS requires each partition to appear as a separate device, so there’s no support for multiple partitions on one logical device.
Operating System: GS/OS: Using notification procedure to patch GS/OS
In some of my recent work, I’ve found it necessary to patch the Apple IIGS® GS/OS® vectors in order to monitor OS calls. My patch works without interfering, but it disappears when the user switches to ProDOS® 8 and back to GS/OS. I tried unsuccessfully to fix this by using the notification queue, asking GS/OS to notify me when the user was coming back from ProDOS 8. How can I safely and reliably patch GS/OS on a permanent basis?
You should be able to patch GS/OS with System 5.0.4. Two observations may help:
• If you ask for all notification events, you’ll get at least one disk-insert event before you get any restart events, since the device driver for the startup disk will “fake” a disk insert to get the appropriate disk-switched statuses set before doing any real work.
• Your procedure may not be the first notification procedure called at restart time. For example, the Resource Manager inserts a procedure so that it can reopen the system resource file on return from ProDOS 8. If this mechanism was broken as you say, the Resource Manager’s notification procedure wouldn’t work either.
Operating System: GS/OS: Apple IIGS System 5.0.4 hard disk installation
How do I install the System 5.0.4 software on my Apple IIGS® SCSI hard disk? Does the Installer update the system?
1) Make backup copies of System.Disk and System.Tools, making sure they keep the same names.
2) Launch the Installer from System.Tools (backup) and install SCSI Driver on the backup of System.Disk. The Installer script knows to delete a couple of fonts as well as the Tutorial folder to make room for the SCSI stuff on a 3.5" disk.
3) Boot the backup of System.Disk and install 5.0.4 onto your hard drive. If you want Shaston 16 and Times 12, install “Additional Fonts” last.
The Installer knows how to make the stuff fit on a floppy. (It are smart <grin>.) It also knows how to update your system without requiring you to trash your existing system folder.
Operating System: GS/OS: Apple IIGS OSVolume error messages
Under GS/OS® 5.0.3, the OSVolume call for GS/OS returns a $27 error code when you use the call on a floppy disk that has never been initialized. It also returns $27 when you make the call to a disk that has been initialized previously as a Macintosh® disk.
We can’t reproduce the problem. Under 5.0.3, a disk which has never been initialized returns error $27 (I/O error) but a disk formatted under HFS correctly returns error $52 (unsupported volume type). $52 is what the FSTs internally report back to SCM if they don’t claim the disk, and if the last FST bounces it the error filters back to the application.
Operating System: GS/OS: Apple IIGS CloseView INIT works with System 5.0.3 or later
When the Apple IIGS® CloseView INIT is copied to my system disk as instructed in the documentation, every move of the mouse erases that portion of the screen until eventually all menus are pulled down and visible. When a newer system disk is used, the problem does not occur.
CloseView is compatible only with Apple IIGS System 5.0.3 and later, because of a change in the way QuickDraw™ II redraws the cursor while hardware shadowing is enabled.
Operating System: Memory Management: Get heap size using PurgeSpace instead of HeapEnd and ApplZone
Our application looks at the low-memory globals HeapEnd and ApplZone to calculate the size of the heap that it’s running in. Is this safe for future compatability or is there a better way?
A better method is to call PurgeSpace and find out how much available memory there really is. This tells you how much memory is available for your application (which is the real point) and it avoids low memory.
Operating System: Memory Management: Heap objects are guaranteed to be at least word aligned
Is the value returned by NewHandle guaranteed to be even? I know Inside Macintosh says the master pointer is guaranteed to be even, but it doesn’t say that the address of the master pointer is even as well.
Yes, the address of a master pointer will be even and all objects pointed to by a master pointer will be even (at minimum, word aligned), but you shouldn’t assume anything more than that. The Memory Manager aligns objects in a way best suited for the underlying hardware. You should not assume you know what that alignment will be, nor should you attempt to force a particular alignment, as that could defeat any performance improvements gained by such alignment and at worst, that could cause compatibility problems on future platforms. The Memory Manager currently aligns objects as follows:
68000 Machines Word aligned
68020 Machines Longword aligned
68030 Machines Longword aligned
68040 Machines Quadword (16 byte) aligned
Again, you must not make any programming assumptions based on this information.
Operating System: Memory Management: Macintosh private stack space
Occasionally, when we operate in our driver at accRun time or when we operate in some of our operating system patches, stack space gets dangerously and sometimes fatally low. Since our driver and patch code runs under the auspices of other applications, we cannot guarantee stack space for other apps, and they certainly have not accounted for us. Is there any way we can use a private stack to ensure we have enough space and always know how much there is?
DTS can’t recommend using a private stack; attempting this generally causes you more trouble than it’s worth. Rather, we recommend you carefully monitor your stack usage. It’s very easy to carelessly eat a lot of space in local stack frames, such as by allocating Str255s locally. Replace such wasteful usages with smaller strings (for example, don’t use a Str255 for a filename, as they’re limited to 31 characters), or use dynamic allocation. (For example, if you need an array of 200 integers, you may find it more convenient to allocate a handle and place the array there, rather than allocating it statically on the stack.) By applying these concepts, you probably can get your stack usage down to a reasonable level without resorting to such practices as a private stack.
If you do feel you need to use a private stack, you will have to disable the stack sniffer while you’re doing so. This can be done my setting the long word at address $110 (StkLowPt) to 0; this will disable the checking done to determine whether the stack has collided with the heap. When you’re done with your private stack, first restore A7, then set StkLowPt to the current A7. This will reenable the checking and start the sniffer off with a reasonable value. Of course, many toolbox routines will not work properly while the stack is in this state; QuickDraw and the Process Manager are two of the first to come to mind. Also, DTS really can’t support applications that attempt to call toolbox routines while using a private stack because it’s not part of the toolbox’s design.
Operating System: Memory Management: Macintosh trap patches from within an application
If you patch a trap from a Macintosh application, is the patch effective for all applications, or just the application that patched the trap?
Patches made from within an application apply only to calls made from the application. This is documented in Inside Macintosh, Volume VI, page 29-7. Global patches must be made at INIT time.
Patches apply only while the application is active because the Process Manager swaps the entire trap table during a major or minor switch. It also swaps selected low-memory globals and deactivates application heap VBL tasks. VBL tasks installed in the system heap are not deactivated on switching. For more information on application contexts, see the Process Management chapter of Inside Macintosh, Volume VI.
Operating System: Memory Management: Checking for GetHandleSize error conditions
Inside Macintosh Volume II, page 33 states that _GetHandleSize returns D0.L >= 0 if the trap is successful or D0.W < 0 if the trap is unsuccessful. What happens if the handle size is 0xFFFF, for instance? A TST.W will indicate an error when in fact there is none. How should I check for this condition?
Inside Macintosh is correct (although confusing…) regarding the determination of an error condition. The way to do it is first test the long to see if it is valid (D0 >= 0). If the long is valid, you can continue with confidence that no error occurred. If, however, the contents of the long in D0 is negative, then the lower word contains the error (and currently the upper word contains $FFFF, the sign extension). The reason to have the manual highlight the fact that only the low word contains the error is to allow you to save the error in standard fashion since all other errors are word sized, and also to caution you against using the processor status on exit from GetHandleSize since it will be based on the low word only. In other words, if the long word is negative, simply ignore the high word. Here is some assembly that will work:
move.L theHandle(a6),A0
_GetHandleSize
tst.L D0
bpl.s @valueOK
move.W D0,theError(A5)
moveQ #0,D0
@ValueOK
Operating System: Memory Management: How Macintosh memory location 0 gets changed
Why does the longword at location $0 get changed to 0x40810000 at every trap?
In System 7, the Process Manager slams a benign value into location $0 to help protect against bus errors when an application inadvertently dereferences a NIL pointer. (There’s no bus-error checking on writes to ROM, so the “benign value” is usually ROMBase+$10000.)
If you’re debugging, you want the opposite effect: you want these inadvertent accesses to “cause” bus errors. If you put a different value in location $0 before the Process Manager starts up (that is, from MacsBug or TMON initialization, or from an INIT like EvenBetterBusError), it will force that value instead. For more information, see the “Macintosh Debugging” article in this issue.
Operating System: Memory Management: Macintosh ID 28 error
Why am I getting an ID 28 error?
Let’s see, where‘s that form letter response for “Beats Me!”... Ah, here it is...
I’m not sure what’s causing your ID 28 error (Stack Meets Heap), but here are a few things you might try, to isolate the problem:
ID 28 is nearly always caused by a code path you didn’t expect, such that a procedure inadvertently calls itself. This doesn’t have to be simple (that is, one of your subroutines may be calling another, which then calls the first again, and so on). Each of these recursive calls adds to the stack (at the very least, four bytes [a return address] each time); if this cycle continues, the stack eventually meets the heap.
Though QuickDraw now checks its stack usage before its heavy-stack-usage operations (like CopyBits), stack collisions are possible if you have a really hungry interrupt handler or QuickDraw bottleneck procedure override.
If it is your intent for your procedures to recurse, it’s possible that the recursion isn’t limited, or that each level of recursion is adding too much data to the stack. For the former, you’ll have to figure out a way to make sure the procedures don’t call each other forever; for the latter, you should minimize the local variables used by the inner procedures (perhaps by declaring them in the outer scope)—this will reduce the amount of data placed on the stack each time.
One specific kind of recursion occurs when you call your main event loop from another procedure as a subroutine. In general, this design should be avoided because of just this problem; this technique can also cause problems if update events get nested.
Operating System: Memory Management: Sharing data between Macintosh applications
What are the preferred methods for sharing data between applications? I want to use the Program-to-Program Communications (PPC) stuff or Apple Events to dynamically link libraries, but the size of the data blocks to be passed between the applications makes copying them around unacceptable. The best method would be to somehow share the data and remain compatible with future systems (presumably with memory protection). How is the system heap on handling large chunks of memory?
As you point out, there could be some memory protection someday, but at this time there’s no indication of how shared memory will be allowed under these tighter rules.In the time being, if you are willing to pay the consequences later, then the following might help:
The four bytes of an address for a location in memory could be passed as data in a PPC data transfer, or Apple events could carry the information. Secondly, the Gestalt mechanism could be used to pass an address between processes or tasks. For your problem this probably is better then the other forms of IPC.
The best thing to do is allocate a shared handle in the system heap. HLock the block only when necessary. Remember, the system heap grows dynamically under System 7.0.
Operating System: Memory Management: Allocating contiguous Macintosh memory
How do you allocate and lock contiguous memory on the Macintosh® under System 6?
There is no method for doing this under System 6.0. In general, the only time you are expected to really need this is for a Macintosh IIci or IIsi under VM.GetPhysical may be used to determine if a block of memory is contiguous. If not, and this is unacceptable, allocate another block (without disposing the first). There is only one discontinuity, so the second block certainly will be contiguous.
Operating System: Memory Management: Using GetPhysical to map logical to physical memory address
How do you translate a Macintosh® logical address to a physical address in System 6?
Under System 6.0.x, an arbitrary memory range may contain at most one physical discontinuity, and then only on the Macintosh IIci or Macintosh IIsi. If a contiguous physical buffer is required, allocate a buffer (with NewHandle, for instance) and use GetPhysical to determine if it is indeed physically contiguous. If it is not, then allocate another buffer immediately. The second buffer should be contiguous since the only discontinuity is contained in the first buffer.
Under 6.0.x, memory is always “locked,” except that caching is enabled for all RAM by default. Calling LockMemory, which works if _MemoryDispatch is implemented, causes the buffer to be noncachable, which is of some value when performing DMA.
Operating System: Memory Management: How to increase Macintosh system heap at startup time
How can I set aside heap space for my device driver at system startup time? I have tried third-party “heap sizers” but they do not seem to help.
Unless you otherwise use the 'sysz' resource in an INIT, the system will only make sure that there is about 16K free for you at init time.
The correct way to increase the size of the system heap at initialization time (for drivers, for example) is to use the 'sysz' resource as documented on page 352 of Inside Macintosh Volume V. This expansion temporarily increases the system heap size by the size specified in the 'sysz' resource. You should be able to sysz as large a space as you may need and then only allocate the amount you actually need at INIT time.
A driver’s INIT should keep system heap space requests to a reasonable limit. Memory requests of 30K, 60K—even 100K with good reason—may be accommodated, but if you find that you are needing very large 'sysz' resources, perhaps your code would be better suited as something other than an INIT.
Operating System: Memory Management: Macintosh system heap size
How do I change the Macintosh® system heap size?
When running System 7.0, the system heap is sized dynamically while running. That is not to say that you cannot run out of system heap space while there is still free RAM available, but the system attempts to resize itself whenever its free space falls below about 16K. In this case there is no way for you to set, increase or decrease the (fixed) amount of system heap as it is dynamic and not fixed.
Under earlier systems, the system boot blocks specify how big the system heap is to be, and this is documented in Macintosh Technical Note #113, “Boot Blocks.”
The 'sysz' resource in an INIT file allows the INIT to specify the amount of free space it needs in the system heap when the INIT is loaded. (This space is reclaimed after the INIT has run if not used by the allocation of memory blocks by the INIT.)
Operating System: Memory Management: Macintosh Memory Manager ROM bug and MMInit
Where can we get our hands on a fix to the ROM bug in the Macintosh® IIci and Macintosh IIfx Memory Manager? Word has it that Apple wrote an INIT (MMInit) to fix this problem. Because we’re using our application on both the Macintosh IIci and the IIfx, and the application uses many handles, this fix would be appreciated.
Under System 6.0.x, Apple had identified a minor problem with the Memory Manager in the Macintosh IIfx, IIci, IIsi, and LC. This problem resulted in a performance degradation in an extremely small number of applications and did not cause system crashes. We believe this was an insignificant problem that affected few applications and very few customers. The problem was not new and was not caused by the introduction of System Software 6.0.5 or 6.0.7.
Based on developer feedback, customer feedback, and extensive in-house testing, Apple has identified very few affected applications. Because the problem affects only an extremely small number of developers, Apple is working with those developers to fix their applications. The best solution, however, is to upgrade to System 7.0, as it includes an enhancement to the Memory Manager to address this issue.
During extensive testing and research, Apple investigated a variety of solutions to enhance the Memory Manager performance. One area researched was a software solution called the Memory Manager INIT (a software “patch”), or MMInit as it’s most often called. Through testing we discovered that this patch did not enhance Memory Manager performance and introduced risks such as decreased performance in some mainstream applications.
An unofficial version of the Memory Manager INIT has surfaced. This INIT should not be used, because it has been modified from Apple’s experimental version and could cause data corruption, data loss, and crashes. Apple strongly urges that you discard the INIT if you have obtained a copy, and not use it. If any version of this INIT is used under System 7.0, it defeats the enhanced Memory Manager and reintroduces the bugs that were present in the System 6.0.x Memory Manager.
You may still wonder if you have been affected by this problem and how to avoid it under 6.0.x. The problem is most severe when allocating pointers in a heap with a rather large number of handles (on the order of tens of thousands). It’s helpful to allocate enough master pointers (via MoreMasters) during initialization. If the Memory Manager has to call MoreMasters later on, not only could it fragment memory, but it could take an exceedingly long time. It’s also helpful not to allocate thousands of handles. Besides requiring lots of master pointers, it takes the Memory Manager a long time to crunch through them during heap compaction.
Operating System: Memory Management: When to use SetCurrentA5
During a Macintosh® application’s life, does the value of A5 change? Why does SetCurrentA5 have to set A5 to CurrentA5? Aren’t A5 and CurrentA5 the same while an application is executing non–interrupt-time code?
A5 is not necessarily always equal to CurrentA5. Because the Macintosh operating system and Toolbox don’t need to access your application’s jump table or global variables (which A5 points to), they often use A5 for other purposes, except for the parts of the Toolbox that need to perform graphics operations and use the QuickDraw globals defined by your application.
Because the operating system or Toolbox can change A5, you must make sure it’s set correctly if the operating system or Toolbox ever calls your code in the form of a callback. For example, if you make an asynchronous File Manager call, your I/O completion routine must call SetCurrentA5 for your I/O completion routine. Other places where you may want to call SetCurrentA5 are in trap patches, your GrowZoneProc, custom MDEFs, WDEFs, or CDEFs, or control action procedures.
Please note that even SetCurrentA5 is not sufficient when writing code that’s executed at interrupt time, such as VBL and Time Manager tasks. When an interrupt occurs that your application wants to handle, there is no guarantee that the low-memory global CurrentA5 belongs to your application. The interrupt could occur while some other application is running under MultiFinder®. In this case, you should use other approaches to setting A5. Please see Technical Note #180, MultiFinder Miscellanea, for further information.
Operating System: Memory Management: Macintosh heap debugging tools
Do you know of any debugging tools for Macintosh® II heap problems besides TMON, which can scramble and check the heap every now and then, and the “Mr. Bus Error” INIT?
For figuring out problems with the stray writes/reads outside your application heap, you should check out Jasik’s debugger. I’m not as familiar with it as I would like, but I’ve heard that it allows you to keep an eye on those types of memory accesses. For deallocation and no heap space, try DTS’s “Leaks” dcmd, available on AppleLink®.
Operating System: Memory Management: Why Macintosh IIsi uses more system heap than Macintosh Plus
Why does the Macintosh® IIsi use so much more system heap than the Macintosh Plus? Is there any way to reduce system heap usage on the IIsi?
No, the reason the Macintosh IIsi has more system heap than the Macintosh Plus is that the IIsi is a color machine and the Plus is not. Color includes a lot of patches and a considerable increased requirement of memory, hence the need for the larger heap size in the IIsi.
Operating System: Memory Management: No maximum size that the Macintosh stack can be grown
Is there a maximum size that the Macintosh® stack can be grown?
No.
Operating System: Memory Management: How can I change the size of my Macintosh application’s stack?
How can I change the size of my Macintosh® application’s stack?
A default stack size is created by the system for each application. If you want to use the default stack size, just call MaxApplZone very early in the application’s startup process. The default size for the stack on a Macintosh Plus and SE is 8K, but it’s 24K for systems supporting Color QuickDraw™. The default may change again with future systems, so it’s best not to make any assumptions. Add to the current stack size and don’t assume a fixed size.
If you are interested in finding the top of the stack, there is a low memory global CurStackBase. It is advisable not to read low memory, but this is one of the safer globals. The following code is from MacApp which increases the stack size. Follow this with MaxApplZone:
PROCEDURE SetStackSpace(numBytes: LONGINT);
VAR
newLimit: LONGINT;
BEGIN
newLimit := Ord(GetCurStackBase) - numBytes;
IF Ord(GetApplLimit) > newLimit THEN
SetApplLimit(Ptr(newLimit));
END;
Alternatively, simply use the following line of code. Shrinking the application’s heap size allows the stack to increase by that same amount. Follow this with MaxApplZone.
SetApplLimit(Ptr(Ord4(GetApplLimit) - kAdditionalStackRequirements));
MaxApplZone; {this code is here to provide context}
InitGraf(@thePort);
Operating System: Memory Management: Increasing Macintosh stack size if system error 28 occurs
Why does my application crash with a system error 28 (“stack into heap”) on a Macintosh® SE or Plus but not on any Mac® II?
The default stack size on 68020/68030-based Macintosh models is 32K to accommodate Color QuickDraw™, while the default stack size in 68000-based Macintosh models is 8K. If you are experiencing stack overflows, increase the size of your stack. It is best to add a fixed amount to the stack without aiming for a specific size or checking the machine type so that, if Apple needs to expand the stack size in the future, you will be less likely to break again.
Operating System: Memory Management: How can I prevent Macintosh low memory conditions?
How can I prevent Macintosh® low memory conditions?
Once memory is low, it’s too late, so before calling NewPtr, NewHandle or other Toolbox routines that allocate memory, check for the available amount of memory. In other words, preflight for the dangerous situation. Use PurgeSpace to help determine if you’re running low on memory. If the heap ever runs below 40K, consider it dangerous. Write a small function such as the following that does such a test for a given amount and returns a Boolean:
FUNCTION IsMemoryAvailable(request): BOOLEAN;
CONST
kMinSpace = 40 * 1024; {40K is a safe amount}
VAR
total, contig: LONGINT;
BEGIN
PurgeSpace(total, contig);
IsMemoryAvailable:= (request < contig)
AND ((request + kMinSpace) < total)
END;
Then, before allocating memory, follow this example of creating a new dialog:
IF IsMemoryAvailable(SizeOf(dialogRecord)) THEN BEGIN
dialog:= NewPtr(SizeOf(dialogRecord));
IF dialog <> NIL THEN
GetNewDialog(id, dialog, behind)
ELSE
{out of memory, call MemError for more info};
END ELSE
{out of memory, report low memory condition to user};
Preflighting low memory is dependent on the situation at the time. In the previous example of creating a new dialog, you might include the Dialog Manager CouldDialog before calling IsMemoryAvailable. This will load the 'DLOG' and 'DITL' into memory and then test if there is enough additional memory to create the dialog. This could still fail if the dialog is using a non-system font or other custom feature. Also, consider that the above test doesn’t include the new regions that are necessary for the window. That’s why there’s a safety margin of 40K. Another useful part of memory management is a GrowZone procedure that can release a reserved block. Once the GrowZone is called, consider it an emergency and do whatever you can to regain the reserve block. The IsMemoryAvailable routine should include a test for this if you include a GrowZone reserve block.
Operating System: OS Utilities: Macintosh GetTrapAddress and StripAddress
What was the earliest Macintosh operating system that had _StripAddress? Do I still have to call GetTrapAddress to find out if a trap exists by comparing its address with the Unimplemented trap for a general utility trap like StripAddress?
StripAddress is available in System 4.1 and later for Macintosh Plus or later models. You should not have any problem on machines running 4.1 or later. StripAddress is always implemented in these machines, even if all that needs to be done is mask the high byte of the address.
You should still call Gestalt once on any machine at the beginning of your application to determine if any/all assumptions your program makes about the hardware it is running on is valid. This is to protect YOU from NOT working on a future machine that has a different mix of features than currently available.
Example case #1: Several programs broke on the Macintosh Portable because they assumed that any machine later than the Macintosh II would have Color QuickDraw. A simple HasCQD with a “You can’t run without Color” alert.would have eliminated user crashes and product revisions.
Example case #2: A spreadsheet program would not use the FPU on a new machine it did not previously know of, even though the FPU was present and WOULD have worked.
Operating System: OS Utilities: Textual Macintosh system error messages
It would be nice if Apple provided a Macintosh system resource with text for all defined error codes. Are there any plans to provide this?
A toolbox call or utility providing up-to-date error messages would be nice, but such a beast does not exist currently. The closest thing available is the MPW ErrMgr (Error File Manager Routines Interface File), which can be used to display errors for Tools written under MPW. This, of course, uses utilities included in the MPW application, so it isn’t of any use to standalone applications.
This feature hasn’t been provided because the error numbers and associated text are meant for a technical audience. Even if they were worded nicely, most of the errors (like Bus Error) wouldn’t mean anything to end users, and might be intimidating or confusing. Since each application has a different audience,it is better left to you to tailor error messages to make sense to your application’s audience.
We realize that it’s inconvenient to create 'STR#' resources from the Errors.h file (DTS does the same thing), but this is probably your best bet. By the way, Appendix A of Inside Macintosh Volume VI explains the error messages in more detail than the Errors.h file.
Operating System: OS Utilities: Disk First Aid error message explained
What does the Macintosh® Disk First Aid message “Unable to verify status of disk” mean?
Disk First Aid does a variety of diagnostics on your disk’s internal HFS structures, repairing problems for which it has complete information—primarily internal consistancy problems, where one set of information has gotten out of step with another, redundant set. When it has found a problem that it cannot repair, it tells you so. For a long time the relatively uninformative message “Unable to verify status of disk” was used. In the most recent version, released with System 7.0, the message “The disk is damaged. Disk First Aid is unable to repair this disk” is displayed. When you see this message, it means something is fairly wrong with the directory structures on your disk. You may not yet have seen any problems with the disk, but it’s likely that you will see them before long. Now would be a good time to back up all your files, reformat your drive, and restore your data from the backup.
Operating System: OS Utilities: Disk First Aid if unable to empty trash
We are unable to empty trash of a Macintosh® folder that appears to be empty. The message “The item could not be deleted because it contains items that are in use” is displayed.
Disk First Aid should solve your problem.
Hierarchical File System (HFS) keeps a count of the number of items in a directory, and probably your folder’s count didn’t get updated when your machine crashed at some point. Therefore, though the Finder can’t see anything in the folder (because it used indexed calls, and like a good application, doesn’t meander through HFS’s private structures), HFS still thinks there’s something there.
If you’ve run System 7 with that volume, be sure to use the latest Disk First Aid that came with System 7, because it knows about the changes in HFS’s data structures that were made for System 7.
Operating System: Process Management: Macintosh background DA alerts
How can I use the Notification Manager to alert the user to bring my DA to the front and then display an alert?
Basically, if your DA is in the foreground and you finish your task, you can just use Alert() to notify the user. If your DA is in the background when it finishes, post a notification with NMInstall that notifies the user by sound, icon, and mark in the process menu (but not an alert) that something is up in your desk accessory. When they switch to your DA, you then display your alert.
The following code is for a DA written in Think C that notifies the user as described above. Portions of the code are borrowed from the Think C example “Hex Dump DA.” Basically, this code keeps track of whether the DA is in the foreground or background by setting the global variable gInBackground at every activate and deactivate event. If there is a notification pending and an activate event is received, the routine MyResponse is called to remove the notification and display the appropriate alert.
Note that for MPW you’ll have to store your globals elsewhere, as MPW doesn’t provide the Think C A4 feature. You’ll have to modify the code to work with your function to get the proper resource IDs.
void PostNotify(StringPtr theStr)
{
extern Boolean gInBackground; /* true=in background */
extern NMRec *gNotify; /* global var pointing to notif.
rec 0=none */
Handle notIcon;
Ptr txtPtr;
/* blast away any other pending notification */
if (gNotify) {
DisposPtr((Ptr) gNotify->nmRefCon);
NMRemove(gNotify);
gNotify = nil;
}
/* see if we should notify or use alert */
if (gInBackground) {
/* allocate memory for notification */
txtPtr = NewPtr(sizeof(Str255));
if (MemError()!=noErr)
return;
gNotify = (NMRec *)NewPtr(sizeof(NMRec));
if (MemError()!=noErr)
return;
/* copy notif. string to dynamically allocated block */
BlockMove(theStr,txtPtr,256);
/* fill out notif. record */
notIcon = GetResource('SICN',OwnedResourceID(NOTIF_ICON));
gNotify->nmStr = nil;
gNotify->qType = nmType;
gNotify->nmMark = 1;
gNotify->nmIcon = notIcon;
gNotify->nmSound = (Handle)-1;
gNotify->nmResp = nil;
gNotify->nmRefCon = (long)txtPtr;
NMInstall(gNotify);
}
else {
ParamText(theStr,"\p","\p","\p");
StopAlert(OwnedResourceID(ALERT_DIALOG),nil);
}
}
/* response procedure-- called on activateEvt */
pascal void MyResponse(QElemPtr nmReqPtr)
{
StringPtr errTxt;
errTxt = (StringPtr) ((NMRec *)nmReqPtr)->nmRefCon;
NMRemove((NMRec *)nmReqPtr);
ParamText(errTxt,"\p","\p","\p");
StopAlert(OwnedResourceID(ALERT_DIALOG),nil);
DisposPtr(errTxt);
}
/*---------------------------------------------------------*/
here's the piece of the code that handles activate events
/*---------------------------------------------------------*/
doActivate(activate)
Boolean activate;
{
extern Boolean gInBackground;
extern NMRec *gNotify;
Rect r;
GrafPtr savePort;
GetPort(&savePort);
SetPort(wp);
r = wp->portRect;
r.top = r.bottom - 16;
r.left = r.left - 16;
InvalRect(&r);
gInBackground = !activate;
if ( activate ) {
if (gNotify) {
MyResponse((QElemPtr)gNotify);
gNotify = nil;
}
}
SetPort(savePort);
}
Operating System: Process Management: Launching a Macintosh application
Under MultiFinder® or Macintosh® System 7, is there a way to set a flag to terminate the current application before launching a different application? Under standard Finder™, the launcher quits before the launchee starts.However, under MultiFinder or System 7, they both must stay in memory for a brief time until control returns to the launcher and it hits the ExitToShell. Because most of our programs are set to use 1 MB, we need 2 MB of memory available for a short time.
Two distinct cases are involved here: the System 7.0 case and the pre-System 7.0 case.
In System 7.0 there is a new way to launch applications. The function is called (appropriately enough) LaunchApplication. The function and its new extended parameter block are documented in the Process Management chapter of Inside Macintosh Volume VI.
You can determine whether your system software has the new Launch Control capabilities by using Gestalt:
OSErr myOSErr;
long response;
myOSErr = Gestalt(gestaltOSAttr, &response);
if (noErr != myOSErr) /* If an OSErr occurs we must be pre-System 7.0 */
/* Handle pre-System 7.0 case */
if BTst(response, gestaltLaunchFullFileSpec)
/* Handle System 7.0 case */
else
/* Handle pre-System 7.0 case */
The above code assumes that you are developing with interfaces and libraries based on MPW® 3.2, as those interfaces and libraries support Gestalt even on system software versions that don’t implement the Gestalt trap.
The portion of the Process Management chapter of Inside Macintosh Volume VI that will interest you is the description of the launchControlFlags field of the parameter block. Here’s what the Process Management chapter has to say:
“When you use the LaunchApplication function, you specify the launch options in the launchControlFlags field of the launch parameter block. These are the constants you can specify in the launchControlFlags field.
CONST
launchContinue = $4000;
launchNoFileFlags = $0800;
launchUseMinimum = $0400;
launchDontSwitch = $0200;
launchAllow24Bit = $0100;
launchInhibitDaemon = $0080;
Set the launchContinue flag if you want your application to continue after the specified application is launched. If you do not set this flag, LaunchApplication terminates your application after launching the specified application, even if the launch fails.”
In other words, you have to request that your launching application continue if you use LaunchApplication—the default is to do precisely what you want. Note that clearing the launchContinue flag is effectively the same as following the LaunchApplication call with an ExitToShell call. Because applications should not terminate within an Apple event handler, they must set the launchContinue flag when calling LaunchApplication from within an Apple event handler.
This leaves the pre-System 7.0 case. System 4.1 and later allows for the use of an extended Launch parameter block also, but it is somewhat different from that of System 7.0. The complete details can be found in Macintosh Technical Note #126, “Sub(Launching) From a High-Level Language.” You’ll need to use the extended version of the parameter block and specify a launch rather than a sublaunch.
Unfortunately, the launching application does in fact _not_ quit until the launchee has come up. It sounds like you will have to launch a tiny utility application that then turns around and launches your real target.
This doesn’t really change what I’ve told you above, but it does potentially color the design of your utility if you intend to open documents in the target. For the pre-System 7.0 case, the utility can simply leave the AppParmHandle alone and launch the real target, which will then deal with the AppParmHandle. In the System 7.0 case, your utility will need an 'odoc' Apple® event handler. In that handler, you will have to coerce the event to one of type appparms and pass that along to the real target when you launch it.
A good example of how all of this works in the System 7.0 case can be found in the ProcDoggie 1.0a6 sample code, which is in the Sample Code folder on the System 7.0 February 1991 beta CD-ROM. Among other things, it demonstrates how to launch, and how to handle or send the required AppleEvents ('oapp' or 'odoc').
Operating System: Process Management: System 7 and MultiFinder’s “puppet strings”
When my application is running, it relies on the MultiFinder’s “puppet strings” (which choose Open from the application’s File menu and suppress the SFGetFile dialog) to open a document that was double-clicked in the Finder. Why doesn’t this work under System 7? The high-level event-aware bit in my 'SIZE' resource is clear.
System 7 will not pull puppet strings for an applications that makes use of the System 7 Standard File routines, such as StandardGetFile and CustomGetFile, nor will it pull them if the application’s high-level event- aware bit is set.
If you update an older application to take advantage of any System 7 features, be sure to also add support for the 'odoc' and other required Apple events. Sample code showing how to support the required Apple events is available on the System 7 Golden Master CD.
Operating System: Process Management: Notification Manager and color flashing icons
How can I get a color icon to flash in my application menu? The Notification Manager documentation says I can use an 'SICN' to flash an icon, but I can get only a black-and-white flashing icon.
At this time, you can’t have the Notification Manager flash a color icon. The best you can do is to have a black-and-white version of your small color icon flash. Sorry about this. That’s all it can do right now.
Operating System: Process Management: System 6 versus System 7 Desktop Manager
If the Desktop Manager (the version that comes with AppleShare) is installed under System 6.0.x, does it have equivalent functionality to that of System 7.0?
The Desktop Manager in System 7 is completely-backward compatible with that of System 6.0.x. The System 7 version has been highly optimized, and is more robust than the original.
Operating System: Process Management: Notification Manager’s nmIcon field & icon resources
Notification Manager’s nmIcon field & icon resources
Inside Macintosh Volume VI, page 24-7 states that a notification record’s nmIcon field should contain “a handle to a small icon or to an icon family,” but for the initial release of System 7, the Notification Manager recognizes only the 'SICN'.
The format for icon family resources has not yet been documented; it is not the same as that of existing resources such as 'ICN#' or 'ics#'. The only way currently to post a notification with an icon is to use the black & white 'SICN'.
Operating System: Process Management: Icon family documentation not available yet
According to page 24-7 of Inside Macintosh® Volume VI, the nmIcon field “contains a handle to a small icon or to an icon family containing a small color icon…” I give up, what is a handle to an icon “family”?
An icon family is just what its name implies: It’s a data structure containing icons of different sizes and colors. As you might have noticed, parts of the system software take advantage of this feature to draw color notification icons, such as the Alarm Clock, in the menu bar.
Unfortunately, Apple does not yet provide documentation on the format of these “icon families,” or how to get or use them, and the interfaces for accessing the calls are as of yet incomplete. Until the documentation is released, it is not possible for developers to take advantage of these routines to use color icons with the Notification Manager.
Operating System: Process Management: Code for placing a Macintosh file in proper place on the desktop
If I move a Macintosh® file from one folder to another and clear the “inited” bit, will the Finder™ then place that file in the proper place? Is that the best way to handle files that I move?
Here’s a little program that does just that. It takes a file (from SFGetFile) and moves it to the desktop by PBCatMove and then clears the inited bit (PBHGet/SetFInfo).
void InitStuff()
{
InitGraf(&thePort);
InitFonts();
InitWindows();
InitMenus();
TEInit();
InitDialogs(nil);
FlushEvents(everyEvent,0);
InitCursor();
}
OSErr MakeFile(HFileParam *pBlock)
{
SFReply reply;
Point where = {100,100};
OSErr err;
StringPtr fName;
WDPBRec wdRec;
Str255 tmpName;
SFGetFile ( where, "\p", nil, -1, (OSType *)"????", nil, &reply );
if (!reply.good)
return -1;
wdRec.ioNamePtr = tmpName;
wdRec.ioWDIndex = 0;
wdRec.ioVRefNum = reply.vRefNum;
wdRec.ioWDProcID = nil;
wdRec.ioWDVRefNum = 0;
err = PBGetWDInfo(&wdRec,false);
if (err!=noErr)
return err;
fName = (StringPtr)NewPtr(256);
BlockMove(reply.fName,fName,256);
pBlock->ioNamePtr = fName;
pBlock->ioVRefNum = wdRec.ioWDVRefNum;
pBlock->ioDirID = wdRec.ioWDDirID;
pBlock->ioFVersNum = 0;
/* err = PBHCreate(pBlock,false);
if (err!=noErr)*/
return err;
}
OSErr MoveFile(HFileParam *pBlock)
{
CMovePBRec pMove;
OSErr err;
Str255 newStr;
BlockMove("\pDesktop Folder",(Ptr)newStr,15);
pMove.ioNamePtr = pBlock->ioNamePtr;
pMove.ioVRefNum = pBlock->ioVRefNum;
pMove.ioNewName = newStr;
pMove.ioNewDirID = fsRtDirID;
pMove.ioDirID = pBlock->ioDirID;
err = PBCatMove(&pMove,false);
return err;
}
OSErr ClearInit(HFileParam *pBlock)
{
OSErr err;
long dirID;
dirID = pBlock->ioDirID;
pBlock->ioFDirIndex = 0;
err = PBHGetFInfo(pBlock,false);
if (err!=noErr)
return -1;
pBlock->ioDirID = dirID;
pBlock->ioFlFndrInfo.fdFlags &= ~(0x0100); /* mask off inited
bit */
err = PBHSetFInfo(pBlock,false);
return err;
}
void main()
{
HFileParam pBlock;
OSErr err;
InitStuff();
err = MakeFile(&pBlock);
if (err==noErr)
err = ClearInit(&pBlock);
if (err==noErr)
err = MoveFile(&pBlock);
if (err!=noErr)
SysBeep(1);
}
Operating System: Process Management: Use Mac® Finder for application file & folder icon placement
When my Macintosh® program creates a file in the Desktop folder, how can I get it to appear where the Finder™ would place it on the desktop?
Don’t set the “INITed” bit when you create your file or folder, and the Finder will take care of icon placement for you.
You should not attempt to place the icon behind the Finder’s back, although the icons’ positions within the folder relate to where they appear on the desktop. You will have a hard (or impossible) time with icon placement, since you don't have access to the private Finder data structure where the positions of the volume icons are stored. You are better off letting the Finder handle placement. Making assumptions about the way the Finder works internally is a bad idea.
Operating System: Process Management: Background applications and alerts
My application, running in the background, detects an error condition and puts up an alert; but only part of the alert is visible (other windows cover most of it). When I switch back to my application, the full alert becomes visible but the “OK” is not highlighted and often the icon is not shown either. Is there something I can do to prevent this?
Applications running in the background should not be putting up alerts. In addition to the problems and complications you have already noted, under System 7.0 the user has the ability to hide a background application’s window set and your alert would not be seen at the time you expect it to.
There is, however, a mechanism in place that your background application can and should use: the Notification Manager. Documented in Inside Macintosh Volume VI, this manager allows a background process to notify the user that there is a alert, message, or situation pending in the background that needs to be taken care of. The user can then bring your application forward and you can present your alert as the foreground application.
Operating System: Process Management: Macintosh Notification Manager and moving memory
Is a Macintosh® Notification Manager’s response procedure actually a completion routine that can be called at interrupt time? Can a Notification Manager response procedure move memory without danger?
So-called “response procedures” aren’t called at interrupt time, so they can, in fact, move memory. Here are some additional notes regarding the Notification Manager:
1) Response procedures can move memory.
2) The notification is triggered from the SystemTask procedure, so if the application does not give time for systemtasks (a tight loop for instance), then the notification is never triggered.
3) The NMRec does have its own drawing A5 world, so applications could draw from the response procedure. However, an application should have its own A5 world for any possible graphics use.
Many of these issues are not documented because Apple doesn’t want developers to, for example, write dialog boxes that suddenly appear on the screen. Inside Macintosh ,Volume VI, pages 24-29, describes the response procedures—that they should be used mainly for deleting notification requests for freeing memory. Note, however, that it’s the Notification Manager that will free the memory if you pass the nmResp a value of -1, but you could free some of your own memory blocks with the response procedure.
Operating System: ProDOS 8: ProDOS 8 KVERSION field doesn’t map to version number
The KVERSION (kernel version) variable in ProDOS® 8 version 1.8 is $08. If we eventually see ProDOS 8 2.0, will the version number be stored as $0A, $20 or what?
The KVERSION field has nothing whatsoever to do with the user-visible version number of ProDOS, as this chart indicates:
Screen KVERSION
------ --------
1.0 $00
1.0.1 $00
1.0.2 $00
1.1 $01
1.1.1 $01
1.2 $02
1.3 $03
1.4 $04
1.5 $05
1.6 $06
1.7 $07
1.8 $08
1.9 $08
Unfortunately, ProDOS 8 contains no way to get the user-displayed version number. The KVERSION field is only for your reference in knowing what MLI calls and features you can expect.
Operating System: ProDOS 8: Apple II BASIC.SYSTEM extended file I/O error message
Why do I get a “FILE TYPE MISMATCH” error message from BASIC.SYSTEM when I try to BLOAD certain files created by GS/OS®?
GS/OS can create extended (forked) files, which cannot be read by ProDOS® 8. If you try to read an extended file with ProDOS 8, you’ll get a Bad Storage Type ($4B) error. BASIC.SYSTEM maps the Bad Storage Type error it gets from ProDOS 8 to “FILE TYPE MISMATCH.”
Operating System: Standard File Toolbox: Tabbing between SFPPutFile custom dialog text fields
How can I get the tab key to tab between text fields in my SFPPutFile custom dialog instead of switching drives?
Here is an event filter that beeps whenever the tab key is pressed (under System 6):
pascal Boolean MyDlgFilter(DialogPtr theDialog,EventRecord *theEvent,short
*itemHit)
{
WindowPtr updateWindow;
char theChar;
switch (theEvent->what) {
case keyDown:
case autoKey:
theChar = theEvent->message & charCodeMask;
switch (theChar) {
case 0x0d: /* CR */
case 0x03: /* enter */
*itemHit = OK;
return true;
case 0x1b: /* ESC */
*itemHit = Cancel;
return true;
case '\t':
SysBeep(1); // <----- do your "tabbing"
here
*itemHit = 0; // <----- this is what you
need to add
return true;
}
break;
}
return false;
}
Within dialog event filters, when the filter decides to process the event, the filter not only must return true, but must also return the item number acted on by the filter. Under System 7, tab is handled by the system automatically and is not controllable from dialog event filters.
Operating System: Standard File Toolbox: File handling within SFPGetFile & SFPPutFile DlgHook functions
How can I obtain the volume reference information in my DlgHook function for a file selected by the user before SFPPutFile or SFPGetFile has completed the reply record?
On exit, SFPGetFile and SFPPutFile generate a working directory reference number in the vRefNum field of the reply record. This is not available to you from within the operation of a DlgHook function. WDRefNums are provided to allow compatibility with older, pre-HFS functions that took vRefNum values of integer size with the older flat file system.
We suggest that, unless you plan to support the flat file system of 64K ROM Macintosh systems, you move your file system interfaces to the HFS interfaces documented in the File Manager sections of Inside Macintosh Volumes IV and V (or to the equivalent high-level calls as documented in Macintosh Technical Note #218, “New High-Level File Manager Calls”). If you’re using the HFS calls, low-memory globals SFSaveDisk and CurDirStore contain, respectively, the negative of the “real” volume reference number for the current volume and the HFS ID of the directory that Standard File is displaying. You then have all the information you need to create, open, rename, or delete files from within the SFPGetFile and SFPPutFile DlgHook functions. If a user is accessing an MFS volume on an HFS system, these calls are designed tohandle file access transparently.
Moving your file system interfaces to the HFS-level conventions has a side benefit of being closer to the System 7 file system specifications. If you look at the new high-level file system calls in Inside Macintosh Volume VI, you’ll recognize much of the HFS information embedded in the new data structures.
If your file system interfaces depend on MFS-style vRefNums, or WDRefNums in the HFS nomenclature, you can use the HFS functions PBOpenWD, PBCloseWD, and PBGetWDInfo to open, close, and obtain volume reference numbers and directory IDs. This is particularly important if, for instance, you’re using the THINK C ANSI file I/O functions, which rely on SetVol to operate correctly.
Complete information on the HFS-level calls that will be most useful in Standard File customization is contained in the File Manager chapters of Inside Macintosh Volumes IV and V, and in Macintosh Technical Notes #66, 77, 102, 140, 179, 190, and 218. For C users, Macintosh Technical Note #246 summarizes a list of the difficulties with mixing C file I/O with Macintosh file I/O. Macintosh Technical Notes #47 and 80 discuss a few points of Standard File customization from the point of view of HFS.
Operating System: Standard File Toolbox: Filtering out invisible folders from a Standard File dialog list
I want to display only visible files and folders in a Standard File dialog, but I can’t find a way to filter out invisible folders—specifically the 000Move&Rename folder. The FileFilter routine filters only files, not folders. If I put in a nonzero TypeList, invisible folders seem to be removed, but I want to open all types of files, just not invisible files or folders. Any suggestions?
This is, in fact, impossible under System 6 using general methods. The problem is that passing -1 as numTypes means not only to display all items, but to display invisible items. A file filter can be used to remove the invisible files but cannot affect invisible folders. The only current way to do this is to use CustomGetFile under System 7, as described in the Standard File Package chapter of Inside Macintosh Volume VI. This provides a filter that allows you to filter both files and folders. This will give you the right functionality, but will work only under System 7. We recommend that you use this method under System 7, and a more standard SFGetFile when running under earlier systems.
Operating System: Standard File Toolbox: Custom Standard File dialog edit fields under System 7
How do I change the active edit field inside a custom Standard File dialog under System 7? In a related problem I am finding that the selection range for all edit fields in the dialog equals the number of characters in the file name field when tabbing around.
The Standard File Package (SFP) routines don’t behave exactly the same as they did under System 6. Therefore, doing something like trying to change the active item number doesn’t work under System 7’s version of the SFP routines. The problem is that System 7 Standard File has a whole set of interfaces dedicated to the active item list and which item is currently active, whereas System 6 SF routines just use the dialog data to store this information. The solution to the problem, then, is to use CustomGetFile to accomplish the same thing if you are running under System 7. I’ve included a sample program which uses the new routine to change the focus and check the bounds of several editText items.
Your second problem is brought on by a bug in Standard File. The workaround is to install an activate procedure for Standard File (it’s a parameter to the CustomGetFile call) which calls SelIText on the appropriate field to select the entire range. The included sample also does this.
/* CustomGetFile example
Steve Falkenburg -- MacDTS
This sample uses CustomGetFile to add two edit text fields
to the standard get file box, and checks the values the user
enters into those fields. If the values are incorrect, the
user is alerted to change them, and the focus of the dialog
is changed to the proper field.
The standard file bug causing selection ranges to be calculated
improperly is also fixed in this sample by calling SelIText in
the activate procedure for edit text items.
*/
/* prototypes */
void InitStuff(void);
void CustomGet(void);
pascal void MyActProc(DialogPtr theDlg,short item,
Boolean activating, Ptr data);
pascal short DlgHook(short item,DialogPtr theDlg,Ptr userData);
Boolean CheckField(DialogPtr theDlg,short item);
/* constants */
#define kTextField1 10
#define kTextField2 11
#define kSFDlg 128
#define kAlertDlg 129
void main(void)
{
InitStuff();
CustomGet();
}
/* initialize managers */
void InitStuff(void)
{
InitGraf(&qd.thePort);
InitFonts();
InitWindows();
InitMenus();
TEInit();
InitDialogs(nil);
FlushEvents(everyEvent,0);
InitCursor();
}
/* do getfile */
void CustomGet(void)
{
Point where = {-1,-1};
SFReply reply;
DialogPtr theDialog;
short item;
StandardFileReply sfReply;
short activeList[5];
/* set-up active items list */
activeList[0] = 3;
activeList[1] = 7;
activeList[2] = 10;
activeList[3] = 11;
CustomGetFile(nil,-1,nil,&sfReply,kSFDlg,where,DlgHook,
nil,activeList,MyActProc,nil);
}
/* activate procedure- this procedure handles the activate/deactivate of
textedit items and corrects the selection bug in standard file which
normally causes the selStart and selEnd fields of the texthandle to be
incorrect
*/
pascal void MyActProc(DialogPtr theDlg,short item,Boolean activating,Ptr data)
{
short iType;
Handle iHndl;
Rect iRect;
TEHandle textH;
GetDItem(theDlg,item,&iType,&iHndl,&iRect);
if (iType != editText)
return;
if (activating) {
SelIText(theDlg,item,0,32000);
return;
}
}
/* this dialog hook checks the contents of the additional edit fields
when the user selects a file. The focus of the dialog is changed if one
of the fields is out of range.
*/
pascal short DlgHook(short item,DialogPtr theDlg,Ptr userData)
{
if (item==ok) {
if (!CheckField(theDlg,kTextField1))
item = kTextField1 + sfHookSetActiveOffset;
else if (!CheckField(theDlg,kTextField2))
item = kTextField2 + sfHookSetActiveOffset;
}
return item;
}
/* this procedure checks the range of a given edittext item to make sure it
contains a number from 0 to 256. If not, it alerts the user that the
field must be re-entered.
*/
Boolean CheckField(DialogPtr theDlg,short item)
{
short iType;
Handle iHndl;
Rect iRect;
Str255 iText;
long num;
GetDItem(theDlg,item,&iType,&iHndl,&iRect);
GetIText(iHndl,iText);
StringToNum(iText,&num);
if (num<0 || num>256 || iText[0]==0) {
StopAlert(kAlertDlg,nil);
return false;
}
else
return true;
}
The resource file follows:
/*
Dialog and Alert templates for use with CustomGetFile example.
Steve Falkenburg -- MacDTS
*/
#include "types.r"
/* CustomGetFile dialog */
resource 'DLOG' (128, purgeable) {
{0, 0, 206, 344},
dBoxProc,
invisible,
noGoAway,
0x0,
128,
""
};
resource 'DITL' (128, purgeable) {
{ /* array DITLarray: 11 elements */
/* [1] */
{135, 252, 155, 332}, Button { enabled, "Open" },
/* [2] */
{104, 252, 124, 332}, Button { enabled, "Cancel" },
/* [3] */
{0, 0, 0, 0}, HelpItem { disabled,
HMScanhdlg {
-6042
}
},
/* [4] */
{8, 235, 24, 337}, UserItem { enabled },
/* [5] */
{32, 252, 52, 332}, Button { enabled, "Eject" },
/* [6] */
{60, 252, 80, 332}, Button { enabled, "Desktop" },
/* [7] */
{29, 12, 159, 230}, UserItem { enabled },
/* [8] */
{6, 12, 25, 230}, UserItem { enabled },
/* [9] */
{91, 251, 92, 333}, Picture { disabled, 11 },
/* [10] */
{175, 16, 191, 91}, EditText { enabled, "" },
/* [11] */
{175, 106, 191, 181}, EditText { enabled, "" }
}
};
/* input check value alert */
resource 'ALRT' (129) {
{110, 130, 208, 414},
129,
{ /* array: 4 elements */
/* [1] */
OK, visible, sound1,
/* [2] */
OK, visible, sound1,
/* [3] */
OK, visible, sound1,
/* [4] */
OK, visible, sound1
}
};
resource 'DITL' (129) {
{ /* array DITLarray: 2 elements */
/* [1] */
{68, 218, 88, 276},Button {enabled,"OK"},
/* [2] */
{10, 61, 62, 278},
StaticText { disabled,
"Your field entry is out of range. Pleas"
"e enter a number between 0 and 256."
}
}
};
Operating System: Standard File Toolbox: Displaying invisible files under Systems 6 & 7 without typeList
Under System 7 my filter proc for displaying invisible data files no longer works. How can I use Standard File to display the names of invisible files of a specific type under System 7?
System 7.0 can show invisible files in the standard getfile dialog box; however, not all System 6.0x Standard File package calls are handled the same in 7.0.
When using invisible files under 7.0, type filtering should be performed within a filter proc and not with the typeList field of the SFGetFile() call. System 7.0 no longer allows a typeList for detecting invisible files. The actual check for invisible files of a particular type(s) should be done within the file filter procedure.
The SFGetFile() call below displays only folders and invisible 'TEXT' files in the standard getfile dialog box. With the numTypes parameter set to -1, all types of files will be passed to the filter proc.
SFGetFile( where, "", myFilterProc, -1, typeList, nil, &reply );
In this example, the filter proc’s return value depends on the file’s type and Finder flags.
pascal Boolean myFilterProc( fp )
FileParam *fp;
{
if ((fp->ioFlFndrInfo.fdFlags & fInvisible) &&
(fp->ioFlFndrInfo.fdType == 'TEXT'))
return FALSE;
else
return TRUE;
}
Operating System: Standard File Toolbox: Standard File and nontrashable Macintosh folders
When we use Standard File to get a Macintosh file in a folder, it becomes impossible to throw that folder away and empty the trash without quitting first. Is this because the working directory is still open? It is my understanding that applications shouldn’t close working directories that were opened by Standard File. Is there something I should be doing, or is this just a limitation in the system?
Pre-System 7 Standard File calls (SFGetFile/SFPutFile/etc...) call PBOpenWD to open a working directory to the folder where the selected file resides.
This working directory, along with all others created within any application, are closed by MultiFinder (or the Process Manager under System 7) when the application is quit. Before the application quits, you will not be able to throw away the folder. After quitting, however, the directory is closed and the folder can be trashed.
As described in Macintosh Technical Note #190, this is accomplished in the following way: When Standard File calls PBOpenWD(), the ioWDProcID field is ignored, and MultiFinder replaces its contents with a unique process identifier. When your application quits, MultiFinder indexes through all open working directories with your unique process ID and closes them.
Your understanding is correct that you don’t have to close these Standard File working directories yourself. If, however, you want the user to be able to delete the directory *while* your application is still running, you will have to issue a PBCloseWD() call yourself, as in the following example:
WDPBRec theWD;
Point where = {100,100};
SFGetFile ( where, nil, nil, -1, nil, nil, &reply );
<do file stuff here>
theWD.ioVRefNum = reply.vRefNum;
err = PBCloseWD(&theWD,false);
If you’re running under System 7, you are much better off using the new StandardGetFile() and StandardPutFile() routines. They do not use working directories at all, and instead return FSSpecs to refer to files.
If none of the above helps, your problem may be that you have left a file open in the directory the user is trying to delete. This would cause the same error as the one you described.
Operating System: Standard File Toolbox: How to override System 7.0 Standard File dialog centering
Any way to override the new default screen location (upper-middle) for Standard File calls under System 7.0? My Standard File dialog needs to be somewhere else on the screen.
You can use the CustomGetFile (Inside Macintosh Volume VI, page 26-22) and CustomPutFile (Inside Macintosh VI, page 26-20) to place the related Standard File dialogs in the location you specify as a parameter. This should override the centering feature that System 7.0 uses on the StandardGetFile (Inside Macintosh VI, 26-22) and StandardPutFile (Inside Macintosh VI, 26-20) calls.
Operating System: Standard File Toolbox: Retained Macintosh file reference requirements
How do I retain a persistent reference to a file? What can I store in a configuration file so I can find a specific file again at a later launch?
The Macintosh® has two native file systems: the original (64K ROM) Macintosh File System (MFS) and the Hierarchical File System (HFS) (Macintosh Plus and newer). In an attempt to simplify this discussion, I’ll assume you know the differences between them and base my explanation upon the HFS system as it is the current one.
To retain a reference to a file location that will persist across application launch and restarts, store its file name, volume name and directory ID. With this information, you will be able to obtain the volume reference number (a dynamic value based on mount order, subject to change because the addition of another drive can change the mount order) and then use either the new high-level File Manager calls or the parameter block based calls to operate on these files. If you happen to encounter an MFS volume, the HFS File Manager will do the appropriate thing given that you use the calls correctly.
Only if you are supporting MFS for an old system will you need to call the MFSfunctions for obtaining the correct reference values; MFS was a flat file system.
Standard File’s reply.vRefNum value when used with HFS is actually a working directory reference number, not a fixed reference; therefore it will usually change between launches of the application or across restarts.
Documentation for the File Manager is extensive and spread out because it was updated when the Macintosh Plus was released and has been added to subsequently by Technical Notes. Inside Macintosh, Volume II deals with the MFS File Manager, Inside Macintosh, Volumes IV and V deal with the HFS File Manager through System 6.0.x, and Inside Macintosh, Volume VI (on your System 7.0 CD-ROM) lists the new File Manager services available under System 7.0. The following Technical Notes should prove useful to you:
File Manager:
024 - Available Volumes
066 - Determining Which File System is Active
077 - HFS Ruminations
102 - HFS Elucidations
140 - Why PBHSetVol is Dangerous
157 - Problem with GetVInfo
179 - Setting ioNamePtr in File Manager Calls
190 - Working Directories and MultiFinder
204 - HFS Tidbits
218 - New High-Level File Manager Calls
246 - Mixing HFS and C File I/O
Standard File:
047 - Customizing Standard File
080 - Standard File Tips
Operating System: Start & Shutdown Managers: SetTimeout refers to device specified by SetDefaultStartup
SetTimeout lets you specify the number of seconds the system will wait for theinternal hard disk to respond (Inside Macintosh, oluVolume V, page 356). Is this only for a SCSI device at ID=0 or is this the device specified by the SetDefaultStartup call? Can I assume that SetTimeout and SetDefaultStartup are supported if the machine type returned by SysEnvirons is greater than a Macintosh Plus? Is there a better way to determine if these calls are supported?
SetTimeOut is for the internal device, whose ID must be zero.
Operating System: System Configuration: Checking for specific Macintosh type
Page 3-44 of Inside Macintosh Volume VI warns against inferring the existence of certain hardware based on the gestaltMachineType selector, but there is no selector for the information we need. Our product works only on Macintosh Portable-type machines and there is no absolute way to determine whether our INIT is on a Portable. Should we ignore the warning?
There is no selector for determining the type of machine you are on, so in your case, you’ll have to ignore the warning and just test for specific machines. In the future if Apple comes out with a machine which your product does not know about, then you’ll need to update your INIT to look for the new machine as well.
Operating System: System Configuration: Checking for FPUs during installation
We plan to ship a Floating Processor Unit (FPU) version and a non-FPU version of our product (together), and we’re writing an Apple Installer script to install the correct application. How do we handle future CPUs which may have FPUs without knowing about their future Gestalt selectors?
Instead of testing for the existence of an FPU by checking all gestaltFPUTypes greater than 0, turn the logic around and check that there isn’t an FPU. If a value other than 0 is returned, then install the FPU version of your product.
Operating System: System Configuration: Zapping PRAM in System 7 and other fun System 7 stuff
Zapping PRAM in System 7 and other fun System 7 stuff
Silly and useful stuff in System 7.0:
System 7.0 power keys:
• Option Click on the DeskTop.
Start up an application. Hold down option key and click anywhere
in the desktop. The application will hide itself.
• Hold down Option key, select another application from the application menu using the mouse.
The application will hide itself.
• Command Option esc.
Launch an application. Hold down command option esc keys. A dialog appears.
Of course, the function ExitToShell is called to quit these applications.
ExitToShell is very robust and if there is no other application to drop
into, it will launch the application which is stored in the global
FinderName. The Finder will be stored in the FinderName global.
• Zap PRAM
Hold down Command Shift P R while starting up your machine.
Power up power keys.
• Command Option.
Restart the system. Hold down both command and option keys.
You will be prompted with a dialog box to rebuild the desktop file.
• Shift.
Restart the system. Hold down the shift key.
The extensions will not be loaded.
Map control panel application
• Option - “Click Find Button.”
Open Map Control panel. Hold down option button. Click in the Find button.
The cities will be alphabetically searched.
• Option - “Double Click Map icon”
Hold down option key. Launch Map icon from Control Panels folder.
Fun note: Try to open Fat Bits without closing the Control Panels folder
on the DeskTop.
• Type in “Middle of Nowhere” on English systems
• Open the scrapbook. Copy the Color Map. Open Map control panel.
Paste in the Color Map.
Monitors Control Panel
• Click on 7.0 in upper right hand corner of the window.
• Click on 7.0 and hit option key about 12 times in a row.
About the Macintosh...
• Hold down the option button and choose about the Finder from the Apple menu.
Miscellanea:
• You can also have a nifty little Keyboards menu to switch between keyboard
layouts if you use more than one. You just set the “Always show icon” bit on
in the 'itlc' resource in the System on. I use this to put that little
American flag on my Menu bar. Changing a system resource is risky, so be
careful while setting the bit!
• Hold down option and switch application from the application menu item.
The front most window will hide.
• Cmd-Y in the Finder unmounts the disk.
• Labels. Blank out all label names and reboot to see the authors’ names as
labels in the menu.