DT 84 16

From C64 Diskmag Wiki
(Difference between revisions)
Jump to: navigation, search
 
 
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&ouml;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&auml;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&ouml;ti-
 
gen  wir  einen Zeichensatz und eine Ta-
 
belle, die sich aus zuf&auml;llig durcheinan-
 
der  gew&uuml;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&auml;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
 
 
&gt; Die ersten 64 Zeichen des C64-ROM-
 
&gt; Zeichensatzes werden nach $2000-$2200
 
&gt; kopiert. Der Bereich von $2800-$2A00
 
&gt; wird freigemacht, weil dort der
 
</pre>
 
<pre>
 
&gt; Zeichensatz aus $2000 eingeblendet
 
&gt; wird.
 
 
        jmp a2
 
 
 
<-------------------------------------->
 
 
 
rand    inc val
 
        ldy val
 
        lda $dc04
 
        eor $fedc,y
 
        eor $d012
 
        sta $57
 
        rts
 
</pre>
 
<pre>
 
val      .byte 0
 
 
&gt; Hier wird eine Zufallszahl von 0-255
 
&gt; generiert.
 
&gt; Wie dies geschieht, werde ich nicht
 
&gt; erkl&auml;ren.
 
&gt; Der Wert wird in $57 gespeichert.
 
&gt; Das Label 'rand' wird immer dann
 
&gt; angesprungen, wenn ein neuer Zufalls-
 
&gt; wert ben&ouml;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
 
 
&gt; Bildschirm wird initialisiert,
 
&gt; gel&ouml;scht und alle Zeichen von 0-63
 
</pre>
 
<pre>
 
&gt; ausgegeben. Danach wird der Zeichen-
 
&gt; satz ab $2600 eingeschaltet. Da sich
 
&gt; dort nur leerer Speicher befindet,
 
&gt; sieht man zun&auml;chst nichts auf dem
 
&gt; Bildschirm.
 
&gt;
 
&gt; Die Speicherstelle $58 wird
 
&gt; freigemacht, dort wird im folgenden
 
&gt; die Anzahl der Zufallszahlen
 
&gt; gespeichert.
 
 
<-------------------------------------->
 
 
a4      jsr rand
 
        and #$c0
 
        bne a4
 
</pre>
 
<pre>
 
&gt; Eine Zufallszahl wird mit JSR rand
 
&gt; geladen und mit der
 
&gt; and #$c0 Verkn&uuml;pfung darauf &uuml;berpr&uuml;ft,
 
&gt; ob sich diese auch nur von 0-63
 
&gt; erstreckt. Ist der Wert im Akkumulator
 
&gt; nicht null, dann wird nach Label a4
 
&gt; zur&uuml;ckgesprungen und eine neue Zahl
 
&gt; angefordert, da die Zahl in diesem
 
&gt; Moment gr&ouml;&szlig;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
 
 
&gt; Die Tabelle der Zufallszahlen wird
 
&gt; ab $03c0 gespeichert.
 
&gt;
 
&gt; Hier wird u.a. die erste Zahl
 
&gt; verarbeitet, da diese in jedem Fall
 
&gt; einmalig ist. Dazu wird diese
 
&gt; gespeichert und der Z&auml;hler in $58 um
 
&gt; eins erh&ouml;ht. Da die folgende Prozedur
 
&gt; auch auf diesen Bereich zugreift, wird
 
&gt; zudem gepr&uuml;ft, ob $58 bei 64 angelangt
 
&gt; ist, da in diesem Fall die Tabelle
 
</pre>
 
<pre>
 
&gt; voll ist. Wenn ja, wird per BEQ a8
 
&gt; die Generierung der Tabelle beendet.
 
 
a5      ldy #$00
 
a6      lda $03c0,y
 
        cmp $57
 
        beq a4
 
        iny
 
        cpy $58
 
        bne a6
 
 
        jmp a7
 
 
&gt; Die Schleife ab Label a5 &uuml;berpr&uuml;ft, ob
 
&gt; der aktuelle Zufallswert bereits in
 
&gt; der Tabelle vorhanden ist. Wenn ja,
 
</pre>
 
<pre>
 
&gt; wird per BEQ a4 zur&uuml;ckgesprungen.
 
&gt; Ansonsten wird ab Label a7 der Wert in
 
&gt; die Tabelle &uuml;bernommen.
 
&gt;
 
&gt; Die Generierung dieser Tabelle dauert
 
&gt; hier weniger als eine Sekunde.
 
&gt; Per Basic dauert es dagegen mehr oder
 
&gt; weniger als eine Minute!
 
 
<-------------------------------------->
 
 
a8      ldy #$20
 
        ldx #$00
 
        lda #$28
 
        stx $fa
 
        sty $fb
 
</pre>
 
<pre>
 
        stx $fc
 
        sta $fd
 
 
        stx $f9
 
 
&gt; Die Zufallstabelle steht, somit kann
 
&gt; mit dem Prozess des eigentlichen
 
&gt; pixelweisen Einblendens begonnen
 
&gt; werden. Dazu werden die Speicher-
 
&gt; adressen des Quell- und Zielzeichen-
 
&gt; satzes festgelegt. $f9 wird als Z&auml;hler
 
&gt; 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
 
 
&gt; Das x-Register wird zwischenge-
 
&gt; speichert, weil dieses als Schleifen-
 
&gt; z&auml;hler verwendet, das x-Register aber
 
&gt; in dieser Schleife auch anderweitig
 
</pre>
 
<pre>
 
&gt; ben&ouml;tigt wird. Aus $03c0 + x wird ein
 
&gt; Wert aus der Zufallstabelle gelesen
 
&gt; und danach verdoppelt. Der Wert, der
 
&gt; sich daraus ergibt (im Akku) wird mit
 
&gt; 'tay' ins y-Register kopiert. Am Pro-
 
&gt; grammende steht eine weitere Tabelle
 
&gt; namens 'bitpnt'. Diese besteht aus
 
&gt; 128 Werten und liest sich nacheinander
 
&gt; "byte, bit, byte, bit" usw. Dort sind
 
&gt; alle Koordinaten aller Bits in einem
 
&gt; Zeichen abgelegt.
 
&gt;
 
&gt; Wird der Zufallswert verdoppelt, zeigt
 
&gt; dieser als y-Register exakt in der
 
&gt; Tabelle auf die Koordinate des Bits,
 
&gt; das wir einblenden wollen.
 
</pre>
 
<pre>
 
&gt; Beisp.: Zufallswert 9, verdoppelt 18.
 
&gt; Nun z&auml;hlen wir in der Tabelle 'bitpnt'
 
&gt; 18 Werte durch (ab Null!). Dort stehen
 
&gt; die Werte '1' und '1', also Byte 1,
 
&gt; Bit 1. Byte und Bit aus der Tabelle
 
&gt; wird in $5a und $5b gespeichert.
 
&gt;
 
&gt; ********0
 
&gt; *+******1
 
&gt; ********2
 
&gt; ********3
 
&gt; ********4
 
&gt; ********5
 
&gt; ********6
 
&gt; ********7
 
&gt; 01234567
 
</pre>
 
<pre>
 
&gt; Oder wir z&auml;hlen den Zufallswert 9 von
 
&gt; links nach rechts, so erhalten wir die
 
&gt; 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
 
 
&gt; Das Herz der Routine finden wir hier.
 
&gt; Wir laden aus dem aktuellen Zeichen,
 
</pre>
 
<pre>
 
&gt; das sich im Zeichensatz $fa/$fb
 
&gt; befindet, das Byte und pr&uuml;fen zun&auml;chst
 
&gt; mit der AND-Verkn&uuml;pfung, ob das Bit,
 
&gt; das wir einblenden wollen, &uuml;berhaupt
 
&gt; belegt ist. Wenn ja, dann ergibt der
 
&gt; Akku den Wert des belegten Bits und
 
&gt; das Bit wird in den Zeichensatz
 
&gt; hinzuaddiert. Steht im Akku Null, wird
 
&gt; nach Label 'a9' gesprungen, da das Bit
 
&gt; 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
 
 
&gt; Hier werden die Zeiger auf die beiden
 
&gt; Zeichensatz-Bereiche um 8 erh&ouml;ht und
 
&gt; zeigen somit auf das n&auml;chste Zeichen.
 
&gt; Das hei&szlig;t, wir blenden nicht erst ein
 
&gt; Zeichen komplett ein und danach das
 
&gt; n&auml;chste, sondern alle auf einmal.
 
&gt; Jeder Wert der Zufallstabelle wird
 
&gt; zun&auml;chst auf alle 64 Zeichen ange-
 
&gt; wendet.
 
 
        ldy #$20
 
        ldx #$00
 
        lda #$28
 
</pre>
 
<pre>
 
        stx $fa
 
        sty $fb
 
        stx $fc
 
        sta $fd
 
 
&gt; Wenn jedes der 64 Zeichen mit dem
 
&gt; einen Zufallswert bearbeitet wurde,
 
&gt; werden die Zeiger wieder komplett
 
&gt; zur&uuml;ckgestellt, damit der n&auml;chste
 
&gt; Zufallswert verarbeitet werden kann.
 
 
        ldy #$00
 
w2      dey
 
        ldx #$00
 
w1      dex
 
        cpx #$a0
 
</pre>
 
<pre>
 
        bne w1
 
        cpy #$e0
 
        bne w2
 
 
&gt; Dies ist lediglich eine kleine
 
&gt; Warteschleife, die die Einblend-
 
&gt; geschwindigkeit kontrolliert. Je h&ouml;her
 
&gt; die Werte hinter cpx und cpy sind,
 
&gt; desto schneller l&auml;uft die Prozedur ab.
 
 
 
        ldx $02
 
 
        inx
 
        cpx #64
 
        bne a12
 
</pre>
 
<pre>
 
        rts
 
 
&gt; Der oben gespeicherte Wert des x-Re-
 
&gt; gisters wird wieder dorthin geladen
 
&gt; und erh&ouml;ht. Steht dieser auf 64, so
 
&gt; sind alle Zufallswerte verarbeitet und
 
&gt; der gesamte Zeichensatz eingeblendet
 
&gt; worden. Das Programm wird dann auch
 
&gt; 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&ouml;glichkeit. Ganz effektiv ist aber auch
 
das  Einblenden der Zeichen anhand eines
 
bestimmten Musters.
 
 
Das Programm befindet sich als Quellcode
 
f&Uuml;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&Uuml;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&auml;re  vielleicht  auch  eine kleine
 
Aufgabe,  der  Ihr  Euch  jetzt  stellen
 
k&ouml;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&szlig; w&uuml;nscht Euch
 
 
 
 
          Michael Czychowski
 
            Chico of CIVITAS
 
 
 
 
________________________________________
 
</pre>
 

Latest revision as of 00:27, 18 January 2011

Personal tools
Namespaces

Variants
Actions
Navigation
Toolbox