The PAK68/3 Accelerator - [German]

MacinJosh

Tinkerer
Jan 16, 2022
50
54
18
45
Finland
www.atariancomputing.com
minpic01.jpg

Alles unter Kontrolle​

Macintosh-Kontrollfeld für PAK-68 und MacStart​


Michael Parker​

Bei der Konfiguration seines Systems hat´s der Mac-User leicht: einfach ein Kontrollfeld anklicken und die gewünschten Parameter einstellen. Anwender unserer Projekte MacStart und PAK-68/3 kamen dabei bislang zu kurz, weshalb wir hier ein Kontrollfeld nebst ausführlicher `Bauanleitung´ vorstellen wollen.

Für den heutigen Mac-Anwender ist es sicherlich kaum noch vorstellbar, daß es am Anfang nur ein Kontrollfeld gab, und das im heutigen Sinne nicht einmal richtig: Es war nur ein Schreibtischzubehör (kurz DA für Desk Accessory). Bald schon wurde es im Kontrollfeld zu eng, und es wurde in der Systemversion 4.1 durch eine rollbalkengesteuerte Auswahlfunktion erweitert. In dieser Form blieb es den Mac-Usern bis System 6.0x erhalten.

Doch mit System 7 wurde alles anders: Das Kontrollfeld-DA in seiner ursprünglichen Form hat gänzlich das Zeitliche gesegnet, ab jetzt durfte sich jedes cdev selbst Kontrollfeld nennen und sein eigenes, beliebig großes Fenster haben. Doch dem gewissenhaften Programmierer sei geraten, die Standardgröße einzuhalten, damit´s auch unter System 6.0.x noch paßt.

Befehlsempfänger​

Eines jedoch ist seit System 4.1 erhalten geblieben: Der Mechanismus. Im Prinzip ist ein Kontrollfeld nur ein Befehlsempfänger, der auf eine begrenzte Anzahl von Messages hört. Diese Messages befehlen dem Kontrollfeld, zu prüfen, ob es für die aktuelle Soft- beziehungsweise Hardware geeignet ist, sich zu initialisieren, auf vielerlei Events, wie zum Beispiel einen Mausklick, zu reagieren und am Ende wieder alles schön säuberlich aufzuräumen. Diese Messages kamen früher vom besagten Kontrollfeld-DA und werden seit System 7 vom Finder direkt verschickt. Die Event-Befehle sind Pendants altbekannter Recken wie Mausklick, Tastendruck, Cut/Copy/Paste/Clear wie auch Update-, Activate- und Deactivate-Events. Damit nichts anbrennt, bekommt ein Kontrollfeld regelmäßig ein Null-Event, welches dem Befehlsempfänger nicht viel mehr sagen will, als daß er jetzt ein bißchen Zeit hat, regelmäßige Arbeiten wie zum Beispiel die Anzeige der aktuellen Uhrzeit zu verrichten.

Alles Routine​

Das Herzstück eines Kontrollfeldes ist eine Kontrollfeldfunktion mit einer streng festgelegten Parameterliste. Jene Parameter verraten viel über die Besonderheiten von Kontrollfeldern. Neben der schon bekannten Message wird der Kontrollfeldfunktion ein Zeiger auf eine Dialog-Item-Liste übergeben. Dies offenbart, daß ein Kontrollfeld auch nur eine spezielle Art von Dialog darstellt. Als Besonderheit ist Aufbau und Zeichnen nicht Sache des Kontrollfeldes selbst, sondern des Finders. Deshalb stellt ein cdev eine oft genutzte Möglichkeit dar, im Finder ein Fenster zu öffnen, auch wenn man gar nichts kontrollieren will. Die Kontrollfeldfunktion bekommt im Falle eines Mausklicks oder Tastendrucks lediglich im Item-Parameter mitgeteilt, welches Dialog-Item betätigt wurde.
Der Parameter numItems hat unter System 7 nur noch historische Bedeutung: Früher wurde im alten Kontrollfeld-DA die Dialog-Item-Liste des cdevs einfach an die des Kontrollfeld-DAs angehängt. Somit haben sich alle Item-Nummern um die Anzahl dieser Dialog Items verschoben. Um das auszugleichen, bekam das cdev die Anzahl der Items im numItems-Parameter mitgeliefert. Unter System 7 wird dort nichts mehr angehängt, der numItems-Parameter aber noch aus Kompatibilitätsgründen mitgeschleppt.

Kommt eine Message der Event-Gattung herein, macht es sich der Befehlsgeber leicht und reicht einfach den aus der Programmierung von Applikationen bekannten Event-Record durch. Dort kann sich das Kontrollfeld dann selbst nach Herzenslust bedienen und das holen, was es zur Auswertung der Message braucht.

Geben und Nehmen​

Ein letzter Parameter namens cdevValue übernimmt die wechselseitige Kommunikation des Kontrollfelds mit dem Finder beziehungsweise dem alten Kontrollfeld-DA. Wenn sich ein Kontrollfeld einmal initialisiert hat, bekommt es im cdevValue-Parameter genau den Wert überreicht, den es beim letzten Aufruf zurückgegeben hat. Mit diesem Ping-Pong-Verfahren kann sich die Kontrollfeldfunktion zum Beispiel einen Zeiger oder ein Handle auf einen von ihr allozierten Speicherbereich erhalten.
Geht irgend etwas während des Kontrollfeldbetriebes schief, kann es auch anstatt der Adresse des Speicherbereiches eine Fehlermeldung zurückgeben. So weiß der Finder, daß der User mittels Alertbox über diesen Fehler informiert werden muß und die Zeit reif ist, das Kontrollfeld schleunigst zu beenden.

Wunschzettel​

Das c't-Kontrollfeld soll drei Aufgaben erfüllen. Erstens soll es bei einem Mac mit PAK (Prozessoraustauschkarte) [7] dem System begreiflich machen, daß dort wirklich ein Fließkommaprozessor installiert ist. Jeder normale Mac weiß das von Haus aus, nur die PAK-Macs stellen sich hier dumm, weil die ROMs und das System (noch) nichts von dem auf der PAK befindlichen Rechenknecht wissen. Bleibt nicht viel übrig, als dort ein bißchen nachzuhelfen: Eine Ersatzroutine muß her. In [2] stellten wir für diesen Zweck das hasFPU-Init vor, das aber unter System 7 nicht mehr einwandfrei funktioniert.
Seit System 6.0.4 übernimmt nämlich der Gestaltmanager den Auskunftsdienst über System- und Hardwarekonfiguration. Mittels eines Selektors teilt man der Gestaltfunktion mit, was man denn gerne wissen möchte. Fleißig gibt die Funktion Auskunft, nur die Existenz der PAK-FPU bleibt unerkannt. Wohl haben die Systemprogrammierer von Apple solches geahnt, denn sie erlauben, für jeden Selektor die Auskunftsfunktion zu ersetzen. Also schreibt man die Routine neu und ersetzt damit die systemeigene.

Als zweite Aufgabe soll das Kontrollfeld die Installation der Shut-Down-Routine für das MacStart-Projekt übernehmen. Diese hängt man mittels Shut-Down-Manager in die Shut-Down-Sequenz ein. Was diese Routine mit dem Shut-Down so alles anstellt, kann in [3] nachgelesen werden. Als kleines Schmankerl und mithin dritte Aufgabe soll noch der Befehls- beziehungsweise Daten-Cache des Prozessors, zum Beispiel für Geschwindigkeitstests oder Beseitigung von Inkompatibilitäten, ein- und ausgeschaltet werden können.

cdev und mehr​

Eine Kontrollfelddatei benötigt neben der cdev-Ressource, in der sich die Kontrollfeldfunktion befindet, noch eine Menge weiterer Ressourcen. Zum einen ist da die mach-Ressource, die jeweils nur ein Integer-Wort für die System- und ein Wort für die Hardwarekonfiguration enthält. Tatsächlich kann man in die Bits dieser beiden Wörter eine Menge Konfiguration hineinkodieren, im Gestaltzeitalter aber haben sich zwei Belegungen herauskristallisiert. $FFFF 0000 meint: Das Kontrollfeld läuft auf allen Konfigurationen, $0000 FFFF dagegen bedeutet: Frage mit einer speziellen Message die Kontrollfeldfunktion selbst, ob das Kontrollfeld unter dieser Konfiguration laufen kann.
Die DITL-Ressource enthält Angaben über die Anzahl, Struktur und Position der Dialog-Items. Sie wird unter System 7 vom Finder selbständig verwaltet und der Kontrollfeldfunktion nur zur Auswertung von Mausklicks und Tastendrücken oder der Behandlung von User-Items übergeben.

In der nrct-Ressource befinden sich Angaben darüber, welche Rechtecke im Hintergrund des Kontrollfeldfensters gezeichnet werden sollen. Wer seine Rechtecke lieber über die DITL-Ressource zeichnen lassen will, der gibt hier als Rechteck die gesamte Fläche des Kontrollfeldfensters an; auch hier wird der Historie Rechnung getragen. Die Koordinaten der Rechtecke wie auch der DITL-Ressource beziehen sich nicht auf den Punkt (1,1), sondern auf (1,89). Dies rührt daher, daß im alten Kontrollfeld-DA neben der eigentlichen Kontrollfeldfläche Platz für die Icon-Liste der anderen verfügbaren cdevs gelassen werden mußte.

pic02.jpg

So präsentiert sich das vollständige c't-Kontrollfeld dem Anwender.

Damit sowohl im Finder als auch in der cdev-Liste des Kontrollfeld-DA ein Icon für jedes Kontrollfeld angezeigt werden kann, benötigt man als letztes die Bundle-Ressourcen samt Zubehör. Die Kombination aus Ressourcen von je einem Typ BNDL, FREF und ICN# ordnen jeder Kontrollfelddatei eindeutig ein Icon für den Finder zu. Unter System 7 kann man zur Not auch ohne diese Ressourcen leben.

All diese Ressourcen müssen stets die ID -4064 haben; das goldene Fragezeichen geht an den, der sich diese hübsche Zahl ausgedacht hat. Mit dieser Festlegung weiß der Finder allerdings immer, welche Ressourcen er sich beim Aufbau eines Kontrollfeldes greifen muß. Damit man mit der Erstellung der Ressourcen nicht soviel Arbeit hat, sei hier auch auf Apples ResEdit hingewiesen, das für alle notwendigen Ressourcen sehr angenehme Eingabemethoden bereitstellt.

Ein INIT muß sein​

Das schönste Kontrollfeld nützt nichts, wenn kein Code vorhanden ist, der die Patch-Routinen im System installiert; das Ganze muß ja nach altem Brauch während des Systemstarts geschehen. Da gibt´s nur eins: Eine INIT-Ressource muß her. Eine angenehme Eigenschaft von Kontrollfelddateien ist, daß diese, soweit sie sich am richtigen Platz im Systemordner befinden, während des Systemstarts nach INIT-Ressourcen durchforstet werden. Wie ein INIT aufgebaut ist, haben Sie womöglich schon in [1] und [2] kennengelernt. Hier soll nur gesagt werden, daß diese Kontrollfeld-INIT nicht viel mehr macht, als die Einstellungen zu laden, zu prüfen, was installiert werden soll, entsprechende Routinen in den System-Heap zu laden und diese in die entsprechenden Stellen im System einzuklinken.
Die Einstellungen werden System-7-like im Preferences-Ordner abgelegt. Somit wäre auch ein Booten über Netzwerk möglich.

Bauanleitung​

Das Kontrollfeld wurde mit Think C entwickelt. Es besteht im Grunde genommen aus vier Projekten, die jeweils eine Ressource zum Kontrollfeld beitragen: die Kontrollfeldfunktion, die Gestaltersatzroutine für die FPU-Erkennung, die Shut-Down-Routine für die MacStart-Schaltung und ein INIT, welches letztere beiden bei Systemstart im Systemheap installiert. Das Projekt für die cdev-Ressource übernimmt darüber hinaus auch das Zusammenfügen aller Ressourcen zu einem ausgewachsenen Kontrollfeld.
Das gesamte Listing würde den Rahmen dieses Artikels sprengen. Deshalb haben wir uns hier auf die wichtigsten Teile beschränkt. Eine Bauanleitung für INITs findet sich außerdem in [1]. Den gesamten Sourcecode nebst ausführbarem Programm stellen wir auch diesmal auf Sammeldiskette und in der c't-Mailbox zur Verfügung.(cm)

Literatur​

[1] Leonidas Drisis: Starthilfe, c't 2/91, S. 182
[2] Michael Parker, Carsten Meyer: FPU-Starthilfe, INIT für PAK-ausgerüstete Macs, c't 1/92, S. 188
[3] Carsten Meyer: Startautomatik, Macintosh automatisch ein- und ausschalten, c't 10/92 S. 196
[4] Inside Macintosh I, The Ressource Manager, The Dialog Manager, The File Manager, The Control Manager, Addison-Wesley 17737
[5] Inside Macintosh V: The Control Panel, The Shut Down Manager, Addison-Wesley 17719
[6] Inside Macintosh VI: Compatibility Guidelines, The Control Panel, The File Manager, The Finder Interface, Addison-Wesley 57755
[7] Holger Zimmermann: Doppel-PAK, PAK68/3 mit Cache und 68020/030 für 68000-Rechner, c't 11/93 S. 222, c't 12/93, S. 276
 
Last edited:
  • Love
  • Wow
Reactions: alxlab and Melkhior

MacinJosh

Tinkerer
Jan 16, 2022
50
54
18
45
Finland
www.atariancomputing.com
Kasten 1


Kontrollfeld-Messages​

macDev: Die Kontrollfeldfunktion soll ermitteln, ob sie auf der aktuellen System- und Hardwarekonfiguration lauffähig ist. Wenn ja, wird eine `1´ zurückgegeben, ansonsten eine `0´.
initDev: Die Kontrollfeldfunktion soll sich initialisieren, wie zum Beispiel nötigen Speicher allozieren oder Dialog-Items richtig vorbesetzen. Hier sollte auch geprüft werden, ob genügend Speicher für spätere Allokationen verfügbar ist.

activDev: Das Kontrollfeldfenster ist wieder aktiv geworden. Die Kontrollfeldfunktion kann nun auf zwischenzeitliche Veränderungen reagieren beziehungsweise diverse Dialog-Items reaktivieren.

deActivDev: Die Kontrollfeldfunktion hat nun die Möglichkeit, bevor ein anderes Fenster aktiv wird, bestimmte Aktionen, wie zum Beispiel das Dimmen eines Control-Items oder das Entfernen einer Textselektion, durchzuführen.

updateDev: Die Kontrollfeldfunktion wird darüber informiert, daß Teile der Kontrollfeldfläche neu gezeichnet werden müssen. Standard-Items und nrct-Rechtecke werden vom Finder selbständig restauriert, User-Items dagegen müssen von der Kontrollfeldfunktion selbst neu gezeichnet werden.

hitDev: Ein Element der Dialog-Item-Liste wurde angeklickt. Die Kontrollfeldfunktion erfährt über den Item-Parameter, welchem Item der Mausklick galt, und führt entsprechende Reaktionen aus.

keyEvtDev: Eine Taste wurde gedrückt. Die Kontrollfeldfunktion wertet den Tastatur-Event aus und leitet ihn gegebenenfalls an das gerade aktive Textfeld weiter.

undoDev: Die Undo-Operation wurde ausgewählt. Die Kontrollfeldfunktion soll durch Aufhebung der letzten Operation den alten Zustand wiederherstellen.

cutDev: Das Ausschneiden-Kommando wurde ausgewählt. Die Kontrollfeldfunktion sollte die aktuelle Textselektion ausschneiden und im Clipboard ablegen.

copyDev: Ähnlich wie beim Ausschneiden soll auch hier die Selektion eines Edit-Feldes in das Clipboard kopiert werden. Unterschied ist hier nur, daß die Kontrollfeldfunktion die Selektion nicht löscht.

pasteDev: Das Einfügen-Kommando wurde ausgewählt. Die Kontrollfeldroutine soll den Inhalt des Clipboards in das Edit-Feld, in dem gerade der Cursor aktiv ist, an aktueller Stelle einsetzen.

clearDev: Im Bearbeiten-Menü beziehungsweise mit der Backspace-Taste wurde das Löschen-Kommando ausgewählt. Die Kontrollfeldfunktion soll in einem Edit-Feld die aktuell selektierte Textstelle löschen.

nulDev: Ohne daß ein konkretes Ereignis anliegt, hat die Kontrollfeldfunktion jetzt die Möglichkeit, periodische Arbeiten wie zum Beispiel die Anzeige der aktuellen Uhrzeit durchzurühren.

closeDev: Die Kontrollfeldfunktion hat jetzt die Gelegenheit, anliegende Aufräumarbeiten wie das Desallozieren vom Speicher auszuführen. Dies ist immer die letzte Message, die eine Kontrollfeldfunktion erhält.

Kasten 2


Die Kernroutinen des Kontrollfelds `c't-Einstellungen´, zu kompilieren mit Think C ab Version 5.0.

C:
// c't Einstellungen.h:
// Enthält Definitionen und Prototypes
// die von allen Sourcen benötigt werden

//IDs fuer STR# Resourcen
#define ProcessorTypeStrID 128
#define ProcessorUnknownStrIndex 1
#define ProcessorStrOffset 1

#define PrefStrID 129
#define PrefFileNameStrIndex 1
#define PrefResNameStrIndex 2

//ID des AlertTemplates
#define ChangeAfterRestartDlgID 128

// Record, Zeiger und Handle auf die Resource, die die Einstellungen
// enthält
typedef struct
{
    //Werte für Einstellungen und Steuerung des Kontrollfeldes
    long kindOfFPU;
    long processorType;
    Boolean gestaltFPUEnabled;
    Boolean macStartEnabled;
    Boolean instructionCacheEnabled;
    Boolean dataCacheEnabled;
    Boolean messageDone;
}
PrefRec, *PrefPtr, **PrefHandle;


// Diese Funktionen verwalten die Einstellungen mittels Datei
// im Preferences-Ordner
extern Boolean LoadPrefs( PrefHandle* prefHandle );
extern Boolean SavePrefs( PrefHandle prefHandle );

// Weitere Funktionen, die von der INIT-Resource, wie auch von der
// cdev-Resource benutzt werden
// Sie sind in einer Source c't Einstellungen Common.c zusammengefaßt
extern Boolean IsGoodConfiguration( void );
extern void SetInstructionCache( Boolean set );
extern void SetDataCache( Boolean set );
extern Boolean GetInstructionCache( void );
extern Boolean GetDataCache( void );

// Routinen, die zur Dialogsteuerung gebraucht werden
void SetBox( DialogPtr dialogList, int itemNr, Boolean setting );
Boolean InvertAndGetBox( DialogPtr dialogList, int itemNr );
void SetControl( DialogPtr dialogList, int itemNr, int setting );
int GetControl( DialogPtr dialogList, int itemNr );
void SetText( DialogPtr dialogList, int itemNr, Str255 string );
void EnableControl( DialogPtr dialogList, int itemNr, Boolean setting );
void DoAfterRestartMessage( PrefHandle prefHandle );
void EnableDialogItems( DialogPtr CPDialog, int numItems, PrefHandle prefHandle );
void DisableDialogItems( DialogPtr CPDialog, int numItems, PrefHandle prefHdl );

===============================================================

C:
// c't Einstellungen cdev.c:

// Enthält die Kontrollfeld-Routine und alle notwendigen Funktionen
// um das Steuern der Controls und TextItems im Kontrollfeld-Dialog
// zu ermöglichen

#include <GestaltEqu.h>
#include `c't Einstellungen.h´

// IDs der DITL-Items
enum
{
    BalloonHelpAvailableTextID = 1,
    IconID,
    AuthorTextID,
    FPUGestaltRoutineEnabledID,
    FPUKindID,
    MacStartRoutineEnabledID,
    InstalledProcessorTextID,
    ProcessorTypeTextID,
    InstructionCacheEnabledID,
    DataCacheEnabledID
};

(...)

// FPU-Werte in Gestalt-Version beginnen mit Null,
// in der Darstellung im Menu ab 1; deshalb Offset von 1
#define MenuOffset 1

// Auswertungsroutinen für Events der Kontrollfeld-Schnittstelle
// Die Prototypes müssen sein, da die main-Funktion die erste in der
// Aufschreibung sein muß.
long HandleMacDev( void );
long HandleInitDev(DialogPtr CPDialog, int numItems );
long HandleHitDev( DialogPtr CPDialog, int numItems, int item,
    PrefHandle prefHandle );
long HandleActivDev( DialogPtr CPDialog, int numItems, PrefHandle
    prefHandle );
long HandleDeactivDev( DialogPtr CPDialog, int numItems, PrefHandle
    prefHandle );
long HandleCloseDev( PrefHandle prefHandle );

// In diese Routine springt System 7 gemäß den Modalitäten von
// Inside Macintosh V-323 ff
// Diese Routine muß die oberste in Aufschreibung und Resource sein:
// Die cdev-Resource wird in ihrem ersten Byte angesprungen

long pascal main( int message, int item, int numItems, int CPanelID,
    EventRecord* theEvent, long cdevValue, DialogPtr CPDialog )
{
    //Checke cdevValue vor der Weiterbearbeitung
    if( initDev != message && macDev != message )
        if( 0 == cdevValue || cdevUnset == cdevValue )
            return( 0 );

    // Bearbeite die verschiedenen Events, die das System an uns
    // übergibt
    switch( message )
    {
    case initDev:
            return( HandleInitDev( CPDialog, numItems ) );
    case hitDev:
            return( HandleHitDev( CPDialog, numItems, item,
                (PrefHandle)cdevValue ) );
    case closeDev:
            return( HandleCloseDev( (PrefHandle)cdevValue ) );
    case nulDev:
            return( cdevValue );
    case updateDev:
            return( cdevValue );
    case activDev:
            return( HandleActivDev( CPDialog, numItems,
                (PrefHandle)cdevValue ) );
    case deactivDev:
            return( HandleDeactivDev( CPDialog, numItems,
                (PrefHandle)cdevValue ) );
    case keyEvtDev:
            return( cdevValue );
    case macDev:
            return( HandleMacDev( ) );
    case undoDev:
            return( cdevValue );
    case cutDev:
            return( cdevValue );
    case copyDev:
            return( cdevValue );
    case pasteDev:
            return( cdevValue );
    case clearDev:
            return( cdevValue );
    default:
            return( cdevUnset );
    }
    // cdevValue wird im Nicht-Fehlerfall im Ping-Pong-Verfahren
    // zwischen dieser Funktion und der übergeordneten Steuer-
    // Routine des Systems hin- und hergereicht. Da Kontrollfeld-
    // funktionen keine Globalen benutzen dürfen, verwenden wir
    // diesen Wert zum Erhalt unserer Einstellungen während der
    // verschieden Aufrufen dieser Routine. Der Hin-Weg geschieht
    // über den Rückgabewert, der Her-Weg über cdevValue.
}

(...)

long HandleMacDev( void )
{
    // Ermittle, ob die aktuelle Konfiguration des Rechners
    // geeignet ist
    return( IsGoodConfiguration( )?(long)1long)0 );
}

long HandleInitDev (DialogPtr CPDialog, int numItems )
{   
    PrefHandle prefHandle;
    long error;
    Str255 processorTypeStr;

    // Lade Einstellungen: Wenn dies nicht gelingt: Kontrollfeld
    // mit ResourceFehler beenden
    if( !LoadPrefs( &prefHandle ) ) return( cdevResErr );

    // Aktiviere alle Controls entsprechend
    EnableDialogItems( CPDialog, numItems, prefHandle );

    // Setze Box-Einstellung für GestaltFPU-Routine
    SetBox( CPDialog, numItems + FPUGestaltRoutineEnabledID,
        (*prefHandle)->gestaltFPUEnabled );

    // Setze (trotzdem) den FPUType auf den eingestellten Wert
    SetControl( CPDialog, numItems + FPUKindID,
        (*prefHandle)->kindOfFPU + MenuOffset );

    // Setze Box-Einstellung für MacStart-Routine
    SetBox( CPDialog, numItems + MacStartRoutineEnabledID,
        (*prefHandle)->macStartEnabled );

    // Hole den Namen des aktuellen Prozessors
    GetIndString( processorTypeStr, ProcessorTypeStrID,
        (*prefHandle)->processorType + ProcessorStrOffset );
    // Konnte keiner gefunden werden, dann ist der Prozessor
    // unbekannt
    if( !processorTypeStr[ 0 ] )
        GetIndString( processorTypeStr, ProcessorTypeStrID,
            ProcessorUnknownStrIndex );
    //Setze den Namen des Prozessors in das Textfeld ein
    SetText( CPDialog, numItems + ProcessorTypeTextID,
        processorTypeStr );

    // Gebe unseren (einzigen) Speicherbereich mit den Einstellungen an
    // die Kontrollfeldroutine zurück
    return( (long)prefHandle );
}

// Je nachdem, wohin die Maus geklickt hat, wird die entsprechende
// Funktion ausgeführt

long HandleHitDev( DialogPtr CPDialog, int numItems, int item,
    PrefHandle prefHandle )
{
    // Da vor der ItemListe unseres Dialoges die DialogItems des
    // Kontrollfeldes liegen (könnten), müssen diese von den
    // übergebenen ItemIDs abgezogen werden
    switch( item - numItems )
    {
    case FPUGestaltRoutineEnabledID:
 
        // Hole und invertiere Inhalt der CheckBox für die
        // Aktivierung der FPU-Bestätigung. Übergebe Wert den
        // Einstellungen
        (*prefHandle)->gestaltFPUEnabled = InvertAndGetBox(
            CPDialog, numItems + FPUGestaltRoutineEnabledID );


        //Mache anschließendes PopUpMenu entsprechend verfügbar

        EnableControl( CPDialog, numItems + FPUKindID,
            (*prefHandle)->gestaltFPUEnabled );

        // Zeige beim ersten Ändern einer FPU-Einstellungen die
        // Meldung an, daß diese Änderung erst nach Neustart wirksam
        // werden
        DoAfterRestartMessage( prefHandle );
        break;
      
    case FPUKindID:
        // Übernehme FPU-Wert
        (*prefHandle )->kindOfFPU = GetControl( CPDialog, numItems +
            FPUKindID ) - MenuOffset;
        DoAfterRestartMessage( prefHandle );
        break;
      
    case MacStartRoutineEnabledID:
        // Hole und invertiere Inhalt der CheckBox für die
        // Aktivierung des InstructionCaches. Übergebe Wert den
        // Einstellungen
        (*prefHandle )->macStartEnabled = InvertAndGetBox( CPDialog,
            numItems + MacStartRoutineEnabledID );     
        DoAfterRestartMessage( prefHandle );
        break;

    case InstructionCacheEnabledID:
        // Hole und invertiere Inhalt der CheckBox für die
        // Aktivierung des InstructionCaches. Übergebe Wert den
        // Einstellungen
        (*prefHandle )->instructionCacheEnabled = InvertAndGetBox(
            CPDialog, numItems + InstructionCacheEnabledID );
        //Schalte InstructionCache sofort ein bzw. aus
        SetInstructionCache( (*prefHandle)->
            instructionCacheEnabled );
        break;

    case DataCacheEnabledID:
        // Hole und invertiere Inhalt der CheckBox für die
        // Aktivierung des DataCaches. Übergebe Wert den
        // Einstellungen
        (*prefHandle)->dataCacheEnabled = InvertAndGetBox( CPDialog,
            numItems + DataCacheEnabledID );
        //Schalte InstructionCache sofort ein bzw. aus
        SetDataCache( (*prefHandle)->dataCacheEnabled );
        break;
    }
    // Gebe unseren (einzigen) Speicherbereich mit den Einstellungen an die
    // KontrollfeldRoutine zurück
    return( (long)prefHandle );
}

// Falls während der Zeit der Deaktivierung sich die Cache-Zustände
// geändert haben, wird dies hier nachvollzogen
long HandleActivDev( DialogPtr CPDialog, int numItems,
    PrefHandle prefHandle )
{
    //Aktiviere alle Controls entsprechend
    EnableDialogItems( CPDialog, numItems, prefHandle );
    // Hat der Prozessor des Rechners einen InstructionCache
    if( (*prefHandle)->processorType >= gestalt68020 )
    {
        // Hole dessen aktuellen Zustand und setze CheckBox
        // entsprechend
        (*prefHandle)->instructionCacheEnabled =
            GetInstructionCache( );
        SetBox( CPDialog, numItems + InstructionCacheEnabledID,
            (*prefHandle)->instructionCacheEnabled );
    }
    // Hat der Prozessor des Rechners einen DataCache
    if( (*prefHandle)->processorType >= gestalt68030 )
    {
        // Hole dessen aktuellen Zustand und setze CheckBox
        // entsprechend
        (*prefHandle)->dataCacheEnabled = GetDataCache( );
        SetBox( CPDialog, numItems + DataCacheEnabledID,
            (*prefHandle)->dataCacheEnabled );
    }
    return( (long)prefHandle );
}

long HandleDeactivDev( DialogPtr CPDialog, int numItems,
    PrefHandle prefHandle )
{
    // Deaktiviere alle Controls
    DisableDialogItems( CPDialog, numItems, prefHandle );
    return( (long)prefHandle );
}
long HandleCloseDev( PrefHandle prefHandle )
{
    long error;
    // Schreibe Resource (mit den aktuellsten Einstellungen) zurück
    // Schlug dies fehl: Meldung, daß Einstellungen nicht gespeichert
    // wurden
    if( !SavePrefs( prefHandle ) ) return( cdevResErr );
    // Gebe irgendeinen unverfänglichen Wert zurück
    return( cdevUnset );
}

===============================================================

C:
// c't GestaltFPUProc.c:
//  Gestalt Manager-Ersatzroutine für FPU-Bestätigung

// Der Gestalt-Manager ersetzt seit 6.0.4 die Systemfunktion
// SysEnvirons. Einzelne Systemwerte können mittels Selektoren
// abgefragt werden. Für die Beschreibung des Koprozessors dient der
// Selektor gestaltFPUType. Für diesen Selektor liefert die
// GestaltFunktion:
// KeinCopro, 68881, 68882, 68040 eingebaut
// Der Gestalt-Manager erlaubt es, für jeden Selektor die
// entsprechende Ermittlungsroutine zu ersetzen. Die systemeigene
// Ermittlungsroutine für den FPU-Selektor ersetzen wir somit durch
// untenstehende Funktion.
// Weiteres Siehe Inside Macintosh, Volume VI, 3-28 ff
// An der Adresse fpuType wird bei der Installation der Typ der zu
// bestätigenden FPU eingetragen. Diese Adresse hat in der Resource
// den Offset 6, beginnend vom Resource-Anfang
// Diese Funktion findet sich schon compiliert als Hex-Code
// in der Resource-Description-Datei mit der Resource-Type `Proc´
// und der Resource-ID 128 wieder.

pascal OSErr main( OSType selector, long* gestaltResponse )
{
    asm
    {
        bra.s @weiter               ;Überspringe Speicherstelle
    @fpuType:                       ;fpuType ist gleichbed. mit Offset 6
        dc.w 0                      ;Ablagestelle für den FPUType
    @weiter:
        moveq.l #0,d0               ;Lösche d0 auf Langwort
        move.w  @fpuType,d0         ;Füge FPUType in Langwort ein
        move.l  gestaltResponse,a0  ;Gebe das Langwort an den Rückgabe-
        move.l  d0,(a0)             ;zeiger gestaltResponse weiter
    }
    return( noErr );
}

===============================================================

C:
// c't Einstellungen Common.c:

//  Gemeinsame Routinen des cdev´s und des INIT´s:
//  Festellen, ob aktuelle Konfiguration geeignet ist
//  Setzen und Lesen der Caches
//  Laden und Schreiben der Preferences


#include `c't Einstellungen.h´

#define EIFlag 0
#define EDFlag 8
#define EIMask 0x00000001
#define EDMask 0x00000100

(...)

Boolean GetInstructionCache( void )
{
    int state;
    asm 68020
    {
        movec.l cacr,d0     ;Lade CacheControlRegister nach a0
        andi.l #EIMask,d0   ;Blende alles außer
                            ;InstructionCacheEnableFlag aus
        move.w d0,state     ;Speichere ausmaskiertes Bit
    }
    return( 0 != state );
}

Boolean GetDataCache( void )
{
    int state;
    asm 68020
    {
        movec.l cacr,d0     ;Lade CacheControlRegister nach a0
        andi.l #EDMask,d0   ;Blende alles außer
                            ;DataCacheEnableFlag aus
        move.w d0,state     ;Speichere ausmaskiertes Bit
    }
    return( 0 != state );
}

void SetInstructionCache( Boolean setting )
{
    if( setting )
        asm 68020
        {
            movec.l cacr,d0     ;Lade CacheControlRegister nach a0
            bset #EIFlag,d0     ;Setze das Enable-Flag für den
                                ;InstructionCache
            movec.l d0,cacr     ;Lade CacheControlRegister nach a0
        }
    else
        asm 68020
        {
            movec.l cacr,d0     ;Lade CacheControlRegister nach a0
            bclr #EIFlag,d0     ;lösche das EnableFlag für den
                                ;InstructionCache
            movec.l d0,cacr     ;Lade CacheControlRegister nach a0
        };
}

void SetDataCache( Boolean setting )
{
    if( setting )
        asm 68020
        {
            movec.l cacr,d0     ;Lade CacheControlRegister nach a0
            bset #EDFlag,d0     ;Setze das DataCache-EnableFlag
            movec.l d0,cacr     ;Lade CacheControlRegister nach a0
        }
    else
        asm 68020
        {
            movec.l cacr,d0     ;Lade CacheControlRegister nach a0
            bclr #EDFlag,d0     ;Lösche das DataCache-EnableFlag
            movec.l d0,cacr     ;Lade CacheControlRegister nach a0
        };
}

(...)



Zu diesem Artikel existieren Programmbeispiele​

0394_206.doc
0394_206.zip
0394_206.sea
 

Attachments

  • 0394_206.zip
    42.2 KB · Views: 59
  • 0394_206.sea.zip
    58.5 KB · Views: 72
  • 0394_206.doc.zip
    819 bytes · Views: 84
Last edited:
  • Love
  • Wow
Reactions: alxlab and Melkhior

Melkhior

Tinkerer
Jan 9, 2022
98
49
18
The mess is likely due to old Macs using \r as end-of-line, Linux/UNIX don't like that as they use \n. If the DVD contains a text file, converting the EOL first might be useful. On linux
Code:
cat old.txt | tr '\r' '\n' > new.txt
would do the trick.

This is some great stuff you're giving us!
 
  • Like
Reactions: MacinJosh

MacinJosh

Tinkerer
Jan 16, 2022
50
54
18
45
Finland
www.atariancomputing.com
I now realize that all the links are pointing to my internal site where I've put them. I'll replace the images with their "large" counterparts.

Also, I keyword-searched the collection and this is the last PAK-related article I found.