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.
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.
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.
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.
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