Difference between revisions of "Apple Pippin"

 
(6 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
[[File:Pippin-Atmark-Console-Set.jpg|thumb]]
 
[[File:Pippin-Atmark-Console-Set.jpg|thumb]]
 
[[File:Bandia-Pippin-pcb.jpg|thumb]]
 
[[File:Bandia-Pippin-pcb.jpg|thumb]]
 +
[[File:Pippinlogo2.gif|right]]
  
 
Pippin is a set of technologies designed by [[Apple Computer]] for Bandai Digital Entertainment Corporation in Japan. Pippin lets you run specially-modified Macintosh CD-ROMs on a low-cost player that plugs into a standard television set. Runs on a [[PowerPC 603]] processor.
 
Pippin is a set of technologies designed by [[Apple Computer]] for Bandai Digital Entertainment Corporation in Japan. Pippin lets you run specially-modified Macintosh CD-ROMs on a low-cost player that plugs into a standard television set. Runs on a [[PowerPC 603]] processor.
  
 
=Technical Specifications=
 
=Technical Specifications=
 +
[[File:Technote.gif|right]]
 
===Hardware===
 
===Hardware===
 
* 66MHz [[PowerPC 603]] [[RISC]] microprocessor
 
* 66MHz [[PowerPC 603]] [[RISC]] microprocessor
Line 40: Line 42:
 
* Pippin System Software upgrades released through CD-ROM stamping operations
 
* Pippin System Software upgrades released through CD-ROM stamping operations
 
* 68k emulator
 
* 68k emulator
* [[Macintosh Toolbox]] intact  
+
* [[Macintosh Toolbox]] intact
  
 
=Pippin Technical Notes=
 
=Pippin Technical Notes=
Line 662: Line 664:
  
 
==Pippin Authentication==
 
==Pippin Authentication==
 +
===Introduction===
 
In order for Pippin CD-ROMs to run on a Pippin Power Player, they must first go through a Pippin authentication process. The authentication process is about applying an Apple-approved RSA signature, in the form of an electronic encrypted key, onto a Pippin CD-ROM.
 
In order for Pippin CD-ROMs to run on a Pippin Power Player, they must first go through a Pippin authentication process. The authentication process is about applying an Apple-approved RSA signature, in the form of an electronic encrypted key, onto a Pippin CD-ROM.
 +
 +
===RSA's Authentication Software Library===
 +
Apple has licensed RSA for their public key authentication software library. The foundation of this library is non-reversible (i.e., one-way) mathematical algorithms based on using large prime numbers as keys to encrypt messages. With RSA's public key authentication system, keys are generated in pairs. One key is held privately by its owner, and the other key, the public key, is given out to be used by others to decrypt the owner's generated "keyed" messages. Public keys cannot be interchanged or swapped, and a message encrypted with a private key can only be decrypted with its corresponding matching public key.
 +
 +
Encrypted messages make very good electronic signatures since they can only be decrypted by a public key which is registered to a specific person (or company). Knowing a person's public key, however, will never offer any clue as to what that person's private key might be. Since only private keys can create an encrypted message, the system is secure.
 +
 +
===Authenticating a Pippin CD===
 +
For Pippin, the "message" to be encrypted is the entire contents of the CD. Since this typically is a lot of data, and the algorithms are slow, the CD contents are first "digested" by a hashing algorithm which produces a small digest of the CD contents. The digest later can be used to test that the current CD content matches what it was when the digest was first created and than signed (encrypted).
 +
 +
To create a Pippin-authentic CD requires two sets of key pairs. Each authorized CD stamping house has a public pair and private pair. Apple also holds both a public pair and private pair. Apple's private key is on a computer locked inside a safe which is connected to an internet mail system. Apple's public key is inside every Pippin ROM. The stamping house's private key is inside a "digesting" program at the stamping house and their public key is on file with Apple inside the safe.
 +
 +
The authentication process steps are as follows:
 +
 +
1. An authorized CD stamping house digests the CD content, then signs the digest (on the CD) by encrypting it with their private key.
 +
 +
2. The stamping house then emails the signed digest encrypted with their private key to Apple's computer in the safe.
 +
 +
3. Apple's "safe" computer unsigns the digest using the stamping house's public key, and then re-signs it using Apple's private key.
 +
 +
4. The digest, which has now been effectively signed by Apple's private key, is then e-mailed back to the stamping house.
 +
 +
5. Back at the stamping house, a program is run to apply the signed authentic digest onto the CD.
 +
 +
Figure 1 illustrates the flow of the Pippin authentication process.
 +
 +
Figure 1 : The Pippin Authentication process
 +
 +
[[File:Figure1111.gif]]
 +
 +
Through this process, private keys never have to be revealed to anyone and the only data which leaves the owner's facility, via e-mail, is encrypted with a private key.
 +
 +
After the stamping house applies the signed authentic digest to the CD, the CD is Pippin-authentic. During the boot process, the Pippin ROM creates a temporary digest using the same algorithm as was used to make the original, then unsigns the digest on the CD to compare the two. Only an exact match will allow the boot process to continue.
 +
 +
Note: Pippin disks are not exactly encrypted since they still will mount on a Macintosh just fine. However, the still have a signature applied to them which can be read and tested.
  
 
==Applejack Input Device Driver==
 
==Applejack Input Device Driver==
The Applejack input device driver combines the features of a game-player pad and a mouse or trackball in a small handheld device. Generally, Applejack input devices are attached to a Pippin Power Player (a CD-ROM multimedia player device derived from the PowerPC Macintosh).
+
===Introduction===
 +
The Pippin input device, Applejack, is a custom ADB device containing trackball information and a series of 18 button states. The Applejack driver resides in the Pippin ROM and loads at system boot time. On a Macintosh, the Applejack driver resides in the system extension file.
 +
 
 +
The Applejack driver uses a 'pipp' button mapping resource which allows any Applejack button to be mapped with either a mouse button or keyboard key function. The trackball data, however, is always treated as a "mouse" and there is no provision for remapping it.
 +
 
 +
While provision for default button mapping is provided, applications can also include a custom 'pipp' resource for setting button functions. On Pippin ROMs, a custom 'pipp' resource would be loaded automatically when an application is launched. For applications that do not use mouse or keyboard mappings (not highly recommended), the Applejack raw data is directly readable from the driver.
 +
 
 +
===Setting Up===
 +
The Applejack Software Developer's Kit diskette contains the application for editing the 'pipp' mapping resource, and an system extension file.
 +
 
 +
# From the SDK diskette, copy the application file to your Macintosh hard drive.
 +
# Drag-and-drop the system extension file to the "Extensions" folder in your System Folder.
 +
# Ensure that the Applejack input device driver(s) are plugged into the ADB jack adapter(s) on the backside of your Macintosh.
 +
# Restart the Macintosh to initialize the system extension file.
 +
 
 +
You are now ready to customize the Applejack input device driver.
 +
 
 +
===Customizing the Applejack===
 +
There are two ways to customize the 'pipp' mapping resource of the Applejack input device driver(s).
 +
 
 +
The simplest way involves using the application as an interface for redefining device button mapping. This mechanism is as simple as aligning an attached Applejack device (or possibly, unattached Applejack device, as the case may be) with a visual device on the Macintosh screen. By clicking on the on-screen buttons, a developer customizes an Applejack device(s).
 +
 
 +
The second way involves modifying the 'pipp' mapping resource code files manually, specifically defining how the button mechanisms on the device(s) should work.
 +
 
 +
====The Applejack Control 2.2.0 Application====
 +
The application is the interface used for editing the 'pipp' mapping resource. Double-click on the application icon and a window similar to Figure 1 will appear.
 +
 
 +
Figure 1 : Applejack Control 2.2.0 Application Launch Window
 +
 
 +
[[File:Figurea1.gif]]
 +
 
 +
If the application does not find any Applejack device(s) physically connected to the bus, the window displays a "NO GAME PADS FOUND" message across the window instead, as follows.
 +
 
 +
Figure 2 : NO GAME PAD FOUND Window
 +
 
 +
[[File:Figurea2.gif]]
 +
 
 +
Regardless of whether an Applejack device(s) is connected or not, the button settings may be edited. By clicking on desired buttons, a developer can customize the Applejack device(s).
 +
 
 +
A dialog box similar to Figure 3 or Figure 4 appears, depending on the button clicked on.
 +
 
 +
Figure 3 : Applejack Control 2.2.0 Dialog Box--Customizing Keyboard Key Functions
 +
 
 +
[[File:Figurea3.gif]]
 +
 
 +
When defining specific keyboard keys, select the "Keyboard Key" option, and press the key desired, which will appear in the character fill-in box. Also, modifiers can be designated (click on appropriate box) with a specific keyboard key, if desired. Then, click on "Ok" to proceed.
 +
 
 +
When defining mouse button functions, click on the appropriate "mouse" functions, as desired, then click on "Ok" to proceed.
 +
 
 +
Figure 4 : Applejack Control 2.2.0 Dialog Box--Customizing Mouse Button Functions
 +
 
 +
[[File:Figurea4.gif]]
 +
 
 +
By clicking "Ok" after defining each button, the Applejack driver's local data is updated. If an Applejack device is attached, the newly defined button functions can be tested immediately with the newly "customized" Applejack device(s).
 +
 
 +
By quitting the application, the 'pipp' resource within the system extension file is updated. If you would like to write the 'pipp' resource into a separate file, use the "File:Make Resource..." menu item.
 +
 
 +
=====Applejack Default Button Settings=====
 +
The Driver in the Pippin ROM creates default settings for the Applejack buttons if there is no Applejack extension installed. The default Applejack button settings are as follows:
 +
 
 +
[[File:Sect2.gif]]
 +
 
 +
====Modifying the 'pipp' Button Mapping Resource====
 +
Alternatively, 'pipp' resources can be built and keys (functions) remapped by looking at the driver's global data. Figure 5 illustrates the Applejack Input Device Driver and its corresponding button mapping.
 +
 
 +
Figure 5 : Applejack Input Device--Button Mapping
 +
 
 +
[[File:Figure55.gif]]
 +
 
 +
The 'pipp' resource is identical to the driver's global data and is a structure of type AJGlobalData. This global data is pointed to by the .refCon field of the Cursor Device Manager record for each Applejack device, as defined in the following code.
 +
<pre>
 +
typedef struct SwitchData {
 +
Byte    function;
 +
Byte    modifiers;
 +
Byte    keyCode;
 +
Byte    charCode;
 +
} SwitchData, *SwitchDataPtr;
 +
 
 +
typedef struct AJGlobalData {
 +
long    signature;
 +
Byte    MyTalkR0;
 +
Byte    handlerID;
 +
Byte    ourMBState;
 +
Byte    ourLockState;
 +
long    switchStates;
 +
SwitchData      switchMappingArray[18];
 +
long    nextjADBProc;
 +
long    cursorHandler;
 +
} AJGlobalData, *AJGlobalDataPtr;
 +
</pre>
 +
Most notably in the above code is the signature. The driver installer has initialized the signature to equal 'pipp' so that applications can look through the ADB device table and find this structure. Further, the function field of the SwitchData switchMappingArray is defined as follows:
 +
<pre>
 +
enum {
 +
 
 +
kNothing = 0,    // maps to nothing
 +
kMouse  = 1,    // maps to standard mouse button operation
 +
kMouseDblClick = 2,    // maps to mouse button double click
 +
kMouseLock = 3,    // toggles the mouse button state
 +
kKeyboard = 4,    // maps to a keyboard key
 +
kFrontPanel = 5,    // not used
 +
kModifier = 6    // maps to a modifier key
 +
};
 +
</pre>
 +
Each element of the switchMappingArray array represents one of the switches on Applejack. The array index is equal to the bit numbers, as shown in Figure 6.
 +
 
 +
Figure 6 : ADB Register 0 Four-Byte Packet and Bit Number to Button Mapping
 +
 
 +
[[File:Figure66.gif]]
 +
 
 +
If a button is mapped as kKeyboard, then the Applejack driver posts a keyDown event with the .keyCode, .keyChar and .modifiers fields in the event record.
 +
 
 +
The following code shows an enumeration of equates for the .modifiers field.
 +
<pre>
 +
enum {
 +
kCommandBit = 0,
 +
kShiftBit = 1,
 +
kCapsLockBit = 2,
 +
kOptionBit = 3,
 +
kControlBit = 4
 +
};
 +
</pre>
 +
If a button is mapped as kModifier, then the Applejack driver sets the keyMap global for the keyCode specified in the .keyCode field. The other fields are ignored in this case.
 +
 
 +
The following code is another enumeration of equates for the .modifiers field.
 +
<pre>
 +
enum {
 +
kCommandKey    = 0x37,
 +
kShiftKey      = 0x38,
 +
kCapsLockKey    = 0x39,
 +
kOptionKey      = 0x3A,
 +
kControlKey    = 0x36
 +
};
 +
</pre>
 +
To change the mapping of a button, map a pointer to the AJGlobalData structure, then put in new values for the .switches fields for the desired switch. A good reason to do this would be if you wanted to read the Applejack raw data but did not want a button to also be generating system events.
 +
 
 +
The following code maps a pointer to the AJGlobalData structure for each connected Applejack, and then changes the selected switch.
 +
<pre>
 +
void ChangeSwitchMapping (short whichSwitch, short function, short modifiers,
 +
short keyCode, short charCode);
 +
 
 +
void ChangeSwitchMapping (short whichSwitch, short function, short modifiers,
 +
short keyCode, short charCode);
 +
{
 +
ADBAddress address;
 +
ADBDataBlock dataBlock;
 +
AJGlobalDataPtr myAJ;
 +
CursorDevicePtr myCrsrDev;
 +
short       index,i;
 +
 
 +
//We need to copy these changes into the currently installed drivers.
 +
//Where are the Applejacks?
 +
 
 +
//The Applejack driver uses the .refcon field of the cursor device record to
 +
//store a pointer to its globals, a AJGlobalDataPtr.
 +
 
 +
if(whichSwitch>=0 && whichSwitch<=17)
 +
{ // where are the AppleJacks?
 +
index = CountADBs();
 +
while(index>0)
 +
{
 +
address=GetIndADB(&dataBlock,index);
 +
if((dataBlock.origADBAddr)==kDevAddr)
 +
{ // make sure that this is really us
 +
if(dataBlock.dbDataAreaAddr)
 +
{
 +
myCrsrDev=(CursorDevicePtr)dataBlock.dbDataAreaAddr;
 +
if(myCrsrDev)
 +
{
 +
myAJ=(AJGlobalDataPtr)myCrsrDev->refCon;
 +
if(myAJ->signature=='pipp')
 +
{      // got it.
 +
myAJ->switchMappingArray.function[whichSwitch]=function;
 +
myAJ->switchMappingArray.modifiers[whichSwitch]=modifiers;
 +
myAJ->switchMappingArray.keyCode[whichSwitch]=keyCode;
 +
myAJ->switchMappingArray.charCode[whichSwitch]=charCode;
 +
}
 +
}
 +
}
 +
}
 +
index--;
 +
}
 +
</pre>
 +
Some other ways to use this function could be as follows:
 +
 
 +
* Map the yellow button (S10, bit 9) to do nothing:
 +
ChangeSwitchMapping(9,kNothing,0,0,0);
 +
* Map the red button (S8, bit 14) to be equal to command-Q (quit):
 +
ChangeSwitchMapping(14,kKeyboard,((1<<kCommandBit)),0x0C,'Q');
 +
* Map the green button (S7, bit 15) to be equal to the shift key:
 +
ChangeSwitchMapping(15,kModifier,0,kShiftKey,0);
 +
 
 +
===Reading Raw Applejack Data===
 +
To read raw Applejack data yourself, use code like the previous sample code, and ensure that you map a pointer to the AJGlobalData for each connected Applejack. You need to do this only once, but remember the pointer since it will not be moved or purged.
 +
 
 +
Then, examine myAJ->switchStates to read the state of a button. Each button correlates with a bit in switchStates. The bit number is the same as defined in the .switchMappingArray array index.
 +
 
 +
For example, suppose you want to know if the yellow button is pressed; the following statement might apply:
 +
<pre>
 +
if(!((myAJ>switchStates)&(1<<9))) // 0==DOWN
 +
{                                                      // 1==UP
 +
Do something useful here, yellow button is down...
 +
}
 +
</pre>
 +
Be sure to keep separate pointers for each Applejack found (maximum of 4) even if you only support a single player play. If the bit number returns a value of `0', then the button is pressed. If a value of `1' is returned, the button is not pressed. No other event loop is required.
  
 
==Pippin Video==
 
==Pippin Video==
This document contains PippinVideo.h and myPippinVideo.c. PippinVideo.h is a header file that contains enumerated constants and structures necessary to access functionality unique to the Pippin video architecture. myPippinVideo.c is sample code that illustrates features unique to the Pippin video architecture.  
+
This document contains PippinVideo.h and myPippinVideo.c. PippinVideo.h is a header file that contains enumerated constants and structures necessary to access functionality unique to the Pippin video architecture. myPippinVideo.c is sample code that illustrates features unique to the Pippin video architecture.
 +
 
 +
===PippinVideo.h===
 +
<pre>
 +
// =================================================================================
 +
//
 +
// PippinVideo.h
 +
//
 +
// Copyright 1995, Apple Computer
 +
//
 +
// send comments/bugs: [email protected]
 +
//
 +
// (change this to a real header)
 +
//
 +
// This file contains enumerated constants and structures necessary
 +
// to access functionality unique to the Pippin video architecture
 +
//
 +
// =================================================================================
 +
 
 +
enum {
 +
kSetProgressiveScan = 0, // Progressive Scan
 +
kSetInterlace, // Interlaced scan, no convolution
 +
kSetInterlaceConv, // Interlaced scan, Convolution, no scaling
 +
kSetInterlaceConvScale // Interlaced scan, convolution, and scaling
 +
};
 +
 
 +
#define cscSetScanMode 128 // Used to select a scan mode for the Taos driver
 +
#define cscGetScanMode 128
 +
 
 +
// structure for Requesting/Controlling Scan Mode information
 +
 
 +
typedef struct VDControlMode VDControlMode;
 +
 
 +
struct VDControlMode
 +
{
 +
UInt32 csModeSelect;
 +
Ptr csBaseAddressA;
 +
Ptr csBaseAddressB;
 +
};
 +
</pre>
 +
===myPippinVideo.c===
 +
<pre>
 +
//==================================================================================
 +
//
 +
// myPippinVideo.c
 +
//
 +
// send comments/bugs [email protected]
 +
//
 +
// v1.1 March 28, 1996
 +
//
 +
// (change this to a real header)
 +
//
 +
// Sample code illustrating features unique to the Pippin video architecture
 +
// Shows how to use driver calls to change video scan modes
 +
//
 +
//==================================================================================
 +
 
 +
 
 +
#include <stdio.h>
 +
#include <stdlib.h>
 +
#include <Memory.h>
 +
#include <Displays.h>
 +
#include <Video.h>
 +
#include "PippinVideo.h"
 +
 
 +
// Prototypes
 +
unsigned long GetUserInputData (void);
 +
void DoCurrentSettings(void);
 +
void DoSetScanMode(void);
 +
 
 +
// Globals
 +
OSErr err;
 +
short currentDepth;
 +
GDHandle myGDHandle;
 +
short videoDriverRefNum;
 +
short currentScanMode;
 +
DisplayIDType currentDisplayType;
 +
UInt32 currentBaseAddress = 0;
 +
short currentPage;
 +
 
 +
//==================================================================================
 +
//
 +
// main()
 +
//
 +
// Starting point for everything
 +
//
 +
//==================================================================================
 +
 
 +
 
 +
void main(void)
 +
{
 +
OSErr err;
 +
VDControlMode myControlModeStruct;
 +
VDDisplayConnectInfoRec myVDDisplayConnectInfoRec;
 +
VDSwitchInfoRec switchInfo;
 +
CntrlParam pBlock;
 +
short input = 1;
 +
MaxApplZone();
 +
 
 +
// ooo Need to check for Pippin Gestalt Selecter here
 +
 
 +
printf("\nThis demo illustrates special functionality of the Pippin video
 +
architecture\n");
 +
 
 +
printf("\n\tInsert explanation and other stuff here\n\n");
 +
 
 +
DoCurrentSettings();
 +
while ( input != 999 )
 +
{
 +
printf("\nPlease enter a selection:\n");
 +
printf("  1 = Set Scan Mode\n");
 +
// printf("  2 = Swap Video Pages\n");
 +
printf("  3 = Current Settings\n");
 +
printf("input (999 to exit)>");
 +
input = GetUserInputData();
 +
switch ( input )
 +
{
 +
case 1:
 +
DoSetScanMode();
 +
break;
 +
case 2:
 +
// DoSwapPages();
 +
break;
 +
case 3:
 +
DoCurrentSettings();
 +
break;
 +
case 999:
 +
break;
 +
default:
 +
printf("Invalid selection\n");
 +
break;
 +
}
 +
}
 +
printf("\nPress Command-Q to Quit . . .\n");
 +
}
 +
 
 +
//==================================================================================
 +
//
 +
// DoCurrentSettings()
 +
//
 +
// Gets Current Video Stuff by calling PBStatus repeatedly
 +
// cscGetScanMode
 +
// cscGetConnection
 +
// cscGetMode <-- with different pages
 +
//
 +
//==================================================================================
 +
 
 +
 
 +
void DoCurrentSettings(void)
 +
{
 +
OSErr err;
 +
VDControlMode myControlModeStruct;
 +
VDDisplayConnectInfoRec myVDDisplayConnectInfoRec;
 +
VDPageInfo myVDPageInfoRec;
 +
VDSwitchInfoRec switchInfo;
 +
CntrlParam pBlock;
 +
 
 +
printf("\n");
 +
printf("Scanning for driverRefNum: ");
 +
 
 +
// We get the First video device because we know there is only one device hooked
 +
// up to Pippin
 +
 
 +
myGDHandle = DMGetFirstScreenDevice(dmOnlyActiveDisplays);
 +
videoDriverRefNum = (*myGDHandle)->gdRefNum;
 +
printf("%i\n", videoDriverRefNum);
 +
printf("Current Scan Mode: ");
 +
pBlock.ioCompletion = nil;
 +
pBlock.ioCRefNum = videoDriverRefNum;
 +
pBlock.csCode = cscGetScanMode;
 +
 
 +
*(Ptr *)&pBlock.csParam[0] = (Ptr)&myControlModeStruct;
 +
err = PBStatus( (ParmBlkPtr)&pBlock, true );
 +
if ( err )
 +
printf("Unsupported Functionality, err = %i\n", err);
 +
else
 +
{
 +
currentScanMode = myControlModeStruct.csModeSelect;
 +
switch (myControlModeStruct.csModeSelect)
 +
{
 +
case kSetProgressiveScan:
 +
printf("kSetProgressiveScan\n");
 +
break;
 +
case kSetInterlace:
 +
printf("kSetInterlace\n");
 +
break;
 +
case kSetInterlaceConv:
 +
printf("kSetInterlaceConv\n");
 +
break;
 +
case kSetInterlaceConvScale:
 +
printf("kSetInterlaceConvScale\n");
 +
break;
 +
default:
 +
printf("Err -- unknown Scan Mode, %i\n",
 +
myControlModeStruct.csModeSelect );
 +
}
 +
}
 +
 +
printf("Current Display Type: ");
 +
pBlock.ioCRefNum = videoDriverRefNum;
 +
pBlock.csCode = cscGetConnection;
 +
*(Ptr *)&pBlock.csParam[0] = (Ptr)&myVDDisplayConnectInfoRec;
 +
err = PBStatus( (ParmBlkPtr)&pBlock, true );
 +
currentDisplayType = myVDDisplayConnectInfoRec.csDisplayType;
 +
 
 +
switch ( currentDisplayType )
 +
{
 +
case kVGAConnect:
 +
printf("kVGAConnect\n");
 +
break;
 +
case kNTSCConnect:
 +
printf("kNTSCConnect\n");
 +
break;
 +
case kPALConnect:
 +
printf("kPALConnect\n");
 +
break;
 +
default:
 +
printf(" -- something else (not VGA, NTSC, or PAL)\n");
 +
break;
 +
}
 +
 +
printf("Current Screen Depth: ");
 +
currentDepth = (*((*myGDHandle)->gdPMap))->pixelSize;
 +
printf("%i\n", currentDepth);
 +
printf("Page Info:\n");
 +
printf("  Current Page: ");
 +
pBlock.csCode = cscGetMode;
 +
*(Ptr *)&pBlock.csParam[0] = (Ptr)&myVDPageInfoRec;
 +
err = PBStatus( (ParmBlkPtr)&pBlock, true );
 +
currentPage = myVDPageInfoRec.csPage;
 +
printf("%i\n", currentPage);
 +
pBlock.csCode = cscGetBaseAddr;
 +
myVDPageInfoRec.csPage = 0
 +
*(Ptr *)&pBlock.csParam[0] = (Ptr)&myVDPageInfoRec;
 +
err = PBStatus( (ParmBlkPtr)&pBlock, true );
 +
printf("  Page: %i, Base Address: %X\n", myVDPageInfoRec.csPage,
 +
myVDPageInfoRec.csBaseAddr);
 +
 
 +
myVDPageInfoRec.csPage = 1;
 +
err = PBStatus( (ParmBlkPtr)&pBlock, true );
 +
printf("  Page: %i, Base Address: %X\n", myVDPageInfoRec.csPage,
 +
myVDPageInfoRec.csBaseAddr);
 +
printf("  Page Count: ");
 +
pBlock.csCode = cscGetPages;
 +
err = PBStatus( (ParmBlkPtr)&pBlock, true );
 +
printf("%i\n", myVDPageInfoRec.csPage);
 +
printf("\n");
 +
}
 +
 
 +
//==================================================================================
 +
//
 +
// DoSetScanMode()
 +
//
 +
// Request and set the scan mode;
 +
//
 +
//==================================================================================
 +
 
 +
 
 +
void DoSetScanMode(void)
 +
{
 +
short input = 1;
 +
CntrlParam pBlock;
 +
VDControlMode myControlModeStruct;
 +
 
 +
pBlock.ioCompletion = nil;
 +
pBlock.ioCRefNum = videoDriverRefNum;
 +
pBlock.csCode = cscSetScanMode;
 +
 
 +
*(Ptr *)&pBlock.csParam[0] = (Ptr)&myControlModeStruct;
 +
 
 +
while ( input != 999 )
 +
{
 +
printf("\nPlease enter a selection:\n");
 +
printf("  1 = Progressive Scan\n");
 +
printf("  2 = Interlace\n");
 +
printf("  3 = Interlace, Convolution\n");
 +
printf("  4 = Interlace, Convolution, Scaling\n");
 +
printf("input (999 to exit)>");
 +
input = GetUserInputData();
 +
 
 +
if ( input == 999 ) break;
 +
 
 +
if ( input == 1 )
 +
 
 +
{
 +
if ( currentDisplayType != kVGAConnect ) printf("err -- not in VGA
 +
mode\n");
 +
else
 +
{
 +
myControlModeStruct.csModeSelect = kSetProgressiveScan;
 +
err = PBControl( (ParmBlkPtr)&pBlock, true );
 +
}
 +
}
 +
else
 +
{
 +
if ( currentDisplayType == kVGAConnect ) printf("err -- not in NTSC/PAL
 +
mode\n");
 +
else
 +
{
 +
if (input == 2) myControlModeStruct.csModeSelect = kSetInterlace;
 +
else if (input == 3) myControlModeStruct.csModeSelect =
 +
kSetInterlaceConv;
 +
else if (input == 4) myControlModeStruct.csModeSelect =
 +
kSetInterlaceConvScale;
 +
err = PBControl( (ParmBlkPtr)&pBlock, true );
 +
}
 +
}
 +
if (err) printf("err in PBControl: %i", err);
 +
}
 +
}
 +
 
 +
 
 +
//==================================================================================
 +
//
 +
// GetUserInputData()
 +
//
 +
// Whats until the user inputs anything other than 0
 +
//
 +
//==================================================================================
 +
 
 +
 
 +
unsigned long GetUserInputData (void)
 +
{
 +
long tempLong = 0;
 +
do scanf ("%ld", &tempLong); while (tempLong == 0);
 +
return (tempLong);
 +
}
 +
</pre>
  
 
=External Links=
 
=External Links=
 
* https://web.archive.org/web/20060215213241/http://www.mandrake.demon.co.uk/Apple/pip1.html
 
* https://web.archive.org/web/20060215213241/http://www.mandrake.demon.co.uk/Apple/pip1.html
 +
 +
=Related Articles=
 +
* [[The 66 Most Asked Questions Regarding Pippin]]
 +
* [[Pippin @World]]
  
 
=See Also=
 
=See Also=

Latest revision as of 00:39, 28 February 2023

Pippin-Atmark-Console-Set.jpg
Bandia-Pippin-pcb.jpg
Pippinlogo2.gif

Pippin is a set of technologies designed by Apple Computer for Bandai Digital Entertainment Corporation in Japan. Pippin lets you run specially-modified Macintosh CD-ROMs on a low-cost player that plugs into a standard television set. Runs on a PowerPC 603 processor.

Technical Specifications

Hardware

  • 66MHz PowerPC 603 RISC microprocessor
    • Superscaler, three instructions per clock cycle
    • 8KB data and 8KB instruction caches
    • IEEE standard single and double precision Floating Point Unit (FPU)
  • 6MB combined system and video memory, advanced architecture
    • Easy memory expansion cards in 2, 4 and 8MB increments
  • 128K SRAM store/restore backup
  • 4X CD-ROM drive
  • Two high-speed serial ports, one of which is GeoPort ready
  • PCI-compatible expansion slot
  • Two ruggedized ADB inputs
    • Supports up to four simultaneous players over Apple Desktop Bus (ADB)
    • Will support standard ADB keyboards and mice with connector adapters

Video

  • 8-bit and 16-bit video support
  • Dual frame buffers for superior frame-to-frame animation
  • Support for NTSC and PAL composite, S-Video and VGA (640x480) monitors
  • Horizontal and vertical video convolution

Audio

  • Stereo 16-bit 44kHz sampled output
  • Stereo 16-bit 44kHz sampled input
  • Headphone output jack with individual volume control
  • Audio CD player compatibility

Software

  • Runtime environment derived from Mac OS
  • PPC native version of QuickDraw
  • Reduced system memory footprint (computer specific features removed)
  • Disk-resident System Software stamped on CD-ROM with title
  • System boots off of CD-ROM
  • Pippin System Software upgrades released through CD-ROM stamping operations
  • 68k emulator
  • Macintosh Toolbox intact

Pippin Technical Notes

Startup Process

History

On all existing Macintosh computers, the boot process remains the same as it has been since the early days of the Macintosh. That startup process is as follows:

  1. After the loading of the Process Manager, the file name stored in the boot blocks as the startup application is launched.
  2. After a standard format of a hard disk or floppy, this value is set to "Finder". So the Finder is launched as the main application.

On the initial Pippin, CD-ROMs developers were taught a simple way of setting up the startup application by modifying the boot blocks on the volume. While this worked as needed, it was a hack and is not an acceptable solution for shipping disks. It required the target application to be in the "blessed" System Folder, or in some cases, people made the root level of the volume the System Folder. This makes the disks very unattractive when the disk is used in a non-Pippin system (due to the need for the startup application to be in the System Folder). It could also cause problems with future Pippins as there would be more "unique" considerations that would need to be handled as the ROM attempts to override what is on the Pippin CD-ROMs.

The New Pippin Way

The basic startup sequence has been modified for Pippin to allow additional flexibility and better aesthetics on non-Pippin Macintoshes. Further, the new startup process does not require any modification of the boot blocks.

At the point where the application stored in the boot blocks is launched, the startup process has been modified for Pippin purposes. If there is a file called "PippinFinder" in the System Folder, then it is launched. PippinFinder should only be used for developers that want to handle multiple applications per CD. For developers wanting to do this, please see the document regarding PippinFinder.

For single application titles, the startup process is simple. Create an alias to the application you want to launch and place it in the Startup Items folder. Also make sure that PippinFinder has been removed from the System Folder. That is all that is needed. The boot process with launch your application on the next launch rather then launching the Finder. And the final disk that is pressed will not contain the real Finder in the System Folder. The file named "Finder" will actually be just another copy of PippinFinder on final shipping CD-ROMs.

Considerations for Developers

Pippin can have a variable amount of memory, but the size resource can only be configured once, so care should be made in setting this resource.

Pippin has been designed to use as little memory as possible. QuickTime that ships with all Macintoshes is much better in its memory allocation, using very little memory until QuickTime functionality is actually needed. The reason the memory allocation setting is important will become clear. If you have your preferred memory size set to a size which will use up all available application memory space then it means the system heap is unable to grow larger then it is after the startup process.

A better way of writing your application would be to utilize temporary memory more effectively. Make you application work well within a reasonable partition (2 MB) then utilize temporary memory as available. This would allow you application to work well on any memory configuration of Pippin. Will also allow the application to work more flexible on the entire Macintosh family as well.

If you application is configured to use all available memory, then any system extensions or managers that require system heap memory space will not function fully and in some cases not at all. To make sure you run well on all Pippins, you should do all your testing on the base model Pippin with no expanded memory.

Launch Process Override for Developer Enabler

For developers, there is an override in the developer Enabler that allows them to override the above described boot process and go directly to the Finder. While booting, and before the extension loading has completed, hold down the "P" and "L" keys. This will allow the Pippin boot process to fall through and the boot to continue onto the Finder. If you have an alias in the Startup Items folder, the Finder will still attempt to launch the title in the Startup Items folder. This method will not work on shipping systems since the Finder on those machines is not a real Finder, but is another copy of PippinFinder.

Pippin Standard File

Introduction

When developing titles for the Pippin Power Player, many assumptions about storage that are typically made in the Macintosh environment must be slightly altered. Unlike a Macintosh, Pippin does not have a hard disk and the only guaranteed storage media available is 128k of internal NVRAM (non-volatile random access memory). An optional floppy disk drive could be installed as well, but this should not be assumed. Of the 128k built-in NVRAM, 8k is used by the system software, leaving 120k for general purpose storage. Obviously, assumptions made about file storage while working with virtually unlimited hard disk space are very different than working with a limited and relatively small amount of storage.

The following sections offer specific considerations for developers to keep in focus while developing new titles so they will be able to work effectively within Pippin storage limitations. In general, however, developers should build their titles with the intention of eliminating unnecessary storage, or saved data. With such a small amount of storage, utilizing available NVRAM as efficiently as possible is critical.

Non-Volatile RAM (NVRAM)

The internal NVRAM is represented as a small HFS (Hierarchical File System) volume. By small HFS, this means that only two levels of hierarchy is allowed: the first level being the root level, the second level being folders appearing at the root level. In fact, within Pippin's NVRAM, folders can only appear at the root level, and no other folders are allowed within those folders. Nonetheless, despite this limited hierarchy, all normal file manager calls will treat NVRAM as a normal HFS disk.

Single Folder Per Title

In order to reduce confusion, it is strongly recommended that developers save all files, preferences, and any other data in a single folder at the root level of either the NVRAM or a floppy disk. This folder would have a name closely related to the title name, and a name that would be included as a string resource. The title-named folder will provide organization for the user, and further simplify tasks such as copying, moving, and deleting files that are associated with particular a title.

Preference Files

On the Macintosh, Preferences files are stored in the System Folder of the start-up disk. Since Pippin boots from a CD-ROM, dynamic Preferences files cannot be stored there. Therefore, if a title needs a writable Preferences file, it is suggested that the Preferences file also be stored in the title-named folder (see section 3). By ensuring that the Preferences file is of type "pref':" it does not also need to be displayed to the user.

Pippin Standard File

Since the target audience for Pippin is not always computer users, the Macintosh Standard File is unnecessarily complex. New system software that simplifies the Standard File interface is provided on Pippin. Still, the new calls in the Pippin Standard File behave in a similar fashion to the Macintosh Standard File, and the main differences between the two is that the Pippin Standard File has larger colored icons, no "New Folder" button, and no "Desktop Button."

There are several new Pippin Standard file functions described in Pippin.h. PippinStandardGetFile, PippinStandardPutFile and PippinStandardDeleteFile are the three main functions:

pascal void PippinStandardGetFile(FileFilterProcPtr filefilter
	short numTypes,
	SFTypeList typeList,
	StandardFileReply *reply);

pascal void PippinStandardPutFile(ConstStr255Param prompt
	ConstStr255Param defaultName,
	StandardFileReply *reply);
pascal OsErr PippinStandardDeleteFile(long *bytesRequested);

PippinStandardGetFile and PippinStandardPutFile in the Pippin Standard File work the same as StandardGetFile and StandardPutFile in the Macintosh Standard File. PippinStandardDeleteFile, however, is a new call in the Pippin Standard File which was created so files may be deleted while a title is running. This call does not allow copying or moving of files though. These tasks should be accomplished with the Pippin Navigation CD, which is included with each shipped Pippin unit.

The Pippin Standard File calls the title-named folder that is also specified in the "pipn" resource.

Pippin Launch

Introduction

The PippinFinder Technical Note describes the "replacement" Finder file for the Pippin System Folder, and that the actual code that drives a multiple application-interface is inside the Pippin Launch file. Apple provides an initial interface, a simple button interface, with the buttons changing appearance when they are selected. In summary, Pippin Launch is the file that PippinFinder uses, and this document is describing the "PCde" resource that Apple provides for developers to use. If you wish functionality beyond what PCde code implements, you will need to write your own code module. (See the "PippinFinder" Technical Note for details on how to create your own code module.)

Note: If you have a single-title CD and do not want to use a multiple-application interface via PippinFinder, you must ensure that the Pippin Launch file is removed from your System Folder on your Pippin CD. If not removed, you could cause problems with the boot process. The PCde module allows developers to easily customize the visual appearance of the Pippin startup environment when a Pippin CD is booted. The PCde module will only use the 2Meg provided to it via the PippinFinder. This is not of concern since it will all be disposed of before the title is launched.

To distinguish between the Apple provided PCDe module, and potential PCDe modules that may be created by developers, throughout the rest of this document, the Apple provided PCDe will be referenced as "ApplePCDe".

PCde Interface Philosophy

The Launcher presents the user with a single window that contains a background picture and an arbitrary number of buttons.

The background can be a PICT of any size, although it is recommended that the PICT be 640 x 480 pixels in size so it will completely fill Pippin's screen, much like the Macintosh "desktop". If the PICT is not big enough to fill the entire screen, the remaining area will be filled with the black.

Each button is a rectangular PICT of any size. There are as many as three PICT resources associated with each button:

  • one for the button that is un-highlighted
  • one for the button that is highlighted (used when the mouse is within the button rectangle if the resource is present)
  • one for the button that is in a "pressed" state (used when the user presses the mouse button when the mouse is within the button rectangle).

Each of these buttons should be the same pixel dimensions. Each, when present, are displayed at the coordinates of the button which are specified separately.

The behavior of the window is that, whenever the mouse is found to be within any of the buttons, the button's "highlighted" graphic is displayed (if it exists). If a "mouse within" sound exists, it is played as soon as the mouse is detected within the button rectangle. If the mouse leaves the highlighted button, the button's un-highlighted button graphic is again displayed. No mouse actions other than positioning movement is required by the user to get either graphical and audible feedback.

Launcher Resource Overview

The resource fork of the Pippin Launch file contains all the data used by the ApplePCde. This includes all graphics and sound data, as well as small descriptive resources which tell the Launcher where to display buttons, how to highlight them, what sounds to play, etc. These resources can be edited with the resource editor ResEdit 2.1.3 (or higher) utility to create a custom launching environment for Pippin CDs.

There are only two types of resources that need to be created:

  • a single "background" resource (i.e., pbkg)
  • some number of "button" resources (i.e., pbtn)

The following sections describe these resource types in more detail. Included in the resource fork of the Pippin Launch file on the Pippin Developer SDK CD are ResEdit "template" resources which simplify the creation of the background and button resources.

The Background Resource

The background resource, pbkg, tells the Launcher which PICT resource are to be the background picture for the launcher's window. It also tells the Launcher which sound, snd, should be played when the Launcher first starts up. Only one pbkg resource should be present in the Launcher resource fork.

The contents of the pbkg resource are as follows:

Background PICT id - This is the resource ID of a PICT resource that is the background picture for the Launcher window. The dimensions of the PICT are used to set the size of the Launcher window.

Background PICT handle - This is used at runtime to hold a handle to the background picture and should not be filled in by the user. Reserved

Startup snd id - This is the resource ID of a snd resource. The sound, if specified, is played when the launcher starts up and can be used to play introductory music or instructions. Set this to zero if you don't want to use a startup sound.

Button Resources

There can be any number of button resources present (i.e., any number of the resource pbtn). Each describes where a button is placed in the window, whether it is a hot highlighted or un-highlighted graphic, whether it is a "pressed" graphic, and what sounds should be played for the "mouse entering the button" and "mouse pressing the button" events.

The contents of the pbtn resource are as follows:

Button rectangle - This is used to specify the top left coordinates of the position of all button art for the button. The bottom and right members of the rectangle are ignored by the Launcher and are calculated using the size of the button PICT. Only the top and left fields are necessary. Required

Button PICT id - This is the resource ID of the PICT for the un-highlighted, or normal state, of the button. Required

Button PICT handle - This is used at runtime and should not be filled in by the user. Reserved

Highlighted button PICT id - This is the resource ID of the PICT for the highlighted state of the button. This PICT, if specified, is displayed whenever the mouse is determined to be within the button rectangle. Optional

Highlighted button PICT handle - This is used at runtime and should not be filled in by the user. Reserved

Button pressed PICT id - This is the resource ID of the PICT for the pressed state of the button. This PICT is displayed when the mouse button is pressed and is within the button rectangle. Optional

Button pressed PICT handle - This is used at runtime and should not be filled in by the user. Reserved

Mouse within snd id - This is the resource ID of the sound ("snd') resource that is played whenever the mouse enters the button rectangle. Optional

Mouse within snd handle - This is used at runtime and should not be filled in by the user. Reserved

Launch object type - The value of this field specifies what the ApplePCde should do with the file specified by the "App or doc filename" field when the user presses the mouse button while the mouse is within the button rectangle. Required

  • Values for this field are as follows:
    • 0 - no action; ignore the "launch object" file
    • 1 - launch object is an application file
    • 2 - launch object is a document file

App or doc filename - This field contains the full HFS pathname of an application or document and generally is the action that is performed when the user presses the button. Applications and documents are simply launched.

If this field is left empty, ApplePCde will take no action when the user presses the button. It is crucial that you get this field name correct, any errors in the path name could result in a hang of the OS or a crash.

Customizing ApplePCde

This section describes a step-by-step process for creating custom ApplePCde resources.

  1. Make a copy of the Pippin Launch file so that you do not modify your original. It will be easier to "start over" or begin a new project if you keep an unmodified copy of Pippin Launch on hand.
  2. Prepare your Pippin Launch art and sound files. This may be done using any tools which can create Macintosh PICT and snd data. Many Macintosh graphics programs can save graphics in PICT file format. However, the ApplePCde requires all data to reside in its "resource fork".

Some programs, such as Adobe Photoshop, permit graphics to be saved directly as a PICT resource file. This can simplify your work. Otherwise, you can create graphics and use the Clipboard to copy and paste them directly into the Pippin Launch resource fork using ResEdit.

Sound resource data can be created using the Macintosh microphone or with A/V sound input capabilities. Most likely, for high quality audio, the microphone will not be used. However, it can be useful to "prototype" your sounds with the microphone using the resulting low quality sound as place holders for your final data.

Creating Launcher Art

The first step is to choose your background art. The graphic should be a full screen image (640 x 480 pixels) so as to cover the Pippin TV screen. If you have a fully rendered scene, you may only need to cut rectangles out of the background (like a cookie cutter) in order to form your un-highlighted button art. However, button art can be anything you like, even something totally unrelated to the background.

Once you have chosen your background picture, save it as a PICT resource so that you can import it later using ResEdit. Alternatively, you can open the Pippin Launch file using ResEdit, and paste the PICT directly into the Pippin Launch's resources. If you do not have a graphics program that supports the creation of PICT resources, you will need to import your art this way.

Assigning PICT Resource IDs

When you paste a PICT into the Pippin Launch resource file, ResEdit assigns a number, called a resource ID, to the data. This number gives the picture a unique name amongst all PICTs in the file. You should assign a resource ID to each picture to help you recall which picture is which. You might choose to use a certain range of numbers for each of the button pictures so that it is easy for you to know which pictures are related to each other by their ID. For example, you might use the IDs 150, 151, and 152 for a button, its highlighted state, and its pressed state, respectively. You might use 160, 161, and 162 for another button. In this example, it's easy to tell which PICTs are associated with each other, and what each of them is by looking at the resource ID. While this methodology can help you keep things organized, it is not required.

Button Rectangles

Whether you decide to use the "cookie cutter" method mentioned earlier for making buttons from a fully rendered scene, or some other method altogether, you will need to gather some precise information about the placement of the button art work. If you are cutting buttons out of a background, you will want to use a graphics program that can tell you the XY position of the rectangular patch you copy from the background. This information must be entered into the button rectangle field of the pbtn resource, each of which is used to store button information. This information must be transcribed exactly or the button will not be drawn in the correct position.

Making Highlighted Buttons: An Example

Once you have cut out buttons from a background, or other source, you may wish to make a graphic for the button's highlighted state. This will be displayed whenever the user's mouse pointer is within the rectangle of the button. This is a form of "hot highlighting" that can be used to indicate that a button exists in an area of the screen. This art is optional. If it is not present, the button will not appear different when the mouse is "over" it.

One technique for making highlighting button art is to begin with a copy of the original button art. Using Adobe Photoshop, for example, you can form a selection area around the edges of whatever graphic element is prominently considered as the button. Invert the selection, and then use an airbrush tool to make a colored halo around the art. This technique can be used to create the appearance of highlights of arbitrary shape and color.

Similar techniques can be used to make "button pressed" art. Keep in mind, though, that the art for the button, its highlighted state, and its pressed state do not have to be related to each other. In fact, a completely different graphic for each state may be appropriate, depending on the "look" you are trying to create. For example, you might use a person's face as the button, the same face with raised eyebrows for a highlighted state, and the same face with an open eyed, open mouthed expression for the pressed state.

Using Sound

Sounds can be used to augment the Launcher's behavior. You can use a "startup sound" that is played when the Launcher first starts, perhaps playing a musical theme or an introduction to your product: "Welcome to XYZZY...". Sounds can also be played whenever a user puts the mouse pointer over a button. This can be useful as a audible prompt to "try pressing me", for example, or as something instructional about what will happen if the button is pressed.

Launcher sounds are loaded into memory, so whatever you decide to use must fit into Pippin's memory. You can economize, for example, by using the same sound for all button presses.

To use a sound, simply "paste" it into the Launcher resource file using ResEdit, and assign the sound's resource ID to one of a button's functions by typing in the sound's resource ID into one of the "snd ID" slots of a button: mouse within, button pressed.

Launch Object

A launch object determines what happens when the user presses a given button. There are three possible actions:

  • do nothing
  • launch an application
  • open a document

The action of "do nothing" seems likes it is not very useful. However, you can use these types of buttons to play audible instructions by simply associating the appropriate sound resource with the button press. If the user presses the button, some instructions are played out loud, but no other action is taken.

The next two actions, launching an application and opening a document, are self-evident as to what they do. You would use launch a document to open authored files, such as HyperCard stacks. For a stand-alone application, you would simply launch an application. Of course, if there is only one application on your CD, you would probably just want to launch it directly as described in the "Pippin Startup Process" Technical Note and it is not necessarily for you to use PippinFinder or the Pippin Launch mechanism.

Customizing PCde Code

While the source code is currently not provided for the ApplePCde resource, it is simple enough for a developer to write his own PCde in C or Pascal (Actually in any language you want as long as it is able to support Pascal calling conventions at its entry point).

Memory Utilization

When PippinFinder calls to the existing PCde module, it has created a 2Meg handle in temporary, initialized a heap into it, and set the current zone to that newly allocated memory. Since control is maintained by the code module until a launch selection is made, the heap remains valid till control is passed back to PippinFinder. When PippinFinder regains control, the heap is disposed and the specified FSSpec is launched.

Use of Temporary Memory

When launching applications, Macintosh system software creates a heap zone in the "Multifinder heap" based on the "SIZE" resource information (familiar to users as the Finder's "Get Info" information about an application icon). All resource and other memory allocation takes place within that heap zone unless the application software takes explicit steps to manage memory in other ways. Most applications are designed to simply use their own application heap.

Beginning with System 7.0, application programming interfaces for the use of so called "temporary memory" were made public. Temporary memory is simply memory allocated from the Multifinder heap, the same heap used for application heap allocation. As such, programmers were directed to not use temporary memory for extended periods of time because it could cause the Multifinder heap to become fragmented and, thus, prevent applications from launching due to the lack of appropriate contiguous free space.

Since Pippin is intended primarily as an multimedia playback appliance, however, PCde developers are encouraged to use temporary memory if their memory needs exceed the 2Meg heap provided to them. Since PippinFinder does not know about the temporary memory being used by the PCde module, the module must make the effort to release all used memory in this area before returning code to PippinFinder.

PippinFinder

The PippinFinder file is only to be used with CDs that have a multiple-application interface. Since most titles developed for Pippin will involve only a single application launched immediately at start-up, the PippinFinder file is not used and therefore should not be placed in the System Folder. Even with multiple application titles, the PippinFinder does not provide the interface for launching the applications within a title CD; the interface is provided by a Pippin Launch file.

The PippinFinder file, when used with multiple-application titles, is used to search and find the Pippin Launch file. The Pippin Launch file contains a resource of type PCde with an ID of zero. When launching, the PCde code resource is loaded and executed, and thus provides an interface for multiple application selection.

The API for the Pippin Launch code module is as follows:

    pascal OSErr PippinCode(FSSpecPtr fileToLaunch, Boolean* restart);

The PippinCode module works in that when it is called, it expects to returned an FSSpec in the FSSpecPtr. Another varred parameter, called shutdown is used to let PippinFinder know that the code module, as requested by the user, wants to restart the machine.

With version 1.0 of PippinFinder, a return of any error will result in PippinFinder hanging in an endless loop. By returning an invalid FSSpec will also result in PippinFinder hanging in the same loop. It is therefore vital that the code module does adequate error checking.

To help limit memory leaks before the code module is called, a heap of 2Meg is created in temporary memory space and a zone is initialized there. If you need more memory, use additional temporary memory space. When returned from the PippinCode module, the handle which contains the 2Meg code module is released.

This describes the total functionality of PippinFinder. Apple is also providing a PippinCode module that will be described in a separate Pippin Technical Note. For functionality beyond what Apple's PippinCode provides, developers are directed to write their own PCde code modules.

Stopping INIT Icons

The Pippin OS frequently includes extensions such as QuickTime and Applejack. Extensions almost always draw an icon when loading, which is what produces the row of icons across the bottom of the screen when the system is booting. The Pippin user experience though should not include such computer specific messages. The user probably will not even know what QuickTime is. Therefore, developers should stop the drawing of icons during the boot process for Pippin CDs.

Stopping an icon from drawing on the screen at boot time is relatively easy. Just erase its mask with ResEdit and QuickDraw won't draw it. This procedure shows how to prevent QuickTime from drawing its icon but the process is the same for all extensions.

 

 

Note: A few extensions draw 'cicn's rather than the 'ICN#' resources shown here. The rule is: Open the icon that is drawn at boot time. You will just have to try this, and if the icon stil shows up, look for another icon that you may have missed.

Click on the mask, then use the eraser tool to erase the entire mask. Finally, close and save the extension.

 

Creating Pippin CD-ROMs

Introduction

All CD-ROM titles to be played on Pippin Power Players must be "Pippinized" in order to successfully run on a Pippin. This technical note describes the hardware, software, and procedures required to make Pippin-ready CD-ROMs though either modification of already released CD-ROM titles, or in initializing a brand new CD-ROM title.

Required Equipment

Ensure that all required equipment, either hardware or software, is readily at hand before beginning the CD-ROM "pippinizing" processes. Do not begin these procedures if you do not have all equipment immediately available.

Hardware

The following hardware is required to complete these procedures:

  • Power Macintosh 6100/66 or higher. AV Power Macintosh models are optional.
  • external hard drive with a minimum of 200MB
  • CD-ROM duplicating device (e.g., Yamaha CDR-100 or any other duplicating device). 4x speed duplicating device models are recommended, although lower speed devices will work as well.
  • SCSI/SCSI connectors short extender cable
  • SCSI/SCSI-2 connectors short extender cable
  • SCSI connector terminator
  • SCSI-2 connector terminator
  • Pippin Power Player testing unit with external SCSI connector cable
  • Applejack controller
  • TV monitor
  • Blank CD-R disks (preferably gold dye type)

The following hardware is optionally required to complete these procedures:

  • keyboard and adapter cable
  • external memory card, if needed for development.
  • AV cable +/- S-video cable
  • modem
  • printer
  • network cables or other necessary networking hardware

Software

Ensure that the following software is readily available before beginning this procedure.

Note: All software versions listed are minimum levels; higher levels are also acceptable.

  • System 7.5.1 (or higher) must be installed on the Power Macintosh.
  • CD-ROM drivers are packaged with System 7.5.1. Specifically, the following extensions must be present on the Power Macintosh before beginning this procedure:
    • Apple CD-ROM
    • Apple Photo Access
    • Audio CD Access
    • Foreign File Access
    • High Sierra File Access
    • ISO 9660 File Access

Note: In general, it is best to have the latest CD-ROM drivers installed on your Power Macintosh. If using System 7.5.1, install Update 5.1.1. If using System 7.5.2 or later, Update 5.1.1 is not necessary.

Note: If using enhanced multimedia CD formats, ensure that you have the appropriate additional CD driver extensions installed.

  • CD-ROM duplicating software, such as Toast CD-ROM Pro(TM) 2.5.6.
  • SCSIProbe 3.5 (shareware) or any other volume mounting utility.
  • ResEdit 2.1.3 or any other resource editing application.
  • Hard Disk formatting application, such as Hard Disk Tool Kit(TM) 1.75 by FWB or APS PowerTools(TM) 2.8.1.
  • Pippin System Folder (available from Pippin SDK).
  • Demo or application software to be installed.
  • Authentication software, if necessary. (See "Authentication" Technical Notes.)
  • AppleJack 2.2.0 application and system extension if customizing the Applejack Controller (available from Pippin SDK). (See "Applejack Input Device Driver" Technical Notes).

Setting Up

The following subsections provide a step-by-step procedure to make "Pippin-ready" CD-ROMs.

Note: Do not skip steps! Work carefully to ensure that the specified procedure is properly implemented.

Hardware Configuration

Configure the Power Macintosh, external hard drive, and CD-ROM duplicating device as follows:

  1. Set SCSI ID on the external hard drive to an unused value other than existing SCSI IDs (i.e., typically, a Power Macintosh's internal hard drive has a SCSI ID set to "0"; the internal CD-ROM is usually set to "3"; the CD-ROM duplicating device can be set to "1").
  2. Using the SCSI/SCSI cable, attach one end to the back of the Power Macintosh; attach the other end to the external hard drive's SCSI connector.
  3. Using the SCSI/SCSI-2 cable, attach the SCSI end of the cable to the remaining SCSI connector on the external hard drive; attach the SCSI-2 end of the cable to the CD-ROM duplicating device.
  4. Place the SCSI-2 terminator on the open SCSI-2 connector on the CD-ROM duplicating device.

 

Preparing External Hard Drive

The external hard drive must be formatted or partitioned before beginning the "Pippinizing" procedure. Ensure that the following steps are carefully carried out. Do not skip any steps.

  1. Using SCSI Probe 3.5 (or higher) control panel, mount the external hard drive (i.e., first select "Update", then "Mount" to mount the external drive).
  2. Using Hard Disk Toolkit 1.75 (or higher), select the external hard drive ID from the listed SCSI IDs.
  3. Select "Format" to format the selected hard drive. When the application queries what type of partition is desired, select "Standard Partition" and highlight "Maximum Macintosh".
  4. Partition size should not be greater than 640MB, since writable CD-ROMs are that same size. Ideally, create a partition that is CD-ROM size.

Creating a "Pippin-Ready" CD-ROM

Follow the appropriate process in the following sections to create a "Pippin-ready" CD-ROM:

  • To modify an already released CD-ROM, follow the procedure in section 4.1.
  • To create a brand new "Pippin-ready" CD-ROM, skip to section 4.2, "Creating a New Pippin CD-ROM," on page 8.

Modifying a Released CD-ROM Title

Before beginning this procedure, ensure that all configuration steps as outlined in section 3, "Setting Up," have been completed. You cannot proceed with this procedure if any steps in section 3 and its subsections have been skipped.

1. Insert released CD-ROM in Power Macintosh CD drive.

2. Drag and drop the entire volume of CD-ROM title to newly formatted partition on the external hard drive.

Note: Do not use "Select All" to copy volume because hidden files could potentially be left behind in the copy process. By dragging and dropping, you are ensured that all files/folders and/or paths within the volume are duplicated to the partition.

3. Using ResEdit 2.1.3 (or higher), find any hidden files or folders within the copied volume, and make them visible on the external hard drive.

4. Rename the volume folder of the recently copied volume (in the partition) by adding "old" to the end of the volume name.

5. Press "Select All" files within the volume folder of the recently copied volume (in the partition).

6. Drag and drop all selected files to the "root level" of the partition (on external hard drive).

7. Rename the partition to the same title name as the original volume name.

8. Launch the title to test that the copy process was successful.

Note: Sometimes titles are developed with specific requirements of using a hard drive to launch. In such cases, use a utility such as DiskLocker 1.3 to lock your hard drive before testing the title. Launch the application from the "locked" hard drive partition. If the application still does not launch properly, you may want to recheck the development work of the title. Once the testing is successful, remember to "unlock" the hard drive before preceding.

9. Drag and drop old empty volume folder to the Trash.

10. Drag and drop Pippin System Folder into the title volume partition (available from Pippin SDK).

11. Ensure that the following minimum file set exists in the Pippin System Folder

 

Note: Although the Finder file is included in Figure 2, the Finder is not included in the license and should not be released with the Pippin end-product. Refer to sections 4.3.1 through 4.3.3 to see how and when to properly remove the Finder from your Pippin CD-ROM.

12. If any additional software, preferences, and/or extensions are needed to run the title (e.g., networking software, modem software, Applejack application and system extension, ADB device software, Pippin Launch, etc.), add them to the title volume partition at this time.

Note: If additional software needs to be installed with an Installer file, be sure to install the software onto the Pippin, and not the Power Macintosh, or else the System Folder components will not get installed.

13. Ensure that the Pippin System Folder is called "System Folder".

14. Create a new folder in the System Folder called "temp".

15. Drag and drop the PippinFinder file into the temp folder.

16. Unmount and shut down the external hard drive.

17. Attach the external hard drive to the Pippin test unit by connecting the available external SCSI cable to the hard drive.

18. Attach an Applejack controller to the Pippin test unit, or, optionally, attach a keyboard adapter and keyboard to the Pippin test unit.

19. Place a SCSI terminator on the extra SCSI connector slot on the external hard drive, if necessary.

20. Boot the hard drive with the Pippin test unit connected.

Note: If having difficulty booting the hard drive, restart the drive after adding a SCSI terminator.

21. Configure the title to run on the Pippin with the final Pippin configuration.

22. Launch the title on the Pippin to test all title capabilities. Expanded memory should not be used during testing of the title capabilities, and memory allocations should be efficiently used and kept to a minimum.

23. Test thoroughly.

Note: Do not skip the final testing step. Test all title capabilities. At this stage of the process especially, it is crucial to determine whether the title is going to work on a Pippin, or not. If the title does not work, then the developer must figure out why and how to make the title work before proceeding with this process.

24. Upon successful thorough testing, continue with "Front-End Interface Configuration".

Creating a New Pippin CD-ROM

Before beginning this procedure, ensure that all configuration steps as outlined in section 3, "Setting Up," have been completed. You cannot proceed with this procedure if any steps in section 3 and its subsections have been skipped.

1. Drag and drop all new title files from wherever they have been stored on the Power Macintosh to the "root level" of the newly formatted partition on the external hard drive.

2. Ensure that any hidden files have also been copied (use ResEdit 2.1.3 (or higher) in needed).

3. Rename the partition to coincide with the title name.

4. Launch the title to test that the copy process was successful.

Note: Sometimes titles are developed with specific requirements of using a hard drive to launch. In such cases, use a utility such as DiskLocker(TM) 1.3 to lock your hard drive before testing the title. Launch the application from the "locked" hard drive partition. If the application still does not launch properly, you may want to recheck the development work of the title. Once the testing is successful, remember to "unlock" the hard drive before preceding.

5. Drag and drop the Pippin System Folder into the title volume partition (available from Pippin SDK).

6. Ensure that the minimum file set shown in Figure 1 on page 4 exists in the Pippin System Folder (if not, contact Pippin development at [email protected]).

Note: Although the Finder file is included in Figure 2, the Finder is not included in the license and should not be released with the Pippin end-product.

7. If any additional software, preferences, and/or extensions are needed to run the title (e.g., networking software, modem software, Applejack system extension and application, ADB device software, Pippin Launch, etc.), add them to the title volume partition at this time.

Note: If additional software needs to be installed with an "Installer" file, be sure to install the software onto the Pippin, and not the Power Macintosh, or else the System Folder components will not get installed.

8. Ensure that the Pippin System Folder is called "System Folder".

9. Create new folder in the System Folder called "temp".

10. Drag and drop the PippinFinder file into the temp folder.

11. Unmount and shut down the external hard drive.

12. Attach the external hard drive to the Pippin test unit by connecting the available external SCSI cable to the hard drive.

13. Attach an Applejack controller to the Pippin test unit, or, optionally, attach a keyboard adapter and keyboard to the Pippin test unit.

14. Place a SCSI terminator on the extra SCSI connector slot on the external hard drive, if necessary.

15. Boot the hard drive with the Pippin test unit connected.

Note: If having difficulty booting the hard drive, restart the drive after adding a SCSI terminator.

16. Configure the title to run on the Pippin with the final Pippin configuration.

17. Launch the title on the Pippin to test all title capabilities. Expanded memory should not be used during testing of the title capabilities, and memory allocations should be efficiently used and kept to a minimum.

18. Test thoroughly.

Note: Do not skip the final testing step. Test all title capabilities. At this stage of the process especially, it is crucial to determine whether the title is going to work on a Pippin, or not. If the title does not work, then the developer must figure out why and how to make the title work before proceeding with this process.

Front-End Interface Configuration

Since there are many ways to configure a title's front-end interface, deciding on a strategy of how a developer wants the title to be launched is very important. The following subsections outline just three ways to configure titles' launching mechanisms. Of course, many other customized mechanisms will be attempted and are possible by engineers. However, a key point to note is that what works for one title will not always work for another title since each and every title is unique, and has very different requirements.

Use one of the following described interface configuration mechanism that best suits your title's needs, or design your own, with the understanding that such a chore may be far more time-consuming than may first seem to be.

Note: If you are unsure about which interface option to use, simply choose one and attempt it. If the final launch test fails, select an alternative option. If you exhaust all options, contact Pippin development at [email protected] with a description of your processes and problem.

Option: Launching Title with an "Alias" of Title

By using this interface configuration mechanism successfully, the title application will launch automatically upon inserting the CD-ROM title into the Pippin test unit.

Note: Some titles will not allow an "alias" to launch the title, thus requiring the developer to select another option.

1. Make an "alias" (press \xf0 m) of the title application file (located in the volume title partition of the external hard drive).

2. Drag and drop the alias file to the Startup Items folder within the System Folder.

3. Drag and drop the (Macintosh) Finder file and the temp folder to the Trash.

4. Rename the PippinFinder file to "Finder".

5. Open the new renamed Finder with ResEdit.

6. Under "File" in the Menu bar, select "Get Info for Finder", and a window similar to Figure 3 will appear.

Figure 3 : "Info for Finder" Window BEFORE Changes Are Made

 

7. Change Type from "APPL" to "FNDR" and Creator from "pfdr" to "MACS". Also, under "Finder flags", deselect "Has BNDL" and "Use Custom Icon", as shown in Figure 4.

Figure 4 : "Info for Finder" Window AFTER Changes Are Made

 

8. Close and save the new Finder file.

9. If any additional software, preferences, and/or extensions are needed to run the title (e.g., networking software, modem software, Applejack system extension and application, ADB device software, Pippin Launch, etc.), configure them at this time.

10. Configure hardware as desired (e.g., customizing Applejack controller, ADB devices, etc.).

11. Reboot the Pippin to test whether the title is automatically launched.

12. If the title launches upon reboot, retest all title capabilities. (If the title will not launch, proceed with another interface configuring option.)

13. Test thoroughly.

Note: Do not skip the final testing step. Test all title capabilities.

14. Upon successful thorough testing, continue with section 5, "Final Steps: Pressing the Newly Pippinized CD-ROM," on page 15.

Option 2: Launching Title with Application in "Startup Items"

By using this interface configuration mechanism successfully, the title application will automatically be launched upon inserting the CD-ROM title into the Pippin test unit.

Note: Some titles will not allow the application file to launch from a location other than the "root" on the volume; thus requiring the developer to select another option.

1. Drag and drop the title application file to the Startup Items folder within the System Folder.

Note: This mechanism will not work if your title requires other components to also be in the Startup Items folder within the System Folder.

2. Drag and drop the PippinFinder file from the temp folder to the System Folder.

3. Drag and drop the (Macintosh) Finder file and the temp folder to the Trash.

4. Rename the PippinFinder file to "Finder".

5. Open the new renamed Finder with ResEdit.

6. Under "File" in the Menu bar, select "Get Info for Finder", and a window similar to Figure 5 will appear.

Figure 5 : "Info for Finder" Window BEFORE Changes Are Made

 

7. Change Type from "APPL" to "FNDR" and Creator from "pfdr" to "MACS". Also, under "Finder flags", deselect "Has BNDL" and "Use Custom Icon", as shown in Figure 6. Figure 6 : "Info for Finder" Window AFTER Changes Are Made

 

8. Close and save the new Finder file.

9. If any additional software, preferences, and/or extensions are needed to run the title (e.g., networking software, modem software, Applejack system extension and application, ADB device software, Pippin Launch, etc.), configure them at this time.

10. Configure hardware as desired (e.g., customizing Applejack controller, ADB devices, etc.).

11. Reboot the Pippin to test whether the title is automatically launched.

12. If the title launches upon reboot, retest all title capabilities. (If the title will not launch, proceed with another interface configuring option.)

13. Test thoroughly.

Note: Do not skip the final testing step. Test all title capabilities.

14. Upon successful thorough testing, continue with "Final Steps: Pressing the Newly Pippinized CD-ROM".

Option 3: Pippin Launch

By using this interface configuration mechanism successfully, a custom user interface is modified according to the requirements of the title.

1. Reconnect the external hard drive to the Power Macintosh following the steps defined in "Hardware Configuration".

2. Drag and drop the Pippin Launch file to the System Folder (available from Pippin SDK).

3. Drag and drop the PippinFinder file from the temp folder to the System Folder.

4. Drag and drop the (Macintosh) Finder file and the temp folder to the Trash.

5. Duplicate the PippinFinder file (press \xf0 d).

6. Rename the PippinFinder copy file to "Finder".

7. Open the new renamed Finder with ResEdit.

8. Under "File" in the Menu bar, select "Get Info for Finder", and a window similar to Figure 7 will appear.

Figure 7 : "Info for Finder" Window BEFORE Changes Are Made

 

9. Change Type from "APPL" to "FNDR" and Creator from "pfdr" to "MACS". Also, under "Finder flags", deselect "Has BNDL" and "Use Custom Icon", as shown in Figure 8.

Figure 8 : "Info for Finder" Window AFTER Changes Are Made

 

10. Close and save the new Finder file.

11. If any additional software, preferences, and/or extensions are needed to run the title (e.g., networking software, modem software, Applejack system extension and application, ADB device software, Pippin Launch, etc.), configure them at this time.

12. Configure hardware as desired (e.g., customizing Applejack controller, ADB devices, etc.).

13. Double-click on Pippin Launch file.

14. Use ResEdit 2.1.3 to configure Pippin Launch as desired. (See "Pippin Launch" Technical Note)

15. Launch the title on the Pippin to test all title capabilities.

16. Test thoroughly.

Note: Do not skip the final testing step. Test all title capabilities.

Final Steps: Pressing the Newly Pippinized CD-ROM

Assuming that all steps in proceeding sections have been properly followed, you may begin the final steps: the pressing of the newly Pippinized CD-ROM.

1. Inactivate AppleTalk on the Power Macintosh.

2. Disable networking on the Power Macintosh (i.e., LocalTalk should be selected).

Note: Disabling networking connections is crucial to do before continuing this procedure. Networking interruptions will interfere with the CD-ROM mastering process.

3. Reconnect the external hard drive to the Power Macintosh following the steps defined in "Hardware Configuration".

4. Insert a blank, unused, unpressed gold dye type CD-R disk into the duplicating device.

5. Launch Toast CD-ROM Pro 2.5.6 (or higher).

6. Ensure that "Macintosh HFS CD-ROM" (or "Mac Volume" for higher versions of Toast CD-ROM Pro) is displayed in the Toast application window. If not, select "Macintosh HFS CD-ROM" from the "Format" menu.

7. Click on the "Data..." button.

8. Select title volume from the displayed list of volumes.

9. Ensure that the "Bootable" option is tagged on the bottom of the displayed window.

10. Ensure that both CD writer and CD is tagged for synchronized speed from the "Recorder" menu and specifies either 4x or 2x, depending on the CD-ROM duplicating device.

11. Click on the "Search..." button to ensure that the Power Macintosh is seeing the CD-ROM duplicating device. (If not seen, double check all SCSI connections.)

12. Click on the "Write CD..." button to write to the blank CD-ROM.

13. Click on the "Write Disk..." button from within the next window.

14. The CD-ROM pressing begins. The time to press a CD-ROM varies anywhere from 2 to 60 minutes or more (largely dependent on the speed of the CD-ROM duplicating device).

15. Using the newly pressed CD-ROM, conduct a final test on the Pippin testing unit using the new CD-ROM to launch the title.

16. Test thoroughly.

Note: Do not skip the final testing step. Test all title capabilities. If errors are found, redo the process and press another CD-ROM.

Flash Access

The Flash Access chip is a writable FlashROM chip with a 120K maximum capacity located on the Pippin main logic board. Since the Pippin does not have a hard drive to store information, and external storage devices cannot be assumed to always be present, a developer has very limited space to work with. Developers must therefore recognize the storage limitations of the Flash Access chip, and plan their titles accordingly.

Flash storage will appear to a developer just like a standard Macintosh volume. To work within the limitations of this chip, title developers are encouraged to keep their "save game" options and memory storage requirements to a minimum. All design considerations and/or enhancements should be made with storage requirements clearly planned for.

If within the design of a title, users are encouraged to keep their storage space clean, performance problems with storage will be kept to a minimum. If users are provided with these guidelines up front, many users will have little difficulty playing within this limited space. Without these guidelines clearly stated, or automatically managed within the title's design itself, memory storage dilemmas will inevitably be incurred.

Developing efficient memory usage titles for Pippin is critical to the ultimate success of the title on the Pippin. Titles continually running into memory barriers obviously are going to take a big hit with popularity ratings as well.

Pippin Authentication

Introduction

In order for Pippin CD-ROMs to run on a Pippin Power Player, they must first go through a Pippin authentication process. The authentication process is about applying an Apple-approved RSA signature, in the form of an electronic encrypted key, onto a Pippin CD-ROM.

RSA's Authentication Software Library

Apple has licensed RSA for their public key authentication software library. The foundation of this library is non-reversible (i.e., one-way) mathematical algorithms based on using large prime numbers as keys to encrypt messages. With RSA's public key authentication system, keys are generated in pairs. One key is held privately by its owner, and the other key, the public key, is given out to be used by others to decrypt the owner's generated "keyed" messages. Public keys cannot be interchanged or swapped, and a message encrypted with a private key can only be decrypted with its corresponding matching public key.

Encrypted messages make very good electronic signatures since they can only be decrypted by a public key which is registered to a specific person (or company). Knowing a person's public key, however, will never offer any clue as to what that person's private key might be. Since only private keys can create an encrypted message, the system is secure.

Authenticating a Pippin CD

For Pippin, the "message" to be encrypted is the entire contents of the CD. Since this typically is a lot of data, and the algorithms are slow, the CD contents are first "digested" by a hashing algorithm which produces a small digest of the CD contents. The digest later can be used to test that the current CD content matches what it was when the digest was first created and than signed (encrypted).

To create a Pippin-authentic CD requires two sets of key pairs. Each authorized CD stamping house has a public pair and private pair. Apple also holds both a public pair and private pair. Apple's private key is on a computer locked inside a safe which is connected to an internet mail system. Apple's public key is inside every Pippin ROM. The stamping house's private key is inside a "digesting" program at the stamping house and their public key is on file with Apple inside the safe.

The authentication process steps are as follows:

1. An authorized CD stamping house digests the CD content, then signs the digest (on the CD) by encrypting it with their private key.

2. The stamping house then emails the signed digest encrypted with their private key to Apple's computer in the safe.

3. Apple's "safe" computer unsigns the digest using the stamping house's public key, and then re-signs it using Apple's private key.

4. The digest, which has now been effectively signed by Apple's private key, is then e-mailed back to the stamping house.

5. Back at the stamping house, a program is run to apply the signed authentic digest onto the CD.

Figure 1 illustrates the flow of the Pippin authentication process.

Figure 1 : The Pippin Authentication process

 

Through this process, private keys never have to be revealed to anyone and the only data which leaves the owner's facility, via e-mail, is encrypted with a private key.

After the stamping house applies the signed authentic digest to the CD, the CD is Pippin-authentic. During the boot process, the Pippin ROM creates a temporary digest using the same algorithm as was used to make the original, then unsigns the digest on the CD to compare the two. Only an exact match will allow the boot process to continue.

Note: Pippin disks are not exactly encrypted since they still will mount on a Macintosh just fine. However, the still have a signature applied to them which can be read and tested.

Applejack Input Device Driver

Introduction

The Pippin input device, Applejack, is a custom ADB device containing trackball information and a series of 18 button states. The Applejack driver resides in the Pippin ROM and loads at system boot time. On a Macintosh, the Applejack driver resides in the system extension file.

The Applejack driver uses a 'pipp' button mapping resource which allows any Applejack button to be mapped with either a mouse button or keyboard key function. The trackball data, however, is always treated as a "mouse" and there is no provision for remapping it.

While provision for default button mapping is provided, applications can also include a custom 'pipp' resource for setting button functions. On Pippin ROMs, a custom 'pipp' resource would be loaded automatically when an application is launched. For applications that do not use mouse or keyboard mappings (not highly recommended), the Applejack raw data is directly readable from the driver.

Setting Up

The Applejack Software Developer's Kit diskette contains the application for editing the 'pipp' mapping resource, and an system extension file.

  1. From the SDK diskette, copy the application file to your Macintosh hard drive.
  2. Drag-and-drop the system extension file to the "Extensions" folder in your System Folder.
  3. Ensure that the Applejack input device driver(s) are plugged into the ADB jack adapter(s) on the backside of your Macintosh.
  4. Restart the Macintosh to initialize the system extension file.

You are now ready to customize the Applejack input device driver.

Customizing the Applejack

There are two ways to customize the 'pipp' mapping resource of the Applejack input device driver(s).

The simplest way involves using the application as an interface for redefining device button mapping. This mechanism is as simple as aligning an attached Applejack device (or possibly, unattached Applejack device, as the case may be) with a visual device on the Macintosh screen. By clicking on the on-screen buttons, a developer customizes an Applejack device(s).

The second way involves modifying the 'pipp' mapping resource code files manually, specifically defining how the button mechanisms on the device(s) should work.

The Applejack Control 2.2.0 Application

The application is the interface used for editing the 'pipp' mapping resource. Double-click on the application icon and a window similar to Figure 1 will appear.

Figure 1 : Applejack Control 2.2.0 Application Launch Window

 

If the application does not find any Applejack device(s) physically connected to the bus, the window displays a "NO GAME PADS FOUND" message across the window instead, as follows.

Figure 2 : NO GAME PAD FOUND Window

 

Regardless of whether an Applejack device(s) is connected or not, the button settings may be edited. By clicking on desired buttons, a developer can customize the Applejack device(s).

A dialog box similar to Figure 3 or Figure 4 appears, depending on the button clicked on.

Figure 3 : Applejack Control 2.2.0 Dialog Box--Customizing Keyboard Key Functions

 

When defining specific keyboard keys, select the "Keyboard Key" option, and press the key desired, which will appear in the character fill-in box. Also, modifiers can be designated (click on appropriate box) with a specific keyboard key, if desired. Then, click on "Ok" to proceed.

When defining mouse button functions, click on the appropriate "mouse" functions, as desired, then click on "Ok" to proceed.

Figure 4 : Applejack Control 2.2.0 Dialog Box--Customizing Mouse Button Functions

 

By clicking "Ok" after defining each button, the Applejack driver's local data is updated. If an Applejack device is attached, the newly defined button functions can be tested immediately with the newly "customized" Applejack device(s).

By quitting the application, the 'pipp' resource within the system extension file is updated. If you would like to write the 'pipp' resource into a separate file, use the "File:Make Resource..." menu item.

Applejack Default Button Settings

The Driver in the Pippin ROM creates default settings for the Applejack buttons if there is no Applejack extension installed. The default Applejack button settings are as follows:

 

Modifying the 'pipp' Button Mapping Resource

Alternatively, 'pipp' resources can be built and keys (functions) remapped by looking at the driver's global data. Figure 5 illustrates the Applejack Input Device Driver and its corresponding button mapping.

Figure 5 : Applejack Input Device--Button Mapping

 

The 'pipp' resource is identical to the driver's global data and is a structure of type AJGlobalData. This global data is pointed to by the .refCon field of the Cursor Device Manager record for each Applejack device, as defined in the following code.

typedef struct SwitchData {
	Byte    function;
	Byte    modifiers;
	Byte    keyCode;
	Byte    charCode;
} SwitchData, *SwitchDataPtr;

typedef struct AJGlobalData {
	long    signature;
	Byte    MyTalkR0;
	Byte    handlerID;
	Byte    ourMBState;
	Byte    ourLockState;
	long    switchStates;
	SwitchData      switchMappingArray[18];
	long    nextjADBProc;
	long    cursorHandler;
} AJGlobalData, *AJGlobalDataPtr;

Most notably in the above code is the signature. The driver installer has initialized the signature to equal 'pipp' so that applications can look through the ADB device table and find this structure. Further, the function field of the SwitchData switchMappingArray is defined as follows:

enum {

	kNothing 	= 0,    // maps to nothing
	kMouse  	= 1,    // maps to standard mouse button operation
	kMouseDblClick	= 2,    // maps to mouse button double click
	kMouseLock	= 3,    // toggles the mouse button state
	kKeyboard	= 4,    // maps to a keyboard key
	kFrontPanel	= 5,    // not used
	kModifier	= 6     // maps to a modifier key
};

Each element of the switchMappingArray array represents one of the switches on Applejack. The array index is equal to the bit numbers, as shown in Figure 6.

Figure 6 : ADB Register 0 Four-Byte Packet and Bit Number to Button Mapping

 

If a button is mapped as kKeyboard, then the Applejack driver posts a keyDown event with the .keyCode, .keyChar and .modifiers fields in the event record.

The following code shows an enumeration of equates for the .modifiers field.

enum {
	kCommandBit	= 0,
	kShiftBit	= 1,
	kCapsLockBit	= 2,
	kOptionBit	= 3,
	kControlBit	= 4
};

If a button is mapped as kModifier, then the Applejack driver sets the keyMap global for the keyCode specified in the .keyCode field. The other fields are ignored in this case.

The following code is another enumeration of equates for the .modifiers field.

enum {	
	kCommandKey     = 0x37,
	kShiftKey       = 0x38,
	kCapsLockKey    = 0x39,
	kOptionKey      = 0x3A,
	kControlKey     = 0x36
};

To change the mapping of a button, map a pointer to the AJGlobalData structure, then put in new values for the .switches fields for the desired switch. A good reason to do this would be if you wanted to read the Applejack raw data but did not want a button to also be generating system events.

The following code maps a pointer to the AJGlobalData structure for each connected Applejack, and then changes the selected switch.

void ChangeSwitchMapping (short whichSwitch, short function, short modifiers,
short keyCode, short charCode);

void ChangeSwitchMapping (short whichSwitch, short function, short modifiers,
short keyCode, short charCode);
{
ADBAddress		address;
ADBDataBlock		dataBlock;
AJGlobalDataPtr		myAJ;
CursorDevicePtr		myCrsrDev;
short	       					index,i;

//We need to copy these changes into the currently installed drivers.
//Where are the Applejacks?

//The Applejack driver uses the .refcon field of the cursor device record to
//store a pointer to its globals, a AJGlobalDataPtr.

if(whichSwitch>=0 && whichSwitch<=17)
	{						// where are the AppleJacks?
	index = CountADBs();
	while(index>0)
		{
		address=GetIndADB(&dataBlock,index);
		if((dataBlock.origADBAddr)==kDevAddr)
			{				// make sure that this is really us
			if(dataBlock.dbDataAreaAddr)
			{
			myCrsrDev=(CursorDevicePtr)dataBlock.dbDataAreaAddr;
			if(myCrsrDev)
				{
				myAJ=(AJGlobalDataPtr)myCrsrDev->refCon;
				if(myAJ->signature=='pipp')
					{      		// got it.
					myAJ->switchMappingArray.function[whichSwitch]=function;
					myAJ->switchMappingArray.modifiers[whichSwitch]=modifiers;
					myAJ->switchMappingArray.keyCode[whichSwitch]=keyCode;
					myAJ->switchMappingArray.charCode[whichSwitch]=charCode;
					}
				}
			}
		}
	index--;
	}

Some other ways to use this function could be as follows:

  • Map the yellow button (S10, bit 9) to do nothing:
ChangeSwitchMapping(9,kNothing,0,0,0);
  • Map the red button (S8, bit 14) to be equal to command-Q (quit):
ChangeSwitchMapping(14,kKeyboard,((1<<kCommandBit)),0x0C,'Q');
  • Map the green button (S7, bit 15) to be equal to the shift key:
ChangeSwitchMapping(15,kModifier,0,kShiftKey,0);

Reading Raw Applejack Data

To read raw Applejack data yourself, use code like the previous sample code, and ensure that you map a pointer to the AJGlobalData for each connected Applejack. You need to do this only once, but remember the pointer since it will not be moved or purged.

Then, examine myAJ->switchStates to read the state of a button. Each button correlates with a bit in switchStates. The bit number is the same as defined in the .switchMappingArray array index.

For example, suppose you want to know if the yellow button is pressed; the following statement might apply:

if(!((myAJ>switchStates)&(1<<9))) 				// 0==DOWN
	{                                                       // 1==UP
	Do something useful here, yellow button is down...
	}

Be sure to keep separate pointers for each Applejack found (maximum of 4) even if you only support a single player play. If the bit number returns a value of `0', then the button is pressed. If a value of `1' is returned, the button is not pressed. No other event loop is required.

Pippin Video

This document contains PippinVideo.h and myPippinVideo.c. PippinVideo.h is a header file that contains enumerated constants and structures necessary to access functionality unique to the Pippin video architecture. myPippinVideo.c is sample code that illustrates features unique to the Pippin video architecture.

PippinVideo.h

// =================================================================================
//
//		PippinVideo.h
//
//		Copyright 1995, Apple Computer
//
//		send comments/bugs: [email protected]
//
//		(change this to a real header)
//
//		This file contains enumerated constants and structures necessary
//		to access functionality unique to the Pippin video architecture
//
// =================================================================================

enum {
	kSetProgressiveScan = 0,	// Progressive Scan
	kSetInterlace,			// Interlaced scan, no convolution
	kSetInterlaceConv,		// Interlaced scan, Convolution, no scaling
	kSetInterlaceConvScale		// Interlaced scan, convolution, and scaling
};

#define	cscSetScanMode	128		// Used to select a scan mode for the Taos driver
#define	cscGetScanMode	128		

// structure for Requesting/Controlling Scan Mode information

typedef struct VDControlMode VDControlMode;

struct VDControlMode 
{
	UInt32 	csModeSelect;
	Ptr	csBaseAddressA;
	Ptr	csBaseAddressB;
};

myPippinVideo.c

//==================================================================================
//
//		myPippinVideo.c
//
//		send comments/bugs [email protected]
//
//		v1.1	 March 28, 1996
//
//		(change this to a real header)
//
//		Sample code illustrating features unique to the Pippin video architecture
//		Shows how to use driver calls to change video scan modes
//
//==================================================================================


#include <stdio.h>
#include <stdlib.h>
#include <Memory.h>
#include <Displays.h>
#include <Video.h>
#include "PippinVideo.h"

// Prototypes
unsigned long 		GetUserInputData (void);
void			DoCurrentSettings(void);
void			DoSetScanMode(void);

// Globals
OSErr			err;
short			currentDepth;
GDHandle		myGDHandle;
short			videoDriverRefNum;
short			currentScanMode;
DisplayIDType		currentDisplayType;
UInt32			currentBaseAddress = 0;
short			currentPage;

//==================================================================================
//
//		main()
//
//		Starting point for everything
//
//==================================================================================


void main(void)
{
	OSErr				err;
	VDControlMode			myControlModeStruct;
	VDDisplayConnectInfoRec		myVDDisplayConnectInfoRec;
	VDSwitchInfoRec			switchInfo;
	CntrlParam			pBlock;
	short				input = 1;
	MaxApplZone();

	// ooo Need to check for Pippin Gestalt Selecter here 

	printf("\nThis demo illustrates special functionality of the Pippin video
		architecture\n");

	printf("\n\tInsert explanation and other stuff here\n\n");

	DoCurrentSettings();		
	while ( input != 999 )
	{
		printf("\nPlease enter a selection:\n");
		printf("  1 = Set Scan Mode\n");
//		printf("  2 = Swap Video Pages\n");
		printf("  3 = Current Settings\n");
		printf("input (999 to exit)>");
		input = GetUserInputData();
		switch ( input )
		{
			case 1:
				DoSetScanMode();
				break;
			case 2:
//				DoSwapPages();
				break;
			case 3:
				DoCurrentSettings();
				break;
			case 999:
				break;
			default:
				printf("Invalid selection\n");
				break;
		}
	}
	printf("\nPress Command-Q to Quit . . .\n");
}

//==================================================================================
//
//		DoCurrentSettings()
//
//		Gets Current Video Stuff by calling PBStatus repeatedly
//			cscGetScanMode
//			cscGetConnection
//			cscGetMode			<-- with different pages
//
//==================================================================================


void	DoCurrentSettings(void)
{
	OSErr						err;
	VDControlMode					myControlModeStruct;
	VDDisplayConnectInfoRec				myVDDisplayConnectInfoRec;
	VDPageInfo					myVDPageInfoRec;
	VDSwitchInfoRec					switchInfo;
	CntrlParam					pBlock;

	printf("\n");
	printf("Scanning for driverRefNum: ");

	// We get the First video device because we know there is only one device hooked 
	// up to Pippin

	myGDHandle = DMGetFirstScreenDevice(dmOnlyActiveDisplays);	
	videoDriverRefNum = (*myGDHandle)->gdRefNum;
	printf("%i\n", videoDriverRefNum);
	printf("Current Scan Mode: ");
	pBlock.ioCompletion = nil;
	pBlock.ioCRefNum = videoDriverRefNum;
	pBlock.csCode = cscGetScanMode;

	*(Ptr *)&pBlock.csParam[0] = (Ptr)&myControlModeStruct;
	err = PBStatus( (ParmBlkPtr)&pBlock, true );
	if ( err )
		printf("Unsupported Functionality, err = %i\n", err);
	else
	{
		currentScanMode = myControlModeStruct.csModeSelect;
		switch (myControlModeStruct.csModeSelect)
		{
			case kSetProgressiveScan:
				printf("kSetProgressiveScan\n");
				break;
			case kSetInterlace:
				printf("kSetInterlace\n");
				break;
			case kSetInterlaceConv:
				printf("kSetInterlaceConv\n");
				break;
			case kSetInterlaceConvScale:
				printf("kSetInterlaceConvScale\n");
				break;
			default:
				printf("Err -- unknown Scan Mode, %i\n",
					myControlModeStruct.csModeSelect );
		}
	}
	
	printf("Current Display Type: ");
	pBlock.ioCRefNum = videoDriverRefNum;
	pBlock.csCode = cscGetConnection;
	*(Ptr *)&pBlock.csParam[0] = (Ptr)&myVDDisplayConnectInfoRec;
	err = PBStatus( (ParmBlkPtr)&pBlock, true );
	currentDisplayType = myVDDisplayConnectInfoRec.csDisplayType;

	switch ( currentDisplayType )
	{
		case kVGAConnect:
			printf("kVGAConnect\n");
			break;
		case kNTSCConnect:
			printf("kNTSCConnect\n");
			break;
		case kPALConnect:
			printf("kPALConnect\n");
			break;
		default:
			printf(" -- something else (not VGA, NTSC, or PAL)\n");
			break;
	}
			
	printf("Current Screen Depth: ");
	currentDepth = (*((*myGDHandle)->gdPMap))->pixelSize;
	printf("%i\n", currentDepth);
	printf("Page Info:\n");
	printf("  Current Page: ");
	pBlock.csCode = cscGetMode;
	*(Ptr *)&pBlock.csParam[0] = (Ptr)&myVDPageInfoRec;
	err = PBStatus( (ParmBlkPtr)&pBlock, true );
	currentPage = myVDPageInfoRec.csPage;
	printf("%i\n", currentPage);
	pBlock.csCode 				= cscGetBaseAddr;
	myVDPageInfoRec.csPage 		= 0
	*(Ptr *)&pBlock.csParam[0]	= (Ptr)&myVDPageInfoRec;
	err = PBStatus( (ParmBlkPtr)&pBlock, true );
	printf("  Page: %i, Base Address: %X\n", myVDPageInfoRec.csPage,
		myVDPageInfoRec.csBaseAddr);

	myVDPageInfoRec.csPage 		= 1;
	err = PBStatus( (ParmBlkPtr)&pBlock, true );
	printf("  Page: %i, Base Address: %X\n", myVDPageInfoRec.csPage,
		myVDPageInfoRec.csBaseAddr);
	printf("  Page Count: ");
	pBlock.csCode 				= cscGetPages;
	err = PBStatus( (ParmBlkPtr)&pBlock, true );
	printf("%i\n", myVDPageInfoRec.csPage);
	printf("\n");
}

//==================================================================================
//
// 		DoSetScanMode()
//
//		Request and set the scan mode;
//
//==================================================================================


void	DoSetScanMode(void)
{
	short			input = 1;
	CntrlParam		pBlock;
	VDControlMode	myControlModeStruct;

	pBlock.ioCompletion = nil;
	pBlock.ioCRefNum = videoDriverRefNum;
	pBlock.csCode = cscSetScanMode;

	*(Ptr *)&pBlock.csParam[0] = (Ptr)&myControlModeStruct;

	while ( input != 999 )
	{
		printf("\nPlease enter a selection:\n");
		printf("  1 = Progressive Scan\n");
		printf("  2 = Interlace\n");
		printf("  3 = Interlace, Convolution\n");
		printf("  4 = Interlace, Convolution, Scaling\n");
		printf("input (999 to exit)>");
		input = GetUserInputData();

		if ( input == 999 ) break;

		if ( input == 1 )

		{
			if ( currentDisplayType != kVGAConnect ) printf("err -- not in VGA
				mode\n");
			else
			{
				myControlModeStruct.csModeSelect = kSetProgressiveScan;
				err = PBControl( (ParmBlkPtr)&pBlock, true );
			}
		}
		else
		{
			if ( currentDisplayType == kVGAConnect ) printf("err -- not in NTSC/PAL
				mode\n");
			else
			{
				if (input == 2) myControlModeStruct.csModeSelect = kSetInterlace;
				else if (input == 3) myControlModeStruct.csModeSelect =
					kSetInterlaceConv;
				else if (input == 4) myControlModeStruct.csModeSelect =
					kSetInterlaceConvScale;
				err = PBControl( (ParmBlkPtr)&pBlock, true );
			}
		}
		if (err) printf("err in PBControl: %i", err);
	}
}


//==================================================================================
//
//		GetUserInputData()
//
//		Whats until the user inputs anything other than 0
//
//==================================================================================


unsigned long GetUserInputData (void)
{
	long	tempLong = 0;				
	do scanf ("%ld", &tempLong); while (tempLong == 0);	
	return (tempLong);
}

External Links

Related Articles

See Also