Magic Disk 64

home to index to html: MD9405-KURSE-ASSEMBLER_KURS_2_(TEIL_7).html
         Assembler-Kurs Teil 7          
Bevor wir uns den ROM-Routinen  des  C64
zuwenden,   werden   noch    die    vier
Bit-Verschiebebefehle ASL, LSR, ROL  und
ROR erklärt. Diese Befehle benötigen wir
erst im Kursteil  9  bei  der  Multipli-
kation und Division von Ganzzahlen.     
Trotzdem  sollen  diese  Befehle   schon
jetzt behandelt werden, da  Sie  in  der
Folge   9   genug   Probleme   mit   dem
Verständnis der Fließkomma-Zahlen  haben
werden und  nicht  noch  zusätzlich  mit
neuen   Befehlen   konfrontiert   werden
sollen.                                 
Die Verschiebebefehle                   
ASL (Arithmetic Shift Left)             
---------------------------             
Bei diesem Befehl wird der gesamt  Akku-
inhalt, oder der Inhalt der  angegebenen
Speicherstelle bitweise nach links  ver-
schoben. Das Bit 7 wird in das Carry-Bit
ausgelagert, in Bit  0  des  Bytes  wird
eine 0 eingefügt.                       
            7 6 5 4 3 2 1 0             
   Carry <= * * * * * * * * <= 0        
Ein  einmaliges  Linksverschieben   ent-
spricht  einer  Verdoppelung   der   ur-
sprünglichen Zahl.                      
Beispiel: LDA #$19                      
          ASL                           
          STA $1000                     
$19  entspricht  der  binären  Bitfolge:
00011001. Ein ASL führt nun zu  00110010
($32) und  einer  0  im  Carry-Bit.  Das
Ergebnis der Verschiebung  wird  in  der
Speicherstelle $1000 abgelegt.          
Aber  neben  der  Möglichkeit  der  Ver-
doppelung einer Zahl kann  man  mit  ASL
auch bequem  die  Bits  einer  Speicher-
stelle über  das  Carry-Bit  testen.  Es
werden das Negativ-  und  das  Zero-Flag
beeinflußt.                             
Der   Befehl   ASL    bietet    folgende
Adressierungsmöglichkeiten:             
ASL          Akku-orientiert            
ASL $1000    absolut                    
ASL $1000,X  absolut X-indiziert        
ASL $FA      Zeropage-absolut           
ASL $FA,X    Zeropage-abs. X-indiziert  
LSR (Logical Shift Right)               
-------------------------               
LSR bildet das Gegenstück  zu  ASL.  Das
betroffene  Bit  wird  nun  nach  rechts
geschoben. Dabei gelangt das  bit  0  in
das Carry-Bit und in Bit 7 wird  eine  0
eingesetzt.                             
           7 6 5 4 3 2 1 0              
      0 => * * * * * * * * => Carry     
Beispiel: LDA #$19                      
          LSR                           
          STA $1000                     
Aus der Bitfolge 00011001 wird durch LSR
ein  00001100.  Außerdem   enthält   das
Carry-Bit jetzt die links aus  dem  Byte
geschobene 1. Das Ergebnis  wird  wieder
in der  Speicherstelle  $1000  abgelegt.
LSR hat in diesem Fall die dezimale Zahl
25  ($19)   ganzzahlig   halbiert.   Das
gesetzte Carry-Bit  signalisiert  dabei,
daß ein Rest aufgetreten ist (25 :2 = 12
Rest 1).                                
LSR erlaubt  die  selben  Adressierungs-
arten  und   beeinflußt   die   gleichen
Falggen wie der ASL-Befehl.             
ROL (ROtate Left)                       
-----------------                       
Der ROL-Befehl hat große Ähnlichkeit mit
dem ASL, nur daß das  Byte  jetzt  nicht
mehr nur verschoben wird, sondern  um  1
Bit rotiert. Wie auch bei ASL landet das
Bit  7  im  Carry.  Das  Carry-Bit  wird
anschließend in Bit 0 übertragen.  Somit
ist das  Bit  7  schließlich  in  Bit  0
gelangt.                                
            7 6 5 4 3 2 1 0             
   Carry <= * * * * * * * * <= Carry    
Beispiel: LDA #$B1                      
          ROL                           
          STA $1000                     
In  den  Akku  wird  die  Bitkombination
10110001 geladen. Nach dem ROL  befindet
sich der Wert 01100011  ($63)  im  Akku,
der in die Speicherstelle $1000 abgelegt
wird. Das  Carry-bit  enthält  ebenfalls
eine 1.                                 
ROR (ROtate Right)                      
------------------                      
Wie nicht anders zu  erwarten  war,  ist
ROR wieder das Gegenstück zu ROL.  Jetzt
wird das Byte  nicht  um  ein  Bit  nach
links, sondern nach rechts  rotiert.  Es
befindet sich daher Bit 0 im Carry.  Der
Inhalt des Carry-Bits rotiert nun in Bit
7 hinein.                               
            7 6 5 4 3 2 1 0             
   Carry => * * * * * * * * => Carry    
Beispiel: LDA #$B1                      
          ROR                           
          STA $1000                     
Auch für ROR wird das Beispiel  durchge-
führt. Aus 10110001 wird  nach  ROR  die
bitfolge  11011000.  Das  Carry-Bit  ist
auch in diesem Beispiel gesetzt.        
Die zuletzt besprochenen Befehle  lassen
dieselben  Adressierungsarten  wie   der
ASL-Befehl zu, und  auch  sie  verändern
die Flaggen N und Z.                    
ROM-Routinen                            
------------                            
Unsere Assembler-Programme stehen  immer
im  RAM  (Random  Access  Memory),   dem
Lese-/Schreib-Speicher. In das ROM (Read
Only Memory) können  wir  nicht  hinein-
schreiben, es kann nur  gelesen  werden.
Folglich sind die  oben  erwähnten  ROM-
Routinen einige gegebene unterprogramme,
die wir  in  unsern  eigenen  Assembler-
Programmen verwenden können.            
Der  Sinn  der  Benutzung  dieser   ROM-
Routinen  soll  Ihnen  am  Beispiel  des
"Bildschirm    löschens"    verdeutlicht
werden:                                 
Bisher benötigten wir eine Schleife, die
den  gesamten   sichtbaren   Bildschirm-
bereich mit dem SPACE-Zeichen " "  voll-
gePOKEd hat. Es war also ein erheblicher
Programmieraufwand   erforderlich.   Nun
geht das Ganze  aber  viel  kürzer.  Wir
springen einfach mit JSR ein  ROM-Unter-
programm an, das  das  Bildschirmlöschen
für uns übernimmt.  Ein  "Clear  Screen"
wird  jetzt  einfach   mit   JSR   $E544
ausgeführt.                             
Übrigens werden  alle  ROM-Routinen  mit
einem   JSR   angesprungen,   da   diese
allesamt mit RTS enden.                 
Einige ROM-Routinen benötigen vor  ihrem
Aufruf gewisse Informationen,  ohne  die
sie nicht fehlerfrei arbeiten können.   
Zum Beispiel  braucht  die  Routine  zum
Setzen des Cursors die Zeilenposition im
X-Register und die  der  Spalten  im  Y-
Register.                               
LDX #$00                                
LDY #$08                                
JSR $E50C                               
Dieses Programm setzt den Cursor in  der
Zeile 0 auf die Spalte 8.               
Das folgende Programm  gibt  den  ASCII-
Text an der aktuellen Cursorposition aus
LDA #$00                                
LDY #$C1                                
JSR $AB1E                               
Der auszugebende Text für diese  Routine
muß im  Speicher  an  der  Stelle  $C100
beginnen, und mit einem Byte $00  enden.
Als Zeiger  auf  diese  Textstelle  fun-
gieren hierbei der Akku  (niederwertiges
Byte der  Adresse)  und  das  Y-Register
(höherwertiges  Byte).  Wie  Sie   einen
ASCII-Text direkt  im  Speicher  ablegen
können, verrät Ihnen das Handbuch  Ihres
Assemblers.  Oft  gibt  es  dafür  einen
Befehl der Art                          
C100  .ASC "beispieltext"               
Der Text liegt dann folgendermaßen im   
Speicher:                               
C100  42 45 49 53 50 49 45 4C   beispiel
C108  54 45 58 54 00 00 00 00   text    
Eine weitere wichtige  Routine  ist  die
Tastaturabfrage JSR $FFE4. Hierbei steht
der ASCII-Code der gedrückten  Taste  im
Akkumulator.                            
Das Beispielprogramm                    
C000 JSR $FFE4                          
C003 BEQ $C000                          
überprüft, ob irgendeine Taste gedrückt 
wurde. In BASIC hätten wir              
10 GET A$                               
20 IF A$ = "" THEN 10                   
geschrieben.                            
Natürlich kann ich Ihnen in diesem  Kurs
nicht alle verfügbaren ROM-Routinen vor-
stellen. Wenn  ich  aber  Ihr  Interesse
daran geweckt  habe,  dann  sollten  Sie
sich    ein    Buch     zulegen,     das
"dokumentierte ROM-Listings" enthält.   
Aber wo genau liegt eigentlich der  ROM-
Bereich im Speicher?                    
Wir haben bis jetzt von $AB1E bis  $E50C
aufgerufen. Bei $C000-$CFFF  liegt  aber
ein  RAM-Bereich,  den  wir  schon   oft
genutzt haben. Es muß daher mehr als nur
einen ROM-Bereich geben.                
In der Tat gibt  es  3  unterschiedliche
ROM-bereiche. Von $A000-$BFFF liegt  das
ROM   des   BASIC-Interpreters.   Dieser
Interpreter sorgt dafür, daß Sie  gleich
nach dem Einschalten des  Computers  das
BASIC verfügbar haben.                  
Zwischen $D000- $DFFF befinden sich  die
I/O-Bausteine,  die  für  die  Ein-  und
Ausgaben verantwortlich sind.           
Ab $E000  bis  zum  Ende  des  Speichers
$FFFF liegt das Betriebssystem-ROM.     
Speicherbelegungsplan des C64:          
$FFFF ------------------------------    
      |Betriebssystem|     RAM     |    
$E000 ----------------------------------
      |     I/O      | Zeichensatz |RAM|
$D000 ----------------------------------
      |     RAM      |                  
$C000 ------------------------------    
      |  BASIC-ROM   |     RAM     |    
$A000 ------------------------------    
      |              |                  
      |     RAM      |                  
      |              |                  
$0800 ----------------                  
      |    (RAM)     |                  
$0000 ----------------                  
Der  mit  "Zeichensatz"  gekennzeichnete
Bereich   enthält    den    Zeichensatz-
Generator (character generator), den ich
im Kursteil 8 mit der Erstellung selbst-
definierter  Zeichen   näher   erläutern
werde.                                  
Wenn   Sie   den   Speicherbelegungsplan
ansehen, stellen Sie  fest,  daß  einige
bereiche mit derselben Adresse  mehrfach
belegt sind. So liegt z.B. von $E000 bis
$FFFF  nicht  nur  das   Betriebssystem,
"darunter" befindet sich auch  noch  ein
RAM-Bereich. Ähnlich verhält es sich mit
dem Bereich von $D000-$DFFF,  der  sogar
dreifach belegt ist.                    
Aber wie kann man zwischen den  mehrfach
belegten bereichen auswählen?           
Dazu dient die Speicherstelle  $01,  der
sogenannte  Prozessorport.  Je  nachdem,
welcher Wert  in  dieser  Speicherstelle
steht,  verändern  sich  die   Zugriffs-
möglichkeiten auf den Speicher.         
Als Assembler-Programmierer könnten  wir
zum Beispiel mit                        
LDA #$36                                
STA $01                                 
das  gesamte  BASIC  abschalten  un  das
darunterliegende RAM für  unsere  Zwecke
nutzen.   Wir   hätten    somit    einen
durchgehenden RAM-Speicher von $0800 bis
$CFFF geschaffen. Leider können wir aber
nicht  mehr  auf  die  ROM-Routinen  des
BASIC-Interpreters zugreifen.           
LDA #$37                                
STA $01                                 
stellt den  Ausgangszustand  wieder  her
und schaltet das BASIC-ROM an.          
 $01 $A000-$BFFF $D000-$DFFF $E000-$FFFF
----------------------------------------
 $37   BASIC       I/O         ROM      
 $36   RAM         I/O         ROM      
 $35   RAM         I/O         RAM      
 $34   RAM         RAM         RAM      
 $33   BASIC       Charset     ROM      
 $32   RAM         Charset     ROM      
 $31   RAM         Charset     RAM      
 $30   RAM         RAM         RAM      
Diese Tabelle des  Prozessorports  zeigt
Ihnen die Möglichkeiten auf.            
Auf den ersten Blick wirkt das  mit  der
Mehrfachbelegung   un   dem   Umschalten
zwischen    Bereichen    alles     etwas
umständlich. Anders geht es aber  nicht.
Mit  unserem  maximal  2   Byte   langem
Adressteil (z.B. LDA $FFFF)  können  wir
nur den Bereich von $0000-$FFFF, also 64
KByte  andressieren.  Würde   man   alle
mehrfach        belegten        Bereiche
hintereinander schreiben, käme man  aber
auf einen Speicherbereich von 64 KByte +
24 KByte = 88 KByte.                    
Als  praktischen   Anschauungsunterricht
laden Sie nun am  Besten  das  Beispiel-
programm aus dem Menü: ASSEMBLER-KURS 7.
                                 (rt/wk)



Valid HTML 4.0 Transitional Valid CSS!