Ein Großbildschirm ist sicherlich der Traum vieler ST-Besitzer - und wegen der hohen Kosten bleibt er für die meisten bestimmt auch weiterhin ein Traum. Trotzdem sind Großbildschirme und die damit verbundene Auflösungserhöhung nicht mehr aus dem Computeralltag wegzudenken, da sie in vielen Anwendungsgebieten enorme Vorteile bringen (z.B. DTP, CAD).
Ist man nun aber doch glücklicher Besitzer eines Großbildschirmes, hat man das Problem, daß sich ein nicht unbeträchtlicher Teil der gängigen Software außerstande sieht, diese Pixel-Darstellungswunder ordnungsgemäß zu betreiben. Also ist Software gefragt, die durch andere als die Standardauflösungen des ST nicht gleich außer Rand und Band gerät.
Angenommen, Sie wollten nun als (Hobby-) Programmierer mit naturgemäß immer zu kleinem Geldbeutel (und ohne Großbildschirm) solche Programme schreiben, würde bei Ihnen ein mittelgroßes Problem auftauchen, weil Sie die einwandfreie Funktion der Programme mangels Großbildschirm leider nicht austesten können.
„BigSTE“ kann Ihren SM 124 oder Fernseher zwar leider auch nicht in einen 10mal so teuren Großbildschirm verwandeln, aber das Programm kann Ihrem STE zumindest vorgaukeln, daß Sie neuerdings ein paar Pixel mehr darstellen können.
Insider werden jetzt zu Recht einwenden, daß ein Programm mit der eben beschriebenen Fähigkeit bereits existiert („Bigscreen“ von Julian Reschke [ 1 ]), das Ganze also kalter Kaffee ist. Ich habe mich daher ausschließlich der STEs mit ihren neuen Grafikfähigkeiten angenommen und ein Programm ähnlich „Bigscreen“ entwickelt, das die erweiterten Hardware-Fähigkeiten nutzt. Ging bei einem „normalen“ ST und „Bigscreen“ noch sehr viel wertvolle Prozessorzeit dabei verloren, die geänderte Auflösung auf dem Bildschirm darzustellen, macht das ein STE quasi mit Links, man muß nur wissen wie. Deswegen erst einmal ein kleiner Exkurs in die Videohardware der STEs.
Beim STE sind unter anderem die folgenden drei Videoregister ins Leben gerufen worden [2], die es dem Programmierer ermöglichen, dem Videochip flexiblere Darstellungen des Grafikspeichers mitzuteilen. Alle drei Register können sowohl gelesen, als auch beschrieben werden (s. Tab.l).
Diese drei Register machen es möglich, daß wir erhöhte Auflösungen ohne nennenswerten Arbeitsaufwand darstellen können. Natürlich stellt der Monitor jetzt nicht plötzlich 1280 * 800 Pixel dar, wir sehen immer nur einen bestimmten, verschiebbaren Ausschnitt daraus.
Aber, um es noch einmal zu betonen, der Rechenaufwand ist beim STE fast Null, während sich ein ST (ohne E) fast zu Tode arbeiten muß, um ein ähnliches Ergebnis zu liefern.
Das VBASELO-Register macht es möglich, pixelweise vertikal und in 16-Pixel-Schritten (Wortlänge!) horizontal zu scrollen. Pixel weise horizontal scrollen kann man erst mit Hilfe des HSCROLL-Registers, indem dort eine weitere Verschiebung um 0 bis 15 Pixel eingetragen wird.
Zum Verständnis der Wirkungsweise des LINEWID-Registers ein kleines Beispiel: Im Monochrommodus (1 Bitplane) hat eine Bildzeile bei 960 Pixeln horizontaler Auflösung eine Länge von 960 / 16 = 60 Wörtern.
40 Wörter (640 Pixel) werden in hoher Auflösung standardmäßig zur Anzeige gebracht, 20 Wörter müssen im virtuellen Bildschirm also übersprungen werden, um zu den Daten der nächsten Zeile zu gelangen (siehe Bild 1).
Diesen Offset kann man nun in das LINEWID-Register eintragen, und aus wirren Pixel-Mustern wird plötzlich ein ansehnliches Bild, wobei man beachten muß, daß man den Offset auch in Wörtern und nicht in Bytes angibt.
Sobald man jetzt aber in das HSCROLL-Register einen Wert ungleich 0 einträgt, hat man wieder Pixel-Müll auf dem Bildschirm, den man nur durch Verkleinern des Wertes im LINEWID-Register um 1 beseitigen kann. Angezeigt wird in diesem Moment ein Teil des 1. Wortes, dann 39 Wörter komplett und ein Teil des 4L Wortes, also 41 Wörter insgesamt. Daher beträgt die Distanz zur nächsten Zeile jetzt nur noch 19 anstatt 20 Wörter, was entsprechend im LINEWID-Register berücksichtigt werden muß.
Vorrangige Aufgabe des Programmes ist es natürlich, erst einmal dem GEM eine höhere Auflösung mitzuteilen. Dies geschieht durch eine Routine, die sich in den GEM-Vektor einschleift, auf den ersten OPEN WORKSTATION-Aufruf (v_opnwk) wartet und dessen Rückgabewerte sowie einige negative Line-A-Variablen [3] entsprechend abändert. Vorher muß natürlich noch der Bildschirmspeicher so vergrößert werden, daß er die Daten der erhöhten Auflösung aufnehmen kann.
Bezeichnung | Adresse | Bedeutung |
---|---|---|
VBASELO | $FF820D | Low-Byte der Bildschirmbasisadresse. Ermöglicht es, die Adresse auf eine Wortgrenze (bisher 256-Byte-Grenze) zu legen (niederwertigstes Bit wird nicht genutzt, deswegen nur gerade Adressen). |
LINEWID | $FF820E | Offset zur nächsten Zeile. Enthält die Anzahl der Wörter, die am Ende einer Zeile addiert werden, um zur nächsten Zeile zu gelangen. Das High-Byte wird nicht genutzt, daher sind nur Werte von 0 bis 255 möglich. |
HSCROLL | $FF8264 | Anzahl der Bits, um die der Bildschirm nach rechtsverschoben werden soll (ermöglicht horizontales, pixelweises Scrollen). Die Bits 4 bis 15 werden nicht genutzt, daher sind nur Werte im Bereich von 0..15 möglich. Bei einer Verschiebung um höhere Beträge muß das VBASELO-Register mitbenutzt werden. |
Tabelle 1: Die drei Videoregister des STE
Ist das getan, muß das LINEWID-Register entsprechend gesetzt werden (s.o.), um die geänderte Auflösung sichtbar zu machen. Ab jetzt ist nur noch ein Ausschnitt des gesamten Bildes zu sehen.
Um mit dem Programm sinnvoll arbeiten zu können, ist es wünschenswert, den angezeigten Bildausschnitt verschieben zu können. Dabei bietet es sich an, die Bewegung bzw. die Position des Mauszeigers bei der Wahl des Ausschnittes einzubeziehen, so daß der angezeigte Bereich immer mit dem Mauszeiger mitwandert.
Zwei Routinen erledigen diese Aufgabe:
Das waren soweit die wichtigsten Aktionen, die das Programm erledigen muß, um grundsätzlich zu funktionieren. Nun aber noch ein paar Worte zu den Nebensachen, die auch getan werden müssen, und die dem Programmierer das Leben meist am schwersten machen:
„BigSTE“ muß aus dem Auto-Ordner heraus gestartet werden!
(falls Sie einen GDOS-Treiber besitzen, unbedingt nach dessen Installation!!!)
Da „BigSTE“ vor der Initialisierung des AES installiert werden muß, ist es nötig zu testen, ob das Programm in der Boot-Phase aus dem AUTO-Ordner heraus gestartet wurde. Das können wir überprüfen, indem wir einen appl_init -Aufruf durchführen und den ersten Eintrag im global-Feld auf 0 testen [4]. Bekommt man dort bereits die Versionsnummer des AES und nicht den Wert 0 zurückgeliefert, wurde das Programm erst nach der Initialisierung des AES gestartet, also zu spät.
„BigSTE“ läuft nur auf den STEs!
Deswegen muß überprüft werden, ob der Rechner, auf dem das Programm gestartet wurde, auch ein STE ist. Um das zu testen, fallen mir mehrere Möglichkeiten ein:
Letzteres Verfahren ist wohl das „sauberste“ und funktioniert folgendermaßen: Die Systemvariable_p cookie {Adresse $5AO) enthält ein Langwort, das ab TOS 1.6 einen Zeiger auf einen Cookie-Jar darstellt [5]. Hat dieser Zeiger den Wert NULL (bei älteren TOS-Versionen), gibt es keinen Cookie-Jar, und der Test wird mit dem Ergebnis, daß es sich bei dem verwendeten Rechner wohl um keinen STE handelt, abgebrochen. Existiert aber ein Cookie-Jar, findet man an der Adresse, auf die _p_cookie zeigt, eine Tabelle mit Wertepaaren vor. In dieser Tabelle sollte sich ein Eintrag mit der Kennung _VDO befinden, wobei der zugehörige Wert die Version der Video-Hardware beschreibt. Hierbei steht ein Wert von $00000000 für die Video-Hardware eines normalen STs, $00010000 steht für die eines STEs und $00020000 für die eines TTs.
Das Programm soll nicht mehrfach installiert werden können!
Da die vom Programm benutzten Vektoren mit Hilfe des XBRA-Verfahrens umgelegt werden, kann man das relativ einfach abtesten, indem man die jeweiligen Vektorketten nach der eigenen XBRA-Kennung absucht. Dieses Verfahren funktioniert aber leider nur, wenn sich Programme, die sich vorher schon in dieselben Vektoren eingeklinkt haben, auch der XBRA-Kennung bedienen.
Wenn in niedriger und mittlerer Auflösungsstufe die Info-Box des Desktops angezeigt wird, wird vom Betriebssystem der TIMER-B benutzt, um die durchlaufenden Farben im Atari-Logo zeichnen zu können. Erstens benötigt „BigSTE“ diesen Timer zum Scrollen, und zweitens wird nach Verlassen der Info-Box der alte Vektor vom Betriebssystem nicht restauriert, daher wird der eigene Vektor vom Programm in jeder VBL-Routine aufs neue eingetragen, um eine einwandfreie Funktion des Programms zu gewährleisten. Auf eine bunte Info-Box muß man jetzt leider verzichten, aber das dürfte wohl eines der kleineren Übel sein.
Mit „BigSTE“ hat man die Möglichkeit, Auflösungen in gewissen Grenzen einzustellen. Die Programmierung der Auflösungseingabe wäre aber relativ aufwendig geworden und hätte das Programm unnötig aufgebläht, da das Programm in Assembler geschrieben ist. Daher habe ich noch ein kurzes Programm in GFA-BASIC geschrieben, das die Konfiguration von „BigSTE“ übernimmt. Es sollte, wie „BigSTE“, im AUTO-Ordner liegen, sinnvollerweise davor, damit sich die Konfiguration direkt auswirken kann. Das Programm wird bei einem Start aus dem AUTO-Ordner nur bei vorher aktiviertem CapsLock durchlaufen, ansonsten gleich wieder beendet! Man hat hier die Möglichkeit, folgende Einstellungen vorzunehmen:
Die Hardcopy-Routine des Betriebssystems kommt mit einer geänderten Bildschirmauflösung leider nicht zurecht, deswegen ist der Vektor dump vec (Adresse $502) auf eine eigene kleine (um nicht zu sagen winzige) Routine verbogen worden. Diese Routine macht schlicht und einfach nichts, außer sofort wieder zurückzuspringen. Auf eine Hardcopy-Funktion muß also leider verzichtet werden.
Zum Schluß noch ein paar Einschränkungen beim Umgang mit „BigSTE“:
Ein Auflösungswechsel über das Desk-top sollte vermieden werden, da „BigSTE“ auf diesen Wechsel nicht reagieren kann. (Es ist aber problemlos möglich, über einen Reset und eine entsprechende Konfiguration von „BigSTE“ die Auflösungsstufen zu wechseln.)
Werden Programme gestartet, die bezüglich der Bildschirmdarstellung „unsauber“ programmiert sind, kann es bei manchen dieser Programme passieren, daß auch nach deren Beendigung die Bildschirmdarstellung nicht mehr korrekt ist. Hier hilft dann meistens nur ein Reset.
Ich habe es trotz unzähliger Versuche leider nicht geschafft, in mittlerer und hoher Auflösung mit Hilfe der STE-Register pixelweise horizontal zu scrollen, ohne daß ein unschöner Seiteneffekt auftritt.
Und zwar klappt ständig ein Teil des rechten Bildes auf die linke Seite um, wenn der Inhalt des HSCROLL-Registers auf 0 wechselt. Hier scheint die Bildsynchronisation gehörig aus dem Tritt zu geraten. Alle Versuche, dieses Register zu verschiedenen Zeitpunkten während des Bildaufbaues zu ändern, haben keine befriedigenden Ergebnisse gebracht. Was bleibt, ist die Vermutung, daß pixelweises, horizontales Scrolling hardwaremäßig nur für die niedrige Auflösungsstufe gedacht ist. Auf eine diesbezügliche Anfrage bei Atari habe ich leider keine Antwort erhalten. Wer hier eine Lösung kennen sollte, möge sie mir bitte mitteilen. In mittlerer und hoher Auflösungsstufe kann deswegen leider auch nur in 16-Pixel-Schritten horizontal gescrollt werden.
Quellennachweis:
[1] Julian F. Reschke: Der weiche Großbildschirm, ST-Magazin 11/1988
[2] Martin Backschat: STarkes noch STErker, ST-Magazin 12/1989
[3] Julian F. Reschke: Saubere Fenster, ST-Magazin 10/1988
[4] Laurenz Prüßner: Reine Existenzfrage, ST-Magazin 2/1990
[5] Julian F. Reschke: Vorhang auf für die Keksdose, ST-Magazin 3/1990
; -----------------------------------------------------------
;
; BigSTE für Atari-STE
;
; Beschreibung: Simulation erhöhter Auflösungen auf dem Atari STE
; (STE-Hardware erforderlich)
;
; Autor: Matthias Andrä
; Sprache: Assembler
; Progammname: 'BIG_STE,PRG1 (unbedingt so benennen !!!)
;
; Version: 1.2 (c) 1991 MAXON Computer
;
; -----------------------------------------------------------
GEMDOS equ 1
GEM equ 2
XBIOS equ 14
LINE_A equ $A000 ; Line-A-Initialisierung
v_lin_wr equ $02 ; Line-A-Variable (Zeilenbreite)
BYTES_LIN equ -$02 ; negative Line-A-Variablen
V_REZ_VT equ -$04
V_REZ_HZ equ -$0C
V_REZ_WR equ -$28
V_CEL_MY equ -$2A
V CEL MX equ -$2C
V_CEL_HT equ -$2E
MOUSE_Y equ -$0258
MOUSE_X equ -$025A
DEV_TAB equ -$02B4
VBLVEKTOR equ $70 ; benutzte Vektoren
GEMVEKTOR equ $88
TIMERBVEK equ $0120
dump_vec equ $0502 ; Zeiger auf Hardcopy-Routine
_p_cookies equ $05A0 ; Zeiger auf Cookie-Jar
VBASEHI equ $FF8201 ; diverse (STE-)Video-Register
VBASEMID equ $FF8203
VBASELO equ $FF320D
LINEWID equ $FF820E ; Offset zur nächsten Zeile
HSCROLL equ $FF8264 ; Register für pixelweises Scrollen
IERA equ $FFFA07 ; Interrupt EnableRegister
ISRA equ $FFFA0F ; Interrupt In-Service Register
IMRA equ $FFFA13 ; Interrupt Mask Register
TBCR equ $FFFA1B ; Timer B Control Register
TBDR equ $FFFA21 ; Timer B Data Register
; ----------------------------------------------
text
bra.s start ; zu Programmstart springen
dc.b 'BSTE' ; Programmkennung
; Nachfolgende Variablen werden von 'K_BIGSTE.PR6'
; gepatcht und dienen zur Konfiguration von ’BigSTE'
aufloesung: dc.w 1 ; Farbauflosung (Mid/Low)
; BigSTE wird nicht installiert, wenn 'aufloesung' >1 !!!
rez_plus: dc.w 320,200,0,200,640,560
; Tabelle: zusätzliche Auflösungen
; wird zu Standardauflösung addiert
rand: dc.w 16,16,32,16,32,32
; Tabelle: hör./vert. Schieberänder
start:
movea.l 4(SP),A6 ; Basepageadresse
movea.w #$0500,A5 ; Größe der Basepage + Stackgröße
adda.l 12(A6),A5 ; + Größe TEXT-Segments
adda.1 20(A6),A5 ; + Größe DATA-Segments
adda.l 28(A6),A5 ; + Größe BSS-Segments
move.l A5,D1 ; = Gesamtlänge
and.b #$FE,D1 ; Länge gerade
add.l A6,D1 ; + Basepageadresse
movea.l D1,SP ; Stackende
move.l A5,-(SP) ; Programmlänge
move.l A6,-(SP) ; Basepageadresse
move.l #$4A0000,-(SP)
trap #GEMDOS ; Mshrink
lea 12(SP),SP
lea test_ste(PC),A0 ; auf STE testen
bsr supexec ; im Supervisormodus ausführen
tst.b ste ; STE-Hardware vorhanden?
beq no_ste ; nein, Abbruch
bsr appl_init ; 'appl_init' durchführen
tst.w global ; geglückt ?
bne auto ; dann Abbruch, da BigSTE nicht
; aus Auto-Ordner gestartet wurde
cmpi.w #2,aufloesung ; 'aufloesung' > 1 ?
bge not_installed ; dann BigSTE nicht installieren
dc.w LINEA ; Line-A-Init
move.l A0,linea_var ; Variabien-Startadresse merken
move.w #3,-(SP) ; Logbase
trap #XBIOS ; logische Bildschirmadresse
addq.l #2,SP
move.l D0,videobase ; merken
move.w #4,-(SP) ; Getrez
trap #XBIOS ; Auflösungsstufe holen
addq.l #2,SP ; Stack korrigieren
cmp.w #2,D0 ; hohe Auflösung ?
beq.s res_ok ; dann weiter
cmp.w aufloesung(PC),D0
; tats. Farbauflösung = gewünschter ?
beq.s resok ; ja, dann weiter
move.w aufloesung(PC),-(SP) ; Auflösung setzen (Voreinstellung)
move.l #-1,-(SP)
move.l #-1,-(SP)
move.w #5,-(SP)
trap #XBIOS
lea 12(SP),SP
move.w aufloesung(PC),D0
res_ok:
move.w D0,resolution ; merken
add.w D0,D0 ; *2
lea planes(PC),A0
move.w 0(AO,D0.w),planeanz
add.w D0,D0 ; *2 *2 = *4
lea rand(PC),A0 ; Zeiger auf Randtabellen
move.w 0(A0,D0.w),h_rand ; horizontaler Rand
move.w 2(A0,D0.w),v_rand ; vertikaler Rand
lea rez(PC),A0 ; Zeiger auf Auflösungstabelle
move.w 0(A0,D0.w),D6 ; Standardauflösung holen
move.w 2(A0,D0.w),D7
move.w D6,h_mon
move.w D7,v_mon
addi.w #1,h_mon ; +1 = Breite
addi.w #1,v_mon ; +1 = Höhe
move.w v_mon(PC),D3
lsr.w #1,D3
move.b D3,count ; halbe vertikale Auflösung
lea rez_plus(PC),A0 ; Tabelle Auflösungserhöhung
move.w 0(A0,D0.w),D4
add.w 2(A0,D0.w),D4 ; keine Auflösungserhöhung?
beq not_installed ; dann Ende
add.w 0(A0,D0.w),D6 ; X-Wert addieren
add.w 2(A0,D0.w),D7 ; Y-Wert addieren
move.w D6,h_rez ; und merken
move.w D7,v_rez
addq.w #1,D6 ; Breite
addq.w #1,D7 ; Höhe
lsr.w #3,D6 ; Breite / 8
mulu planeanz(PC),D6 ; * Anzahl Planes
mulu D6,D7 ; * Hohe = Bildschirmbedarf
add.l #255,D7 ; +255
and.1 #$FFFF00,D7 ; auf 256 Byte Grenze bringen
move.l D7,D6
sub.l #$8000,D6 ; -32k vorhandenen Bildschirmspeicher
move.l #-1,D0 ; Größten freien Speicherblock
bsr malloc ; erfragen
move.l D0,D5 ; Länge in D5
bsr malloc ; Speicher reservieren
movea.l D0,A0 ; Startadresse in A0
move.l D0,D4 ; und D4 merken
bsr mfree ; und gleich wieder freigeben
add.l D5,D4 ; Länge Speicherblock dazuaddieren
cmp.l videobase(PC),D4 ; Block direkt am Video-Ram?
bne.s new_v_ram ; nein, weiter
cmp.l D6,D5 ; genug Speicher frei?
blt memfull ; nein, Meldung ausgeben
sub.l D6,D5 ; Freier Speicher minus benötigter
move.l D5,D0 ; nach D0
bsr malloc ; 1. Block reservieren
movea.l D0,A6 ; Startadresse in A6 merken
move.l D6,D0 ; benötigter Speicherplatz
bsr malloc ; Block unter Video-Ram reservieren
tst.l D0 ; geklappt ?
bmi memfull ; nein, Meldung ausgeben
move.l D0,videobase ; Startadresse merken
movea.l A6,A0 ; Startadresse 1. Block
bsr mfree ; Block wieder freigeben
bra.s install1
new_v_ram:
cmp.l D7,D5 ; genug Speicher frei ?
blt memfull ; nein, Meldung ausgeben
move.l D7,D0 ; Speicher für Bildschirm
bsr malloc ; reservieren
tst.l D0 ; geklappt ?
bmi memfull ; nein, Meldung ausgeben
move.l D0,videobase ; Startadresse merken
; Das alte Videoram (32k) liegt jetzt brach,
; da kein Speicherblock direkt darunter
; reserviert werden konnte !
install1:
andi.l #$FFFF00,videobase ; auf 256-Byte-Grenze bringen
lea install2(PC),A0 ; ’install2' im
bsr supexec ; Supervisormodus
tst.b installiert ; BigSTE bereits installiert ?
bne installed ; dann Meldung und Abbruch
lea TEXT8(PC),A0 ; Bildschirm löschen
bsr printline
move.w #-1,- (SP)
move.l videobase(PC),-(SP) ; Physikalische
move.l videobase(PC),-(SP) ; und logische
move.w #5,-(SP)
trap #XBIOS ; Bildschirmadresse setzen
lea 12(SP),SP
lea TEXT0(PC),A0 ; Headertext
bsr printline
lea TEXT3(PC),A0 ; "BigSTE installiert"
bsr printline
clr.w -(SP)
move.l A5,-(SP)
move.w #$31,-(SP) ; Ftermres
trap #GEMDOS ; Programm resident halten und Ende
install2:
lea GEMVEKTOR, A0
bsr.s inst_test ; BigSTE schon im GEM-Vektor
bne.s install2end ; ja, Abbruch
move.l (A0),oldgenrvec ; alten GEM-Vektor sichern und
move.l #new_gem,(A0) ; eigene Routine eintragen
lea VBLVEKTOR,A0
bsr.s inst_test ; BigSTE schon im VBL-Vektor
bne.s install2end ; ja, Abbruch
move.l (A0),oldvblvec ; alten VBL-Vektor sichern und
move.l #new_vbl,(A0) ; eigene Routine eintragen
move.l dump_vec,olddumpvec ; alten Hardcopy-Vektor sichern
move.l #hardcopy,dump_vec ; Dummy-Routine eintragen
move.l TIMERBVEK,oldtimerb ; alten Timer-B-Vektor sichern
move.l #timer_b,TIMERBVEK ; Timer-B-Routine eintragen
ori.b #1,IERA ; Timer-B erlauben
ori.b #1,IMRA
install2end:
rts
; -- Testen ob ’BSTE'-Kennung bereits in
; Vektorkette vorhanden ist --------------
inst_test:
sf installiert
movea.l (A0),A1
testloop:
cmpa.l #$08,A1
blt.s testend
cmpi.l #'XBRA',-12(A1) ; XBRA-Kennung gefunden ?
bne.s testend ; nein, Ende
cmpi.l #'BSTE',-8(A1) ; Eigene Programmkennung gefunden ?
seq installiert ; Ja, BigSTE bereits installiert
beq.s testend ; und Ende
movea.l -4(A1),A1 ; Nein, XBRA-Kette weiterverfolgen
beq.s testend
bra.s testloop
testend:
tst.b installiert
rts
; -- Verschiedene (Fehler)-Meldungen ausgeben —
installed:
movea.l videobase(PC),A0
bsr mfree
lea TEXT1,A0 ; Headertext
bsr printline
lea TEXT7(PC),A0 ; "BigSTE bereits installiert"
bsr printline
bra.s waitkey
no_ste:
lea TEXT1(PC),A0 ; Headertext
bsr printline
lea TEXT6(PC),A0 ; "Benötigte Hardware fehlt"
bsr printline
bra.s waitkey
memfull:
lea TEXT1(PC),A0 ; Headertext
bsr printline
lea TEXT2(PC),A0 ; "Nicht genug Speicher"
bsr printline
waitkey:
move.w #7,-(SP)
trap #GEMDOS ; auf Tastendruck warten
addq.l #2,SP
bra.s ende ; und Ende
not_installed:
lea TEXT1(PC),A0 ; Headertext
bsr printline
lea TEXT4(PC),A0 ; "BigSTE nicht installiert"
bsr printline
bra.s ende
auto:
move.w #1,intin
move.l #TEXT5,addrin ; BigSTE aus Auto-Ordner starten !
bsr form_alert ; Meldung ausgeben ...
bsr appl_exit ; Applikation abmelden
ende:
clr.w -(SP)
trap #GEMDOS ; Ende
; — Rechner auf Vorhandensein der
; STE-Hardware testen -----------
test_ste:
movea.l _p_cookies,A0 ; Cookie-Jar vorhanden ?
beq.s tst_end ; Nein, dann kein STE
cookie_tst:
cmpi.l #'_VDO',(A0)+ ; gesuchte Cookie-ID gefunden?
beq.s cookie_val ; ja, dann Wert abtesten
lea 4(A0),A0 ; nächster Cookie
tst.l (A0) ; Ende der Liste ?
bne.s cookie_tst ; Nein, weiter
tst_end:
rts
cookie_val:
cmpi.l #$010000,(A0) ; Cookie-Wert mind. STE-Videohardware?
sge ste ; Flag entsprechend setzen
rts ; und zurück
; -- Hardcopy-Dummyroutine ----------------------
dc.b 'XBRA'
dc-b 'BSTE'
olddumpvec:
ds.l 1
hardcopy:
rts ; Bloß schnell wieder raus...
; ------------------------------------------------
; Timer-B-Interrupt starten und Mausaktionen überwachen ...
; -- VBL-Interrupt -----------------------------
dc.b 'XBRA'
dc.b 'BSTE'
oldvblvec:
ds.l 1
new_vbl:
sf half ; 1. Hälfte Bildschirm zählen
clr.b TBCR ; Timer anhalten
move.l #timer_b,TIMERBVEK ; Eigene Timer-B-Routine auf jeden
ori.b #1,IERA ; Fall einsetzen und
ori.b #1,IMRA ; Timer-B erlauben
move.b count(PC),TBDR ; 1/2 Bildschirm zählen
move.b #8,TBCR ; Event-Count-Mode starten
mouse:
movem.l D0-A0,-(SP) ; benutzte Register retten
movea.l linea_var(PC),A0 ; Adresse Line-A-Variablen
move.w MOUSE_X(A0),D0 ; Maus X-Position
move.w MOUSE_Y(A0),D1 ; Maus Y-Position
cmp w mousex(PC),D0 ; Mauaposition geändert ?
bne.s setnew ; ja, weiter
cmp.w mousey(PC),D1
beq mouseend ; nein, Abbruch
setnew:
move.w D0,mousex ; geänderte Mausposition verarbeiten
move.w D1,mousey
move.w x_pos(PC),D2 ; linke Ecke Bildschirmanzeige
move.w y_pos(PC),D3 ; obere Ecke
move.w D2,D4
move.w D3,D5
add.w h_mon(PC),D4 ; rechte Ecke
add.w v_mon(PC),D5 ; untere Ecke
add.w h_rand(PC),D2 ; Verschieberänder zu
sub.w h_rand(PC),D4 ; Bildschirmgrenzen
add.w v_rand(PC),D3 ; addieren (links und oben) und
sub.w v_rand(PC),D5 ; subtrahieren (rechts und unten)
cmp.w D2,D0 ; linker Rand erreicht ?
bgt.s pos1
move.w D2,D6
sub.w D0,D6 ; Verachiebewert (positiv)
sub.w D6,x_pos ; von Anzeigeposition subtrahieren
bge.s pos2
clr.w x_pos ; auf Null setzen
bra.s pos2
pos1:
cmp.w D4,D0 ; rechter Rand erreicht ?
blt.s pos2
move.w D4,D6
sub.w D0,D6 ; Verschiebewert (negativ)
sub.w D6,x_pos
move.w x_pos(PC),D6
add.w h_mon(PC),D6
cmp.w h_rez(PC),D6 ; schon ganz rechts?
blt.s pos2
move.w h_rez(PC),D6
sub.w h_mon(PC),D6
addq.w #1,D6
move.w D6,x_pos ; neue X-Position
pos2:
cmp.w D3,D1 ; oberer Rand erreicht?
bgt.s pos3 ; nein, weiter
move.w D3,D7
sub.w D1,D7 ; Verschiebewert
sub.w D7,y_pos
bge.s adresse
clr.w y_pos
bra.s adresse
pos3:
cmp.w D5,D1 ; unterer Rand erreicht ?
blt.s adresse ; nein, weiter
move.w D5,D7
sub.w D1,D7 ; Verschiebewert
sub.w D7,y_pos
move.w y_pos(PC),D7
add.w v_mon(PC),D7
cmp.w v_rez(PC),D7 ; schon ganz unten?
blt.s adresse ; nein, weiter
move.w v_rez(PC),D7
sub.w v_mon(PC),D7
addq.w #1,D7
move.w D7,y_pos ; max. untere Position
adresse:
moveq #0,D0
move.l D0,D1
move.w x_pos(PC),D0
move.w y_pos(PC),D1
movea.l videobase(PC),A0 ; Bildschirmbasisadresse holen
move.w D0,D2
and.w #$0F,D2
move.w D2,shift
lsr.w #4,D0 ; X-Position auf Wortgrenze
mulu planeanz(PC),D0 ; * Anzahl Planes
add.w D0,D0 ; in Bytes
adda.l D0,A0 ; zu Bildschirmbasis addieren
move.w h_rez(PC),D0 ; hor. Auflösung
addq.w #1,D0 ; +1
lsr.w #3,D0 ; /8
mulu planeanz(PC),D0 ; * Anzahl Planes = Bytes pro Zeile
mulu D1,D0 ; * Höhe
adda.l D0,A0 ; zu Bildschirmbasis addieren
move.l A0,videoadr ; neue Videoadresse merken
mouseend:
movem.l (SP)+,D0-A0 ; benutzte Register restaurieren
move.l oldvblvec(PC),-(SP) ; alte VBL-Routine
rts ; anspringen
; ---------------------------------------------
; Am Ende des Bildaufbaues Videoadressen setzen
; -- Timer-B-Interrupt ------------------------
dc.b 'XBRA'
dc.b 'BSTE'
oldtimerb:
ds.l 1
timer_b:
move.l D0,-(SP)
clr.b TBCR ; Timer Stop
move.b count (PC),TBDR ; Bildschirmzeilen zahlen
move.b #8,TBCR ; Event-Count-Mode starten
not.b half
bne.s hbl2end ; erst halber Bildschirm gezählt ?
setvideo:
tst.l videoadr ; aktuelle Videoadresse
beq.s hbl2end ; schon gesetzt ?
move.b videoadr+1(PC),VBASEHI ; Videoadresse Highbyte
move.b videoadr+2(PC),VBASEMID ; Videoadresse Midbyte
move.b videoadr+3(PC),VBASELO ; Videoadresse Lowbyte
clr.l videoadr ; gesetzt
move.w line_wid(PC),D0 ; Video-Offset
tst.w resolution ; Auflösung > Low-Resolution
bne.s hbl1end ; dann Ende
tst.w shift ; Wortgrenze (Pixelverschiebung=0)
beq.s set_shift ; ja, weiter
sub.w planeanz(PC),D0 ; nein, Offset - (1 *Anzahl Planes)
set_shift:
move.w shift(PC),HSCROLL ; Verschiebung in Pixeln
hbl1end:
move.w D0,LINEWID ; Video-Offset zur nächsten
; Zeile in Wortlänge
hbl2end:
move.l (SP)+,D0
bclr #0,ISRA ; In-Service-Bit löschen
rte
; ---------------------------------------------------
; Auf v_opnwk-Aufruf warten und Variablen patchen ...
; -- Trap #2 ----------------------------------------
dc.b 'XBRA'
dc.b 'BSTE'
oldgemvec:
ds.l 1
new_gem:
cmp.l #$73,D0 ; VDI-Aufruf ?
bne.s oldgem ; nein, zum normalen Aufruf
movea.l D1,A0
move.l $0C(A0),intoutadr ; intout-Adresse merken
movea.l (A0),A0 ; contrl-Adresse
cmpi.w #1,(A0) ; v_opnwk-Aufruf ?
bne.s oldgem ; nein, zum normalen Aufruf
move.l 2(SP),oldgemret ; Return-Adresse merken
move.l #set_vdi,2(SP) ; und neue setzen,
oldgem:
move.l oldgemvec(PC),-(SP) ; Normalen VDI-Aufruf
rts ; ausführen
set_vdi:
movea.l intoutadr(PC),A0 ; intout-Adresse
move.w h_rez(PC),(A0) ; horizontale Auflösung setzen
move.w v_rez(PC),2(A0) ; vertikale Auflösung setzen
set_linea:
movea.l linea_var(PC),A0
move.w h_rez(PC),V_REZ_HZ(A0) ; horizontale Auflösung setzen
addq.w #1,V_REZ_HZ(A0)
move.w h_rez(PC),DEV_TAB(A0)
move.w v_rez(PC),V_REZ_VT(A0) ; vertikale Auflösung setzen
addq.w #1,V_REZ_VT(A0)
move.w v_rez(PC),DEV_TAB+2(A0)
move.w V_REZ_HZ(A0),D0 ; horizontale Auflösung
lsr.w #3,D0 ; /8 = Bytes pro Zeile
move.w D0,V_CEL_MX(A0)
subq.w #1,V_CEL_MX(A0) ; maximale Cursorspalte
mulu planeanz(PC),D0 ; * Anzahl Planes
move.w D0,v_lin_wr(A0) ; Bytes pro Zeile
move.w D0,BYTES_LIN(A0)
mulu V_CEL_HT(A0),D0 ; * Zeichensatzhöhe
move.w D0,V_REZ_WR(A0) ; = Bytes pro Charakterzeile
moveq #0,D0
move.w V_REZ_VT(A0),D0 ; vertikale Auflösung
divu V_CEL_HT(A0),D0 ; / Zeichensatzhöhe
subq.w #1,D0 ; - 1
move.w D0,V_CEL_MY(A0) ; = maximale Cursorzeile
lea set_video(PC),A0 ; ’set_video' im
bsr.s supexec ; Supervisormodus ausführen
movea.l oldgemret(PC),A0
jmp (A0) ; in aufrufendes Programm zurück
set_video:
movea.l linea_var(PC),A0 ; Zeiger auf Line-A-Variablen
lea line_w(PC),A2 ; Zeiger auf Tabelle (Bytes/Zeile)
move.w resolution(PC),D1 ; Auflösungsstufe holen
add.b D1,D1 ; *2
move.w V_REZ_HZ(A0),D0 ; horizontale Auflösung
lsr.w #4,D0 ; /16
mulu planeanz(PC),D0 ; * Planesanzahl = Worte pro Zeile
sub.w 0(A2,D1.w),D0 ; - Worte pro Zeile (Standard)
move.w D0,LINEWID ; = Video-Offset zur nächsten Zeile
move.w D0,line_wid ; Offset merken
move.l oldgemvec(PC),GEMVEKTOR ; alten GEM-Vektor restaurieren
rts
; -- Betriebssystemaufrufe ----------------------
printline:
pea (A0) ; Startadresse in AO
move.w #$09,-(SP) ; Text auf Bildschirm ausgeben
bra.s trapgemdos
malloc:
move.l D0,-(SP) ; Länge in D0
move.w #$48,-(SP) ; Speicher reservieren
bra.s trapgemdos
mfree:
pea (A0) ; Adresse in A0
move.w #$49,-(SP) ; Speicher freigeben
trapgemdos:
trap #GEMDOS
bra.s stackkor
supexec:
pea (A0) ; Startadresse der Routine in a0
move.w #38,-(SP) ; im Supervisormodus
trap #XBIOS ; ausführen
stackkor:
addq.l #6,SP
rts
; -- GEM-Aufrufe --------------------------------
form_alert:
move.l #$340001,control
move.l #$010001,control+4
bra.s call2gem
appl_init:
move.l #$0A0000,control
bra.s call1gem
appl_exit:
move.l #$130000,control
call1gem:
move.l #$010000,control+4
call2gem:
clr.w control+8
move.l #aespb,D1
move.w #$C8,D0
trap #GEM
rts
; -----------------------------------------------
.data
rez: dc.w 319,199,639,199,639,399
; Tabellen:Standardauflösungen
line_w: dc.w 80,80,40
planes: dc.w 4,2,1
mousex: dc.w 0 ; alte Maus-X-Position
mousey: dc.w 0 ; alte Maus-Y-Position
half: dc.b 0
count: dc.b 0
ste: dc.b 0
installiert: dc.b 0
TEXT0: dc.b 27,'E'
TEXT1: dc.b 13,10,27,'p',' BigSTE ',27,’q Version 1.2',13,10
dc.b '5/91, Matthias Andrä',13,10,0
TEXT2: dc.b 'Nicht genug freier Speicher!!!',13,10,0
TEXT3: dc.b 'Installation durchgeführt ...',13,10,0
TEXT4: dc.b 'Nicht installiert ...',13,10,0
TEXT5: dc.b '[1][ |BigSTE muß unbedingt bei|Systemstart aus dem Auto-Ordner|herausgestartet werden!][ Ok ]',0
TEXT6: dc.b 'Hardwarevoraussetzungen nicht gegeben !',13,10,0
TEXT7: dc.b 'BigSTE bereits installiert!!!',13,10,0
TEXT8: dc.b 27,'E',0
aespb: dc.1 control,globa1,intin,intout,addrin,addrout
bss
linea_var: ds.l 1
intoutadr: ds.l 1
videobase: ds.l 1
videoadr: ds.l 1
oldgemret: ds.l 1
x_pos: ds.w 1 ; Darstellung ab X-Position
y_pos: ds.w 1 ; Darstellung ab Y-Position
h_mon: ds.w 1 ; hor. Monitorauflösung
v_mon: ds.w 1 ; vert. Monitorauflösung
hrez: ds.w 1 ; eingestellte hör. Auflösung
v_rez: ds.w 1 ; eingestellte vert. Auflösung
h_rand: ds.w 1 ; eingestellter hor. Schieberand
v_rand: ds.w 1 ; eingestellter vert. Schieberand
line_wid: ds.w 1
resolution: ds.w 1
planeanz: ds.w 1
shift: ds.w 1
control: ds.w 5
global: ds.w 15
intin: ds.w 16
intout: ds.w 7
addrin: ds.l 3
addrout: ds.l 1
end
' ******************************************
' * BigSTE-Konfigurationsprogramm 12/90 *
' * Version 1.02 Matthias Andra *
' * (c) 1991 MAXON Computer *
' ******************************************
'
Bootdev%=Dpeek(&H446)+65 ! Bootlaufwerk
Bste$=Chr$(Bootdev%)+":\AUTO\BIG_STE.PRG" ! Pfad BigSTE
Desktopinf$=Chr$(Bootdev%)+":\DESKTOP.INF" ! Pfad DESKTOP.INF
'
If Dpeek(Lpeek(Gb+4))<>0 Or (Bios(11,-1) And &H10)
' Programm normal gestartet,
' oder bei Systemstart aus Auto-Ordner mit Caps-Lock aktiv?
Void Bios(11,0) ! Caps-Lock desaktivieren
Print
If Exist(Bste$) Then ! 'BIG_STE.PRG' suchen
Open "U",#1,Bste$
Seek #1,&H1C+2
If InputS(4,#1)="BSTE" Then ! Programmkennung korrekt?
@Konfiguration ! Dann konfigurieren
Else
Print "'BIG_STE.PRG' ist nicht BigSTE ..."
Fehler!=True ! Programm unbekannt
Endif
Close #1
Else
Print "'BIG_STE.PRG' nicht gefunden ..."
Fehler!=True ! BigSTE nicht im Auto-Ordner.
Endif
Print
If Fehler! Then
Print "Konfiguration nicht möglich !!!"
Else
Print "BigSTE konfiguriert ..."
@Patch_desktop_inf ! Auflösung in "DESKTOP.INF" anpassen
Endif
Print
Endif
'
Pause 20
Edit
'
Procedure Konfiguration
' Einlesen der alten BigSTE-Parameter,
' Verändern der Werte durch Benutzer und
' neues Setzen der BigSTE-Parameter
Local A$,B$,A%
Repeat
Cls
Print '''''''Chr$(27);"p BigSTE -Konfiguration ";Chr$(27);"q"
Print " Version 1.02"
Print " von Matthias Andrä"
'
Seek #1,&H1C+6
'
A$="j"
Print At(1,5);"BigSTE Installation (j,n)?: ";
Form Input 1 As A$
A$=Upper$(A$)
A%=Cvi(Input$(2,#1))
Relseek #1,-2
If A$="J" Then
Print #1,Mki$(A% And 1);
Relseek #1,-2
@Werteingabe(7,"Farb-Auflösungsmodus [0,1] ?: ",0,1,1,1)
'
Print At(1,9);"Niedrige Auflösung (in Pixel)"
@Werteingabe(10,"Horizontal [320..1280]?: ",320,1280,16,4)
@Werteingabe(11," Vertikal [200..800]?: ",200,800,8,3)
Print At(1,9);"Mittlere Auflösung (in Pixel)"
@Werteingabe(10,"Horizontal [640..2560]?: ",640,2560,16,4)
@Werteingabe(11," Vertikal [200..800]? : ",200,800,8,3)
Print At(1,9);"Hohe Auflösung (in Pixel)"
@Werteingabe(10,"Horizontal [640..2560]?: ",640,2560,16,4)
@Werteingabe(11," Vertikal [400..1600]? : ",400,1600,16,4)
'
Print At(1,13);"Schieberand (niedrige Auflösung)"
@Werteingabe(14,"Horizontal [0..120] ?: ", 0,120,1,3)
@Werteingabe(15," Vertikal [0.75] ?: ", 0, 75,1,2)
Print At(1,13);"Schieberand (mittlere Auflösung)"
@Werteingabe(14,"Horizontal [0..240] ?: ",0,240,1,3)
@Werteingabe(15," Vertikal [0..75] ?: ", 0,75,1,2)
Print At(1,13);"Schieberand (hohe Auflösung) "
@Werteingabe(14,"Horizontal [0. 240] ?: ", 0,240,1,3)
@werteingabe(15," Vertikal [0.150] ?: ", 0,150,1,3)
'
B$="j"
Print At (1,17);"Eingaben in Ordnung (j, n): ";
Form Input 1 As B$
B$=Upper$(B$)
Else
Print #1,Mki$(A% Or 2);
Endif
Until A$<>"J" Or B$="J"
Return
'
Procedure Werteingabe(Y%,Text$,Min%,Max%,Schritt%,Stellen%)
' Automatisierte Werteingaberoutine
Local Wert$
Wert$=Str$(Cvi(Input$(2,#1))+Min%)
Repeat
Print At(1,Y%);Chr$(27);"K";Text$;
Form Input Stellen% As Wert$
Wert$=Str$((Val(Wert$) Div Schritt%)* Schritt%)
Until Val(Wert$)>=Min% And Val(Wert$)<=Max%
Print At(1,Y%);Chr$(27);"K";Text$;Wert$
Relseek #1,-2
Print #1,Mki$(Val(Wert$)-Min%);
Return
'
Procedure Patch_desktop_inf
Local A$,A%,B%,P%
Print
If Exist(Desktopinf$)
If Exist(Bste$) Then
Open "U",#1,Desktopinf$
Open "I",#2,Bste$
Seek #2,&H1C+2
If Input$(4,#2)=”BSTE" Then ! BigSTE Programmkennung korrekt?
A%=Cvi(Input$(2,#2)) ! BigSTE Auflösungsstufe lesen.
If A%<2 Then ! Soll BigSTE installiert werden?
A%=2-A% ! Auflösung in 'DESKTOP.INF'-Format
A$=Input$(Lof(#1),#1)
P%=Instr(A$,"#E ") ! Auflösungsinformation im "DESKTOP.INF"
If P%>0 Then ! gefunden?
B%=Val("&"+Mid$(A$,P%+7,1)) ! Lesen
If B%<>A% ! Auflösungen unterschiedlich?
Seek #1,p%+6
Out #1,Asc(Hex$(A%)) ! Auflösung in "DESKTOP.INF" schreiben.
Print "BigSTE-Auflösung in 'DESKTOP.INF' angepafit ..."
Endif
Endif
Endif
Else
Print "'BIGSTE.PRG' ist nicht BigSTE ..." ! Programm unbekannt.
Endif
Close
Else
Print "'BIG_STE.PRG' nicht gefunden ..."
Endif
Else
Print "'DESKTOP.INF' nicht gefunden ..."
Endif
Print
Return