Parkwächter - Schoner für die Festplatte

Bildschirmschoner auf Software-Basis gehören heute wohl zum Computer-Alltag. Wird eine gewisse Zeit keine Aktion am Rechner vorgenommen, so sorgt ein im Hintergrund laufendes Programm dafür, daß der Bildschirm dunkel geschaltet wird. Auf diese Weise wird ein Einbrennen des Bildinhalts in die Bildröhre verhindert. Aber nicht nur der Bildschirm läßt sich schonen, sondern auch die Festplatte. Hierzu muß lediglich dafür gesorgt werden, daß diese eine gewisse Zeit nach dem letzten Zugriff automatisch geparkt wird.

Diese Idee ist nicht einmal neu. So sorgte bereits das Betriebssystem der Festplatten der Firma Vortex vor einigen Jahren dafür, daß der Motor der Platten nach einer bestimmten Zeit abgeschaltet wurde. Diese Lösung war natürlich plattenspezifisch. Seit der Einführung des XHDI-Protokolls läßt sich so etwas nun für jede Platte realisieren, vorausgesetzt man verwendet einen Festplattentreiber, der die XHDI-Spezifikation (eXtended HardDisk Interface) unterstützt.

Das XHDI-Protokoll

Neben dem AHDI-Festplattentreiber von Atari erfreuen sich Treiber von Fremdherstellern schon seit einiger Zeit großer Beliebtheit. Dies liegt in erster Linie daran, daß AHDI bis auf die eigentlichen Treiberfunktionen keinen zusätzlichen Komfort bietet. Dabei ist es sehr praktisch, mit einem Treiber zu arbeiten, der beispielsweise das Booten von beliebigen Partitionen erlaubt oder andere Konfigurationsmöglichkeiten bietet.

Nimmt man die derzeit erhältlichen Festplattentreiber für den Atari unter die Lupe, stellt man fest, daß viele der zusätzlichen Features recht ähnlich sind. Angesprochen wurden diese bisher allerdings durch unterschiedliche Schnittstellen, da keine Normierung des Funktionsumfangs existierte. Die XFIDI-Spezifikation stellt nun eine einheitliche Schnittstelle zur Verfügung, die es erlaubt, eine Reihe plattenspezifischer Funktionen unabhängig vom verwendeten Treiber aufzurufen. Welche Funktionen sind das nun im einzelnen? Hier ein kurzer Überblick:

UWORD XHGetVersion(void);
Liefert die Versionsnummer des unterstützten XHDI-Protokolls zurück. Das High-Byte enthält die Version, das Low-Byte die Revision. $0123 stünde somit für Version 1.23. Die im folgenden auf geführten Funktionen entsprechen XHDI V1.00.

LONG XHInqTarget(UWORD major, UWORD minor,
*ULING blocksize,
**ULONG device_flags, char product_name);

Informationen über ein Gerät erfragen. block_size enthält eine Angabe über die physikalische Blockgröße auf dem spezifizierten Gerät, device_flags liefert einen Attributvektor, product_name die Produktbezeichung des angegebenen Gerätes

device_flags ist wie folgt organisiert:

Bit 0: Gerät kann gestoppt werden
Bit 1: Gerät hat wechselbare Medien
Bit 2: Auswurfmechanismus des Gerätes kann verriegelt werden
Bit 3: Medium kann per Kommando ausgeworfen werden
Bit 31: Gerät ist zur Zeit reserviert

LONG XHReserve(UWORD major, UWORD minor,
UWORD do_reserve, UWORD key);
Gerät reservieren (do_reserve=1) oder freigeben (do_reserve=0). In manchen Fällen kann es sinnvoll sein, daß ein Programm die XHDI-Funktionen für sich beansprucht und anderen Programmen den Zugriff verwehrt. Für reservierte Geräte sind XHDI-Aufrufe nur dann erlaubt, wenn der von XHReserve beim Reservieren zurückgelieferte Zugriffsschlüssel angegeben wird. Dieser Schlüssel wird auch dann benötigt, wenn ein Gerät wieder freigegeben werden soll.

LONG XHLock(UWORD major, UWORD minor, UWORD dojock, UWORD key);
Auswurfknopf einer Platte verriegeln (do_lock=1) oder entriegeln (do_lock=0). Dieser Befehl ist für Wechselplatten gedacht. Bei verriegeltem Auswurfknopf ist ein Entnehmen des Mediums nicht möglich. Virtuelle Speicherverwaltungen sollten diese Funktion dann nutzen, wenn sich die Swap-Partition auf einer Wechselplatte befindet.

LONG XHStop(UWORD major, UWORD minor, UWORD do_stop, UWORD key);
Platten parken (do_stop=1) oder starten (do_stop=0).

LONG XHEject(UWORD major, UWORD minor, UWORD do_eject, UWORD key);
Diese Funktion wirft ein Medium aus (do_eject=1) oder zieht es ein (do_eject=0). Bisher sind zwar noch keine Platten bekannt, die diese Funktion unterstützen, aber das kann sich ja in Zukunft noch ändern.

ULONG XHDrvMap(void);
Liefert einen Bit-Vektor zurück, der die Laufwerke beschreibt, die vom XHDI-Protokoll unterstützt werden. Der Aufbau dieses Vektors ist analog dem der GEMDOS-Funktion Drvmap().

LONG XHInqDev (UWORD bios_device,
*UWORD major, UWORD *minor, ULONG start_sector, BPB bpb);
Es werden Major Device Number, Minor Device Number, Startsektor und BPB des angegebenen BIOS-Gerätes zurückgeliefert. Dabei wird im Gegensatz zum BIOS-Aufruf GETBPB der Media-Change-Status nicht zurückgesetzt.

**LONG XHInqDriver (UWORD bios_device, char *name, char *version,char company, UWORD ahdi_version,
*UWORD maxIPL);
Diese Funktion gibt treiberspezifische Informationen zurück.

name: Zeiger auf Zeichenkette mit Treibernamen
version: Zeiger auf Zeichenkette mit Versionsnummer des Treibers
company: Zeiger auf Zeichenkette mit Namen des Herstellers
ahdi_version: AHDI-Versions-Level maxIPL: höchstes IPL (Interrupt Priority Level), unter dem der Treiber für das angegebene Gerät arbeitsfähig ist

Für die Beschreibung der XHDI-Aufrufe gilt folgende Terminologie:

major: Major Device Number
0..7: Atari-konforme Platte am ACSI-Bus
8..15: Platten am SCSI-Bus
16..63: reserviert für Erweiterungen
64: Gerät am Floppy-Controller
65..255: für eigene Erweiterungen

minor: Minor Device Number (LUN des ACSI- oder SCSI-Gerätes)

key: Entweder ein 16-Bit-Schlüssel, ermittelt von XHReserve() oder 0 bei nicht reserviertem Gerät oder unbekanntem Schlüssel

Wer sich detailliert über den Funktionsumfang des XHDI-Protokolls erkundigen will, findet die offizielle Spezifikation und Beispieldateien auf der Diskette zur vorliegenden Ausgabe der ST- Computer, in diversen Mailboxen [1] sowie eine ausführlichere Darstellung in [2].

Nun stellt sich natürlich noch die Frage, welche Treiber die XHDI-Spezifikation zur Zeit unterstützen. Hier wären HD-DRIVER V2.5 (im Lieferumfang von DISKUS und OUTSIDE enthalten), HuSHI V3.0 (Bestandteil der SCSI-Tools von Hard&Soft) sowie zukünftige CBHD-Versionen (gehört zur Scheibenkleister-Software) zu nennen. Weitere Festplattenhersteller haben angekündigt, auch in ihren Treibern das XHDI-Protokoll zu implementieren, so daß für eine breite Basis gesorgt sein dürfte.

XHDI-Anwendung

Aus dem XHDI-Überblick ist ersichtlich, daß mit XHStop() eine Funktion zum Parken von Platten zur Verfügung steht. Das AUTOPARK-Accessory schickt diesen Aufruf an alle Geräte, die von einem XHDI-Treiber verwaltet werden, sofern über einen gewissen Zeitraum kein Zugriff erfolgt ist. Welche Geräte in Frage kommen, läßt sich durch XHDrvMap() ermitteln. Dabei muß es sich nicht zwangsweise um Festplatten handeln, hier ist das XHDI-Protokoll flexibel. Der zuständige Treiber entscheidet, ob das jeweilige Gerät geparkt werden kann.

Da sich die XHDI-Spezifikation in erster Linie auf physikalische Geräte und nicht auf logische Laufwerke bezieht, nimmt AUTOPARK mit XHInqDev() eine Umrechnung der BIOS-Device-Nummern auf die physikalischen Gerätenummern vor. Alle per XHDI erreichbaren Geräte werden zunächst in einer Liste zusammengestellt. Anschließend werden diejenigen Geräte gestrichen, auf deren logische Laufwerke innerhalb des vorgegebenen Zeitrahmens ein Zugriff erfolgt ist. Die restlichen Geräte werden geparkt. Um alle angeschlossenen Platten sofort zu parken, kann der Knopf „Parken“ angeklickt werden. Wird auf ein geparktes Gerät zugegriffen, sorgt der XHDI-Treiber automatisch dafür, daß dieses auch wieder korrekt entparkt wird.

Die Zeit, die vom letzten Zugriff bis zum Parken verstreichen muß, kann dem AUTOPARK-Accessory auf zwei Wegen mitgeteilt werden. Entweder man benutzt den Accessory-Dialog oder verwendet eine Parameterdatei mit dem Namen „AUTOPARK.INF“, die sich in der Regel auf Laufwerk C befinden muß. Diese Datei enthält die Zeitangabe in Minuten, wobei maximal 3 Stellen ausgewertet werden.

Aller guten Dinge sind zwei

Manch einer mag sich fragen, warum es sich bei AUTOPARK um zwei Programme und nicht ausschließlich um ein Accessory handelt. Auf den ersten Blick hätte man die Funktionalität sicherlich auch in einer einzigen Programmdatei unterbringen können. Man muß allerdings berücksichtigen, daß AUTOPARK einen Systemvektor, nämlich hdv_rw, verbiegt. Das Verbiegen von Vektoren ist jedoch nur residenten Programmen erlaubt, die nicht mehr aus dem Speicher entfernt werden. Accessories sind zwar resident, aber nur bis zum nächsten Auflösungswechsel. Dann nämlich werden alle Accessories aus dem Speicher entfernt und in der geänderten Auflösung erneut geladen. Wurde nun zwischenzeitlich ein Systemvektor verändert, zeigt dieser anschließend ins Leere, da das Accessory keine Gelegenheit hat, den alten Inhalt vor dem Auflösungswechsel wiederherzustellen. Wer also innerhalb eines Accessories Vektoren verbiegt, hat den nächsten Absturz schon vorprogrammiert. Diejenigen, die das EDISON-Utility auf dem TT mit Farbbildschirm einsetzen, können ein Lied davon singen.

Um hdv_rw gefahrlos verbiegen zu können, wird also die PRG-Datei von AUTOPARK benötigt. Diese bleibt auch bei einem Auflösungswechsel im Speicher. Über den cookie jar wird die Adresse der Tabelle mit den letzten Zugriffszeiten an das Accessory weitergereicht.

Festplatten können beim Parken übrigens durchaus unterschiedlich reagieren. So bewegen manche Modelle lediglich ihren Kopf auf die Parkspur, andere wiederum schalten zusätzlich den Motor ab. Wechselplatten bremsen die Cartridge ab, wie es auch beim Betätigen des Auswurfknopfes der Fall ist.

Bitte beachten

Nicht geparkt werden kann eine Platte von AUTOPARK selbstverständlich dann, wenn das Laufwerk von einem anderen Programm, das ebenfalls das XHDI-Protokoll nutzt, mittels XHReserve() reserviert wurde. Dies kann beispielsweise bei den virtuellen Speichermanagern OUTSIDE und VRAM der Fall sein. Zum Arbeiten unter MultiTOS muß bei AUTOPARK.PRG das Global-Bit gesetzt werden, damit das Accessory auch bei aktiver Memory Protection ohne Busfehler auf die Datenstruktur des USPK-cookies zugreifen kann. Ferner muß sich hier die Datei AUTOPARK.INF nicht unbedingt auf Laufwerk C befinden, sondern es gelten die Pfadeinstellungen der GEM-Konfigurationsdatei.

Die Assembler-Direktiven „loadfast“, „tt-mem“ und „ttram“ sind für den EASY RIDER-Assembler gedacht und müssen bei der Verwendung eines anderen Assemblers entfernt werden.

US

Literatur:

[1] Beispielsweise Maus MS2 oder ftp.uni-muenster.de in /pub/atari/docs, jeweils abgelegt unter XHDI-100.ZOO

[2] Julian F. Reschke, „Die XHDI-Spezifikation“, ST-Magazin 6/92

***********************************
*                                 *
* XHDI-Autoparker V1.00 Accessory *
*                                 *
* by Uwe Seimet                   *
*                                 *
* (c) 1992 MAXON Computer         *
*                                 *
***********************************

DIALOG    = 0 
PARKTIME  = 3 
OK        = 6
PARK      = 7
ABORT     = 8

XHStop    = 4 
XHDrvMap  = 6 
XHInqDev  = 7

GEMDOS = 1 
SUPER  = 32 
FOPEN  = 61 
FCLOSE = 62 
FREAD  = 63

XBIOS       = 14 
SUPEXEC     = 38

APPL_INIT       = 10
EVNT_MULTI      = 25
MENU_REGISTER   = 35
OBJC_DRAW       = 42
OBJC_CHANGE     = 47
FORM_DO         = 50
FORM_DIAL       = 51
FORM_CENTER     = 54
GRAF_MOUSE      = 78
WIND_UPDATE     = 107
RSRC_OBFIX      = 114

END_MCTRL = 2 
BEG_MCTRL = 3

_hz_200   = $4ba
p_cookies = $5a0

XHDIMAGIC= $27011992

  loadfast
  ttmem
  ttram

  text

        lea stack+400,sp
        lea intin,a5            ;Pointer auf INTIN-Array

        lea intout,a6           ;Pointer auf
                                ;INTOUT-Array
        moveq #APPL_INIT,d0 
        move.l #$00010000,d1 
        bsr aes
        move (a6),(a5)          ;apid_.nr
        moveq #MENU_REGISTER,d0 
        move.l #$01010100,d1    ;Name in
        lea entry,a0            ;Menüleiste
        bsr aesobj              ;eintragen
        move (a6),d5            ;Nummer des
                                ;Eintrags 
                                ;merken
        bmi quit

        move #_objcnr,(a5) 
        bra.s fix 
obfix:  moveq #RSRC_OBFIX,d0
        move.l #$01010100,d1
        lea objc000,a0          ;Objektdaten
        bsr aesobj              ;umrechnen
fix:    subq #1,(a5)
        bpl obfix

        clr -(sp) 
        pea parname 
        move #FOPEN,-(sp) 
        trap #GEMDOS 
        addq.l #8,sp
        move.l d0,d3            ;keine
        bmi.s loop              ;Parameter-
        pea parbuff 
        pea 3
        move d3,-(sp) 
        move #FREAD,-(sp) 
        trap #GEMDOS 
        lea 10(sp),sp 
        move d3,-(sp) 
        move #FCLOSE,-(sp) 
        trap #GEMDOS 
        addq.l #4,sp 
        lea parbuff,a0 
        bsr get

loop:   move #$10,(a5)          ;MU_MESAG
        tst time 
        beq.s notime
        move #$30,(a5)          ;MU_MESAG|
                                ;MU_TIMER
        move.l #$ea600000,28(a5) ;1 min warten
notime: lea ev_buff,a0          ;Buffer für
                                ;GEM-Messages
        moveq #EVNT_MULTI,d0 
        move.l #$10070100,d1 
        bsr aesobj

        clr.l -(sp) 
        move #SUPER,-(sp) 
        trap #GEMDOS 
        addq.l #6,sp
        move.l d0,-(sp)         ;alter
                                ;Stackpointer

        move.l _p_cookies, d0   ;keine
        beq supret              ;cookies-
        sub.l a3,a3 
        sub.l a4,a4 
        move.l d0,a0 
fxhdi:  movem.l (a0)+,d0/a1
        tst.l d0 
        beq endjar 
        cmp.l #"XHDI",d0 
        bne.s noxhdi 
        cmp.l #XHDIMAGIC,-4(a1) 
        bne.s noxhdi 
        move.l a1,a4 
        bra fxhdi 
noxhdi: cmp.l #"USPK",d0
        bne fxhdi 
        move.l a1,a3 
        bra fxhdi
endjar: move.l a4,d0 ;kein
        beq supret              ;XHDI-Treiber-
        move.l a3,d0            ;AUTOPARK.PRG
        beq supret              ;nicht
                                ;installiert-

        btst #5,1(a6)           ;MU_TIMER?
        beq supret              ;nein-

        move #XHDrvMap,-(sp)    ;XHDI-
        jsr (a4)                ;Gerätevektor
        addq.l #2,sp            ;holen
        move.l d0,d6

*Liste aller XHDI-Devices erstellen
        lea devices,a2          ;Flag für
        move.l #-1,(a2)         ;Tabellenende
        moveq #0,d7 
inquire:bsr inqdev
        bmi.s inqnext 
        move.l major,(a2)+ 
        move.l #-1,(a2) 
inqnext:addq #1,d7 
        cmp #32,d7 
        bne inquire

*Totzeit uberprüfen 
        moveq # 0,d7 
test:   bsr inqdev
        bmi.s next 
        move d7,d0 
        add d0,d0 
        add d0,d0
        move time,d1            ;Zeit in
        mulu #12000,d1          ;200 Hertz-
                                ;Schritten 
        add.l (a3,d0),d1        ;letzte
                                ;Zugriffszeit
        cmp.l _hz_200,d1
        bcs.s next              ;parken-
        move.l major,d0 
        lea devices,a0 
skipdev:cmp.l #-1,(a0)
        beq.s next              ;Listenende
        cmp.l (a0)+,d0 
        bne skipdev
        move.l #-2,-4(a0)       ;aus Liste
        bra skipdev             ;streichen
next:   addq #1,d7
        cmp #32,d7 
        bne test

        lea devices,a2 
park:   cmp.l #-1,(a2)
        beq.s supret 
        cmp.l #-2,(a2)+ 
        beq park
        move.l -4(a2),major
        clr -(sp)               ;Dummy-Key
        move #1,-(sp)           ;Platte parken
        move minor,-(sp)
        move major,-(sp)
        move #XHStop,-(sp)
        jsr (a4)
        lea 10(sp),sp
        bra park

supret: move #SUPER,-(3p)
        trap #GEMDOS 
        addq.l #6,sp

message:btst #4,1(a6)           ;MU_MESAG?
        beq loop                ;nein-
        lea ev_buff,a0
        cmp #40,(a0)            ;AC_OPEN?
        bne loop                ;nein-
        cmp 8(a0),d5            ;AUTOPARK?
        bne loop                ;nein-
        moveq #BEG_MCTRL,d0
        bsr update
        bsr.s dialog
        moveq #END_MCTRL,d0
        bsr update
        bra loop

quit:
        moveq #19,d0            ;appl_exit
        move.l #$00010000,d1 
        bsr aes 
        clr -(sp)
        trap #GEMDOS            ;das war's

dialog:
        lea objc000,a2 
        move #PARKTIME*24,d0 
        move.l 12(a2,d0),a0 
        move.l (a0),a0 
        moveq #0,d0 
        move time,d0 
        bsr int
        moveq #FORM_CENTER,d0 
        move.l #$00050100,d1 
        move.l a2,a0 
        bsr aesobj
        movem.l 2(a6),a3-a4     ;form__xy,
                                ;form_wh
        clr d2
        movem.l a3-a4,2(a5) 
        movem.l a3-a4,10(a5) 
        bsr form_dial 
        moveq #OBJC_DRAW,d0 
        move.l #$06010100,d1 
        move.l #$00000002,(a5) 
        move.l 2(a6),4(a5) 
        move.l 6(a6),8(a5)
        move.l a2,a0            ;Dialogbox
        bsr aesobj              ;darstellen
        moveq #FORM_DO,d0
        move.l #$01010101,d1
        move #PARKTIME,(a5)     ;Eingabefeld
        move.l a2,a0            ;Dialog
        bsr aesobj              ;starten
        move (a6),d3 
        bclr #15,d3
        cmp #ABORT,d3           ;Abbruch?
        beq.s abort             ;ja-
        cmp #PARK,d3            ;alle Geräte
        beq.s parkall           ;parken-
        move #PARKTIME*24,d0 
        move.l 12(a2,d0),a0 
        move.l (a0),a0 
        bsr get 
abort:  moveq #3,d2
        movem.l a3-a4,2(a5)
        bsr fo_dial
        moveq #OBJC_CHANGE,d0
        move.l #$08010100,d1
        move.l a5,a0 
        move d3,(a0)+ 
        clr (a0)+
        movem.l a3-a4,(a0) 
        clr.l 12(a5)
        move.l a2,a0            ;Exit-Button
        bra aesobj              ;deselektieren

parkall:
        move #2,(a5)            ;Biene als
        moveq #GRAF_MOUSE,d0    ;Mauscursor
        move.l #$01010100,d1
        bsr aes
        pea stop(pc)
        move #SUPEXEC,-(sp)
        trap #XBIOS
        addq.l #6,sp
        clr (a5)                ;Pfeil als
        moveq #GRAF_MOUSE,d0    ;Mauscursor
        move.l #$01010100,d1 
        bsr aes 
        bra abort

stop:
        move.l _p_cookies,d0    ;keine
        beq.s error             ;cookies-
        move.l d0,a0 
nxhdi:  movem.l (a0)+,d0/a4
        tst.l d0 
        beq.s error 
        cmp.l #"XHDI",d0 
        bne.s nxhdi
        cmp.l #XHDIMAGIC,-4(a4) 
        bne.s nxhdi

        move #XHDrvMap,-(sp)    ;XHDI-
        jsr (a4)                ;Gerätevektor
        addq.l #2,sp            ;holen
        move.l d0,d6 
        moveq #0,d7 
nxt:    bsr inqdev
        bmi.s nxtdev
        clr -(sp)               ;Dummy-Key
        move #1,-(sp)           ;Platte parken
        move minor,-(sp) 
        move major,-(sp) 
        move #XHStop,-(sp) 
        jsr (a4) 
        lea 10(sp),sp 
nxtdev: addq #1,d7
        cmp #32,d7 
        bne nxt 
error:  rts

fo_dial:
        movem.l a3-a4,10(a5) 
form_dial:
        moveq #FORM_DIAL,d0 
        move.l #$09010100,d1 
        move d2,(a5)
aesobj:
        move.l a0,addrin 
aes:    lea contrl,a0
        move d0,(a0) 
        movep.l d1,3(a0) 
        move.l #aespb,d1 
        move #$c8,d0 
        trap #2 
        rts

update:
        move d0,(a5) 
        moveq #WIND_UPDATE,d0 
        move.l #$01010000,d1 
        bra aes

*Gerätenummer zu logischem Laufwerk erfragen 
inqdev:
        moveq #-1,d0
        btst d7,d6              ;kein
        beq.s nodev             ;XHDI-Device-
        clr.l -(sp)
        clr.l -(sp)
        pea minor
        pea major
        move d7,-(sp)
        move #XHInqDev,-fsp)    ;Gerätenummern
        jsr (a4)                ;holen
        lea 20(sp),sp 
nodev:  tst d0
        rts

*Umwandlung HEX in ASCII 
int:
        tst.l d0
        beq int5                ;Null-
        moveq #2,d3 
        move.l a0,a1
        move.l #100,d2          ;Startwert für Subtraktion 
int1:   moveq #-1,d1            ;zählt Subtraktionen
int0:   addq.b #1,d1
        sub.l d2,d0             ;so oft wie möglich subtrahieren
        bcc into add.l d2,d0
        divu #10,d2             ;nächste Stelle
        tst.b d1
        bne int3
        cmp.l a1,a0
        beq int4
int3:   add.b #"0",d1           ;Ziffer nach
        move.b d1,(a0)+         ;ASCII wandeln
int4:   dbra d3,int1
        clr.b (a0) 
        rts
int5:   move.b #"0",(a0)+
        clr.b (a0) 
        rts

*Umwandlung ASCII in HEX 
get:
        moveq #0,d0             ;Ergebnis löschen
        moveq #0,d1 
getloop:move.b (a0)+,d1         ;Ziffer holen 
        beq.s getret            ;Ende-
        sub.b #'0',d1           ;in HEX wandeln
        add.l d0,d0 
        move.l d0,-(sp) 
        asl.l #2,d0 
        add.l (sp)+,d0 
        add.l d1,d0 
        bra getloop 
getret: move d0,time
        rts


        data

aeapb:  dc.l contrl,global
        dc.l intin,intout 
        dc.l addrin,addrout

entry:  dc.b "  XHDI-Autoparker",0

parname:dc.b "AUTOPARK.INF",0

        even

G_BOX       = 20
G_TEXT      = 21
G_BUTTON    = 26 
G_FTEXT     = 29

objc000:dc.w $ffff
        dc.w $0001,$0008 
        dc.w G_BOX
        dc.w $0000,$0010
        dc.l $00021100 
        dc.w $0000,$0000 
        dc.w $0027,$000d

        dc.w $0002 
        dc.w $ffff,$ffff 
        dc.w G_BUTTON 
        dc.w $0001,$0011 
        dc.l spec000 
        dc.w $0008,$0001 
        dc.w $0017,$0801

        dc.w $0003 
        dc.w $ffff,$ffff 
        dc.w G_TEXT 
        dc.w $0000,$0000 
        dc.l spec001 
        dc.w $000b,$0004 
        dc.w $0410,$0001

        dc.w $0004 
        dc.w $ffff,$ffff 
        dc.w G_FTEXT 
        dc.w $0008,$0000 
        dc.l spec002 
        dc.w $0002,$0006 
        dc.w $0023,$0001

        dc.w $0005 
        dc.w $ffff,$ffff 
        dc.w G_TEXT
        dc.w $0000,$0000 
        dc.l spec003 
        dc.w $0004,$0008 
        dc.w $061e,$0001

        dc.w $0006 
        dc.w $ffff,$ffff 
        dc.w G_TEXT 
        dc.w $0000,$0000 
        dc.l spec004 
        dc.w $000a,$0009 
        dc.w $0012,$0001

        dc.w $0007 
        dc.w $ffff,$ffff 
        dc.w G_BUTTON 
        dc.w $0007,$0000 
        dc.l spec006 
        dc.w $0005,$000b 
        dc.w $0009,$0001

        dc.w $0008 
        dc.w $ffff,$ffff 
        dc.w G_BUTTON 
        dc.w $0005,$0000 
        dc.l spec006 
        dc.w $000f,$000b 
        dc.w $0009,$0001

        dc.w $0000 
        dc.w $ffff,$ffff 
        dc.w G_BUTTON 
        dc.w $0025,$0000 
        dc.l spec007 
        dc.w $0019,$000b 
        dc.w $0009,$0001

spec000:dc.b "XHDI-Autoparker V1.00",0

spec001:dc.l txt001,plt001,val001 
        dc.w $0005 
        dc.w $0006 
        dc.w $0000 
        dc.w $1180 
        dc.w $0000 
        dc.w $ffff 
        dc.w $0017,$0001 
txt001: dc.b "(C) 1992 by Uwe Seimet",0
plt001: dc.b 0
val001: dc.b 0

spec002:dc.l txt002,plt002,val002 
        dc.w $0003 
        dc.w $0006 
        dc.w $0002 
        dc.w $1180 
        dc.w $0000 
        dc.w $ffff 
        dc.w $0004,$0024 
txt002: dc.b "___",0
plt002: dc.b "Zeit bis zum Parken in Minuten: ___",0
val002: dc.b "999",0

spec003:dc.l txt003,plt003,val003 
        dc.w $0005 
        dc.w $0006 
        dc.w $0000 
        dc.w $1180 
        dc.w $0000 
        dc.w $ffff 
        dc.w $002a,$0001 
txt003: dc.b "XHDI-kompatibler Treiber und AUTOPARK.PRG",0
plt003: dc.b 0
val003: dc.b 0

spec004:dc.l txt004,plt004,val004 
        dc.w $0005 
        dc.w $0006 
        dc.w $0000 
        dc.w $1180 
        dc.w $0000 
        dc.w $ffff 
        dc.w $0019,$0001 
txt004: dc.b "müssen installiert sein!",0
plt004: dc.b 0

val004: dc.b 0

spec005:dc.b "OK",0 


spec006:dc.b "Parken",0 

spec007:dc.b "Abbruch",0 

_objcnr equ 0009


        bss

contrl: ds.w 11

global: ds.w 15

intin:  ds.w 64

intout: ds.w 64

addrin: ds.w 64

addrout: ds.w 64 

ev_buff: ds.w 8 

ap_buff: ds.w 8 

        even

stack:  ds.l 100

time:   ds.w 1

major:  ds.w 1
minor:  ds.w 1

devices: ds.w 68

parbuff: ds.b 4 ;Puffer für Parameterdatei

***************************************************
*                                                 *
*               XHDI-Autoparker V1.00             *
*                                                 *
*   Parkt Geräte, die von einem XHDI-Treiber      *
*  verwaltet werden, nach einer einstellbaren     *
*               Zeit automatisch.                 *
*                                                 *
* Benötigt werden AUTOPARK.PRG und AUTOPARK.ACC   *
*                                                 *
*                 by Uwe Seimet                   *
*                                                 *
*           (c) 1992 MAXON Computer               *
*                                                 *
***************************************************

GEMDOS   = 1 
CCONWS   = 9 
SUPER    = 32 
PTERMRES = 49 
POPEN    = 61 
FCLOSE   = 62 
FREAD    = 63 
MSHRINK  = 74

XBIOS    = 14 
SUPEXEC  = 38

resvalid = $426 
resvector= $42a 
hdv_rw   = $476 
_hz_200  = $4ba
_p_cookies= $5a0

XHDIMAGIC= $27011992 
USPK     = $5553504b

    loadfast

    ttmem
    ttram



        text

        move.l 4(sp),a5
        move.l 12(a5),a6            ;TEXT-Segment
        add.l 20(a5),a6             ;DATA-Segment
        add.l 28(a5),a6             ;BSS-Segment
        lea $100(a6),a6             ;für Basepage
        pea (a6) 
        pea (a5) 
        clr -(sp)
        move #MSHRINK,-{sp)         ;überzähligen
        trap #GEMDOS                ;Speicher
        lea 12(sp),sp               ;freigeben

        pea install(pc) 
        move #SUPEXEC,-(sp) 
        trap #XBIOS 
        addq.l #6, sp
        tst.b instflg               ;bereits
        bne.s quit                  ;installiert-

        pea message1 
        move #CCONWS,-(sp) 
        trap #GEMDOS 
        addq.l #6,sp
        add.l #newcook-lastacst,a6  ;für cookies 
        add.l cookmem,a6            ;benötigter
        sub.1 28(a5),a6             ;Speicher
        clr -(sp)
        pea (a6)                    ;Programm
        move #PTERMRES,-(sp)        ;resident
        trap #GEMDOS                ;halten

quit:   pea message2
        move #CCONWS,-(sp) 
        trap #GEMDOS 
        addq.l #6,sp
        clr -(sp)                   ;nicht
        trap #GEMDOS                ;installieren

install:
        move.l _p_cookies,d0        ;cookie jar
        bne.s jar                   ;vorhanden-

        move.l resvalid,valsave
        move.l resvector,vecsave
        move.l #reset,resvector
        move.l #$31415926,resvalid
        moveq #31,d1                ;32 cookie-
                                    ;Einträge
        lea newcook,a0 
        move.l a0,_p_cookies 
        bra.s newjar

jar:    move.l d0,a0
        lea newcook,a1
        moveq #0,d2                 ;zählt cookies
loop:   movem.l (a0)+,d0-d1
        cmp.l #DSPK,d0
        seq instflg                 ;schon
        beq.s ret                   ;installiert-
        movem.l d0-d1,(a1)          ;Einträge
        addq.l #8,a1                ;kopieren
        addq.l #1,d2
        tst.l d0
        bne loop
        subg.l #8,a0                ;cookie jar
        cmp.l d1,d2                 ;voll?
        bcs.s nofull                ;nein-
        lea -8(a1),a0               ;8 zusätzliche
        addq.l #8,d1                ;Einträge
        move.l #newcook,_p_cookies 
newjar: move.l d1,d2
        addq.l #1,d2
        asl.l #3,d2 
        move.l d2,cookmem 
nofull: lea lastacst,a1
        move.l #"USPK",(a0)+ 
        move.l a1,(a0)+ 
        movem.l d0-d1,(a0) 
        lea lastacst,a0 
        moveq #31,d0 
init:   move.l _hz_200,(a0)+        ;Timerwerte
        dbra d0,init                ;zurücksetzen
        move.l hdv_rw,old_rw 
        move.l #new_rw,hdv_rw 
ret:    rts


        dc.l "XBRA" 
        dc.l "USPK"
old_rw: dc.l 0
new_rw:
        move 14(sp),d0              ;Drivenummer
        cmp #32,d0                  ;Absicherung
        bcc.s norw                  ;gegen falsche
                                    ;Drivenummer
        add d0,d0 
        add d0,d0
        lea lastacst,a0             ;Zugriffszeit
        move.l _hz_200,(a0,d0)      ;merken
norw:   move.l old_rw(pc),a0
        jmp (a0)

*cookie jar nach Reset zurucksetzen 
reset:
        clr.l _p_cookies 
        move.l valsave,resvalid 
        move.l vecsave,resvector 
        jmp (a6)


        data

message1:dc.b $0d,$0a
        dc.b "XHDI-Autoparker V1.00 installiert" 
        dc.b $0d,$0a
        dc.b "(c) 1992 by Uwe Seimet",$0d,$0a,$00

message2:dc.b $0d,$0a
        dc.b "XHDI-Autoparker ist bereits " 
        dc.b "installiert",$0d,$0a,$00

        bss

lastacst:ds.l 32    ;Tabelle mit Zugriffszeiten 

valsave: ds.l 1     ;altes Reset-Magic

vecsave: ds.l 1     ;alter Reset-Vektor

newcook: ds.l 512   ;Platzhalter für 256 Einträge 

cookmem: ds.l 1     ;Größe des neuen cookie jar 

instflg: ds.b 1     ;Flag für Zweitinstallation

Uwe Seimet
Aus: ST-Computer 09 / 1992, Seite 100

Links

Copyright-Bestimmungen: siehe Über diese Seite