Besitzern von Farbmonitoren, die diese an einem ATARI ST betreiben, fällt meist zuerst eine - vor allem gemessen an dem guten Bild des SW-Monitors SM124 -unangenehme Flimmereigenschaft auf. Dies liegt daran, daß der Farbmonitor an den PAL-STs standardmäßig im 50-Hz-Modus betrieben wird, obwohl fast alle normalen Monitore auch 60 Hz verkraften. Dieser Artikel zeigt eine Möglichkeit, auch ohne Betriebssystemänderung praktisch jedes Programm auch mit 60 Hz laufen zu lassen, und das ohne zusätzlichen Aufwand beim Start der Diskette.
Das hier vorgestellte Programm läuft unter GFA-Basic und läßt sich ohne Probleme compilieren. Es ist von der TOS-Version unabhängig und läuft (bei mir) mit jeder Speicherkonfiguration .
Obwohl bisher noch absolut keine Schwierigkeiten aufgetreten sind, sollten grundsätzlich nur Sicherheitskopien, keine Originale, mit dem Programm bearbeitet werden -man weiß ja nie, ob irgendein Kopierschutz nicht gerade die veränderten Diskettenbytes abfragt.
Hier noch einmal die genaue Definition der Aufgabe: Nach einem Reset soll die Speicherstelle $ff8201, die die 50/60-Hz-Ausgabe des Videochips steuert, gelöscht werden, und das möglichst ohne zusätzlichen Aufwand und unter Verwendung von möglichst wenig Speicherplatz auf der Diskette.
Aus naheliegenden Gründen kann ein Programm im AutoOrdner hier nicht weiterhelfen, dabei kommerziellen (ins-besonders Spiel-) Programmen die normale Diskettenstruktur oft nicht eingehalten wird (oder ganz einfach kein Platz mehr auf der Diskette ist). Außerdem muß ein Auto-Ordner-Programm immer erst ge sucht und geladen werden.
Es bietet sich daher an, bei Disketten, die auch zusammen mit dem Farbmonitor benutzt werden, einen Bootsektor zu installieren, der bei einem Reset automatisch ausgeführt wird und auf 60 Hz umstellt. Bootsektor einer Diskette ist immer der erste Sektor, der sich auf ihr befindet. Beträgt die (Wort-) Summe aller Wörter in ihm $1234, so wird angenommen, daß sich ein ausführbares, im Speicher frei verschiebbares Installationsprogramm auf ihm befindet (ab Sektoradresse 0), und er wird im Verlauf der Reset-Routine (früher als z.B. der Auto-Ordner) ausgeführt (Rückkehr in Betriebssystem mit 'RTS'). Da sich dort aber auch noch andere Informationen befinden, hier ein kurzer schematischer Aufbau:
$00-$01
BRA.S anf; Branch zum Anfang des Programms
$02-$07
OEM-Bereich, ungenutzt (?)
$08-$ 1D
Hier wird die Anzahl der Tracks usw. definiert
$1E-$1FD
frei für Installationsprogramme
$1FE-$1FF
wird so berechnet, daß die Quersumme $1234 beträgt
Interessant ist hier : Es befinden sich am Anfang des Bootblocks zwei freie Bytes, die bei Bootsektoren einen Sprung zum Anfang des eigentlichen Installationsprogramms bewirken. Normalerweise wird hier der relative Sprung mit BRA.S be nutzt. Es schließen sich 6 Bytes an, die als OEM-Bereich bezeichnet und nicht benutzt werden. Da das Installationsprogramm, das hier in die Diskette eingeschleust werden soll, äußerst kurz ist (lösche ^ $ff8201, also clr.b $ff8201, und springe dann zurück), und möglichst Kompatibilität mit Disketten gewahrt bleiben soll, die den Bootblock bereits selbst benutzen, geht das Programm so vor:
Lies den Bootsektor der augenblicklich eingelegten Diskette ein:
Summiere alle Wörter des Bootblocks. Wenn die Summe $1234 beträgt, notiere, daß der Bootblock bereits ausführbar ist, und frage, ob der Bootblock überschrieben werden oder ob das alte Installationsprogramm nach dem neuen ausgeführt werden soll. Wenn Letzteres (Normalfall!), siehe nach, ob der erste Befehl ein BRA.S ist. Wenn ja, notiere die Anfangsadresse des alten Installationsprogramms. Wenn nein, so ist die Anfangsadresse nicht ermittelbar, brich ab.
Schreibe in die ersten 6 Bytes des Bootblocks das neue Installationsprogramm, nämlich:
clr.b $ff8201
rts
oder
clr.b $ff8201
bra.s alt
Je nachdem, ob ein altes Installationsprogramm schon existierte oder nicht, alt sei hier die relative Anfangsadresse des alten Programms.
Berechne das letzte Wort des Bootblocks so, daß die Summe aller Wörter $1234 ergibt.
Schreibe den Block wieder zurück auf die Diskette.
Für die Diskettenoperationen beim Spielen mit dem Bootsektor sollten übrigens immer die XBIOS-Funktionen benutzt werden, da diese nicht die Disk-infos auf dem Bootsektor selbst benutzen.
Das Programm hält sich selbst nicht an die in Punkt (3) aufgestellte Forderung, daß ein Bootsektor immer mit BRA.S beginnen sollte, deshalb kann das Programm nicht zweimal auf dieselbe Diskette angewandt werden.
' Makeparm V2.1
' Ändert den Parameterblock, so daß beim Start von Disk
' auf 60 Hz umgeschaltet wird.
' Achtung: Wenn eine Warnung erscheint, Änderungen zunächst
' nur auf Sicherheitskopien durchführen!!
'
' Geschrieben 1.8.1987 von
'
' Frank Wübbeling
' Stadtlohnweg 33 /E 30
' 4400 Münster
'
' Last Update 23.10.87
'
' (c) MAXON Computer GmbH 1987
'
starter:
ALERT 1,"Bitte zu bearbeitende|Disk einlegen.",1,"Ok|Exit",a
IF a=2
END
ENDIF
a$=SPACE$(512)
' Schaffe Raum für einen Diskettenblock
v=XBIOS(8,L:VARPTR(a$),L:1,0,1,0,0,1)
' Lies den ersten Block der Diskette
IF v<0
ALERT 3,"Parameterblock nicht lesbar!",1,"Ok",a
' Fehler beim lesen
GOTO starter
ENDIF
s=0
FOR i=1 TO 512 STEP 2
s=(s+ASC(MID$(a$,i))*256+ASC(MID$(a$,i+1))) AND 65535
' Bilde die Quersumme über alle Daten des ersten Blocks
NEXT i
' Wenn Summe=$1234, dann ist der Block ausführbar
IF s=&H1234
ALERT 3,"Bootblock existiert bereits!|Soll die Ausführung umgeleitet|werden?",1,"Ja|Nein|Exit",a
IF a=2
a=0
ENDIF
IF a=3
GOTO starter
ENDIF
IF a=1 AND ASC(a$)<>96
' Seltener Fall: der Block ist ausführbar, aber der erste Befehl
' ist kein Branch - da kann man nichts machen
' Oder ist die Disk bereits auf 60 Hz?
ALERT 3,"Patchen kann nicht|durchgeführt werden!",1,"Exit",a
GOTO starter
ENDIF
sc=ASC(MID$(a$,2))
' Sc enthält die Startadresse des alten Bootprogramms-2
ELSE
a=0
ENDIF
b$=MID$(a$,3,6)
b$=""
RESTORE
FOR i=1 TO 6
READ c
b$=b$+CHR$(c)
NEXT i
' Hier steht das Maschinenprogramm:
DATA &h42,&h38,&h82,&h0a
' clr.b $ff820a.w
DATA &h4e,&h75
' rts
IF a=1
b$=LEFT$(b$,4)+CHR$(&H60)+CHR$(sc-4)
' wenn der Bootblock bereits ausführbar ist:
' Branch zum Urprogramm ersetzt das RTS
ENDIF
a$=b$+MID$(a$,7)
' Ersetzt die ersten 6 Bytes im Bootblock durch das Maschinenprogramm
s=0
FOR i=1 TO 510 STEP 2
s=(s+ASC(MID$(a$,i))*256+ASC(MID$(a$,i+1))) AND 65535
NEXT i
s=(&H1234-s) AND 65535
b$=CHR$(s/256)+CHR$(s AND 255)
a$=LEFT$(a$,510)+b$
' Berechnet ein Wort und fügt es am Schluß in den Bootblock ein,
' Damit die Quersumme $1234 ist (=> Block ausführbar)
v=XBIOS(9,L:VARPTR(a$),L:1,0,1,0,0,1)
' Schreibt den ersten Block wieder zurück
IF v<0
ALERT 3,"Bootblock konnte nicht|geschrieben werden.",1,"Ok",a
' Fehler beim Zurückschreiben - vielleicht Diskette geschützt?
ENDIF
GOTO starter