Tutorial

Remote

Code:
Schritte:

Adresse / Links
Daten / Rechts

Cheat Sheet

Impressum | Datenschutzerklärung

Überblick

Allgemeines

Der MC16B Prozessor ist ein reiner 16 Bit CPU, d.h. alle Berechnungen und Adressen finden auf 16 Bit statt. Im Gegensatz zu vielen anderen 16 Bit Architekturen ist hier der Speicher auch in diese Einheiten geteilt (ein Wort ist die kleinste edressierbare Einheit). Wie bei einer 8 Bit CPU gibt es somit keine Endianess.

Prozessorregister

Der Prozessor besitzt 16 Allzweckregister, welche im Code mit $0 bis $15 bezeichnet werden. Ein solches Register ist exakt ein Wort groß.

Weiterhin gibt es das PC Register, welches auf den nächsten auszuführenden Befehl zeigt. Es kann mit den Sprungbefehlen verändert werden. Wird ein CPU Reset durchgeführt so wird dieses auf 0 gesetzt. Dieses Register ist ein Wort groß.

Zusätzlich gibt es noch das LINK Register, welches bei einem Sprung auf den vorherigen PC gesetzt wird. Damit sind Unterprogrammaufrufe möglich. Dieses Register ist ein Wort groß.

Es gibt drei Flags (jeweils 1 Bit Register), welche bei Rechnen (ALU) Operationen eventuell verändert werden. Sie heißen CARRY (z.B. für Additonsübertrag), SIGN (wenn das Ergebnis negativ war = 15 Bit gesetzt) und ZERO (wenn das Ergebnis 0 war). Die Flags können bei den Sprungbefehlen als Bedingung verwendet werden.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ALU Rechenoperationen

Operationen

OperationPseudocode
add $A,$B$A := $A+$B
adc $A,$B$A := $A+$B+CARRY
sub $A,$B$A := $A-$B
sbb $A,$B$A := $A-$B-CARRY
rsub $A,$B$A := $B+$A
cmp $A,$BSetzt nur Flags wie sub $A,$B
and $A,$B$A := $A & $B
test $A,$BSetzt nur Flags wie and $A,$B
xor $A,$B$A := $A xor $B
or $A,$B$A := $A | $B
mov $A,$B$A := $B, ändert keine Flags
shr $A,$B$A := $A >> $B, zieht 0 nach
ror $A,$B$A := $A >> $B, zieht CARRY nach
sar $A,$B$A := $A >> $B, zieht MSB von $A nach
rol $A,$B$A := $A << $B, zieht CARRY nach
shl $A,$B$A := $A << $B, zieht 0 nach

Varianten

OperandenBeispielAnmerkungen
op $A, $Badd $0,$4Reg $0 := Reg $0 + Reg $4
op $A, #Band $8,99Reg $8 := Reg $8 & 99
op $A, short #Badd $11, 1für kleine Werte -31 .. 31
op $A, long #Band $12, 0xFF00für alle Werte

Wenn als zweiter Operand ein Wert angegeben wird, so wird ohne Angabe von short / long üblicherweise die long Variante verwendet.

Sind beide Operanden Register, oder ist der rechte Operand ein short Wert, so benötigt der Opcode nur ein Wort, sonst zwei.

Ein Wert kann auch ein konstanter Ausdruck sein (d.h. vom Assembler zur Assemblierzeit auswertbar).

Abkürzungen

Die Schieberegister shr,ror,sar,rol,shl können auch ohne zweiten Operanden verwendet werden. Dies entspricht einem Shift um eins mit der kurzen Kodierung.

Statt add $A, short 1 kann auch inc $A benutzt werden; für sub $A, short 1 kann dec $A,1 verwendet werden.

Mit neg $A wird das Ergebnis negiert, mit not $A invertiert (Kurzschreibweise des rsub Befehls)

Keine Operation wird mit nop (ohne Parameter) durchgeführt.

Sprünge

Operationen

OperationUmgangssprachlichFlags
jbvorzeichenlos <CARRY == 1
jaevorzeichenlos >=CARRY == 0
jlvorzeichnbehaftet <SIGN == 1
jgevorzeichnbehaftet >=SIGN == 0
jbevorzeichenlos <=ZERO == 1 | CARRY == 1
javorzeichenlos >ZERO == 0 & CARRY == 0
jlevorzeichnbehaftet <=ZERO == 1 | SIGN == 1
jgvorzeichnbehaftet >ZERO == 0 & SIGN == 0
je==ZERO == 1
jne!=ZERO == 0
jmpimmerohne Bedingung

Operanden

OperandenBeispielAnmerkungen
op $Ajmp $6PC := $6
op #Bjmp loopPC := loop
op near #Bjmp near loopfür kleine Werte -511 .. 511
op far #Bjmp far libraryfür alle Werte

Wird near oder far weggelassen, so wird near genommen. Sprünge mit einem Wert sind immer relative Sprünge im Vergleich zum PC nach dem Befehl.

Sprünge mit Registern sind immer absolute Sprünge.

Link Register

Bei jedem durchgeführten Sprung wird der vorherige PC in ein spezielles Link register gesichert. Mit dem Befehle loadlink $A wird das Linkregister in ein Allzweckregister kopiert.

Speicherbefehle und Adressen

Laden und Speichern

Mit load $A,[$B] wird der Wert von Adresse aus Register $B in Register $A geladen.

Mit store [$B],$A wird der Wert aus Register $A an die Adresse von aus Register $B gespeichert.

Es gibt keine Möglichkeit, direkt Werte zu speichern, oder Adressen direkt anzugeben. Diese müssen vorher z.B. mit einem mov Befehl in ein Register geladen werden.

Man kann in einem load Befehl problemlos das Adressregister als Zielregister verwenden: load $A,[$A] ist möglich, die Adresse wird erst benutzt und anschließend wird das Register mit dem Wert überschrieben.

Adressen

  • 0x0000 - 0x07FF: 2 KiW ROM
  • 0x8000 - 0x80FF: 256 W RAM
  • 0xFF00 - 0xFF3F schreiben: untere Displayspalte + Update (von Rechts)
  • 0xFF40 - 0xFF7F schreiben: obere Displayspalte Latch (Adresse egal)
  • 0xFF80 schreiben: rechtes Hexdisplay
  • 0xFF81 schreiben: mnittleres Hexdisplay
  • 0xFF82 schreiben: linkes Hexdisplay
  • 0xFF83 schreiben: beide Operandendisplays
  • 0xFF84 schreiben: Dezimalpunkte (von rechts nach links)
  • 0xFF90, 0xFF92 lesen: ADDR Input
  • 0xFF91, 0xFF93 lesen: DATA Input
  • 0xFF90, 0xFF91 schreiben: Clock anhalten bis Enter gedrückt wurde(Wert egal)
  • 0xFF94 schreiben: obere Statuslampen (von links nach rechts)
  • 0xFF95 schreiben: untere Statuslampen (von links nach rechts)
  • 0xFFC0 schreiben: Pixeldisplay löschen (Wert egal)

Labels und Konstanten

Ausdrücke

Der Assembler kann Ausdrücke auswerten. Somit kann man an allen Stellen, wo konstante Werte erlaubt sind auch konstante Ausdrücke schreiben. Somit ist mov $0,8+1 gleichbedeutend zu mov $0,9. Nicht erlaubt sind verbindungen von Ausdrücken mit Register, da diese nicht mehr konstant auswertbar wären.

Labels

Zur Vereinfachung der Sprungbefehle kann man zu Begin einer Zeile ein Label voranstellen. Damit wird die nun kommende Programmstelle benannt. Ein Label besteht aus einem Bezeichner gefolgt von einem Doppelpunkt.

Hierarchische Labels

Labels können hierarisch organisiert werden, dazu werden die verschiedenen Ebenen mit einem Punkt getrennt. Damit ist es z.B. möglich lokale Labels innerhalb einer Funktion zu deklarieren.

Beispiel

func1:
mov $0,5
.loop: dec $0
jnz .loop

func2: and $2,4
.loop: xor $2,0xFF
je .loop

func3:
.part1: mov $10,99
jmp .end
.part2: mov $10,11
.end:

func4: jmp func3.part1

Konstanten

Ähnlich wie Labels können auch Konstanten definiert werden. Statt des Doppelpunktes verwendet man nach dem Bezeichner ein Gleichheitszeichen gefolgt vom dem konstanten Ausdruck.

Beispiel

SizeOfArray=20*40
mov $0,SizeOfArray

Tools

Operandendisplays

Das Berechnen der Bitmaske für die Operandendisplays kann etwas aufwändig werden. Hier gibt es ein eingebautes Tool um den Code zu ermitteln.

Über / Lizenzen

MC16B CPU entwickelt von ThiloA, brainsh und Merlin09

HTML Assembler Version 0.1

Dieser HTML / JavaScript Assembler verwendet

Diese MC16b Ide + Assembler + Emulator wurde entwickelt von Thilo Ackermann und ist unter MIT Lizenz freigegeben.

Impressum | Datenschutzerklärung