von Harald Schönfeld Na, hat Euch der erste Teil schon ein wenig für QUICK begeistern können ? Ich hoffe es, denn der heutige Text steigt gleich voll in die "maschinennahe Pro- grammierung" ein, damit man sofort seh- en kann, was man in BASIC so alles ver- paßt. Zudem verlangt er dem einen oder anderen sicher schon ein bißchen Denk- arbeit ab. Vorweg noch eine Information: Bei PPP erschien in diesen Tagen das QUICKmagazin 6, auf dem sich ein Update des QUICK-Quelltexteditors befindet. In Zukunft wird natürlich dieser verbess- erte Editor auf der QUICK-Systemdisk bei uns ausgeliefert. Zunächst noch ein Wort zum letzten Text: Irgendwie sind da ein paar "(" und ")" verloren gegangen, bzw. durch "Ä" und "Ü" ersetzt worden. Da ich nun aber auch mit dem passenden Editor (CSM) ausgerüstst bin, müßte es dieses- mal klappen. Die Zeitanzeige Heute möchte ich zeigen, wie es in QUICK möglich ist eine einfache Zeitan- zeige zu programieren, die immer (also unabhängig von dem QUICK-Programm in dem sie läuft) funktioniert. Wie man weiß, gibt es ja schon einen 3 Byte-Zähler (18,19,20) im ATARI, der jede 50tel Sekunde um eins erhöht wird. Will man daraus jedoch eine leserliche Zeit machen, fängt das Herumgerechne an, so daß BASIC garantiert viel zu langsam ist, um die Zeit "nebenbei" an- zuzeigen. In QUICK macht man das des- halb besser ganz anders. Wir stürzen uns dazu gleich auf den VBI. Der Vertical Blank Interrupt wird ja nach jedem Bildschirmaufbau (also jede 50tel Sekunde) aufgerufen. Im VBI tut dann das Betriebssystem einiges, was uns hier aber nicht weiter inter- essiert. Wichtig ist nur, daß es in QUICK möglich ist, sich in diesen VBI einzuklinken. Das heißt wir haben so die Möglichkeit ein Programm zu schrei- ben, das exakt 50 mal pro Sekunde auf- gerufen wird (Unabhängig vom eigentlich laufenden QUICK-Programm). Damit ist das weitere Verfahren eigent- lich schon relativ klar: Wir schreiben einen VBI, der jedesmal, wenn er aufgerufen wird, einen Zähler (den 50stel-Sekunden-Zähler) um 1 er- höht. Hat dieser Zähler die Zahl 50 erreicht, bedeutet dies, daß wir den Sekunden-Zähler um 1 erhöhen müssen, und den anderen wieder auf Null setzen müssen. Haben wir dann irgendwann 60 Sekunden erreicht, geht das Spielchen mit dem Minutenzähler weiter, und ir- gendwann dürfen wir dann auch den Stun- denzähler erhöhen. Nun müssen wir noch irgendwie die Uhr- zeit auf dem Bildschirm sichtbar mach- en. Dazu nehme ich hier den unfeinen aber einfachen Weg, eine ARRAY-Variable (=String) direkt in den Bildschirmspei- cher zu legen. Der Grafik 0 Bildschirm beginnt bei QUICK immer bei 44096. Da ich die Uhrzeit im rechten oberen Eck anzeigen möchte, lege ich den Stringan- fang auf die Adresse 44128 (also ca. x-Position 32 in 0ter Zeile). Glück- licherweise ist es ja in QUICK möglich Variablen an jede Stelle im Speicher zu legen. Man muß sich dies also nicht vorschreiben lassen, wie das ja im BASIC der Fall wäre. Damit die Uhrzeit dann auch leserlich erscheint, müssen wir natürlich die Zahlen, die in SEK, MIN und STD stehen in Ziffern-Zeichen umwandeln. Dazu benutzen wir selbstverständlich ein Unterprogramm, denn diese Aufgabe wird ja 3 mal benötigt. Ich gehe dabei so vor, daß ich die Zahl zunächst durch 10 dividiere, so daß ich die Zehnerstelle in der Form einer Zahl von 0 bis 9 habe. Nun muß diese Zahl in ein Zeichen "0" bis "9" umgewandelt werden. Dazu sieht man am besten in einer Tabelle nach, in der der INTERNE Code der Zei- chen steht. Es stellt sich heraus, daß die Zahl+16 den Zeichencode der ent- sprechenden Ziffer ergibt. Dann wird die dividierde Zahl mit 10 multipli- ziert. Dabei kommt aber nicht die ur- sprüngliche heraus, weil die Einerstel- len beim Dividieren verloren gingen. Naja, und so brauchen wir diese Zahl nur vom ursprünglichgen Wert subtra- hieren, und schon haben wir auch die Einer-Zahl vorliegen. Die beiden Zeich- en werden nun ans rufende Programm (in diesem Fall der VBI(!)) zurückgelief- ert. Hier werden sie nun einzeln in den String eingetragen. Außerdem setze ich dann noch 2 ":" in den String ein, so daß die Zeit dann im "HH:MM:SS"-Format angezeigt wird. Und um es nochmal deut- lich zu sagen: Den String muß man nicht printen, weil er selbst im Bildschirm- speicher liegt. Praktisch, nicht wahr ? Man könnte anstatt den String zu ver- wenden zwar auch in den Bildschirm POKEN, aber das ist langsamer und un- praktischer. So, und damit sind wir auch schon fertig. Wie dem eifrigen Leser aufgefallen sein könnte, habe ich bisher nur den allge- meinen Algorithmus zur Lösung des Pro- blems beschrieben. Man könnte diesen Algorithmus nun ohne größere Schwierig- keiten in Assembler oder z.B. auch ACTION! übertragen. Aber das ist eine andere Geschichte. Es stellt sich die Frage: Wie geht's in QUICK ? Und damit's spannend bleibt, erkläre ich jetzt erst mal ein paar benötigte QUICK-Befehle. Zunächst brauchen wir ein paar globale Variablen, in denen wir die Zeit spei- chern können. Da wir pro Zeitmessein- heit nie weiter als bis 60 zählen müssen, können wir uns mit BYTE-Variab- len begnügen. Deren Deklaration sieht so aus: BYTE ( SEK,MIN,STD ) Außerdem wollen wir einen String der Länge 8 an die Adresse 44128 legen: ARRAY ( ZEIT-ANZ(8)=44128 ) Das "=" heißt hier also nicht "ist gleich" sondern "befindet sich an". Am Anfang wollen wir natürlich die Zeit auf 00:00:00 setzen. Das geht (Gott sei Dank) genauso wie in BASIC: SEK=0 MIN=0 STD=0 Aber alles in getrennten Zeilen ! Jetzt schalten wir den VBI ein. Er wird durch das Unterprogramm "ZEIT" darge- stellt: VBI(ZEIT) Und damit ist das Hauptprogramm eigent- lich fertig. Ab hier könnte dann das "richtige" Programm mit einer beliebi- gen Aufgabe folgen. Wir printen nun einfach ein paar Zeilen. Wie in BASIC kann man PRINT oder ? schreiben. Zu beachten ist aber, daß die Argumente (wie immer in QUICK) in Klammern stehen müssen. Die Argumente werden durch "," getrennt, wobei aber nicht wie im BASIC ein TAB erzeugt wird. Nach Zahlen wird automatisch ein " " erzeugt: ?("Das ist ein Text") So, nun kommen wir zum VBI, der oben eingeschaltet wurde. Das VBI-Unterpro- gramm beginnt mit INTER ZEIT Zu allererst müssen wir im VBI einige Variablen retten, die der Compiler intern in die Programmausführung des QUICK-Programms eingebaut hat. Z.B. kann man ja nicht Multiplizieren ohne intern ein paar Variablen zu gebrau- chen. Damit diese Variablen aber nach dem Ende des VBI genauso aussehen, wie beim Aufruf, speichern wir sie mit IPUSH ZPUSH ab, und holen sie ganz am Ende mit IPULL ZPULL wieder. Wohin diese Variablen gebracht werden weiß nur den Compiler... Der Hauptteil des VBI ist dann das Erhöhen der Zeitvariablen. In BASIC würde man dazu schreiben SEK=SEK+1. In QUICK geht die Erhöhung um eins dagegen so elegant wie in Assembler oder "C" mit: SEK+ Das ist nur bei BYTEs erlaubt. WORDs müßte man mit ADD(WO,1,WO) erhöhen. Nun kümmern wir uns im VBI um die Aus- gabe des Zeitzeichen indem wir in ZEIT-ANZ die entsprechenden Codes rein- schreiben (s.o). Man beachte diesen schönen Namen: ZEIT-ANZ ! Dieser Unterstrich, der im BASIC leider nicht erlaubt ist, macht die Sache richtig leserlich. Beendet wird der VBI dann mit ENDVBI. Dabei ergibt sich gleich noch eine Frage: Wie kann man den VBI jemals wieder ausschalten? Ganz einfach: Gar nicht ! Es bleibt nur eines zu tun. Man kann z.B. auf den VBI(NO-VBI) umschalten, der so aussieht: INTER NO-VBI BEGIN ENDVBI Und der tut dann eben nichts. Nun noch ein Wort zum Unterprogramm BY-TO-ASC, das, wie der Name schon sagt, unsere zweistellige Integer-Zahl in 2 ASC-Zeichen (eigentlich interne Zeichen) umwandelt. Das Prinzip ist ja oben erklärt. Interessant ist hier vor allem die Art der Variablenübergabe: Eine IN-Variable wird empfangen, und 2 OUT-Variablen werden zurückgegeben. Ich möchte hier noch auf die Befehle DIV(A,B,C) und MULT(A,B,C) hinweisen. Diese erzeugen das Ergebins: C=A/B und C=A*C. Wie man eventuell weiß, sind solche Terme in QUICK ja nicht erlaubt. Man muß sie immer in die Grundrechenarten ADD, SUB, MULT und DIV aufgliedern. So, jetzt ist's aber soweit: Für alle, die kein QUICK besitzen folgt nun der Programmtext zum ansehen. Alle die QUICK gekauft haben, können den Text CLOCK.QIK im QUICK-Editor laden und dann ausprobieren. Der Programmtext und das fertig compilierte Programm befin- den sich auf dieser Disk. Übrigens, ganz am Schluß des Textes steht nochmal etwas zu einem anderen Thema ! Quick-Sourcetext D1:CLOCK.QIK ---------------- Length: $0699 Free : $70D2 ---------------- * VBI-Uhr in QUICK * kann in eigenen Prgs. verwendet * werden * * (c) H.Schoenfeld '90 * fuer USER MAG BYTE ( SEK-50,SEK,MIN,STD VBI-Zeitspeicher ) ARRAY ( ZEIT-ANZ(8)=44128 String "im" Bild- * schirm ) MAIN CLOSE(6) OPEN(6,12,0,"E:") GRAPHICS 0 ein SEK-50=0 Zeit auf 00:00:00 SEK=0 MIN=0 STD=0 VBI(ZEIT) Uhr einschalten POS(0,8) ? ?("Nun laeuft der VBI von alleine.") ?("Im Hauptprogramm kann man nun") ?("machen was man will.") ENDMAIN INTER ZEIT LOCAL BYTE ( CH1,CH2 Ein-Zeichen Speicher ) BEGIN IPUSH Register retten ZPUSH SEK-50+ VBI zaehlt nun IF SEK-50=50 automatische jede SEK+ 1/50 Sekunde die SEK-50=0 Zeit hoch und setzt IF SEK=60 SEK, MIN, STD MIN+ entsprechend SEK=0 IF MIN=60 STD+ MIN=0 ENDIF ENDIF ENDIF ZEIT-ANZ(2)=26 2 mal ":" in String ZEIT-ANZ(5)=26 im BS schreiben .BY-TO-ASC(STD,CH1,CH2) BYTEs in ZEIT-ANZ(0)=CH1 2 Zeichen ZEIT-ANZ(1)=CH2 wandeln .BY-TO-ASC(MIN,CH1,CH2) und in ZEIT-ANZ(3)=CH1 String im ZEIT-ANZ(4)=CH2 BS eintragen .BY-TO-ASC(SEK,CH1,CH2) ZEIT-ANZ(6)=CH1 ZEIT-ANZ(7)=CH2 =>"HH:MM:SS" IPULL Register restaurieren ZPULL ENDVBI PROC BY-TO-ASC IN BYTE ( BY Uebergabevar. ans Unterprog. ) OUT BYTE ( C1,C2 Rueckgabe ans rufende Prg. ) LOCAL BYTE ( B1,B2 lokal nur im Unterprg. ) BEGIN DIV(BY,10,B1) Zehnerstellen in B1 ADD(B1,16,C1) in Bildschirmcode MULT(B1,10,B1) Zehnerstellen mal 10 SUB(BY,B1,B2) von Gesamtzahl sub- ADD(B2,16,C2) trahieren und als * Einerstelle in BScode ENDPROC Natürlich werde ich gerne Fragen zu QUICK beantworten. Und da im letzten USER-MAG schon eine gestellt wurde, folgt hier auch gleich eine Antwort. Warum kann man in QUICK zwar eine ST- Maus aber keine AMIGA-Maus abfragen ? Zunächst mal sollte man ja froh sein, daß man überhaupt irgendeine Maus ohne jede Probleme abfragen kann. Warum es aber gerade die ST-Maus ist, hat viele Gründe: 1. ST-kompatible Mäuse gibt es mehrere und die billigsten schon für ca. 60 DM. 2. ST-Mäuse halten länger als AMIGA- Mäuse, weil sie Mikrotaster anstatt billiger Folientaster haben. 3. Andreas Binner und ich haben je einen 1040ST mit 3MByte neben dem XL stehen. Die beiden Computer vertragen sich hervorragend weil: - ATARI an die kleinen gedacht hat, auch wenn's kaum einer glauben mag. Es gibt nämlich einen Assembler für den ST, der auch den 6502-Code des XL ka- piert. Damit kann man umfangreiche, speicherfressende Programme für den XL auf dem ST schreiben! So geschehen mit QUICK und SAM. Die Übertragung ge- schieht dann per serieller Schnittstel- le. - es ein Programm für den ST gibt, mit dessen Hilfe der ST 2 Floppys für den XL simuliert und die Daten dann auch wirklich auf "riesige" ST-Disks abspei- chern kann. Außerdem ersetzt der ST sogar das Centronicsinterface zum An- steuern der Drucker vom XL aus. (Anmerkung der Red.: Einige Fakten: Schon seit mehreren Monaten geht der Trend der 8-Bit-User ganz eindeutig dahin, sich einen AMIGA zuzulegen. Die Absatzzahlen des ST gehen immer weiter zurück, so daß zu befürchten steht, daß ATARI den ST wie den XL/XE bald zurück- stellen wird. Das ist nun mal leider ATARIs Mentalität. Wir rechnen damit im nächsten Jahr oder übernächsten Jahr. Mehrere internationale Softwarefirmen produzieren immer unwilliger Software für den ST, da sich die Absatzzahlen in immer niedrigeren Bereichen bewegen. 1000 verkaufte Einheiten gelten mit- unter schon als viel ! Da werden gerade mit Müh und Not die Entwicklungskosten gedeckt ! Übrigens gibt es jetzt einen echten ST-Emulator für den AMIGA ! Umgekehrt wird das nie zufriedenstel- lend möglich sein ! Und wir alle sprechen aus Erfahrung, wenn wir den AMIGA ganz klar als den Favouriten darstellen. Seine Technologie ist der des ST weit voraus (man denke nur an den Sound !). Aus diesem Grunde sollte QUICK auch sein kleines "Mäuschen" unterstützen) Soviel dazu. Viel Spaß noch mit QUICK ! Bis zum nächsten Monat.