Nutzung einiger TRAP Aufrufe des Monitors in C.

Diese Seiten wurden für den LCC erstellt und gelten nicht für den GCC!

Funktionen des Assembler Include -Wf-include-stdasm=monitor.inc mit dem C Aufruf #include <monitor.h>


1. monitor_print(Zeichenkette); // TRAP 1

Eine mit 0x00 abgesclossene Zeichenkette an die UART senden.
//
        monitor_print("\r\n\Zeichenkette anzeigen\r\n"); // Anzeige des Textes mit Steuerzeichen zwichen den Anführungszeichen.
//


//
        char    zeit[11]   = "00:00:00\r\0";
	monitor_print(zeit);         // Anzeige der in der Variablen zeit gespeicherten Zeichenkette
//


2. monitor_putchar(zeichen); // TRAP 2

Ein Zeichen an die UART senden.
//
        monitor_putchar('*');        // Anzeige des ASCII-Zeichen *
//


//
        unsigned char   zeichen = '#';
        monitor_putchar(zeichen);    // Anzeige des ASCII-Zeichen #
//


3. monitor_getchar(); // TRAP 3

Ein Zeichen von der UART empfangen.
//
        unsigned char   zeichen;
        zeichen = monitor_getchar(); // Eingabe eines ASCII-Zeichen ohne Echo
//


//
        // Eingabe von + oder -
        unsigned char  zeichen = ' ';
        while (!(zeichen == '+' || zeichen == '-')) {
              zeichen = monitor_getchar();
        }
        monitor_putchar(zeichen);    // Echo des eingegebenen Zeichen, wenn es richtig ist.
//


4. monitor_getstat(); // TRAP 17

Ein Zeichen von der UART empfangen, ohne auf eine Eingabe zu warten.
//
        unsigned char e = 0;         // keine Eingabe
        unsigned char f = 0;         // keine Eingabe
        while (e == 0) {
              f = monitor_getstat(); // f = ASCII-Zeichen oder 0 bei keiner Eingabe
              if (f == 'a') {
                 monitor_putchar(f);
              } else {
                 e = f;
              }
        }
//


5. monitor_putbyte(wert); // TRAP 5

Einen 8 Bit Wert hexadezimal über die UART anzeigen.
//
        unsigned char wert = 0x4a;
        monitor_putbyte(wert);        // Es wird 04A angezeigt.
//


6. monitor_getbyte(); // TRAP 7

Eingabe eines hexadezimalen 8 Bit Wertes über die UART. Es sind nur die Ziffern 0 ... 9 und die Buchstaben A ... F und a ... f bei der Eingabe zulässig. Die eingegebenen Zeichen sind nur zu sehen, wenn vorher monitor_echoon(); aufgerufen wurde.
//
        unsigned char wert;
        wert = monitor_getbyte();      // Eingabe eines Hex Wertes von 0x00 bis 0xff
//


7. monitor_putint(wert); // TRAP 4

Einen 18 Bit Wert hexadezimal über die UART anzeigen.
//
        int wert = 0x3456f
        monitor_putint(wert);          // Es wird 3456F angezeigt.
//


8. monitor_getint(); // TRAP 6

Eingabe eines hexadezimalen 18 Bit Wertes über die UART. Es sind nur die Ziffern 0 ... 9 und die Buchstaben A ... F und a ... f bei der Eingabe zulässig. Die eingegebenen Zeichen sind nur zu sehen, wenn vorher monitor_echoon(); aufgerufen wurde.
//
        int wert;
        wert = monitor_getint();       // Eingabe eines Hex Wertes von 0x00000 bis 0x3ffff
//


9. monitor_newline(); // TRAP 12

Senden von CR und LF an die UART.
//
        monitor_newline();
//


10. monitor_space(); // TRAP 13

Senden eines Leerzeichens an die UART.
//
        int wert1 = 0x55;
        int wert2 = 0xaa;
        monitor_newline();
        monitor_putint(wert1);
        monitor_space();
        monitor_putint(wert2);
        monitor_newline();              // Es wird 00055 000AA angezeigt.
//


11. monitor_putregs(); // TRAP 16 und TRAP 12

Anzeige der Adresse an der die Funktion aufgerufen wurde, des SFR_STATUS Registers, des SFR_CC Bit und die aktuellen 16 Register.
//
        monitor_putregs();
//

Ausgaben nach 3 Aufrufen in einem Programm.
;
     00171 00103 0
017E4 00006 00000 00000  02200 02208 02208 00000
007A9 00001 00000 00FC2  00018 00000 00200 00001
     0018F 00103 0
017E4 00006 00000 00000  02200 02208 02208 00001
007A9 00001 00000 00FC2  00018 00000 00200 00001
     002AD 00103 1
017E4 00006 00000 00000  02200 02208 02208 00001
007A9 00001 00000 00FC2  011D4 00000 00200 00001
;

Bedeutung der einzelnen Werte im obigen Protokoll.
;
     UP    EI,MM CC
     Start Rbase

     00171 00103 0
017E4 00006 00000 00000  02200 02208 02208 00000
007A9 00001 00000 00FC2  00018 00000 00200 00001

 ro    r1    r2    r3     r4    r5    r6    r7
 r8    r9    r10   r11    r12   r13   r14   r15
;


12. monitor_intregs(int npc, int cc); // TRAP 16 und TRAP 12


Diese Funktion ist speziell zur Einbindung in die ISR der Taste die mit "Interrupt Lowactiv" verbunden ist gedacht. Sie Zeigt die Register des unterbrochenem Programms an. Um auch Informationen aus der Interrupt Annahme im "Startup Programm" auszuwerten, wird die Registernutzung des C-Compilers ausgenutzt. Der C-Compiler verwendet für die ersten 4 Parameter immer die Register R12 bis R15, wenn das Datenformat dies zulässt. Das "Startup Programm" lädt in R14 bei der Interrupt Annahme das SFR_CC Register und in R12 steht eine Kopie von R11, der Rücksprungadresse und damit von Next-PC. Dies soll dann wie bei der Funktion monitor_putregs(); angezeigt werden. Dazu hat die ISR folgenden Aufbau:

ISR-zur Anzeige der Register in C in den jeweils höchsten Interrupt eines Systems einfügen.


// interrupt_lowactiv (Taste Nord auf dem 3e Board)
void isr10(int reg12, int reg13, int reg14, int reg15) {
	monitor_newline();
	monitor_intregs(reg12, reg14);
	}


Der Assembler Code, der daraus entsteht sieht dann wie folgt aus:

;
_ISR10:           ADDI    R0,  -4
                  JALS    _MONITOR_NEWLINE
                  MOV     R12, R4
                  MOV     R13, R6
                  JALS    _MONITOR_INTREGS
                  ADDI    R0,  4
                  JRS     R11                     ;_isr10  2
                                                  ;


_MONITOR_INTREGS: MOV     R12, R4                 ; Adresse bei der UP gerufen wurde
                  MOVS2I  R13, SFR_STATUS         ; Bit8 = EI, Bit7 = MM, Bit6:0 = RegBase
                  MOV     R14, R5                 ; r14 Bit0 = CC
                  MOVI    R15, 4                  ; RegBase um 4 Ebenen nach oben
                  TRAP    16                      ; 16 pg_regs anzeigen
                  MOVI    R15, 3                  ; RegBase um 3 Ebenen nach oben
                  TRAP    16                      ; 16 pg_regs anzeigen
                  TRAP    12                      ; crlf
                  JRS     R11                     ;
;


Damit entsteht dann folgendes Bild auf der Konsole des Monitors:

;
     002C7 00005 1
017D0 00006 00000 00000  01A26 0001F 020C4 00058
00001 00020 00058 00FC5  00000 340A0 0007F 00001     002C7 00005 1
017D0 00006 00000 00000  00000 340A0 0007F 00001
34080 00048 00032 002C7  002C7 00000 00001 00080

     002C8 00005 1
017D0 00006 00000 00000  01A26 0001F 020C4 00058
00001 00020 00058 00FC5  00000 340A0 0007F 00001     002C8 00005 1
017D0 00006 00000 00000  00000 340A0 0007F 00001
34080 00048 00032 002C8  002C8 00000 00001 00080

     002CE 00005 1
017D0 00006 00000 00000  01A26 0001F 020C4 00058
00001 00020 00058 00FC5  00000 340A0 0007F 00001     002CE 00005 1
017D0 00006 00000 00000  00000 340A0 0007F 00001
34080 00048 00032 002CE  002CE 00000 00001 00080
;


Bedeutung der Anzeige:
;
     Next  EI,MM CC                                  Next  EI,MM CC   ********** Absolute Registeradressen *********
     PC    Rbase                                     PC    Rbase
                                                                      Register = Absolute Registeradressen - Rbase * 8
     002CE 00005 1
017D0 00006 00000 00000  01A26 0001F 020C4 00058                      r0    r1    r2    r3     r28   r29   r30   r31 \_ bei Rbase-2=3
00001 00020 00058 00FC5  00000 340A0 0007F 00001     002CE 00005 1    r32   r33   r34   r35    r36   r37   r38   r39 /
017D0 00006 00000 00000  00000 340A0 0007F 00001                      r0    r1    r2    r3     r36   r37   r38   r39 \_ bei Rbase-1=4
34080 00048 00032 002CE  002CE 00000 00001 00080                      r40   r41   r42   r43    r44   r45   r46   r47 /
;


Der 1. Wert ist die Adresse des nächsten Befehls (PC), der 2. der Wert ist SFR_STAT in der Funktion "monitor_intregs(int npc, int cc);" vor dem Aufruf vom TRAP 16 und der 3. Wert ist das CC Bit. Dann folgen die 16 Register des unterbrochenem Programms mit angezeigtes !RegBase -2 (5-2=3) von R0 bis R15. Ist das unterbrochene Programm wie hier ein mit dem Monitor geladenes MAIN Programm, dann steht in R11 (oben absolut r35) die Rücksprungadresse aus dem GO-Kommando des Monitors (hier 0x00FC5). Darauf folgen dann noch einmal die 3 Werte aus dem Kopf gefolgt von den 16 Registern mit angezeigtes !RegBase - 1 (5-1=4). Hier ist R11 (oben absolut r43) die Rücksprungadresse des Interrupts, also der PC des nächsten Befehls. In R14 steht dann nochmal das SFR_CC Register. Die Liste des hier unterbrochenen Programm von 0x002C0 bis 0x002CF hat dabei folgenden Aufbau (die mit * markierten Befehle, sind die Befehle aus dem obigen Protokoll):

;
  0002C2  000134AE M63: M61: M59: M57: MOVI  R10,    (_aktzeit)
  0002C3  00025540                     L18   R10,    0(R10)
  0002C4  00012E94                     MOVI  R7,     (_i)
  0002C5  00024EE0                     L18   R7,     0(R7)
  0002C6  000014E8                     SEQU  R10,    R7
* 0002C7  00000005                     MOV   R0,     R0
* 0002C8  0000E006                     BNEZC M64
  0002C9  00007EF9                     JALS  _PUTZEIT
  0002CA  000134AE                     MOVI  R10,    (_aktzeit)
  0002CB  00012E94                     MOVI  R7,     (_i)
  0002CC  00024EE0                     L18   R7,     0(R7)
  0002CD  00026F40                     S18   0(R10), R7
* 0002CE  00013496 M64:                MOVI  R10,    (_j)
  0002CF  00025540                     L18   R10,    0(R10)
;


und realisiert von 0x002C2 bis 0x002CD die C-Befehlfolge:

if (aktzeit != i) {
			putzeit();
			aktzeit = i;
		}


13. monitor_echoon();

Setzt das Bit 1 im Register 1 und schaltet damit für die Funktionen monitor_getbyte(); und monitor_getint(); das Echo der eingegebenen Zeichen ein.

monitor_echoon();


14. monitor_echooff();

Löscht das Bit 1 im Register 1 und schaltet damit für die Funktionen monitor_getbyte(); und monitor_getint(); das Echo der eingegebenen Zeichen aus.

monitor_echooff();






SpartanMC