von Tim-Philipp Müller Unser ATARI rechnet ja bekanntlich mit Bits. Natürlich stellt er neben dem ADC und SBC Befehl auch noch Befehle zur Bit- Bearbeitung zur Verfügung: ASL - Arithmetic Shift Left (arithmetisch links schieben) LSR - Logical Shift Right (logisch rechts schieben) ROL - ROtate Left one bit (um 1 Bit links rotieren) ROR - ROtate Right one bit (um 1 Bit rechts rotieren) AND - logical AND (logische UND- Verknüpfung) ORA - Or with accu (mit dem Akku oder-verknüpfen) EOR - Exclusive OR (exclusiv oder-verknüpfen) Das sind ja doch eine ganze Menge. Erstmal zu den Schiebebefehlen (ASL, LSR, ROL, ROR). Wir selbst rechnen ja mit einem Zehnersystem. Was passiert, wenn ich an die Zahl 16 hinten eine 0 dranhänge? Ich habe mit sie quasi mit 10 multipliziert (=160). Der Computer rechnet in einem zweier- System (Binär- oder DUAL- System). Was passiert also, wenn ich ich eine 0 an- füge? Ich multipliziere mit 2. Und das macht der Befehl ASL. Er schiebt die Bits um eine Stelle nach links, fügt eine 0 in Bit-0 ein, und packt das höchstwertige Bit, das ja 'rausgeschoben wurde, ins C-Flag: (C=0) 10001001 = $89 (=137) //////// ASL (C=1) 00010010 = $12 (=274-$100) (C=0) 00101101 = $2D (= 45) //////// ASL (C=0) 01011010 = $5A (= 90) Der Befehl LSR bewirkt genau das Gegen- teil, schiebt er doch alles nach links (dividiert durch 2), fügt in Bit-7 eine 0 an, und packt die herausgeschobene Stelle ins C-Flag: (137=) $89 =10001001 (C=0) ÖÖÖÖÖÖÖÖ ASL (68=) $44 =01000100 (C=1) Da 137 ungerade ist, bleibt bei der Halbierung ein Rest von 1, der im Carry landet. ROL bewirkt nun eigentlich das gleiche wie ASL, nur daß das Carry-Flag anstatt der 0 hintendrangehängt wird. ROR entspricht LSR, nur daß wieder das Carry statt der 0 in Bit-7 eingeschoben wird. Die 4 Schiebebefehle wirken entweder auf den Akku (ASL) oder verschieben eine Speicherzelle (ASL 712). steht für das Semikolon ! BYTE=BYTE*2: ASL BYTE ERG=BYTE*2: LDA BYTE ASL STA ERG WORD=WORD*2: ASL WORD ROL WORD+1 BYTE=BYTE/2: LSR BYTE WORD=WORD/2: LSR WORD+1 ROR WORD ----------------------------------- weiter geht's mit den Verknüpfungen: AND wirkt immer auf den Akku und 'klammer' alle Bits im Akku, die nicht im Wert hinter AND gesetzt sind, aus: LDA #$CE = %11001110 AND #$F AND %00001111 =$E = %00001110 ORA setzt die hinter ORA stehenden Bits schlicht und ergreifend auch im Akku (zu den im Akku stehenden hinzu): LDA #$43 = %01000011 ORA #$85 ORA %10000101 =$C7 = %11000111 EOR 'verdreht' alle Bits im Akku, die auch hinter EOR gesetzt sind: LDA #$FF = %11111111 EOR #$85 EOR %10000101 =$7A = %01111010 ------------------------------------ Ein praktisches Beispiel: Ein Hardcopy- Programm möchte die Farbwerte des Bilds in Grauwerte umwandeln. Es klammert also die oberen 4 Bits der Farbregister (die den Farbwert bestimmen) aus und erhält jeweils nur die Helligkeit. Weil Grauwerte aber so häßlich anzuschauen sind, möchte es alles in Braun- Werten anzeigen. (Braun=Farbwert 1) Also (Beispiel für ein Farbregister): LDA 712 Farbregister AND #$F nur helligkeit ORA #$10 dazu brauner Farbwert setzen STA 712 und eintragen. Falls Sie mit Farbregistern im BIBO- Assembler experimentieren, sollten Sie bedenken, daß der Editor die Farben immer eigenständig zurücksetzt! (also kein RTS am Ende des Programms). --------------------------------- REGISTER 632 = $278 = STICK0 REGISTER 633 = $279 = STICK1 Wenn der Joystick in die betreffende Richtung gedrückt wird, nimmt das entsprechende Bit = 0 an! Bit 0 ('wert'=1): hoch Bit 1 ('wert'=2): runter Bit 2 ('wert'=4): links Bit 3 ('wert'=8): rechts REGISTER 644 = $284 = STRIG0 REGISTER 645 = $285 = STRIG1 Wenn der Trigger (Feuerknopf) gedrückt ist, ist die Speicherzelle = 0! Joystickabfrage: STICK0=$278 STRIG0=$284 HOCH=1 RUNTER=2 LINKS=4 RECHTS=8 JOY LDA STRIG0 Knopf gedrückt? BNE .1 wenn nicht weiter RTS sonst schluß .1 LDA STICK0 AND #HOCHB Hoch-bit BNE .2 ausklammern JSR NACHOBEN .2 AND #RUNTERB Runter-Bit BNE .3 ausklammern JSR NACHUNTEN .3 AND #LINKSB Links-Bit BNE .4 JSR NACHLINKS .4 AND #RECHTSB Rechts-Bit BEQ JOY JSR NACHRECHTS anstatt der Punkte kann man nun eigene Routinen einfügen. Es muß nur darauf geachtet werden, daß entweder der Akku nicht benutzt wird, oder nachher jeweils wieder das Joystick- Register in den Akku geladen wird. ------------------------------- REGISTER 53279 = $D01F = CONSOL Bit 0 (wert=1): START Bit 1 (wert=2): SELECT Bit 2 (wert=4): OPTION Wenn die entsprechende Taste gedrückt wurde, besitzt das Bit den Wert 0. ------------------------------- Nun aber etwas Handfestes - der allseits bekannte Farb-Scroller: 00010 .LI OFF 00020 .OR $4000 00030 00040 COLPF2=$D018 00050 WSYNC=$D40A 00060 VCOUNT=$D40B 00070 RTCLOK=$14 00080 CONSOL=$D01F 00090 00100 SCROL LDA VCOUNT Bild-Zeile 00110 ADC RTCLOK + Counter 00120 STA WSYNC warten.. 00130 STA COLPF2 Farbe Back 00140 00150 LDA CONSOL 00160 AND #1 START? 00170 BNE SCROL nein->weiter 00180 RTS Erstmal die Register- Erklärung: Schreiben wir in 710 einen Farbwert, wird die Hintergrund- Farbe erst beim nächsten Bildschirmaufbau geändert. Wir wollen die Farbe aber während dessen ändern. Also müssen wir so gennante Hardware- Register verwenden. Für die Farben sind dies: (709) 53271 = $D017 = COLPF1 (710) 53272 = $D018 = COLPF2 (712) 53274 = $D01A = COLBK Damit das ganze nicht flackert, muß das erledigt werden, wenn der Elektronen- strahl des Monitors (unsichtbar) vom rechten Bildschirmrand nach links zu- rückfährt, um die nächste Zeile aufzu- bauen. Dazu stellt der Compy uns auch ein Register zur Verfügung: 54282 - $D40A - WSYNC Wird ein beliebiger Wert in dieses Register geschrieben, wird die 6502- Zentraleinheit (die ja unser Programm ausführt), solange gestoppt, bis der Elektronenstrahl das Ende der Bild- schirmzeile erreicht hat. Jetzt fehlt nur noch ein Register: 54283 - $D40B - VCOUNT Dieses Register enthält die Nummer der momentan aufgebauten Bildschirmzeile geteilt durch zwei (bei PAL- Geräten zwischen 0 und 155). Nun also zum Programm: Erst wird ermittelt, in welche Zeile des Bildes gerade aufgebaut wird. Dazu wird dann der Wert der Speicherzelle 20 (der Timer, der alle 1/50 Sekunde, also jeden Bildschirmaufbau erhöht wird) addiert. Das ganze wird jetzt in WSYNC geschrieben, um Flackern zu vermeiden. Dann wird der Wert als Hintergrund- Farbe gesetzt. Nun wird die START-Taste abgefragt. Ist sie nicht gedrückt worden, geht der Kram weiter. Da die Speicherzelle 20 nach dem Bildschirmaufbau ja um eins erhöht worden ist, erhält jede Bild- schirmzeile jetzt ihren vorigen Farbwert+1 (das ist der Wert, der die Zeile darunter gehabt hat). Dadurch wird ein Scroll- Effekt erzeugt. Fügen Sie nach 'LDA VCOUNT' doch einmal einen ASL- oder LSR- Befehl ein. Oder binden Sie unser kleines Programm von vorhin ein, das erst die Helligkeits- Werte ermittelt, und dann den Farbwert setzt. ------------------------------ Hier noch eine kleine Hardware-Register Spielerei: WSYNC=$D40A RANDOM=$D20A COLPF2=$D018 START LDA RANDOM STA COLPF2 JMP START 53770 - $D20A - RANDOM kann als 'Zufallszahl'- Register verwendet werden. Fügen Sie doch nach 'LDA RANDOM' noch einen 'STA WSYNC'- Befehl ein, oder zwei, oder drei, oder ein 'AND #$F'... Viel Spaß beim Experimentieren Good Byte Nächstes Mal geht's um Adressierungs- Arten und zwei weitere 'Akkus'- nämlich das Y- und X-Register.