DT 84 16

From C64 Diskmag Wiki
Revision as of 14:08, 6 October 2010 by Nyquist (Talk | contribs)

(diff) ←Older revision | view current revision (diff) | Newer revision→ (diff)
Jump to: navigation, search

English Translation

              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.
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.
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
         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
> Zeichensatz aus $2000 eingeblendet
> wird.

         jmp a2


<-------------------------------------->


rand     inc val
         ldy val
         lda $dc04
         eor $fedc,y
         eor $d012
         sta $57
         rts
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
         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
> 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
> 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
         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
> 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,
> 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
         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
         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
> 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.
> 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
> 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,
> 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
         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
         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
         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
         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
         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
         .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

                 * * *
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-
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
spricht  nichts  gegen oder man erstellt
vor dem Ausblenden eine neue.




Viel Spaß wünscht Euch



           Michael Czychowski
            Chico of CIVITAS



________________________________________
Personal tools
Namespaces

Variants
Actions
Navigation
Toolbox