|
|
Line 1: |
Line 1: |
− | [http://translate.google.com/translate?hl=de&ie=UTF-8&sl=de&tl=en&u=http://c64mags.untergrund.net/wiki/index.php%3Ftitle%3DDT_84_16&prev=_t English Translation]
| |
− | <pre>
| |
− | Hallo Leute,
| |
− | ______________
| |
| | | |
− | ich möchte Euch auch diesmal wieder ein
| |
− | kurzes Programm vorstellen. Programmiert
| |
− | habe ich es abermals mit dem Turbo-
| |
− | Assembler und ich werde Euch anhand des
| |
− | Quelltextes die Funktionsweise erklären.
| |
− |
| |
− | Das Programm bewirkt folgendes:
| |
− |
| |
− | Ein Zeichensatz, der die ersten 64 Zei-
| |
− | chen umfasst, soll pixelweise eingeblen-
| |
− | det werden. Ihr kennt diesen Effekt
| |
− | vielleicht von diversen Programmen, mit
| |
− | denen man sog. Notes erstellt.
| |
− | </pre>
| |
− | <pre>
| |
− | Dabei werden die Textseiten meist mit
| |
− | bestimmten Effekten eingeblendet. Hier
| |
− | wollen wir dasselbe erreichen. Dieser
| |
− | Einblend-Effekt wird jedoch nicht nach
| |
− | einem zuvor festgelegten Muster bewirkt,
| |
− | sondern per Zufall.
| |
− |
| |
− | Ein Zeichen besteht aus 8 Bytes und je-
| |
− | des Byte aus 8 Bits. Diese 64 Bits wol-
| |
− | len wir per Zufallsgenerator einblenden
| |
− | lassen. Um dies zu realisieren, benöti-
| |
− | gen wir einen Zeichensatz und eine Ta-
| |
− | belle, die sich aus zufällig durcheinan-
| |
− | der gewürfelten Werten zusammensetzt.
| |
− | Anhand dieser einmaligen Werte soll je-
| |
− | des Zeichen eingeblendet werden.
| |
− | </pre>
| |
− | <pre>
| |
− | Die Umsetzung des Ganzen ist eigentlich
| |
− | einfach, das Ganze läuft auch nicht im
| |
− | IRQ ab.
| |
− |
| |
− | Nun zum Code:
| |
− |
| |
− | *= $1000 (Startadresse ist $1000 =
| |
− | 4096 dezimal, das Programm
| |
− | wird somit mit SYS 4096
| |
− | gestartet)
| |
− |
| |
− | sei
| |
− | lda #51
| |
− | sta $01
| |
− | ldy #$00
| |
− | a1 lda $d000,y
| |
− | </pre>
| |
− | <pre>
| |
− | sta $2000,y
| |
− | lda $d100,y
| |
− | sta $2100,y
| |
− | lda #$00
| |
− | sta $2800,y
| |
− | sta $2900,y
| |
− | iny
| |
− | bne a1
| |
− | lda #55
| |
− | sta $01
| |
− | cli
| |
− |
| |
− | > Die ersten 64 Zeichen des C64-ROM-
| |
− | > Zeichensatzes werden nach $2000-$2200
| |
− | > kopiert. Der Bereich von $2800-$2A00
| |
− | > wird freigemacht, weil dort der
| |
− | </pre>
| |
− | <pre>
| |
− | > Zeichensatz aus $2000 eingeblendet
| |
− | > wird.
| |
− |
| |
− | jmp a2
| |
− |
| |
− |
| |
− | <-------------------------------------->
| |
− |
| |
− |
| |
− | rand inc val
| |
− | ldy val
| |
− | lda $dc04
| |
− | eor $fedc,y
| |
− | eor $d012
| |
− | sta $57
| |
− | rts
| |
− | </pre>
| |
− | <pre>
| |
− | val .byte 0
| |
− |
| |
− | > Hier wird eine Zufallszahl von 0-255
| |
− | > generiert.
| |
− | > Wie dies geschieht, werde ich nicht
| |
− | > erklären.
| |
− | > Der Wert wird in $57 gespeichert.
| |
− | > Das Label 'rand' wird immer dann
| |
− | > angesprungen, wenn ein neuer Zufalls-
| |
− | > wert benötigt wird.
| |
− |
| |
− | <-------------------------------------->
| |
− |
| |
− | a2 jsr $e518
| |
− | lda #$01
| |
− | sta $0286
| |
− | </pre>
| |
− | <pre>
| |
− | lda #$93
| |
− | jsr $ffd2
| |
− | ldy #$00
| |
− | a3 tya
| |
− | sta $0400,y
| |
− | iny
| |
− | cpy #$40
| |
− | bne a3
| |
− | lda #26
| |
− | sta $d018
| |
− |
| |
− | lda #$00
| |
− | sta $58
| |
− |
| |
− | > Bildschirm wird initialisiert,
| |
− | > gelöscht und alle Zeichen von 0-63
| |
− | </pre>
| |
− | <pre>
| |
− | > ausgegeben. Danach wird der Zeichen-
| |
− | > satz ab $2600 eingeschaltet. Da sich
| |
− | > dort nur leerer Speicher befindet,
| |
− | > sieht man zunächst nichts auf dem
| |
− | > Bildschirm.
| |
− | >
| |
− | > Die Speicherstelle $58 wird
| |
− | > freigemacht, dort wird im folgenden
| |
− | > die Anzahl der Zufallszahlen
| |
− | > gespeichert.
| |
− |
| |
− | <-------------------------------------->
| |
− |
| |
− | a4 jsr rand
| |
− | and #$c0
| |
− | bne a4
| |
− | </pre>
| |
− | <pre>
| |
− | > Eine Zufallszahl wird mit JSR rand
| |
− | > geladen und mit der
| |
− | > and #$c0 Verknüpfung darauf überprüft,
| |
− | > ob sich diese auch nur von 0-63
| |
− | > erstreckt. Ist der Wert im Akkumulator
| |
− | > nicht null, dann wird nach Label a4
| |
− | > zurückgesprungen und eine neue Zahl
| |
− | > angefordert, da die Zahl in diesem
| |
− | > Moment größer als 63 ist.
| |
− |
| |
− | lda $58
| |
− | bne a5
| |
− | a7 ldx $58
| |
− | lda $57
| |
− | sta $03c0,x
| |
− | inc $58
| |
− | </pre>
| |
− | <pre>
| |
− | lda $58
| |
− | cmp #64
| |
− | beq a8
| |
− | jmp a4
| |
− |
| |
− | > Die Tabelle der Zufallszahlen wird
| |
− | > ab $03c0 gespeichert.
| |
− | >
| |
− | > Hier wird u.a. die erste Zahl
| |
− | > verarbeitet, da diese in jedem Fall
| |
− | > einmalig ist. Dazu wird diese
| |
− | > gespeichert und der Zähler in $58 um
| |
− | > eins erhöht. Da die folgende Prozedur
| |
− | > auch auf diesen Bereich zugreift, wird
| |
− | > zudem geprüft, ob $58 bei 64 angelangt
| |
− | > ist, da in diesem Fall die Tabelle
| |
− | </pre>
| |
− | <pre>
| |
− | > voll ist. Wenn ja, wird per BEQ a8
| |
− | > die Generierung der Tabelle beendet.
| |
− |
| |
− | a5 ldy #$00
| |
− | a6 lda $03c0,y
| |
− | cmp $57
| |
− | beq a4
| |
− | iny
| |
− | cpy $58
| |
− | bne a6
| |
− |
| |
− | jmp a7
| |
− |
| |
− | > Die Schleife ab Label a5 überprüft, ob
| |
− | > der aktuelle Zufallswert bereits in
| |
− | > der Tabelle vorhanden ist. Wenn ja,
| |
− | </pre>
| |
− | <pre>
| |
− | > wird per BEQ a4 zurückgesprungen.
| |
− | > Ansonsten wird ab Label a7 der Wert in
| |
− | > die Tabelle übernommen.
| |
− | >
| |
− | > Die Generierung dieser Tabelle dauert
| |
− | > hier weniger als eine Sekunde.
| |
− | > Per Basic dauert es dagegen mehr oder
| |
− | > weniger als eine Minute!
| |
− |
| |
− | <-------------------------------------->
| |
− |
| |
− | a8 ldy #$20
| |
− | ldx #$00
| |
− | lda #$28
| |
− | stx $fa
| |
− | sty $fb
| |
− | </pre>
| |
− | <pre>
| |
− | stx $fc
| |
− | sta $fd
| |
− |
| |
− | stx $f9
| |
− |
| |
− | > Die Zufallstabelle steht, somit kann
| |
− | > mit dem Prozess des eigentlichen
| |
− | > pixelweisen Einblendens begonnen
| |
− | > werden. Dazu werden die Speicher-
| |
− | > adressen des Quell- und Zielzeichen-
| |
− | > satzes festgelegt. $f9 wird als Zähler
| |
− | > freigemacht.
| |
− |
| |
− | ldx #$00
| |
− |
| |
− | a12 stx $02
| |
− | </pre>
| |
− | <pre>
| |
− | lda $03c0,x
| |
− | clc
| |
− | adc $03c0,x
| |
− |
| |
− | tay
| |
− |
| |
− | lda bitpnt,y
| |
− | sta $5a
| |
− | iny
| |
− | lda bitpnt,y
| |
− | sta $5b
| |
− |
| |
− | > Das x-Register wird zwischenge-
| |
− | > speichert, weil dieses als Schleifen-
| |
− | > zähler verwendet, das x-Register aber
| |
− | > in dieser Schleife auch anderweitig
| |
− | </pre>
| |
− | <pre>
| |
− | > benötigt wird. Aus $03c0 + x wird ein
| |
− | > Wert aus der Zufallstabelle gelesen
| |
− | > und danach verdoppelt. Der Wert, der
| |
− | > sich daraus ergibt (im Akku) wird mit
| |
− | > 'tay' ins y-Register kopiert. Am Pro-
| |
− | > grammende steht eine weitere Tabelle
| |
− | > namens 'bitpnt'. Diese besteht aus
| |
− | > 128 Werten und liest sich nacheinander
| |
− | > "byte, bit, byte, bit" usw. Dort sind
| |
− | > alle Koordinaten aller Bits in einem
| |
− | > Zeichen abgelegt.
| |
− | >
| |
− | > Wird der Zufallswert verdoppelt, zeigt
| |
− | > dieser als y-Register exakt in der
| |
− | > Tabelle auf die Koordinate des Bits,
| |
− | > das wir einblenden wollen.
| |
− | </pre>
| |
− | <pre>
| |
− | > Beisp.: Zufallswert 9, verdoppelt 18.
| |
− | > Nun zählen wir in der Tabelle 'bitpnt'
| |
− | > 18 Werte durch (ab Null!). Dort stehen
| |
− | > die Werte '1' und '1', also Byte 1,
| |
− | > Bit 1. Byte und Bit aus der Tabelle
| |
− | > wird in $5a und $5b gespeichert.
| |
− | >
| |
− | > ********0
| |
− | > *+******1
| |
− | > ********2
| |
− | > ********3
| |
− | > ********4
| |
− | > ********5
| |
− | > ********6
| |
− | > ********7
| |
− | > 01234567
| |
− | </pre>
| |
− | <pre>
| |
− | > Oder wir zählen den Zufallswert 9 von
| |
− | > links nach rechts, so erhalten wir die
| |
− | > Stelle wie hier in der Zeichen-Matrix.
| |
− |
| |
− | ldy $5a
| |
− | ldx $5b
| |
− | lda ($fa),y
| |
− | and bits,x
| |
− | beq a9
| |
− | lda bits,x
| |
− | clc
| |
− | adc ($fc),y
| |
− | sta ($fc),y
| |
− |
| |
− | > Das Herz der Routine finden wir hier.
| |
− | > Wir laden aus dem aktuellen Zeichen,
| |
− | </pre>
| |
− | <pre>
| |
− | > das sich im Zeichensatz $fa/$fb
| |
− | > befindet, das Byte und prüfen zunächst
| |
− | > mit der AND-Verknüpfung, ob das Bit,
| |
− | > das wir einblenden wollen, überhaupt
| |
− | > belegt ist. Wenn ja, dann ergibt der
| |
− | > Akku den Wert des belegten Bits und
| |
− | > das Bit wird in den Zeichensatz
| |
− | > hinzuaddiert. Steht im Akku Null, wird
| |
− | > nach Label 'a9' gesprungen, da das Bit
| |
− | > nicht belegt ist.
| |
− |
| |
− | a9 lda #$08
| |
− | clc
| |
− | adc $fa
| |
− | sta $fa
| |
− | bcc a10
| |
− | </pre>
| |
− | <pre>
| |
− | inc $fb
| |
− |
| |
− | a10 lda #$08
| |
− | clc
| |
− | adc $fc
| |
− | sta $fc
| |
− | bcc a11
| |
− | inc $fd
| |
− |
| |
− |
| |
− | a11 ldx $02
| |
− |
| |
− | inc $f9
| |
− | lda $f9
| |
− | cmp #64
| |
− | bne a12
| |
− | </pre>
| |
− | <pre>
| |
− | lda #$00
| |
− | sta $f9
| |
− |
| |
− | > Hier werden die Zeiger auf die beiden
| |
− | > Zeichensatz-Bereiche um 8 erhöht und
| |
− | > zeigen somit auf das nächste Zeichen.
| |
− | > Das heißt, wir blenden nicht erst ein
| |
− | > Zeichen komplett ein und danach das
| |
− | > nächste, sondern alle auf einmal.
| |
− | > Jeder Wert der Zufallstabelle wird
| |
− | > zunächst auf alle 64 Zeichen ange-
| |
− | > wendet.
| |
− |
| |
− | ldy #$20
| |
− | ldx #$00
| |
− | lda #$28
| |
− | </pre>
| |
− | <pre>
| |
− | stx $fa
| |
− | sty $fb
| |
− | stx $fc
| |
− | sta $fd
| |
− |
| |
− | > Wenn jedes der 64 Zeichen mit dem
| |
− | > einen Zufallswert bearbeitet wurde,
| |
− | > werden die Zeiger wieder komplett
| |
− | > zurückgestellt, damit der nächste
| |
− | > Zufallswert verarbeitet werden kann.
| |
− |
| |
− | ldy #$00
| |
− | w2 dey
| |
− | ldx #$00
| |
− | w1 dex
| |
− | cpx #$a0
| |
− | </pre>
| |
− | <pre>
| |
− | bne w1
| |
− | cpy #$e0
| |
− | bne w2
| |
− |
| |
− | > Dies ist lediglich eine kleine
| |
− | > Warteschleife, die die Einblend-
| |
− | > geschwindigkeit kontrolliert. Je höher
| |
− | > die Werte hinter cpx und cpy sind,
| |
− | > desto schneller läuft die Prozedur ab.
| |
− |
| |
− |
| |
− | ldx $02
| |
− |
| |
− | inx
| |
− | cpx #64
| |
− | bne a12
| |
− | </pre>
| |
− | <pre>
| |
− | rts
| |
− |
| |
− | > Der oben gespeicherte Wert des x-Re-
| |
− | > gisters wird wieder dorthin geladen
| |
− | > und erhöht. Steht dieser auf 64, so
| |
− | > sind alle Zufallswerte verarbeitet und
| |
− | > der gesamte Zeichensatz eingeblendet
| |
− | > worden. Das Programm wird dann auch
| |
− | > mit RTS beendet.
| |
− |
| |
− | <-------------------------------------->
| |
− |
| |
− | bitpnt .byte 0,0,0,1,0,2,0,3,0,4,0,5
| |
− | .byte 0,6,0,7
| |
− | .byte 1,0,1,1,1,2,1,3,1,4,1,5
| |
− | .byte 1,6,1,7
| |
− | </pre>
| |
− | <pre>
| |
− | .byte 2,0,2,1,2,2,2,3,2,4,2,5
| |
− | .byte 2,6,2,7
| |
− | .byte 3,0,3,1,3,2,3,3,3,4,3,5
| |
− | .byte 3,6,3,7
| |
− | .byte 4,0,4,1,4,2,4,3,4,4,4,5
| |
− | .byte 4,6,4,7
| |
− | .byte 5,0,5,1,5,2,5,3,5,4,5,5
| |
− | .byte 5,6,5,7
| |
− | .byte 6,0,6,1,6,2,6,3,6,4,6,5
| |
− | .byte 6,6,6,7
| |
− | .byte 7,0,7,1,7,2,7,3,7,4,7,5
| |
− | .byte 7,6,7,7
| |
− |
| |
− | bits .byte 128,64,32,16,8,4,2,1
| |
− |
| |
− | * * *
| |
− | </pre>
| |
− | <pre>
| |
− | Soviel zum Code. Das zufallsweise Ein-
| |
− | blenden eines Zeichensatzes ist nur eine
| |
− | Möglichkeit. Ganz effektiv ist aber auch
| |
− | das Einblenden der Zeichen anhand eines
| |
− | bestimmten Musters.
| |
− |
| |
− | Das Programm befindet sich als Quellcode
| |
− | fÜr den Turbo-Assembler und als .obj-
| |
− | File auf der Disk dieser Ausgabe.
| |
− |
| |
− | Startet man das Programm, so wird der
| |
− | Zeichensatz eingeblendet. Danach gelangt
| |
− | man wieder zurÜck in den normalen Einga-
| |
− | bemodus. Der Grund, wieso man dort kei-
| |
− | nen blinkenden Cursor antrifft, ist hof-
| |
− | fentlich klar: dieser ist nicht Bestand-
| |
− | </pre>
| |
− | <pre>
| |
− | teil des Zeichensatzes, weil sich dieser
| |
− | jenseits von den ersten 64 Zeichen be-
| |
− | findet. Man kann diesen aber ganz ein-
| |
− | fach einbauen.
| |
− |
| |
− | Versucht es doch mal! :-)
| |
− |
| |
− | Was diese Routine nicht macht ist, den
| |
− | Zeichensatz wieder auszublenden.
| |
− |
| |
− | Das wäre vielleicht auch eine kleine
| |
− | Aufgabe, der Ihr Euch jetzt stellen
| |
− | könntet.
| |
− |
| |
− | Dabei kann man entweder mit der bereits
| |
− | generierten Zufallsliste arbeiten, da
| |
− | </pre>
| |
− | <pre>
| |
− | spricht nichts gegen oder man erstellt
| |
− | vor dem Ausblenden eine neue.
| |
− |
| |
− |
| |
− |
| |
− |
| |
− | Viel Spaß wünscht Euch
| |
− |
| |
− |
| |
− |
| |
− | Michael Czychowski
| |
− | Chico of CIVITAS
| |
− |
| |
− |
| |
− |
| |
− | ________________________________________
| |
− | </pre>
| |