Dokumentation des Monitorprogramms
µP-OS 8052
V 2.1
Terminaleinstellungen:
Terminalemulation: VT52
Duplex-Modus: voll
ASCII-Dateiversandt:
Zeichenverzögerung: 100ms
Zeilenverzögerung: 10ms
CR-Übersetzung: keine
LF-Übersetzung: keine
Allgemeine Befehle | ||
Befehl |
|
Beschreibung |
g xxxx |
go |
Programm ab Adresse xxxx starten |
l xxxx |
list |
Programm ab Adresse xxxx auflisten (disassembliert) |
bs xxxx |
breakpoint set |
Breakpoint auf Adresse xxxx setzten |
bl |
breakpoint list |
Breakpoint-Adresse anzeigen |
bd |
breakpoint delete |
Breakpoint-Adresse löschen |
c |
continue |
Abgebrochenes Programm fortsetzen |
o |
options |
Einstellungen ändern |
r |
reset |
Software-Reset: Gesamter Speicher wird gelöscht und alle Einstellungen zurückgesetzt. |
i |
Intel-Hex |
Programm-Datei im Intel-Hex-Format laden |
xxxx beliebige Adresse im Hex-Format. Drückt man währen der Eingabe ESC, so wird der Befehl abgebrochen.
Befehle im Options-Menu | ||
Befehl |
|
Beschreibung |
l xxxx |
listlengh |
|
s xx |
seriall port |
|
|
|
|
Zeichenausgabe | ||||
Adresse |
Name |
Beschreibung |
Verwendet |
Verändert |
3000h |
CharOut |
Gibt ein Zeichen, das sich im AKKU befindet, aus. |
A |
|
3003h |
ReturnOut |
Gibt ein Return (CR, LF) aus. |
A |
|
3006h |
SpaceOut |
Gibt so viele Leerzeichen aus, wie die Zahl im AKKU vorgibt. |
A |
A |
3009h |
CursorOut |
Gibt einen Cursor-Befehl, der durch AKKU definiert ist, aus: AKKU=00h Cursor hinauf AKKU=01h Cursor hinunter AKKU=02h Cursor nach rechts AKKU=03h Cursor nach links AKKU=04h Cursor auf Position 1/1 (links/oben) AKKU=05h Cursor auf Position x/y x Zeile (>0) y Spalte (>0) x, y müssen nach dem Unterprogrammaufruf zusätzlich mittels CharOut übertragen werden. |
A, DPTR |
A |
300Ch |
StrOut |
Gibt eine Folge von Zeichen, die an der Speicheradresse im DPTR beginnen und mit dem Zeichen 00h enden, aus. |
A, DPTR |
DPTR |
300Fh |
HexNibOut |
Gibt die erste 4 Bit im AKKU in Hex aus. |
A, PSW |
|
3012h |
HexByteOut |
Gibt die Zahl im AKKU in Hex aus. |
A, PSW |
|
3015h |
HexWordOut |
Gibt die Zahl im DPTR in Hex aus. |
A, PSW, DPTR |
|
3018h |
BinBitOut |
Gibt das C-Bit binär aus. |
A, C |
|
301Bh |
BinBitOutACCU |
Gibt das 1. Bit des AKKUs binär aus. |
A, B |
|
301Eh |
BinByteOut |
Gibt die Zahl im AKKU binär aus. |
A, B |
|
3021h |
BinWordOut |
Gibt die Zahl im DPTR binär aus. |
A, B, DPTR |
|
3024h |
NumOut |
Gibt die Zahl im AKKU in Dezimal aus. |
A, B |
|
Zeicheneingabe | ||||
Adresse |
Name |
Beschreibung |
Verwendet |
Verändert |
3027h |
CharInHide |
Schreibt eingegebenes Zeichen in den AKKU |
A |
A |
302Ah |
CharIn |
Wie CharInHide, nur wird das Zeichen auch ausgegeben. |
A |
A |
302Dh |
HexNibIn |
Schreibt eingegebene Hex-Ziffer (0..9, A..F) in den AKKU und gibt sie aus. Wird ESC eingegeben, so wird abgebrochen und C=1 und AKKU=0, sonst C=0. |
A, PSW |
A, PSW, C |
3030h |
HexByteIn |
Wie HexNibIn, nur werden zwei Hex-Ziffern in den AKKU geschrieben. |
A, B, PSW |
A, PSW, C |
3033h |
HexWordIn |
Wie HexNibIn, nur werden vier Hex-Ziffern in den DPTR geschrieben. Wird ESC eingegeben, so wird abgebrochen und C=1 und DPTR=0. |
A, B, PSW, DPTR |
PSW, DPTR, C |
3036h |
BinBitIn |
Schreibt eingegebene Binärziffer (0..1) ins C-Bit und gibt sie aus. |
A, C |
C |
3039h |
BinBitInACCU |
Schreibt eingegebene Binärziffer (0..1) ins Bit 0 des AKKUs gibt sie aus. Wird ESC eingegeben, so wird abgebrochen und C=1. |
A, C |
ACC.0, C |
303Ch |
BinByteIn |
Wie BinBitInACCU, nur werden 8 Ziffern in den AKKU geschrieben. Wird ESC eingegeben, so wird abgebrochen und C=1 und AKKU=0. |
A, B, C |
A, C |
303Fh |
BinWordIn |
Wie in BinBitInACCU, nur werden 16 Ziffer in den DPTR geschrieben. Wird ESC eingegeben, so wird abgebrochen und C=1 und DPTR=0. |
A, B, C, DPTR |
DPTR, C |
3042h |
NumIn |
Wie HexNibIn, nur wird eine Dezimal-Ziffer (0..9) eingelesen und in den AKKU geschrieben |
A, PSW |
A, PSW |
;** Monitorprogramm für 8051/2 EV-Kit **
**
;** von : Roland HEINRICH **
;** Datum: 10.03.1997 **
;** Konstanten **
DPTRSafe XDATA 87EBh ;DPTR-Sicherungsadresse 2 Byte
ACCUSafe XDATA 87EDh ;ACCU-Sicherungsadresse 1 Byte
PSWSafe XDATA 87EEh ;PSW-Sicherungsadresse 1 Byte
SPSafe XDATA 87EFh ;SP-Sicherungsadresse 1 Byte
IESafe XDATA 87F0h ;IE-Sicherungsadresse 1 Byte
DPTR1Mem XDATA 87F1h ;DPTR-Speicheradresse1 2 Byte
DPTR2Mem XDATA 87F3h ;DPTR-Speicheradresse2 2 Byte
BreakPoint XDATA 87F5h ;Breakpoint-Adresse 2 Byte
BreakAdr XDATA 87F7h ;Break-Adresse 2 Byte
BreakMem XDATA 87F9h ;Befehlssicherungsbereich für Breakpoint 3 Byte
BreakDone XDATA 87FCh ;Anzeige ob BP in Programm eingesetzt 1 Byte
ListNum XDATA 87FDh ;Adresse für Anzahl der Befehle bei List
Serielle XDATA 87FEh ;Adresse für Einstellung der seriellen Schnittstelle
PinRegA XDATA 0A002h ;Adresse des Pin-Registers des WSI-Ports A
DirRegA XDATA 0A004h ;Adresse des Direction-Registers des WSI-Ports A
DataRegA XDATA 0A006h ;Adresse des Daten-Registers des WSI-Ports A
Hauptprog CODE 0050h ;Beginnadresse für Hauptprogramm
BreakProg CODE 0A00h ;Beginnadresse für Break-Programm
Tabellen CODE 1000h ;Beginnadresse für Tabellen
GlobSUB CODE 3000h ;Beginnadresse für Globale Unterprogramme
BreakProgH EQU 0Ah ;Beginnadresse für Break-Programm
BreakProgLEQU 00h ;in High- und Low-Byte aufgeteilt
RDat BIT P1.2 ;Receive Eingang für serielle Schnittstelle
TDat BIT P1.3 ;Transmit Ausgang für serielle Schnittstelle
;** Programmcode **
ORG 0000h
JMP Haupt ;Sprung zum Programmbeginn
;** Interrupts verbiegen **
ORG 0003h
JMP 8003h ;External Interrupt 0
ORG 000Bh
JMP 800Bh ;Timer 0 Overflow Interrupt
ORG 0013h
JMP 8013h ;External Interrupt 1
ORG 001Bh
JMP 801Bh ;Timer 1 Overflow Interrupt
ORG 0023h
JMP 8023h ;Serial Interrupt
ORG 002Bh
JMP 802Bh ;Timer 2 Overflow / External Reload Interrupt
;** Hauptprogramm **
ORG Hauptprog
Haupt:
MOV DPTR, #BreakDone ;BreakDone-Byte -> ACCU
MOVX A, @DPTR
JZ Haupt1 ;Wenn BreakDone nicht aktiviert -> JMP Haupt1
CALL ClrBreak
Haupt1:
MOV DPTR, #0000h
CALL StoreBreak ;DPTR -> Break-Adresse = Break-Adresse löschen
MOV DPTR, #Serielle
MOVX A, @DPTR
CJNE A, #01, Haupt2 ;Wenn Serielle=01h -> PA für Schnittstelle initialisieren
MOV DPTR, #DirRegA
MOVX A, @DPTR
CLR ACC.0 ;PA.0 -> Input
SETB ACC.1 ;PA.1 -> Output
MOVX @DPTR, A
JMP Haupt4
Haupt2:
CJNE A, #02h, Haupt3 ;Wenn Serielle=02h -> serielle Schnittstelle initialisieren
CALL SeriellInit
JMP Haupt4
Haupt3:
CLR A
MOVX @DPTR, A
Haupt4:
MOV DPTR, #ResetStr ;Reset-Meldung ausgeben
CALL StrOut
Beginn:
CALL ReturnOut
MOV DPTR, #EingabeStr
CALL StrOut
Loop1:
CALL CharInHide ;auf Eingabe warten, Zeichen -> ACCU
CJNE A, #62h, Loop2 ;Wenn Zeichen='b' -> Breakpoint ändern
CALL CharOut
CALL BreakCh
JMP Beginn
Loop2:
CJNE A, #63h, Loop3 ;Wenn Zeichen='c' -> Programm fortsetzen
CALL CharOut
CALL Continue
JMP Beginn
Loop3:
CJNE A, #67h, Loop4 ;Wenn Zeichen='g' -> Programm starten
CALL CharOut
CALL Go
JMP Beginn
Loop4:
CJNE A, #68h, Loop5 ;Wenn Zeichen='h' -> Help ausgeben
CALL CharOut
MOV DPTR, #HelpStr
CALL StrOut
JMP Beginn
Loop5:
CJNE A, #69h, Loop6 ;Wenn Zeichen='i' -> IntelHex-Eingabe
CALL CharOut
CALL IntelHexIn
JMP Beginn
Loop6:
CJNE A, #6Ch, Loop7 ;Wenn Zeichen='l' -> Befehlslisting
CALL CharOut
CALL List
JMP Beginn
Loop7:
CJNE A, #6Fh, Loop8 ;Wenn Zeichen='o' -> Optionen ändern
CALL CharOut
CALL Options
JMP Beginn
Loop8:
CJNE A, #72h, Loop9 ;Wenn Zeichen='r' -> Software-Reset
CALL CharOut
CALL SReset
JMP Beginn
Loop9:
CJNE A, #64h, Loop10 ;Wenn Zeichen='d' -> Byte anzeigen
CALL CharOut
CALL DisplayByte
JMP Beginn
Loop10:
CJNE A, #65h, Loop1 ;Wenn Zeichen='e' -> Byte editieren
CALL CharOut
CALL EditByte
JMP Beginn
;** Unterprogramme **
;** Schnittstelle initialisieren **
SeriellInit:
MOV TH1, #0FDh ;Timer 1 zu Baud-Rate-Generierung
MOV TL1, #0FDh ;Reloadvalue für 9600 Baud
MOV TMOD, #00100000b ;Timer 1 auf Mode 2
SETB TR1
CLR SM0 ;Serielle Schnittstelle auf Mode 1
SETB SM1
SETB REN ;Datenempfang aktivieren
MOV PCON, #00h
RET
;** Auswahl **
Auswahl:
CALL CharInHide ;auf Eingabe warten
CJNE A, #1Bh, Auswahl1 ;Wenn Zeichen=ESC -> C=0
CLR C
RET
Auswahl1:
CJNE A, #0Dh, Auswahl ;Wenn Zeichen=Return -> C=1
SETB C
RET
;** Programm starten **
Go:
MOV A, #20h ;Space ausgeben
CALL CharOut
CALL HexWordIn ;Startadresse einlesen
JC GoE
CALL ReturnOut
PUSH DPH
PUSH DPL
CALL RestoreBPoint ;Breakpoint-Adresse -> DPTR
MOV A, DPH
JZ Go1
CALL BreakAkt
Go1:
POP DPL
POP DPH
CLR A ;ACCU, PSW, SP auf Anfangswerte setzten
MOV PSW, #00h
MOV SP, #07h
JMP @A+DPTR ;Programm starten
GoE:
RET
;** IntelHex-Eingabe **
IntelHexIn:
MOV DPTR, #IAchtungStr
CALL StrOut
CALL Auswahl
JNC IntelHexInE2
CALL ReturnOut
PUSH B
IntelHexIn1:
MOV A, #3Eh ;'>'-Zeichen ausgeben
CALL CharOut
IntelHexIn2:
CALL CharInHide ;auf Eingabe warten
CJNE A, #3Ah, IntelHexIn2 ;Wenn Zeichen=':' -> Weiter
CALL CharOut
CALL HexByteIn ;Anzahl der Datenbytes -> B
MOV B, A
CALL HexWordIn ;Startadresse -> DPTR
JZ IntelHexIn3
CALL CheckAddr
JC IntelHexInF
IntelHexIn3:
CALL HexByteIn ;Type-Byte einlesen und zwischenspeichern
PUSH ACC
IntelHexIn4:
MOV A, B
JZ IntelHexIn5
CALL HexByteIn ;Datenbyte einlesen
MOVX @DPTR, A ;Datenbyte -> Adresse in DPTR
INC DPTR
DEC B
JMP IntelHexIn4
IntelHexIn5:
CALL HexByteIn ;CheckSum einlesen (wird übergangen)
IntelHexIn6:
CALL CharInHide ;Auf Return (CR oder LF) warten
CJNE A, #0Dh, IntelHexIn7
JMP IntelHexIn8
IntelHexIn7:
CJNE A, #0Ah, IntelHexIn6
IntelHexIn8:
CALL ReturnOut
POP ACC ;Type-Byte zurückholen
JNZ IntelHexInE1 ;Wenn <>00h Einlesen beenden, sonst weiter
JMP IntelHexIn1
IntelHexInF:
MOV DPTR, #IFehlerStr
CALL StrOut
IntelHexInE1:
POP B
IntelHexInE2:
RET
;** Adreß-Bereich prüfen **
CheckAddr:
MOV A, DPH
CJNE A, #80h, CheckAddr1
CheckAddr1:
JC CheckAddrF
CJNE A, #87h, CheckAddr2
JMP CheckAddrF
CheckAddr2:
PUSH ACC
MOV A, B
ADD A, DPL
POP ACC
JNC CheckAddr3
INC A
CJNE A, #87h, CheckAddr3
JMP CheckAddrF
CheckAddr3:
CJNE A, #0A0h, CheckAddr4
CheckAddr4:
JNC CheckAddrF
CLR C
RET
CheckAddrF:
SETB C
RET
;** Optionen ändern **
Options:
MOV DPTR, #OptionStr
CALL StrOut
MOV DPTR, #ListNum
MOVX A, @DPTR
CALL HexByteOut
MOV DPTR, #Option1Str
CALL StrOut
MOV DPTR, #Serielle
MOVX A, @DPTR
CALL HexByteOut
MOV DPTR, #OEingabeStr
CALL StrOut
Options1:
CALL CharInHide
CJNE A, #1Bh, Options2 ;Wenn ESC gedrückt -> Beenden
CALL ReturnOut
RET
Options2:
CJNE A, #6Ch, Options3 ;Wenn Zeichen='l' -> Listingslänge ändern
CALL CharOut
MOV A, #20h ;Space ausgeben
CALL CharOut
CALL HexByteIn
JC Options
MOV DPTR, #ListNum
MOVX @DPTR, A
JMP Options
Options3:
CJNE A, #73h, Options1 ;Wenn Zeichen='s' -> serielle Schnittstelle ändern
CALL CharOut
MOV A, #20h ;Space ausgeben
CALL CharOut
CALL HexByteIn
JC Options
MOV DPTR, #OResetStr
CALL StrOut
MOV DPTR, #Serielle
MOVX @DPTR, A
Options4:
JMP Options4
;** Software-Reset **
SReset:
MOV DPTR, #SResetStr
CALL StrOut
CALL Auswahl
JC Sreset1
RET
Sreset1:
MOV DPTR, #8000h
SReset2:
CLR A
MOVX @DPTR, A
INC DPTR
MOV A, DPH
CJNE A, #88h, SReset2
MOV DPTR, #SRFertigStr
CALL StrOut
RET
;** Byte anzeigen **
DisplayByte:
CALL CharInHide ;Auf Tastendruck warten
CJNE A, #1Bh, DisplayByte1 ;Wenn ESC gedrückt -> Beenden
RET
DisplayByte1:
CJNE A, #63h, DisplayByte2 ;Wenn 'c' gedrückt -> Programm-Speicher anzeigen
CALL CharOut
CALL DisplayCode
RET
DisplayByte2:
CJNE A, #69h, DisplayByte3 ;Wenn 'i' gedrückt -> internen Daten-Speicher anzeigen
CALL CharOut
CALL DisplayIData
RET
DisplayByte3:
CJNE A, #78h, DisplayByte ;Wenn 'x' gedrückt -> externen Daten-Speicher anzeigen
CALL CharOut
CALL DisplayXData
RET
;** Programm-Speicher anzeigen **
DisplayCode:
MOV A, #20h ;Space ausgeben
CALL CharOut
CALL HexWordIn ;Speicher-Adresse eingeben
JC DisplayCodeE ;Bei ESC Beenden
CLR A ;Speicherinhalt -> ACCU
MOVC A, @A+DPTR
MOV DPTR, #DAktuellStr
CALL StrOut
CALL HexByteOut
CALL ReturnOut
DisplayCodeE:
RET
;** internen Daten-Speicher anzeigen **
DisplayIData:
MOV A, #20h ;Space ausgeben
CALL CharOut
CALL HexByteIn ;Speicher-Adresse eingeben
JC DisplayIDataE ;Bei ESC Beenden
MOV DPTR, #DAktuellStr
CALL StrOut
CJNE A, #81h, DisplayIData1
MOV DPTR, #SPSafe
JMP DisplayIData10
DisplayIData1:
CJNE A, #82h, DisplayIData2
MOV DPTR, #DPTRSafe
JMP DisplayIData10
DisplayIData2:
CJNE A, #83h, DisplayIData3
MOV DPTR, #DPTRSafe
INC DPTR
JMP DisplayIData10
DisplayIData3:
CJNE A, #0A8h, DisplayIData4
MOV DPTR, #IESafe
JMP DisplayIData10
DisplayIData4:
CJNE A, #0D0h, DisplayIData5
MOV DPTR, #PSWSafe
JMP DisplayIData10
DisplayIData5:
CJNE A, #0E0h, DisplayIData6
MOV DPTR, #ACCUSafe
JMP DisplayIData10
DisplayIData6:
MOV C, ACC.7
ANL C, PSW.4
JC DisplayIData7
MOV C, ACC.7
ORL C, PSW.4
JNC DisplayIData7
JMP DisplayIData9
DisplayIData7:
MOV C, ACC.6
ANL C, PSW.3
JC DisplayIData8
MOV C, ACC.6
ORL C, PSW.3
JNC DisplayIData8
JMP DisplayIData9
DisplayIData8:
ANL A, #00111111b
CJNE A, #00h, DisplayIData9
MOV A, R0
JMP DisplayIData11
DisplayIData9:
MOV A, R0 ;R0 sichern
PUSH ACC
MOV R0, A ;Speicherinhalt -> ACCU
MOV A, @R0
CALL HexByteOut
CALL ReturnOut
POP ACC
MOV R0, A ;R0 zurückholen
JMP DisplayIDataE
DisplayIData10:
MOVX A, @DPTR
DisplayIData11:
CALL HexByteOut
CALL ReturnOut
DisplayIDataE:
RET
;** externen Daten-Speicher anzeigen **
DisplayXData:
MOV A, #20h ;Space ausgeben
CALL CharOut
CALL HexWordIn ;Speicher-Adresse eingeben
JC DisplayXDataE ;Bei ESC Beenden
MOVX A, @DPTR ;Speicherinhalt -> ACCU
MOV DPTR, #DAktuellStr
CALL StrOut
CALL HexByteOut
CALL ReturnOut
DisplayXDataE:
RET
;** Byte editieren **
EditByte:
CALL CharInHide ;Auf Tastendruck warten
CJNE A, #1Bh, EditByte1 ;Wenn ESC gedrückt -> Beenden
RET
EditByte1:
CJNE A, #63h, EditByte2 ;Wenn 'c' gedrückt -> Programm-Speicher editieren
CALL CharOut
CALL EditCode
RET
EditByte2:
CJNE A, #69h, EditByte3 ;Wenn 'i' gedrückt -> internen Daten-Speicher editieren
CALL CharOut
CALL EditIData
RET
EditByte3:
CJNE A, #78h, EditByte ;Wenn 'x' gedrückt -> externen Daten-Speicher editieren
CALL CharOut
CALL EditXData
RET
;** Programm-Speicher editieren **
EditCode:
MOV A, #20h ;Space ausgeben
CALL CharOut
CALL HexWordIn ;Speicher-Adresse eingeben
JC EditCodeE2 ;Bei ESC Beenden
PUSH B
MOV B, #01h
CALL CheckAddr
POP B
JC EditCodeF
CLR A ;Speicherinhalt -> ACCU
MOVC A, @A+DPTR
PUSH DPH
PUSH DPL
MOV DPTR, #DAktuellStr
CALL StrOut
CALL HexByteOut
MOV DPTR, #ENeuStr
CALL StrOut
POP DPL
POP DPH
CALL HexByteIn
JC EditCodeE1
MOVX @DPTR, A
EditCodeE1:
CALL ReturnOut
EditCodeE2:
RET
EditCodeF:
MOV DPTR, #IFehlerStr ;Fehlermeldung
CALL StrOut
RET
;** internen Daten-Speicher editieren **
EditIData:
MOV A, #20h ;Space ausgeben
CALL CharOut
CALL HexByteIn ;Speicher-Adresse eingeben
JNC EditIData0 ;Bei ESC Beenden
RET
EditIData0:
MOV DPTR, #DAktuellStr
CALL StrOut
CJNE A, #81h, EditIData1
MOV DPTR, #SPSafe
JMP EditIData11
EditIData1:
CJNE A, #82h, EditIData2
MOV DPTR, #DPTRSafe
JMP EditIData11
EditIData2:
CJNE A, #83h, EditIData3
MOV DPTR, #DPTRSafe
INC DPTR
JMP EditIData11
EditIData3:
CJNE A, #0A8h, EditIData4
MOV DPTR, #IESafe
JMP EditIData11
EditIData4:
CJNE A, #0D0h, EditIData5
MOV DPTR, #PSWSafe
JMP EditIData11
EditIData5:
CJNE A, #0E0h, EditIData6
MOV DPTR, #ACCUSafe
JMP EditIData11
EditIData6:
MOV C, ACC.7
ANL C, PSW.4
JC EditIData7
MOV C, ACC.7
ORL C, PSW.4
JNC EditIData7
JMP EditIData9
EditIData7:
MOV C, ACC.6
ANL C, PSW.3
JC EditIData8
MOV C, ACC.6
ORL C, PSW.3
JNC EditIData8
JMP EditIData9
EditIData8:
ANL A, #00111111b
CJNE A, #00h, EditIData9
MOV A, R0
CALL HexByteOut
MOV DPTR, #ENeuStr
CALL StrOut
CALL HexByteIn
JC EditIDataE
MOV R0, A
JMP EditIDataE
EditIData9:
MOV A, R0 ;R0 sichern
PUSH ACC
MOV R0, A ;Speicherinhalt -> ACCU
MOV A, @R0
CALL HexByteOut
MOV DPTR, #ENeuStr
CALL StrOut
CALL HexByteIn
JC EditIData10
MOV @R0, A
EditIData10:
POP ACC
MOV R0, A ;R0 zurückholen
JMP EditIDataE
EditIData11:
MOVX A, @DPTR
CALL HexByteOut
PUSH DPH
PUSH DPL
MOV DPTR, #ENeuStr
CALL StrOut
POP DPL
POP DPH
CALL HexByteIn
JC EditIDataE
MOVX @DPTR, A
EditIDataE:
CALL ReturnOut
RET
;** externen Daten-Speicher editieren **
EditXData:
MOV A, #20h ;Space ausgeben
CALL CharOut
CALL HexWordIn ;Speicher-Adresse eingeben
JC EditXDataE2 ;Bei ESC Beenden
PUSH DPH
PUSH DPL
MOVX A, @DPTR ;Speicherinhalt -> ACCU
MOV DPTR, #DAktuellStr
CALL StrOut
CALL HexByteOut
MOV DPTR, #ENeuStr
CALL StrOut
POP DPL
POP DPH
CALL HexByteIn
JC EditXDataE1
MOVX @DPTR, A
EditXDataE1:
CALL ReturnOut
EditXDataE2:
RET
;** Breakpoint ändern **
BreakCh:
CALL CharInHide ;Auf Tastendruck warten
CJNE A, #1Bh, BreakCh1 ;Wenn ESC gedrückt -> Beenden
RET
BreakCh1:
CJNE A, #73h, BreakCh2 ;Wenn 's' gedrückt -> BP setzen
CALL CharOut
CALL BreakSet
RET
BreakCh2:
CJNE A, #6Ch, BreakCh3 ;Wenn 'l' gedrückt -> BP anzeigen
CALL CharOut
CALL BreakList
RET
BreakCh3:
CJNE A, #64h, BreakCh ;Wenn 'd' gedrückt -> BP löschen
CALL CharOut
CALL BreakDel
RET
;** Breakpoint setzten **
BreakSet:
MOV A, #20h ;Space ausgeben
CALL CharOut
CALL HexWordIn ;BP-Adresse eingeben
JC BreakSetE ;Bei ESC Beenden
PUSH B
MOV B, #03h
CALL CheckAddr ;BP-Adresse prüfen
POP B
JC BreakSetF ;wenn BP-Adresse ungültig -> Fehler
CALL StoreBPoint ;DPTR -> BP-Adresse
MOV DPTR, #BSetStr ;BP-Adresse gesetzt
CALL StrOut
RET
BreakSetF:
MOV DPTR, #BSFehlerStr ;Fehlermeldung
CALL StrOut
BreakSetE:
RET
;** Breakpoint anzeigen **
BreakList:
MOV DPTR, #BListStr
CALL StrOut
CALL RestoreBPoint ;BP-Adresse -> DPTR
MOV A, DPH
JZ BreakList1 ;Wenn BP-Adresse=00xxh -> BreakList1
CALL HexWordOut ;BP-Adresse ausgeben
CALL ReturnOut
RET
BreakList1:
MOV DPTR, #BLKeinStr ;keine ausgeben
CALL StrOut
RET
;** Breakpoint löschen **
BreakDel:
MOV DPTR, #0000h
CALL StoreBPoint ;DPTR -> Breakpoint-Adresse
MOV DPTR, #BDelStr ;BP gelöscht ausgeben
CALL StrOut
RET
;** Breakpoint aktivieren **
BreakAkt:
MOV DPTR, #BAktStr
CALL StrOut
CALL Auswahl
JC BreakAkt1
RET
BreakAkt1: ;Break-Befehle in Programm schreiben
CALL RestoreBPoint ;Breakpoint-Adresse -> DPTR
MOVX A, @DPTR ;Befehle bei Break-Adresse lesen
PUSH ACC
INC DPTR
MOVX A, @DPTR
PUSH ACC
INC DPTR
MOVX A, @DPTR
PUSH ACC
MOV DPTR, #BreakMem ;Befehle in BreakMem sichern
POP ACC
MOVX @DPTR, A
INC DPTR
POP ACC
MOVX @DPTR, A
INC DPTR
POP ACC
MOVX @DPTR, A
CALL RestoreBPoint ;Breakpoint-Adresse -> DPTR
MOV A, #12h ;Breakbefehle an Break-Adresse schreiben
MOVX @DPTR, A ;LCALL-Befehl schreiben
INC DPTR
MOV A, #BreakProgH ;Sprungadresse (BreakProg) schreiben
MOVX @DPTR, A
INC DPTR
MOV A, #BreakProgL
MOVX @DPTR, A
MOV DPTR, #BreakDone ;BreakDone aktivieren
MOV A, #0FFh
MOVX @DPTR, A
RET
;** Break-Befehle löschen **
ClrBreak:
MOV DPTR, #BreakMem ;In BreakMem gesicherte Befehle lesen
MOVX A, @DPTR
PUSH ACC
INC DPTR
MOVX A, @DPTR
PUSH ACC
INC DPTR
MOVX A, @DPTR
PUSH ACC
CALL RestoreBreak ;Break-Adresse -> DPTR
POP ACC ;Gesicherte Befehle an Break-Adresse schreiben
MOVX @DPTR, A
INC DPTR
POP ACC
MOVX @DPTR, A
INC DPTR
POP ACC
MOVX @DPTR, A
MOV DPTR, #BreakDone ;BreakDone deaktivieren
CLR A
MOVX @DPTR, A
RET
;** Programm fortsetzen **
Continue:
CALL ReturnOut
CALL RestoreBreak ;Break-Adresse -> DPTR
MOV A, DPH ;Wenn Break-Adresse=00xxh -> Continue beenden
JZ ContinueE
MOV DPTR, #PSWSafe ;PSW zurückholen
MOVX A, @DPTR
MOV PSW, A
MOV DPTR, #SPSafe ;SP zurückholen
MOVX A, @DPTR
ADD A, #02h ;2, die bei Abbruch von SP abgezogen wurden dazuzählen
MOV SP, A
MOV DPTR, #IESafe ;gesichertes IE-Register zwischenspeichern
MOVX A, @DPTR
PUSH ACC
MOV DPTR, #ACCUSafe ;gesicherten ACCU zwischenspeichern
MOVX A, @DPTR
PUSH ACC
MOV DPTR, #DPTRSafe ;DPTR zurückholen
MOVX A, @DPTR
PUSH ACC
INC DPTR
MOVX A, @DPTR
MOV DPL, A
POP DPH
POP ACC ;zwischengespeicherten ACCU zurückholen
POP IE ;zwischengespeichertes IE-Register zurückholen
RET ;Programm an Abbruchadresse (Stack) fortsetzen
ContinueE:
MOV DPTR, #ContStr
CALL StrOut
RET
;** List **
List:
MOV A, #20h ;Space ausgeben
CALL CharOut
CALL HexWordIn ;Startadresse für Listing eingeben -> DPTR
JC ListE ;Wenn ESC dann beenden
CALL ReturnOut
CALL ReturnOut
PUSH DPH
PUSH DPL
MOV DPTR, #ListNum ;Lädt die Anzahl der Befehle
MOVX A, @DPTR
POP DPL
POP DPH
JNZ List1 ;Wenn Anzahl <>0 -> List1, sonst
MOV A, #10h ;Zähler auf 16 Befehle setzen
List1:
PUSH ACC
CALL DisASM ;Befehl an Adresse im DPTR ausgeben
POP ACC
INC DPTR ;Listingadresse erhöhen
DJNZ ACC, List1 ;Ist Zähler auf 0 -> Listing beenden
ListE:
RET
;** Disassembler **
DisASM:
CALL HexWordOut ;Adresse im DPTR wird ausgegeben
MOV A, #05h
CALL SpaceOut ;5 Space werden ausgegeben
CLR A
MOVC A, @A+DPTR ;Befehlsbyte an Adresse im DPTR einlesen
CALL StoreDPTR1 ;DPTR sichern -> DPTR1
MOV DPTR, #BefehlNum
CLR C ;DPTR:=DPTR+2*ACCU
RLC A ;RLC A = 2*ACCU
JNC DisASM01
INC DPH
DisASM01:
ADD A, DPL
MOV DPL, A
JNC DisASM02
INC DPH
DisASM02:
CLR A ;Adresse an der Befehlsstring beginnt -> DPTR
MOVC A, @A+DPTR
PUSH ACC
MOV A, #01h
MOVC A, @A+DPTR
MOV DPL, A
POP DPH
DisASM1:
CLR A
MOVC A, @A+DPTR
JZ DisASME ;Wenn Zeichen=00h -> Stringausgabe beenden
CJNE A, #01h, DisASM2 ;Wenn Zeichen=01h -> nächstes Befehlsbyte lesen und in
;HEX ausgeben
CALL ReadAddr
CALL HexByteOut
JMP DisASM6
DisASM2:
CJNE A, #02h, DisASM3 ;Wenn Zeichen=02h -> nächstes Befehlsword lesen und in
;HEX ausgeben
CALL ReadAddr ;gelesene Adresse = Bits 8-15 der Sprungadresse
CALL HexByteOut
CALL ReadAddr ;gelesene Adresse = Bits 0-7 der Sprungadresse
CALL HexByteOut
JMP DisASM6
DisASM3:
CJNE A, #03h, DisASM4 ;Wenn Zeichen=03h -> nächstes Befehlsbyte=relative ;Adresse lesen
CALL ReadAddr
CALL RestoreDPTR1 ;gesicherten DPTR1 -> DPTR
INC DPTR ;relative Adresse in absolute umrechnen und in HEX ;ausgeben
ADD A, DPL
MOV DPL, A
CALL HexWordOut
CALL RestoreDPTR2 ;gesicherten DPTR2 -> DPTR
JMP DisASM6
DisASM4:
CJNE A, #04h, DisASM5 ;Wenn Zeichen=04h -> 11 Bit-Adresse lesen und ausgeben
CALL StoreDPTR2 ;DPTR sichern -> DPTR2
CALL RestoreDPTR1 ;gesicherten DPTR1 -> DPTR
CLR A
MOVC A, @A+DPTR ;Befehlsbyte nochmal lesen
RL A ;Die letzten 3 Bit (= Bit 8-10 der Sprungadresse)
RL A ;an den Anfang schieben
RL A
ANL A, #00000111b ;und alle anderen Bits 0 setzten
INC DPTR ;DPTR:=DPTR+2 = Adresse des nächsten Befehlsbytes
INC DPTR
PUSH ACC ;ACCU (Bits 8-10 der Sprungadresse) sichern
MOV A, DPH
ANL A, #11111000b ;Bits 8-10 der nächsten Adresse auf 0 setzten
MOV DPH, A
POP ACC ;ACCU zurückholen
ORL A, DPH ;ACCU mit der näschsten Adresse OR-verknüpfen ->
;Bits 8-15 der Sprungadresse
CALL HexByteOut
CALL RestoreDPTR2 ;gesicherten DPTR2 -> DPTR
CALL ReadAddr ;gelesene Adresse = Bits 0-7 der Sprungadresse
CALL HexByteOut
JMP DisASM6
DisASM5:
CALL CharOut
DisASM6:
INC DPTR
JMP DisASM1
DisASME:
CALL RestoreDPTR1 ;gesicherten DPTR1 -> DPTR
CALL ReturnOut
RET
;** Adresse bei Befehl lesen **
ReadAddr:
CALL StoreDPTR2 ;DPTR sichern -> DPTR2
CALL RestoreDPTR1 ;gesicherten DPTR1 -> DPTR
INC DPTR
CLR A
MOVC A, @A+DPTR
PUSH ACC
CALL StoreDPTR1 ;DPTR sichern -> DPTR1
CALL RestoreDPTR2 ;gesicherten DPTR2 -> DPTR
POP ACC
RET
;** Speicher anzeigen **
ShowReg:
MOV DPTR, #SRegStr
CALL StrOut
MOV DPTR, #ACCUSafe
MOVX A, @DPTR
CALL HexByteOut ;gesicherten ACCU-Inhalt anzeigen
CALL Trenn
MOV A, B
CALL HexByteOut ;B-Inhalt anzeigen
CALL Trenn
MOV A, R0
CALL HexByteOut ;R0-Inhalt anzeigen
CALL Trenn
MOV A, R1
CALL HexByteOut ;R1-Inhalt anzeigen
CALL Trenn
MOV A, R2
CALL HexByteOut ;R2-Inhalt anzeigen
CALL Trenn
MOV A, R3
CALL HexByteOut ;R3-Inhalt anzeigen
CALL Trenn
MOV A, R4
CALL HexByteOut ;R4-Inhalt anzeigen
CALL Trenn
MOV A, R5
CALL HexByteOut ;R5-Inhalt anzeigen
CALL Trenn
MOV A, R6
CALL HexByteOut ;R6-Inhalt anzeigen
CALL Trenn
MOV A, R7
CALL HexByteOut ;R7-Inhalt anzeigen
CALL Trenn
MOV DPTR, #PSWSafe ;gesicherten PSW-Inhalt anzeigen
MOVX A, @DPTR
CALL HexByteOut
CALL Trenn
MOV DPTR, #DPTRSafe ;gesicherten DPTR-Inhalt anzeigen
MOVX A, @DPTR
CALL HexByteOut
INC DPTR
MOVX A, @DPTR
CALL HexByteOut
CALL Trenn
MOV DPTR, #SPSafe ;gesicherten SP-Inhalt anzeigen
MOVX A, @DPTR
CALL HexByteOut
CALL ReturnOut
CALL ReturnOut
RET
Trenn:
MOV A, #20h
CALL CharOut
MOV A, #20h
CALL CharOut
RET
;** Word speichern **
StoreBreak:
PUSH ACC
PUSH DPL
PUSH DPH
MOV DPTR, #BreakAdr
JMP StoreWord
StoreBPoint:
PUSH ACC
PUSH DPL
PUSH DPH
MOV DPTR, #BreakPoint
JMP StoreWord
StoreDPTR1:
PUSH ACC
PUSH DPL
PUSH DPH
MOV DPTR, #DPTR1Mem
JMP StoreWord
StoreDPTR2:
PUSH ACC
PUSH DPL
PUSH DPH
MOV DPTR, #DPTR2Mem
StoreWord:
POP ACC
MOVX @DPTR, A
INC DPTR
POP ACC
MOVX @DPTR, A
POP ACC
RET
;** Word laden **
RestoreBreak:
MOV DPTR, #BreakAdr
JMP RestoreWord
RestoreBPoint:
MOV DPTR, #BreakPoint
JMP RestoreWord
RestoreDPTR1:
MOV DPTR, #DPTR1Mem
JMP RestoreWord
RestoreDPTR2:
MOV DPTR, #DPTR2Mem
RestoreWord:
PUSH ACC
MOVX A, @DPTR
PUSH ACC
INC DPTR
MOVX A, @DPTR
MOV DPL, A
POP DPH
POP ACC
RET
;** Warteschleife für CharOut, CharInHide **
Warten:
DJNZ ACC, Warten
RET
;** Unterprogramme zur Zeichenausgabe **
;** Char-Ausgabe **
CharOut:
PUSH PSW
PUSH DPH
PUSH DPL
MOV DPTR, #Serielle
PUSH ACC
MOVX A, @DPTR
CJNE A, #01h, CharOut1 ;Wenn Serielle=01h -> ser. Schnittstelle auf PA
POP ACC
MOV DPTR, #DataRegA
JMP CharOut5
CharOut1:
CJNE A, #02h, CharOut3 ;Wenn Serielle=02h -> echte ser. Schnittstelle
POP ACC
POP DPL
POP DPH
POP PSW
CLR TI ;echte serielle Schnittstelle
MOV SBUF, A
CharOut2:
JNB TI, CharOut2
RET
CharOut3: ;sonst ser. Schnittstelle auf P1
POP ACC
POP DPL
POP DPH
PUSH B ;simulierte ser. Schnittstelle auf P1
CLR TDat ;Startbit setzen
MOV B, #08h
CharOut4: ;Schleife zur Ausgabe der 8 Datenbits
PUSH ACC
MOV A, #41
CALL Warten
POP ACC
RRC A
MOV TDat, C ;Datenbit setzen
DJNZ B, CharOut4
POP B
PUSH ACC
MOV A, #41
CALL Warten
NOP
NOP
SETB TDat ;Stoppbit setzen
MOV A, #92
CALL Warten
POP ACC
RRC A
POP PSW
RET
CharOut5: ;simulierte ser. Schnittstelle auf PA
PUSH B
PUSH ACC
MOVX A, @DPTR
CLR ACC.1 ;Startbit setzen
MOVX @DPTR, A
POP ACC
MOV B, #08h
CharOut6: ;Schleife zur Ausgabe der 8 Datenbits
RRC A
PUSH ACC
MOV A, #38
CALL Warten
MOVX A, @DPTR
MOV ACC.1, C ;Datenbit setzen
MOVX @DPTR, A
POP ACC
DJNZ B, CharOut6
POP B
PUSH ACC
MOV A, #39
CALL Warten
MOVX A, @DPTR
SETB ACC.1 ;Stoppbit setzen
MOVX @DPTR, A
MOV A, #90
CALL Warten
POP ACC
RRC A
POP DPL
POP DPH
POP PSW
RET
;** Return-Ausgabe **
ReturnOut:
PUSH ACC
MOV A, #0Dh
CALL CharOut
MOV A, #0Ah
CALL CharOut
POP ACC
RET
;** Space-Ausgabe **
SpaceOut:
JZ SpaceOutE
PUSH ACC
MOV A, #20h
CALL CharOut
POP ACC
DEC A
JMP SpaceOut
SpaceOutE:
RET
;** Cursor-Ausgabe **
CursorOut:
PUSH ACC
MOV A, #1Bh ;ESC-Zeichen ausgeben
CALL CharOut
POP ACC
PUSH DPH
PUSH DPL
MOV DPTR, #CurNum
MOVC A, @A+DPTR ;Steuerzeichen von Adresse DPTR (CurNum) + ACCU lesen
POP DPL
POP DPH
CALL CharOut ;und ausgeben
RET
;** String-Ausgabe **
StrOut:
PUSH ACC
StrOut1:
CLR A
MOVC A, @A+DPTR ;Zeichen an Adresse im DPTR lesen
JZ StrOut2 ;Wenn Zeichen=00h, dann Beenden
CALL CharOut ;sonst Zeichen ausgeben
INC DPTR ;Adresse erhöhen
JMP StrOut1 ;und nächstes Zeichen lesen
StrOut2:
POP ACC
RET
;** Hex-Nibble-Ausgabe **
HexNibOut:
PUSH ACC
PUSH PSW
ANL A, #0Fh
CJNE A, #0Ah, HexNibOut1
HexNibOut1:
JC HexNibOut2
ADD A, #37h
JMP HexNibOut3
HexNibOut2:
ADD A, #30h
HexNibOut3:
CALL CharOut
POP PSW
POP ACC
RET
;** Hex-Byte-Ausgabe **
HexByteOut:
SWAP A
CALL HexNibOut
SWAP A
CALL HexNibOut
RET
;** Hex-Word-Ausgabe **
HexWordOut:
PUSH ACC
MOV A, DPH
CALL HexByteOut
MOV A, DPL
CALl HexByteOut
POP ACC
RET
;** Binär-Bit-Ausgabe **
;** Bit im C **
BinBitOut:
PUSH ACC
MOV A, #30h
JNC BinBitOut1
INC A
BinBitOut1:
CALL CharOut
POP ACC
RET
;** Binär-Bit-Ausgabe **
;** Bit im ACCU **
BinBitOutACCU:
PUSH B
MOV B, #30h
JNB ACC.0, BinBitOutACCU1
INC B
BinBitOutACCU1:
XCH A, B
CALL CharOut
XCH A, B
POP B
RET
;** Binär-Byte-Ausgabe **
BinByteOut:
PUSH B
MOV B, #08h
BinByteOut1:
RL A
CALL BinBitOutACCU
DJNZ B, BinByteOut1
POP B
RET
;** Binär-Word-Ausgabe **
BinWordOut:
PUSH ACC
MOV A, DPH
CALL BinByteOut
MOV A, DPL
CALL BinByteOut
POP ACC
RET
;** Dezimalzahl-Ausgabe **
NumOut:
PUSH B
PUSH ACC
MOV B, #64h
DIV AB ;Zahl/100 => A=100er-Stelle; B=Rest
ADD A, #30h ;100er-Stelle wird ausgegeben
CALL CharOut
MOV A, B
MOV B, #0Ah
DIV AB ;Rest von vorher/100 => A=10er-Stelle; B=Rest
ADD A, #30h ;10er-Stelle wird ausgegeben
CALL CharOut
MOV A, B
ADD A, #30h ;Rest=1er-Stelle wird ausgegeben
CALL CharOut
POP ACC
POP B
RET
;** Unterprogramme zu Zeicheneingabe **
;** Char-Eingabe unsichtbar **
CharInHide:
PUSH PSW
PUSH DPH
PUSH DPL
MOV DPTR, #Serielle
MOVX A, @DPTR
CJNE A, #01h, CharInHide1 ;Wenn Serielle=01h -> ser. Schnittstelle auf PA
MOV DPTR, #PinRegA
JMP CharInHide7
CharInHide1:
CJNE A, #02h, CharInHide3 ;Wenn Serielle=02h -> echte ser. Schnittstelle
POP DPL
POP DPH
POP PSW
CharInHide2:
JNB RI, CharInHide2
MOV A, SBUF
CLR RI
RET
CharInHide3: ;sonst ser. Schnittstelle auf P1
POP DPL
POP DPH
CharInHide4: ;simulierte ser. Schnittstelle auf P1
JB RDat, CharInHide4 ;auf Startbit warten
MOV A, #20
CALL Warten
NOP
JB RDat, CharInHide4 ;prüfen ob Startbit noch vorhanden
PUSH B
MOV B, #08h
CharInHide5: ;Schleife um 8 Datenbits einzulesen
PUSH ACC
MOV A, #41
CALL Warten
POP ACC
MOV C, RDat ;Datenbit einlesen
RRC A
NOP
DJNZ B, CharInHide5
POP B
PUSH ACC
MOV A, #39
CALL Warten
POP ACC
NOP
JNB RDat, CharInHide6 ;prüfen ob Stoppbit vorhanden
POP PSW
RET
CharInHide6:
JNB RDat, CharInHide6
JMP CharInHide4
CharInHide7: ;simulierte ser. Schnittstelle auf PA
MOVX A, @DPTR
JB ACC.0, CharInHide7 ;auf Startbit warten
MOV A, #19
CALL Warten
NOP
MOVX A, @DPTR
JB ACC.0, CharInHide7 ;prüfen ob Startbit noch vorhanden
PUSH B
MOV B, #08h
CharInHide8: ;Schleife um 8 Datenbits einzulesen
PUSH ACC
MOV A, #40
CALL Warten
NOP
MOVX A, @DPTR ;Datenbit einlesen
MOV C, ACC.0
POP ACC
RRC A
DJNZ B, CharInHide8
POP B
PUSH ACC
MOV A, #39
CALL Warten
NOP
MOVX A, @DPTR
JNB ACC.0, CharInHide9 ;prüfen ob Stoppbit vorhanden
POP ACC
POP DPL
POP DPH
POP PSW
RET
CharInHide9:
MOVX A, @DPTR
JNB ACC.0, CharInHide9
POP ACC
JMP CharInHide7
;** Char-Eingabe sichbar **
CharIn:
CALL CharInHide
CALL CharOut
PUSH PSW
CJNE A, #0Dh, CharIn1
PUSH ACC
MOV A, #0Ah
CALL CharOut
POP ACC
CharIn1:
POP PSW
RET
;** Hex-Nibbel-Eingabe **
HexNibIn:
CALL CharInHide ;auf Eingabe warten
CJNE A, #1Bh, HexNibIn1 ;Wenn Zeichen=ESC -> C=1 und Beenden
SETB C
CLR A
RET
HexNibIn1:
CJNE A, #30h, HexNibIn2 ;Wenn Zeichen<30h ('0') -> zurück zu Eingabe
HexNibIn2:
JC HexNibIn
CJNE A, #3Ah, HexNibIn3 ;Wenn Zeichen<3A ('9'+1) -> Nummer
HexNibIn3:
JC HexNibIn6
ANL A, #11011111b ;Kleinbuchstaben auf große umwandeln
CJNE A, #41h, HexNibIn4 ;Wenn Zeichen<41h ('A') -> zurück zu Eingabe
HexNibIn4:
JC HexNibIn
CJNE A, #47h, HexNibIn5 ;Wenn Zeichen<47h ('G') -> Buchstabe
HexNibIn5:
JNC HexNibIn
CALL CharOut
CLR C
SUBB A, #37h
RET
HexNibIn6: ;Nummer
CALL CharOut
CLR C
SUBB A, #30h
RET
;** Hex-Byte-Eingabe **
HexByteIn:
PUSH B
CALL HexNibIn
JC HexByteInE
SWAP A
MOV B, A
CALL HexNibIn
JC HexByteInE
ORL A, B
POP B
RET
HexByteInE:
CLR A
POP B
RET
;** Hex-Word-Eingabe **
HexWordIn:
PUSH ACC
CALL HexByteIn
JC HexWordInE
MOV DPH, A
CALL HexByteIn
JC HexWordInE
MOV DPL, A
POP ACC
RET
HexWordInE:
MOV DPTR, #0000h
POP ACC
RET
;** Binär-Bit-Eingabe **
;** Bit -> C **
BinBitIn:
PUSH ACC
BinBitIn1:
CALL CharInHide
CJNE A, #30h, BinBitIn2
CLR C
POP ACC
RET
BinBitIn2:
CJNE A, #31h, BinBitIn1
SETB C
POP ACC
RET
;** Binär-Bit-Eingabe **
;** Bit -> ACCU **
BinBitInACCU:
PUSH ACC
BinBitInACCU1:
CALL CharInHide
CJNE A, #1Bh, BinBitInACCU2
SETB C
POP ACC
RET
BinBitInACCU2:
CJNE A, #30h, BinBitInACCU3
CALL CharOut
CLR C
POP ACC
CLR ACC.0
RET
BinBitInACCU3:
CJNE A, #31h, BinBitInACCU1
CALL CharOut
CLR C
POP ACC
SETB ACC.0
RET
;** Binär-Byte-Eingabe **
BinByteIn:
PUSH B
MOV B, #08h
BinByteIn1:
CALL BinBitInACCU
JC BinByteInE
RL A
DJNZ B, BinByteIn1
POP B
RET
BinByteInE:
CLR A
POP B
RET
;** Binär-Word-Eingabe **
BinWordIn:
PUSH ACC
CALL BinByteIn
JC BinWordInE
MOV DPH, A
CALL BinByteIn
JC BinWordInE
MOV DPL, A
POP ACC
RET
BinWordInE:
MOV DPTR, #0000h
POP ACC
RET
;** Dezimalziffern-Eingabe **
NumIn:
CALL CharInHide
CJNE A, #1Bh, NumIn1
SETB C
CLR A
RET
NumIn1:
CJNE A, #30h, NumIn2
NumIn2:
JC NumIn
CJNE A, #3Ah, NumIn3
NumIn3:
JC NumInN
JMP NumIn
NumInN:
CLR C
SUBB A, #30h
RET
;** Break **
ORG BreakProg
Break:
PUSH IE
MOV IE, #00h
PUSH ACC
PUSH DPL
PUSH DPH
MOV DPTR, #DPTRSafe ;DPTR sichern
POP ACC
MOVX @DPTR, A
INC DPTR
POP ACC
MOVX @DPTR, A
MOV DPTR, #ACCUSafe ;ACCU sichern
POP ACC
MOVX @DPTR, A
MOV DPTR, #IESafe ;IE sichern
POP ACC
MOVX @DPTR, A
MOV DPTR, #PSWSafe ;PSW sichern
MOV A, PSW
MOVX @DPTR, A
MOV DPTR, #SPSafe ;SP sichern
MOV A, SP
CLR C
SUBB A, #02h ;vom SP 2 abziehen, weil darin auch Rücksprungadresse
;des CALL-Befehls des Abbruchs enthalten ist
MOVX @DPTR, A
POP DPH ;Break-Adresse, die von LCALL-Befehl in den Stack
POP DPL ;geschrieben wurde -> DPTR
CLR C ;vom DPTR 03h abziehen, da die Adresse am Stack
MOV A, DPL ;die Adresse nach dem LCALL-Befehl ist.
SUBB A, #03h
MOV DPL, A
MOV A, DPH
SUBB A, #00h
MOV DPH, A
PUSH DPL ;Break-Adresse wieder zurück auf den Stack
PUSH DPH
CALL StoreBreak ;DPTR -> Break-Adresse
CALL ClrBreak ;Break-Befehle im Programm löschen
CALL ShowReg ;Registerinhalte bei Abbruch anzeigen
CALL RestoreBreak ;Break-Adresse -> DPTR
CALL DisASM ;Befehl an Break-Adresse anzeigen
MOV DPTR, #BreakStr ;Abbruch anzeigen
CALL StrOut
JMP Beginn
;** T a b e l l e n **
ORG Tabellen
;** Stringtabellen **
ResetStr:
DB 0Dh, 0Ah
DB 0Dh, 0Ah
DB ' ----- ----- ------', 0Dh, 0Ah
DB ' | uP-OS 8052 |', 0Dh, 0Ah
DB ' | V 2.1 |', 0Dh, 0Ah
DB ' ----- ----- ------', 0Dh, 0Ah
DB 0Dh, 0Ah
DB ' Copyright 1996', 0Dh, 0Ah
DB 0Dh, 0Ah
DB 'Monitorprogramm fuer uP-8051 Entwicklungs-Kit', 0Dh, 0Ah
DB 0Dh, 0Ah
DB 'Monitorprogramm von:', 0Dh, 0Ah
DB ' Roland HEINRICH', 0Dh, 0Ah
DB 'Entwicklungs-Kit von:', 0Dh, 0Ah
DB ' Thomas CLAUSEN & Roland HEINRICH', 0Dh, 0Ah
DB 'Projektidee von:', 0Dh, 0Ah
DB ' Dipl.Ing. Wilhelm GUGGENBERG', 0Dh, 0Ah
DB 'Entwickelt an der:', 0Dh, 0Ah
DB ' HTBLA Wien 10, Ettenreichgasse 54', 0Dh, 0Ah
DB 00h
EingabeStr:
DB 'Monitor -> '
DB 00h
HelpStr:
DB 0Dh, 0Ah
DB 0Dh, 0Ah
DB 'Befehlserklaerung:', 0Dh, 0Ah
DB 0Dh, 0Ah
DB ' g xxxx Programm an der 16-Bit-Adresse xxxx starten', 0Dh, 0Ah
DB ' l xxxx 10 Befehle ab der 16-Bit-Adresse xxxx anzeigen', 0Dh, 0Ah
DB ' bs xxxx Breakpoint auf 16-Bit-Adresse xxxx setzen', 0Dh, 0Ah
DB ' bl Breakpoint anzeigen', 0Dh, 0Ah
DB ' bd Breakpoint loeschen', 0Dh, 0Ah
DB ' dc xxxx Byte im Programm-Speicher anzeigen', 0Dh, 0Ah
DB ' di xx Byte im internen Daten-Speicher anzeigen', 0Dh, 0Ah
DB ' dx xxxx Byte im externen Daten-Speicher anzeigen', 0Dh, 0Ah
DB ' ec xxxx Byte im Programm-Speicher editieren', 0Dh, 0Ah
DB ' ei xx Byte im internen Daten-Speicher editieren', 0Dh, 0Ah
DB ' ex xxxx Byte im externen Daten-Speicher editieren', 0Dh, 0Ah
DB ' c Programm nach Abbruch fortsetzen', 0Dh, 0Ah
DB ' i Programm in IntelHex-Format eingeben', 0Dh, 0Ah
DB ' o Optionen fuer Monitor setzen', 0Dh, 0Ah
DB ' r Software-Reset', 0Dh, 0Ah
DB 0Dh, 0Ah
DB 'Alle Adressen muessen in HEX eingegeben werden.', 0Dh, 0Ah
DB 'Um die Eingabe von Adressen abzubrechen, ESC-Taste druecken.', 0Dh, 0Ah
DB 00h
DAktuellStr:
DB 0Dh, 0Ah
DB 0Dh, 0Ah
DB 'Aktueller Inhalt: '
DB 00h
ENeuStr:
DB 0Dh, 0Ah
DB 'Neuer Inhalt : '
DB 00h
BSetStr:
DB 0Dh, 0Ah
DB 0Dh, 0Ah
DB 'Breakpoint gesetzt.', 0Dh, 0Ah
DB 00h
BSFehlerStr:
DB 0Dh, 0Ah, 0Dh, 0Ah
DB '!! Breakpoint-Adresse ungueltig. !!', 0Dh, 0Ah
DB ' Bereich: 8000-86FF / 9000-9FFF', 0Dh, 0Ah
DB 00h
BListStr:
DB 0Dh, 0Ah, 0Dh, 0Ah
DB 'Breakpoint-Adresse: '
DB 00h
BLKeinStr:
DB 'keine', 0Dh, 0Ah
DB 00h
BDelStr:
DB 0Dh, 0Ah, 0Dh, 0Ah
DB 'Breakpoint-Adresse geloescht.', 0Dh, 0Ah
DB 00h
BAktStr:
DB 0Dh, 0Ah
DB '!! Breakpoint-Adresse gesetzt. !!', 0Dh, 0Ah
DB 0Dh, 0Ah
DB 'Return -> aktivieren', 0Dh, 0Ah
DB 'ESC -> nicht aktivieren', 0Dh, 0Ah
DB 0Dh, 0Ah
DB 00h
BreakStr:
DB 0Dh, 0Ah
DB '!! Programm abgebrochen. !!', 0Dh, 0Ah
DB 0Dh, 0Ah
DB 'c -> Programm fortsetzen', 0Dh, 0Ah
DB 00h
SRegStr:
DB 0Dh, 0Ah
DB 0Dh, 0Ah
DB ' A B R0 R1 R2 R3 R4 R5 R6 R7 PSW DPTR SP', 0Dh, 0Ah
DB '-------- ----- ------ ----- ----- -----------', 0Dh, 0Ah
DB ' '
DB 00h
ContStr:
DB 0Dh, 0Ah
DB '!! Programm kann nicht fortgesetzt werden. !!', 0Dh, 0Ah
DB 00h
IAchtungStr:
DB 0Dh, 0Ah, 0Dh, 0Ah
DB '!! Altes Programm wird moeglicherweise geloescht. !!', 0Dh, 0Ah
DB 0Dh, 0Ah
DB 'Return -> Weiter', 0Dh, 0Ah
DB 'ESC -> Abbruch', 0Dh, 0Ah
DB 00h
IFehlerStr:
DB 0Dh, 0Ah, 0Dh, 0Ah
DB '!! Programm-Adresse ungueltig. !!', 0Dh, 0Ah
DB ' Bereich: 8000-86FF / 9000-9FFF', 0Dh, 0Ah
DB 00h
SResetStr:
DB 0Dh, 0Ah, 0Dh, 0Ah
DB '!! Gesamter Programmspeicher, Optionen und der !!', 0Dh, 0Ah
DB '!! Breakpoint werden geloescht. !!', 0Dh, 0Ah
DB 0Dh, 0Ah
DB 'Return -> Weiter', 0Dh, 0Ah
DB 'ESC -> Abbruch', 0Dh, 0Ah
DB 00h
SRFertigStr:
DB 0Dh, 0Ah
DB 'Software-Reset beendet.', 0Dh, 0Ah
DB 00h
OptionStr:
DB 0Dh, 0Ah, 0Dh, 0Ah
DB 'Optionen:', 0Dh, 0Ah
DB 0Dh, 0Ah
DB 'ESC Zurueck', 0Dh, 0Ah
DB 'l xx Befehlsanzahl bei List aendern', 0Dh, 0Ah
DB ' 00 = Default (10h Befehle)', 0Dh, 0Ah
DB 's xx Serielle Schnittstelle aender', 0Dh, 0Ah
DB ' 00 = simuliert auf Port P1', 0Dh, 0Ah
DB ' 01 = simuliert auf Port PA', 0Dh, 0Ah
DB ' 02 = nicht simulierte', 0Dh, 0Ah
DB 0Dh, 0Ah
DB 'Werte sind immer im Hex-Format einzugeben.', 0Dh, 0Ah
DB 0Dh, 0Ah
DB 'List-Befehlsanzahl: '
DB 00h
Option1Str:
DB 0Dh, 0Ah
DB 'Serielle Schnittstelle: '
DB 00h
OEingabeStr:
DB 0Dh, 0Ah, 0Dh, 0Ah
DB 'Optionen -> '
DB 00h
OResetStr:
DB 0Dh, 0Ah, 0Dh, 0Ah
DB 'Jumperstellung aendern und Hardware-Reset durchfuehren.', 0Dh, 0Ah
DB 00h
;** Nummertabellen **
CurNum:
DB 41h, 42h, 43h, 44h, 48h, 59h
BefehlNum:
DW Ins00, Ins01, Ins02, Ins03, Ins04, Ins05, Ins06, Ins07, Ins08, Ins09, Ins0A, Ins0B, Ins0C, Ins0D, Ins0E, Ins0F
DW Ins10, Ins11, Ins12, Ins13, Ins14, Ins15, Ins16, Ins17, Ins18, Ins19, Ins1A, Ins1B, Ins1C, Ins1D, Ins1E, Ins1F
DW Ins20, Ins01, Ins22, Ins23, Ins24, Ins25, Ins26, Ins27, Ins28, Ins29, Ins2A, Ins2B, Ins2C, Ins2D, Ins2E, Ins2F
DW Ins30, Ins11, Ins32, Ins33, Ins34, Ins35, Ins36, Ins37, Ins38, Ins39, Ins3A, Ins3B, Ins3C, Ins3D, Ins3E, Ins3F
DW Ins40, Ins01, Ins42, Ins43, Ins44, Ins45, Ins46, Ins47, Ins48, Ins49, Ins4A, Ins4B, Ins4C, Ins4D, Ins4E, Ins4F
DW Ins50, Ins11, Ins52, Ins53, Ins54, Ins55, Ins56, Ins57, Ins58, Ins59, Ins5A, Ins5B, Ins5C, Ins5D, Ins5E, Ins5F
DW Ins60, Ins01, Ins62, Ins63, Ins64, Ins65, Ins66, Ins67, Ins68, Ins69, Ins6A, Ins6B, Ins6C, Ins6D, Ins6E, Ins6F
DW Ins70, Ins11, Ins72, Ins73, Ins74, Ins75, Ins76, Ins77, Ins78, Ins79, Ins7A, Ins7B, Ins7C, Ins7D, Ins7E, Ins7F
DW Ins80, Ins01, Ins82, Ins83, Ins84, Ins85, Ins86, Ins87, Ins88, Ins89, Ins8A, Ins8B, Ins8C, Ins8D, Ins8E, Ins8F
DW Ins90, Ins11, Ins92, Ins93, Ins94, Ins95, Ins96, Ins97, Ins98, Ins99, Ins9A, Ins9B, Ins9C, Ins9D, Ins9E, Ins9F
DW InsA0, Ins01, InsA2, InsA3, InsA4, InsA5, InsA6, InsA7, InsA8, InsA9, InsAA, InsAB, InsAC, InsAD, InsAE, InsAF
DW InsB0, Ins11, InsB2, InsB3, InsB4, InsB5, InsB6, InsB7, InsB8, InsB9, InsBA, InsBB, InsBC, InsBD, InsBE, InsBF
DW InsC0, Ins01, InsC2, InsC3, InsC4, InsC5, InsC6, InsC7, InsC8, InsC9, InsCA, InsCB, InsCC, InsCD, InsCE, InsCF
DW InsD0, Ins11, InsD2, InsD3, InsD4, InsD5, InsD6, InsD7, InsD8, InsD9, InsDA, InsDB, InsDC, InsDD, InsDE, InsDF
DW InsE0, Ins01, InsE2, InsE3, InsE4, InsE5, InsE6, InsE7, InsE8, InsE9, InsEA, InsEB, InsEC, InsED, InsEE, InsEF
DW InsF0, Ins11, InsF2, InsF3, InsF4, InsF5, InsF6, InsF7, InsF8, InsF9, InsFA, InsFB, InsFC, InsFD, InsFE, InsFF
;** Befehlstabelle **
Ins00: DB 'NOP', 00h
Ins01: DB 'AJMP ', 04h, 00h
Ins02: DB 'LJMP ', 02h, 00h
Ins03: DB 'RR A', 00h
Ins04: DB 'INC A', 00h
Ins05: DB 'INC ', 01h, 00h
Ins06: DB 'INC @R0', 00h
Ins07: DB 'INC @R1', 00h
Ins08: DB 'INC R0', 00h
Ins09: DB 'INC R1', 00h
Ins0A: DB 'INC R2', 00h
Ins0B: DB 'INC R3', 00h
Ins0C: DB 'INC R4', 00h
Ins0D: DB 'INC R5', 00h
Ins0E: DB 'INC R6', 00h
Ins0F: DB 'INC R7', 00h
Ins10: DB 'JBC ', 01h, ', ', 03h, 00h
Ins11: DB 'ACALL ', 04h, 00h
Ins12: DB 'LCALL ', 02h, 00h
Ins13: DB 'RRC A', 00h
Ins14: DB 'DEC A', 00h
Ins15: DB 'DEC ', 01h, 00h
Ins16: DB 'DEC @R0', 00h
Ins17: DB 'DEC @R1', 00h
Ins18: DB 'DEC R0, ', 00h
Ins19: DB 'DEC R1, ', 00h
Ins1A: DB 'DEC R2, ', 00h
Ins1B: DB 'DEC R3, ', 00h
Ins1C: DB 'DEC R4, ', 00h
Ins1D: DB 'DEC R5, ', 00h
Ins1E: DB 'DEC R6, ', 00h
Ins1F: DB 'DEC R7, ', 00h
Ins20: DB 'JB ', 01h, ', ', 03h, 00h
Ins22: DB 'RET', 00h
Ins23: DB 'RL A', 00h
Ins24: DB 'ADD A, #', 01h, 00h
Ins25: DB 'ADD A, ', 01h, 00h
Ins26: DB 'ADD A, @R0', 00h
Ins27: DB 'ADD A, @R1', 00h
Ins28: DB 'ADD A, R0', 00h
Ins29: DB 'ADD A, R1', 00h
Ins2A: DB 'ADD A, R2', 00h
Ins2B: DB 'ADD A, R3', 00h
Ins2C: DB 'ADD A, R4', 00h
Ins2D: DB 'ADD A, R5', 00h
Ins2E: DB 'ADD A, R6', 00h
Ins2F: DB 'ADD A, R7', 00h
Ins30: DB 'JNB ', 01h, ', ', 03h, 00h
Ins32: DB 'RETI', 00h
Ins33: DB 'RLC A', 00h
Ins34: DB 'ADDC A, #', 01h, 00h
Ins35: DB 'ADDC A, ', 01h, 00h
Ins36: DB 'ADDC A, @R0', 00h
Ins37: DB 'ADDC A, @R1', 00h
Ins38: DB 'ADDC A, R0', 00h
Ins39: DB 'ADDC A, R1', 00h
Ins3A: DB 'ADDC A, R2', 00h
Ins3B: DB 'ADDC A, R3', 00h
Ins3C: DB 'ADDC A, R4', 00h
Ins3D: DB 'ADDC A, R5', 00h
Ins3E: DB 'ADDC A, R6', 00h
Ins3F: DB 'ADDC A, R7', 00h
Ins40: DB 'JC ', 03h, 00h
Ins42: DB 'ORL ', 01h, ', A', 00h
Ins43: DB 'ORL ', 01h, ', #', 01h, 00h
Ins44: DB 'ORL A, #', 01h, 00h
Ins45: DB 'ORL A, ', 01h, 00h
Ins46: DB 'ORL A, @R0', 00h
Ins47: DB 'ORL A, @R1', 00h
Ins48: DB 'ORL A, R0', 00h
Ins49: DB 'ORL A, R1', 00h
Ins4A: DB 'ORL A, R2', 00h
Ins4B: DB 'ORL A, R3', 00h
Ins4C: DB 'ORL A, R4', 00h
Ins4D: DB 'ORL A, R5', 00h
Ins4E: DB 'ORL A, R6', 00h
Ins4F: DB 'ORL A, R7', 00h
Ins50: DB 'JNC ', 03h, 00h
Ins52: DB 'ANL ', 01h, ', A', 00h
Ins53: DB 'ANL ', 01h, ', #', 01h, 00h
Ins54: DB 'ANL A, #', 01h, 00h
Ins55: DB 'ANL A, ', 01h, 00h
Ins56: DB 'ANL A, @R0', 00h
Ins57: DB 'ANL A, @R1', 00h
Ins58: DB 'ANL A, R0', 00h
Ins59: DB 'ANL A, R1', 00h
Ins5A: DB 'ANL A, R2', 00h
Ins5B: DB 'ANL A, R3', 00h
Ins5C: DB 'ANL A, R4', 00h
Ins5D: DB 'ANL A, R5', 00h
Ins5E: DB 'ANL A, R6', 00h
Ins5F: DB 'ANL A, R7', 00h
Ins60: DB 'JZ ', 03h, 00h
Ins62: DB 'XRL ', 01h, ', A', 00h
Ins63: DB 'XRL ', 01h, ', #', 01h, 00h
Ins64: DB 'XRL A, #', 01h, 00h
Ins65: DB 'XRL A, ', 01h, 00h
Ins66: DB 'XRL A, @R0', 00h
Ins67: DB 'XRL A, @R1', 00h
Ins68: DB 'XRL A, R0', 00h
Ins69: DB 'XRL A, R1', 00h
Ins6A: DB 'XRL A, R2', 00h
Ins6B: DB 'XRL A, R3', 00h
Ins6C: DB 'XRL A, R4', 00h
Ins6D: DB 'XRL A, R5', 00h
Ins6E: DB 'XRL A, R6', 00h
Ins6F: DB 'XRL A, R7', 00h
Ins70: DB 'JNZ ', 03h, 00h
Ins72: DB 'ORL C, ', 01h, 00h
Ins73: DB 'JMP @A+DPTR', 00h
Ins74: DB 'MOV A, #', 01h, 00h
Ins75: DB 'MOV ', 01h, ', #', 01h, 00h
Ins76: DB 'MOV @R0, #', 01h, 00h
Ins77: DB 'MOV @R1, #', 01h, 00h
Ins78: DB 'MOV R0, #', 01h, 00h
Ins79: DB 'MOV R1, #', 01h, 00h
Ins7A: DB 'MOV R2, #', 01h, 00h
Ins7B: DB 'MOV R3, #', 01h, 00h
Ins7C: DB 'MOV R4, #', 01h, 00h
Ins7D: DB 'MOV R5, #', 01h, 00h
Ins7E: DB 'MOV R6, #', 01h, 00h
Ins7F: DB 'MOV R7, #', 01h, 00h
Ins80: DB 'SJMP ', 03h, 00h
Ins82: DB 'ANL C, ', 01h, 00h
Ins83: DB 'MOVC A, @A+PC', 00h
Ins84: DB 'DIV AB', 00h
Ins85: DB 'MOV ', 01h, ', ', 01h, 00h
Ins86: DB 'MOV ', 01h, ', @R0', 00h
Ins87: DB 'MOV ', 01h, ', @R1', 00h
Ins88: DB 'MOV ', 01h, ', R0', 00h
Ins89: DB 'MOV ', 01h, ', R1', 00h
Ins8A: DB 'MOV ', 01h, ', R2', 00h
Ins8B: DB 'MOV ', 01h, ', R3', 00h
Ins8C: DB 'MOV ', 01h, ', R4', 00h
Ins8D: DB 'MOV ', 01h, ', R5', 00h
Ins8E: DB 'MOV ', 01h, ', R6', 00h
Ins8F: DB 'MOV ', 01h, ', R7', 00h
Ins90: DB 'MOV DPTR, #', 02h, 00h
Ins92: DB 'MOV ', 01h, ', C', 00h
Ins93: DB 'MOVC A, @A+DPTR', 00h
Ins94: DB 'SUBB A, #', 01h, 00h
Ins95: DB 'SUBB A, ', 01h, 00h
Ins96: DB 'SUBB A, @R0', 00h
Ins97: DB 'SUBB A, @R1', 00h
Ins98: DB 'SUBB A, R0', 00h
Ins99: DB 'SUBB A, R1', 00h
Ins9A: DB 'SUBB A, R2', 00h
Ins9B: DB 'SUBB A, R3', 00h
Ins9C: DB 'SUBB A, R4', 00h
Ins9D: DB 'SUBB A, R5', 00h
Ins9E: DB 'SUBB A, R6', 00h
Ins9F: DB 'SUBB A, R7', 00h
InsA0: DB 'ORL C, /', 01h, 00h
InsA2: DB 'MOV C, ', 01h, 00h
InsA3: DB 'INC DPTR', 00h
InsA4: DB 'MUL AB', 00h
InsA5: DB 'No Instr', 00h
InsA6: DB 'MOV @R0, ', 01h, 00h
InsA7: DB 'MOV @R1, ', 01h, 00h
InsA8: DB 'MOV R0, ', 01h, 00h
InsA9: DB 'MOV R1, ', 01h, 00h
InsAA: DB 'MOV R2, ', 01h, 00h
InsAB: DB 'MOV R3, ', 01h, 00h
InsAC: DB 'MOV R4, ', 01h, 00h
InsAD: DB 'MOV R5, ', 01h, 00h
InsAE: DB 'MOV R6, ', 01h, 00h
InsAF: DB 'MOV R7, ', 01h, 00h
InsB0: DB 'ANL C, /', 01h, 00h
InsB2: DB 'CPL ', 01h, 00h
InsB3: DB 'CPL C', 00h
InsB4: DB 'CJNE A, #', 01h, ', ', 03h, 00h
InsB5: DB 'CJNE A, ', 01h, ', ', 03h, 00h
InsB6: DB 'CJNE @R0, #', 01h, ', ', 03h, 00h
InsB7: DB 'CJNE @R1, #', 01h, ', ', 03h, 00h
InsB8: DB 'CJNE R0, #', 01h, ', ', 03h, 00h
InsB9: DB 'CJNE R1, #', 01h, ', ', 03h, 00h
InsBA: DB 'CJNE R2, #', 01h, ', ', 03h, 00h
InsBB: DB 'CJNE R3, #', 01h, ', ', 03h, 00h
InsBC: DB 'CJNE R4, #', 01h, ', ', 03h, 00h
InsBD: DB 'CJNE R5, #', 01h, ', ', 03h, 00h
InsBE: DB 'CJNE R6, #', 01h, ', ', 03h, 00h
InsBF: DB 'CJNE R7, #', 01h, ', ', 03h, 00h
InsC0: DB 'PUSH ', 01h, 00h
InsC2: DB 'CLR ', 01h, 00h
InsC3: DB 'CLR C', 00h
InsC4: DB 'SWAP A', 00h
InsC5: DB 'XCH A, ', 01h, 00h
InsC6: DB 'XCH A, @R0', 00h
InsC7: DB 'XCH A, @R1', 00h
InsC8: DB 'XCH A, R0', 00h
InsC9: DB 'XCH A, R1', 00h
InsCA: DB 'XCH A, R2', 00h
InsCB: DB 'XCH A, R3', 00h
InsCC: DB 'XCH A, R4', 00h
InsCD: DB 'XCH A, R5', 00h
InsCE: DB 'XCH A, R6', 00h
InsCF: DB 'XCH A, R7', 00h
InsD0: DB 'POP ', 01h, 00h
InsD2: DB 'SETB ', 01h, 00h
InsD3: DB 'SETB C', 00h
InsD4: DB 'DA A', 00h
InsD5: DB 'DJNZ ', 01h, ', ', 03h, 00h
InsD6: DB 'XCHD A, @R0', 00h
InsD7: DB 'XCHD A, @R1', 00h
InsD8: DB 'DJNZ R0, ', 03h, 00h
InsD9: DB 'DJNZ R1, ', 03h, 00h
InsDA: DB 'DJNZ R2, ', 03h, 00h
InsDB: DB 'DJNZ R3, ', 03h, 00h
InsDC: DB 'DJNZ R4, ', 03h, 00h
InsDD: DB 'DJNZ R5, ', 03h, 00h
InsDE: DB 'DJNZ R6, ', 03h, 00h
InsDF: DB 'DJNZ R7, ', 03h, 00h
InsE0: DB 'MOVX A, @DPTR', 00h
InsE2: DB 'MOVX A, @R0', 00h
InsE3: DB 'MOVX A, @R1', 00h
InsE4: DB 'CLR A', 00h
InsE5: DB 'MOV A, ', 01h, 00h
InsE6: DB 'MOV A, @R0', 00h
InsE7: DB 'MOV A, @R1', 00h
InsE8: DB 'MOV A, R0', 00h
InsE9: DB 'MOV A, R1', 00h
InsEA: DB 'MOV A, R2', 00h
InsEB: DB 'MOV A, R3', 00h
InsEC: DB 'MOV A, R4', 00h
InsED: DB 'MOV A, R5', 00h
InsEE: DB 'MOV A, R6', 00h
InsEF: DB 'MOV A, R7', 00h
InsF0: DB 'MOVX @DPTR, A', 00h
InsF2: DB 'MOVX @R0, A', 00h
InsF3: DB 'MOVX @R1, A', 00h
InsF4: DB 'CPL A', 00h
InsF5: DB 'MOV ', 01h, ', A', 00h
InsF6: DB 'MOV @R0, A', 00h
InsF7: DB 'MOV @R1, A', 00h
InsF8: DB 'MOV R0, A', 00h
InsF9: DB 'MOV R1, A', 00h
InsFA: DB 'MOV R2, A', 00h
InsFB: DB 'MOV R3, A', 00h
InsFC: DB 'MOV R4, A', 00h
InsFD: DB 'MOV R5, A', 00h
InsFE: DB 'MOV R6, A', 00h
InsFF: DB 'MOV R7, A', 00h
;** Globale Unterprogramme **
ORG GlobSUB
JMP CharOut
JMP ReturnOut
JMP SpaceOut
JMP CursorOut
JMP StrOut
JMP HexNibOut
JMP HexByteOut
JMP HexWordOut
JMP BinBitOut
JMP BinBitOutACCU
JMP BinByteOut
JMP BinWordOut
JMP NumOut
JMP CharInHide
JMP CharIn
JMP HexNibIn
JMP HexByteIn
JMP HexWordIn
JMP BinBitIn
JMP BinBitInACCU
JMP BinByteIn
JMP BinWordIn
JMP NumIn
END
Umrechnung der Taktperiode für 9600bps in Maschinenzyklen des µP:
fÜ Übertragungstaktfrequenz [Hz] = Übertragungsrate [bps]
TÜ Übertragungstaktperiode = Zeitdauer zur Übertragung eines Bits
fOSZ Oszillatorfrequenz des µPs
TOSZ Periodendauer des Oszillatortaktes
TMZ Maschinenzyklusdauer
SA Startbit
SP Stoppbit
D0-D7 Datenbits 0-7
T Takt des Übertragungstaktes = 96 MZ
TDat Transmit-Data-Leitung = Portpin P1.3
PUSH B |
2 |
|
|
|
CLR TDat |
1 |
|
|
|
MOV B, #08h |
2 |
Startbit senden |
|
|
Label1: |
|
|
|
Datenbits D0-D6 senden |
PUSH ACC |
2 |
12+(2*ACC+2) = 96 |
|
|
MOV A, #41 |
1 |
|
|
pro Datenbit: |
CALL Warten |
2+(2*ACC+2) = 86 |
|
|
12+(2*ACC+2) = 96 |
POP ACC |
2 |
|
|
|
RRC A |
1 |
|
|
Gesamt: 7*96 = 672 |
MOV TDat, C |
2 |
|
|
|
DJNZ B, Label1 |
2 |
Datenbit D7 senden |
|
|
POP B |
2 |
|
|
|
PUSH ACC |
2 |
12+(2*ACC+2) = 96 |
|
|
MOV A, #41 |
1 |
|
|
|
CALL Warten |
2+(2*ACC+2) = 86 |
|
|
|
NOP |
1 |
|
|
|
NOP |
1 |
|
|
|
SETB TDat |
1 |
|
|
|
MOV A, #92 |
1 |
Stoppbit senden; |
|
|
CALL Warten |
2+(2*ACC+2) = 188 |
einen Takt warten |
|
|
POP ACC |
2 |
|
|
|
RRC A |
1 |
6+(2*ACC+2) = 192 |
|
|
RET |
2 |
|
|
|
Transmit-Data-Leitung = Portpin PA1
DataRegA Daten-Registeradresse für PA DPTR
ACC.1 Portpin 1, wenn ACCU in DataRegA geschrieben wird.
PUSH DPH |
2 |
|
|
|
PUSH DPL |
2 |
|
|
|
PUSH B |
2 |
|
|
|
MOV DPTR, #DataRegA |
2 |
|
|
|
PUSH ACC |
2 |
|
|
|
MOVX A, @DPTR |
2 |
|
|
|
CLR ACC.1 |
1 |
|
|
|
MOVX @DPTR, A |
2 |
|
|
|
POP ACC |
2 |
Startbit senden |
|
|
MOV B, #08h |
2 |
|
|
|
Label1: |
|
16+(2*ACC+2) = 96 |
|
Datenbits D0-D6 senden |
RRC A |
1 |
|
|
|
PUSH ACC |
2 |
|
|
pro Datenbit: |
MOV A, #39 |
1 |
|
|
16+(2*ACC+2) = 96 |
CALL Warten |
2+(2*ACC+2) = 82 |
|
|
|
MOVX A, @DPTR |
2 |
|
|
Gesamt: |
MOV ACC.1, C |
2 |
|
|
7*96 = 672 |
MOVX @DPTR, A |
2 |
|
|
|
POP ACC |
2 |
Datenbit D7 senden |
|
|
DJNZ B, Label1 |
2 |
|
|
|
POP B |
2 |
16+(2*ACC+2) = 96 |
|
|
PUSH ACC |
2 |
|
|
|
MOV A, #39 |
1 |
|
|
|
CALL Warten |
2+(2*ACC+2) = 82 |
|
|
|
MOVX A, @DPTR |
2 |
|
|
|
SETB ACC.1 |
1 |
|
|
|
MOVX @DPTR, A |
2 |
|
|
|
MOV A, #90 |
1 |
Stoppbit senden; |
|
|
CALL Warten |
2+(2*ACC+2) = 184 |
einen Takt warten |
|
|
POP ACC |
2 |
|
|
|
RRC A |
1 |
10+(2*ACC+2) = 192 |
|
|
POP DPL |
2 |
|
|
|
POP DPH |
2 |
|
|
|
RET |
2 |
|
|
|
RDat Receive-Data-Leitung = Portpin P1.2
Label1: |
|
|
|
|
JB RDat, CharIn |
2 |
Auf Startbit warten |
|
|
MOV A, #20 |
1 |
½ Takt warten; |
|
|
CALL Warten |
2+(2*ACC+2) = 44 |
Startbit prüfen |
|
|
NOP |
1 |
|
|
|
JB RDat, CharIn |
2 |
6+(2*ACC+2) = 48 |
|
|
PUSH B |
2 |
einen Takt warten; |
|
|
MOV B, #08h |
2 |
Datenbit D0 empfangen |
|
|
Label2: |
|
|
|
Datenbits D1-D7 |
PUSH ACC |
2 |
12+(2*ACC+2) = 96 |
|
empfangen; davor immer |
MOV A, #41 |
1 |
|
|
einen Takt warten |
CALL Warten |
2+(2*ACC+2) = 86 |
|
|
|
POP ACC |
2 |
|
|
pro Datenbit: |
MOV C, RDat |
1 |
|
|
12+(2*ACC+2) = 96 |
RRC A |
1 |
einen Takt warten; |
|
|
NOP |
1 |
Stoppbit empfangen und |
|
Gesamt: |
DJNZ B, Label2 |
2 |
prüfen |
|
7*96 = 672 |
POP B |
2 |
|
|
|
PUSH ACC |
2 |
16+(2*ACC+2) = 96 |
|
|
MOV A, #39 |
1 |
|
|
|
CALL Warten |
2+(2*ACC+2) = 82 |
|
|
|
POP ACC |
2 |
|
|
|
NOP |
1 |
|
|
|
JNB RDat, Label3 |
2 |
kein Stoppbit Label2 |
|
|
RET |
2 |
|
|
|
Label3: |
|
|
|
|
JNB RDat, Label3 |
2 |
warten bis Leitung auf high |
|
|
JMP Label1 |
2 |
|
|
|
Receive-Data-Leitung = Portpin PA0
PinRegA Pin-Registeradresse für PA DPTR
ACC.0 Portpin 0, wenn ACCU in PinRegA geschrieben wird.
PUSH DPH |
2 |
|
|
|
PUSH DPL |
2 |
|
|
|
MOV DPTR, #PinRegA |
2 |
|
|
|
Label1: |
|
|
|
|
MOVX A, @DPTR |
2 |
Auf Startbit warten |
|
|
JB ACC.0, Label1 |
2 |
|
|
|
MOV A, #19 |
1 |
½ Takt warten; |
|
|
CALL Warten |
2+(2*ACC+2) = 42 |
Startbit prüfen |
|
|
NOP |
1 |
|
|
|
MOVX A, @DPTR |
2 |
6+(2*ACC+2) = 48 |
|
|
JB ACC.0, Label1 |
2 |
einen Takt warten; |
|
|
PUSH B |
2 |
Datenbit D0 empfangen |
|
|
MOV B, #08h |
2 |
|
|
|
Label2: |
|
12+(2*ACC+2) = 96 |
|
Datenbits D1-D7 |
PUSH ACC |
2 |
|
|
empfangen; davor immer |
MOV A, #40 |
1 |
|
|
einen Takt warten |
CALL Warten |
2+(2*ACC+2) = 84 |
|
|
|
NOP |
1 |
|
|
pro Datenbit: |
MOVX A, @DPTR |
2 |
|
|
12+(2*ACC+2) = 96 |
MOV C, ACC.0 |
1 |
einen Takt warten; |
|
|
POP ACC |
2 |
Stoppbit empfangen und |
|
Gesamt: |
RRC A |
1 |
prüfen |
|
7*96 = 672 |
DJNZ B, Label2 |
2 |
|
|
|
POP B |
2 |
16+(2*ACC+2) = 96 |
|
|
PUSH ACC |
2 |
|
|
|
MOV A, #39 |
1 |
|
|
|
CALL Warten |
2+(2*ACC+2) = 82 |
|
|
|
NOP |
1 |
|
|
|
MOVX A, @DPTR |
2 |
|
|
|
JNB ACC.0, Label3 |
2 |
kein Stoppbit Label2 |
|
|
POP ACC |
2 |
|
|
|
POP DPL |
2 |
|
|
|
POP DPH |
2 |
|
|
|
RET |
2 |
|
|
|
Label3: |
|
|
|
|
MOVX A, @DPTR |
2 |
warten bis Leitung auf high |
|
|
JNB ACC.0, Label3 |
2 |
|
|
|
POP ACC |
2 |
|
|
|
JMP Label1 |
2 |
|
|
|
Warteschleife
Wartezeit = 2*ACC+2 Maschinenzyklen
Warten: |
|
DJNZ ACC, Warten |
2*ACC |
RET |
2 |
DPTRSafe: 2 Bytes
Adresse an der der DPTR bei Programmabbruch gespeichert wird.
ACCUSafe: 1 Byte
Adresse an der der ACCU bei Programmabbruch gespeichert wird
PSWSafe: 1 Byte
Adresse an der das PSW bei Programmabbruch gespeichert wird.
SPSafe: 1 Byte
Adresse an der der SP bei Programmabbruch gespeichert wird.
IESafe: 1 Byte
Adresse an der das IE-Register bei Programmabbruch gespeichert wird.
DPTR1Mem, DPTR2Mem: jeweils 2 Byte
Adressen an denen der DPTR zwischengespeichert werden kann. Diese Adressen werden im Unterprogamm DisASM (Disassembler) verwendet.
BreakPoint: 2 Byte
Adresse an der die Breakpoint-Adresse gespeichert wird. Die Breakpoint-Adresse muß immer >7FFFh sein, da sie sonst nicht im verwendbaren Programmspeicher liegt. Ist die Breakpoint-Adresse 00xxh, so gilt sie als gelöscht.
BreakAdr: 2 Byte
Adresse an der die Programmadresse gespeichert wird, an der das Programm abgebrochen wird bzw. abgebrochen wurde.
BreakMem: 3 Byte
Adresse an der die Befehlsbytes, die durch die Break-Befehle (LJMP xxxx = 3 Byte) überschrieben werden, gesichert werden.
BreakDone: 1 Byte
Adresse an der 0000h abgelegt wird, wenn keine Break-Befehle ins Programm eingefügt sind, sonst befindet sich an dieser Adresse FFFFh.
Hauptprog:
Adresse, an der das Hauptprogramm des Monitors beginnt.
BreakProg:
Adresse, an der das Break-Programm, das durch die Break-Befehle aufgerufen wird, beginnt.
Tabellen:
Adresse, an der die String- und Zahlentabellen beginnen.
GlobSUB:
Adresse, an der die Umleitungen zu den globalen Unterprogrammen, Zeichenein- und ausgabe, beginnen.
BreakProgH, BreakProgL:
Hohes und niedriges Byte der BreakProg-Adresse. BreakProgH und BreakProgL zusammen müssen immer mit der Adresse BreakProg übereinstimmen. Diese beiden Konstanten werden zum Schreiben der Break-Befehle benötigt.
Die Zahl (ASCII-Code eines Zeichens), die sich im ACCU befindet wird über die serielle Schnittstelle ausgegeben. Je nach Konfiguration wird dabei die Hardware-Schnittstelle oder eine der beiden Software-Schnittstellen verwendet. Die Konfiguration befindet sich im externen Programm/Datenspeicher an der Adresse, die durch die Konstante 'Serielle' angegeben wird.
Konfigurationsmöglichkeiten:
00h und >02h softwaremäßige serielle Schnittstelle auf Port 1 (RxD = P1.2, TxD = P1.3)
01h softwaremäßige serielle Schnittstelle auf Port A (RxD = PA0, TxD = PA1)
02h hardwaremäßige serielle Schnittstelle (RxD = P3.0, TxD = P3.1)
Flußdiagramm:
Gibt ein Return, bestehend aus einem Wagenrücklauf (CR) und einem Zeilenvorschub (LF) über die serielle Schnittstelle aus. Der Inhalt des ACCUs wird dabei nicht verändert.
Flußdiagramm:
Gibt eine mit dem ACCU-Inhalt bestimmte Anzahl von Leerzeichen über die serielle Schnittstelle aus.
Flußdiagramm:
Gibt ein durch den ACCU-Inhalt bestimmtes Cursorsteuerungszeichen über die serielle Schnittstelle aus.
Cursorsteuerung allgemein:
Zur Steuerung des Cursors im Terminalprogramm des angeschlossenen Computers müssen zwei Zeichen ausgegeben werden.
Ein ESC-Zeichen (ASCII-Code: 1Bh)
und ein Steuerzeichen (siehe Tabelle)
Cursorsteuerung bei diesem Unterprogramm:
Bei diesem Unterprogramm werden automatisch beide Zeichen über die serielle Schnittstelle übermittelt. Welches Steuerzeichen gesendet wird, muß mittels des ACCUs definiert werden (siehe Tabelle). Die wirklichen Steuerzeichen werden im Unterprogramm aus einer Tabelle, mit der Startadresse 'CurNum' ausgelesen.
Steuerzeichen:
ACCU-Inhalt |
ASCII-Code |
Erklärung |
00h |
41h |
Cursor eine Zeile hinauf |
01h |
42h |
Cursor eine Zeile hinunter |
02h |
43h |
Cursor eine Spalte nach rechts |
03h |
44h |
Cursor eine Spalte nach links |
04h |
48h |
Cursor auf Position 1/1 = linkes oberes Eck |
05h |
59h |
Cursor auf Position x/y |
Der letzte Steuerungsbefehl hat eine Besonderheit: Mit ihm kann der Cursor auf eine beliebige Stelle am Bildschirm positioniert werden. Die Werte für x und y müssen dazu anschließend an den Steuerungsbefehl extra über die serielle Schnittstelle übertragen werden (z.B.: mittels CharOut).
Flußdiagramm:
Gibt eine Zeichenfolge, die im Programmspeicher steht über die serielle Schnittstelle aus. Der Anfangsadresse der Zeichenfolge wird im DPTR pbergeben, das Ende wird durch das Zeichen 00h angezeigt.
Flußdiagramm:
Gibt die Bits 0-3 im AKKU als hexadezimales Nibble über die serielle Schnittstelle aus.
Flußdiagramm:
Gibt den AKKU als zwei hexadezimale Nibbles über die serielle Schnittstelle aus.
Flußdiagramm:
Gibt den DPTR als vier hexadezimale Nibbles über die serielle Schnittstelle aus.
Flußdiagramm:
Gibt das C-Bit als binäre Ziffer über die serielle Schnittstelle aus.
Flußdiagramm:
Gibt das Bit 0 des AKKUs als binäre Ziffer über die serielle Schnittstelle aus.
Flußdiagramm:
Gibt den AKKU als binäre Ziffernfolge über die serielle Schnittstelle aus.
Flußdiagramm:
Gibt den DPTR als binäre Ziffernfolge über die serielle Schnittstelle aus.
Flußdiagramm:
Gibt den AKKU in dezimaler Form über die serielle Schnittstelle aus.
Flußdiagramm:
Liest ein Zeichen von der seriellen Schnittstelle in den AKKU.
Flußdiagramm:
Liest ein Zeichen von der serielle Schnittstelle in den ACCU und gibt dieses Zeichen wieder über die Schnittstelle aus. Ein Return (0Dh) wird als Wagenrücklauf (CR = 0Dh) und Zeilenvorschub (LF = 0Ah) ausgegeben.
Flußdiagramm:
Liest eine hexadezimale Ziffer von der seriellen Schnittstelle ein und schreibt sie als Zahl in den AKKU. Die Ziffer wird gleichzeitig wieder über die Schnittstelle ausgegeben.
Wird bei der Eingabe ESC gedrückt, so wird die Eingabe abgebrochen. => C=1 und AKKU=0
Bei normaler Eingabe ist C=0.
Flußdiagramm:
Liest zwei hexadezimale Ziffern von der seriellen Schnittstelle ein und schreibt sie als Zahl in den AKKU. Die Ziffern werden gleichzeitig wieder über die Schnittstelle ausgegeben.
Wird bei der Eingabe ESC gedrückt, so wird die Eingabe abgebrochen. => C=1 und AKKU=0
Nach normaler Eingabe ist C=0.
Flußdiagramm:
Liest vier hexadezimale Ziffern von der seriellen Schnittstelle ein und schreibt sie als Zahl in den DPTR. Die Ziffern werden gleichzeitig wieder über die Schnittstelle ausgegeben.
Wird bei der Eingabe ESC gedrückt, so wird die Eingabe abgebrochen. => C=1 und DPTR=0
Nach normaler Eingabe ist C=0.
Flußdiagramm:
Liest eine binäre Ziffer (0..1) von der seriellen Schnittstelle ein und schreibt sie in C-Bit. Die Ziffer wird gleichzeitig wieder über die Schnittstelle ausgegeben.
Flußdiagramm:
Liest eine binäre Ziffer von der seriellen Schnittstelle ein und schreibt sie ins Bit 0 des AKKUs. Die Ziffer wird gleichzeitig wieder über die Schnittstelle ausgegeben.
Wird während der Eingabe ESC gedrückt, so wird die Eingabe abgebrochen. => C=1 und AKKU=0
Bei normaler Eingabe ist C=0.
Flußdiagramm:
Liest ein Byte in binärer Form von der seriellen Schnittstelle ein und schreibt es als Zahl in den ACCU. Die einzelnen binären Ziffern werden gleichzeitig wieder über die Schnittstelle ausgegeben.
Wird während der Eingabe ESC gedrückt, so wird die Eingabe abgebrochen. => C=1 und AKKU=0
Bei normaler Eingabe ist C=0.
Flußdiagramm:
Liest ein Word in binärer Form von der seriellen Schnittstelle ein und schreibt es als Zahl in den DPTR. Die einzelnen binären Ziffern werden gleichzeitig wieder über die Schnittstelle ausgegeben.
Wird während der Eingabe ESC gedrückt, so wird die Eingabe abgebrochen. => C=1 und DPTR=0
Bei normaler Eingabe ist C=0.
Flußdiagramm:
Liest eine dezimale Ziffer von der seriellen Schnittstelle ein und schreibt sie als Zahl in den AKKU. Die Ziffer wird gleichzeitig wieder über die Schnittstelle ausgegeben.
Wird bei der Eingabe ESC gedrückt, so wird die Eingabe abgebrochen. => C=1 und AKKU=0
Bei normaler Eingabe ist C=0.
Flußdiagramm:
Haupt | Fügen Sie Referat | Kontakt | Impressum | Nutzungsbedingungen