Das Terminal (PI5)

Aus C und Assembler mit Raspberry
Version vom 29. November 2024, 12:10 Uhr von Satyria (Diskussion | Beiträge) (Die Seite wurde neu angelegt: „// // screen.S // #include "config.h" #include "base.h" #include "mailbox.h" #define maxZeichen 240 #define maxZeilen 108 →‎Dimension: #define FONT_WIDTH 8 #define FONT_HEIGHT 8 #define FONT_MAX 256 .section .text // bolean Init_Screen (void) // .globl Init_Screen Init_Screen: stp x29, x30, [sp, -16]! mov x29, sp ldr w0,=BCM_MAILBOX_PROP_OUT //Kanal ldr x1,=pScreen //ScreenStruktur 1: bl BcmMailBox_Write //Rufe die Mailbox auf…“)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)

// // screen.S //

  1. include "config.h"
  2. include "base.h"
  3. include "mailbox.h"
  1. define maxZeichen 240
  2. define maxZeilen 108

/* Dimension */

  1. define FONT_WIDTH 8
  2. define FONT_HEIGHT 8
  3. define FONT_MAX 256

.section .text

// bolean Init_Screen (void) // .globl Init_Screen Init_Screen: stp x29, x30, [sp, -16]! mov x29, sp

ldr w0,=BCM_MAILBOX_PROP_OUT //Kanal ldr x1,=pScreen //ScreenStruktur 1: bl BcmMailBox_Write //Rufe die Mailbox auf

ldr x0,=m_nBufferPtr //lade die Speicheradresse ldr w0,[x0] cmp w0,#0 beq 1b

and w0,w0,#0x3FFFFFFF //Passe die Adresse an ldr x1,=graphicsAddress //und sichere sie str w0,[x1]

ldp x29, x30, [sp], 16 ret

// void DrawPixel(u32 x, u32 y) // Zeichne einen Pixel auf den Bildschirm .globl DrawPixel DrawPixel: stp x29, x30, [sp, -16]! stp x10, x11, [sp, -16]! mov x29, sp

   //Überprüfe, ob der Pixel in den Screen passt

cmp w0,#SCREEN_X bge 1f cmp w1,#SCREEN_Y bge 1f

   //Berechne Position des Pixels: graphicsAddress+(((SCREEN_X*y)+x)*4)

mov w10,SCREEN_X mul w10,w10,w1 add w10,w10,w0 lsl w10,w10,#2 ldr x11,=graphicsAddress ldr w11,[x11] add w10,w10,w11

   //Schreibe die Farbe in die Position

ldr x11,=DrawColor ldr w11,[x11] str w11,[x10] 1: ldp x10, x11, [sp], 16 ldp x29, x30, [sp], 16 ret

//u32 GetPixel(u32 x, u32 y) //Abfrage, der Farbe des Pixels im Screen .globl GetPixel GetPixel: stp x29, x30, [sp, -16]! stp x10, x11, [sp, -16]! mov x29, sp

   //Überprüfe, ob der Pixel im Screen ist

cmp w0,#SCREEN_X bge 1f cmp w1,#SCREEN_Y bge 1f

   //Berechne Position des Pixels: graphicsAddress+(((SCREEN_X*y)+x)*4)

mov w10,SCREEN_X mul w10,w10,w1 add w10,w10,w0 lsl w10,w10,#2 ldr x11,=graphicsAddress ldr w11,[x11] add w10,w10,w11

   //Lade die Farbe des Pixels nach w0

ldr w0,[x10] b 2f

1:

   //Wenn Position des Pixel nicht im Screen ist, dann NULL zurück 

mov w0,#0

2: ldp x10, x11, [sp], 16 ldp x29, x30, [sp], 16 ret


//void SetDrawColor(u8 r, u8 g, u8 b) //definiert die Zeichenfarbe .globl SetDrawColor SetDrawColor: stp x29, x30, [sp, -16]! mov x29, sp

   //Berechne die Farbe mit: (0xFF << 24) | (r << 16) | (g << 8) | b;

mov w3,#0xFF lsl w3,w3,#24 lsl w0,w0,#16 lsl w1,w1,#8 orr w3,w3,w0 orr w3,w3,w1 orr w3,w3,w2

   //Und lege sie in der Variablen "DrawColor" ab

ldr x0,=DrawColor str w3,[x0]

ldp x29, x30, [sp], 16 ret

//void SetFrontColor(u8 r, u8 g, u8 b) //definiere die Vordergrundfarbe, für zum Beispiel des Chars .globl SetFrontColor SetFrontColor: stp x29, x30, [sp, -16]! mov x29, sp

   //Berechne die Farbe mit: (0xFF << 24) | (r << 16) | (g << 8) | b;

mov w3,#0xFF lsl w3,w3,#24 lsl w0,w0,#16 lsl w1,w1,#8 orr w3,w3,w0 orr w3,w3,w1 orr w3,w3,w2

   //Und lege sie in der Variablen "FrontColor" ab

ldr x0,=FrontColor str w3,[x0]

ldp x29, x30, [sp], 16 ret

//void SetBackColor(u8 r, u8 g, u8 b) //definiere die Hintergrundfarbe, für zum Beispiel des Chars .globl SetBackColor SetBackColor: stp x29, x30, [sp, -16]! mov x29, sp

   //Berechne die Farbe mit: (0xFF << 24) | (r << 16) | (g << 8) | b;

mov w3,#0xFF lsl w3,w3,#24 lsl w0,w0,#16 lsl w1,w1,#8 orr w3,w3,w0 orr w3,w3,w1 orr w3,w3,w2

   //Und lege sie in der Variablen "BackColor" ab

ldr x0,=BackColor str w3,[x0]

ldp x29, x30, [sp], 16 ret

//void DrawChar(char c, u32 x0, u32 y0) //Zeichnet einen Char an die Position x0, y0 auf den Screen .globl DrawChar DrawChar: stp x29, x30, [sp, -16]! stp x20, x21, [sp, -16]! stp x10, x11, [sp, -16]! stp x12, x13, [sp, -16]! stp x14, x15, [sp, -16]! mov x29, sp

   Sichere zunächst die Position

mov w20,w1 // x0 mov w21,w2 // y0

   //Berechne den Zeiger auf das richtige Zeichen 

ldr x10,=font lsl w0,w0,#3 add x10,x10,x0

   //for (w11 = 0; w11 < FONT_HEIGHT; w11++)

mov w11,#0 1: cmp w11,#FONT_HEIGHT bge 2f

   //for (w12 = 0; w12 < FONT_WIDTH; w12++)

mov w12,#0 3: cmp w12,#FONT_WIDTH bge 4f


   //Überprüfe das Bit nach folgender Formel:
   //(Zeile >> (7 - BitPos)) & 1;

ldrb w13,[x10,x11] mov w14,#7 sub w14,w14,w12 lsr w13,w13,w14 and w13,w13,#1

   //Wenn Ergebniss 0 ist, dann Hintergrund zeichnen

cbz w13,5f

   //Ansonsten in der Vordergrundfarbe

ldr x13,=FrontColor ldr w13,[x13] ldr x14,=DrawColor str w13,[x14] b 6f

5: ldr x13,=BackColor ldr w13,[x13] ldr x14,=DrawColor str w13,[x14]

6:

   //Zeichne den Pixel an die Position

mov w0,w12 add w0,w0,w20 mov w1,w11 add w1,w1,w21 bl DrawPixel

   //end_for w12

add w12,w12,#1 b 3b 4:

   //end_for w11

add w11,w11,#1 b 1b 2: ldp x14, x15, [sp], 16 ldp x12, x13, [sp], 16 ldp x10, x11, [sp], 16 ldp x20, x21, [sp], 16 ldp x29, x30, [sp], 16 ret

//********************************************************** // Konsole //**********************************************************

// Dimensionen für die Konsole

  1. define CHAR_WIDTH 8
  2. define CHAR_HEIGHT 10
  3. define NUM_COLS (SCREEN_X / CHAR_WIDTH)
  4. define NUM_ROWS (SCREEN_Y / CHAR_HEIGHT)

//void ClearScreen() //Löscht den Inhalt des Screens in der Hintergrundfarbe .globl ClearScreen ClearScreen: stp x29, x30, [sp, -16]! stp x10, x11, [sp, -16]! mov x29, sp

   //Setze die Zeichenfarbe auf die Hintergrundfarbe
   ldr x10,=BackColor

ldr w10,[x10] ldr x11,=DrawColor str w10,[x11]

   //for (w11 = 0; w11 < SCREEN_Y; w11++)

mov w11,#0 1: cmp w11,#SCREEN_Y bge 2f

   //for (w10 = 0; w10 < SCREEN_X; w10++)

mov w10,#0 3: cmp w10,#SCREEN_X bge 4f

   //DrawPixel(x, y);

mov w0,w10 mov w1,w11 bl DrawPixel

   //end_for w10

add w10,w10,#1 b 3b 4:

   //end_for w11

add w11,w11,#1 b 1b 2:

   //Setze cursor_x auf 0
   mov x10,#0
   ldr x11,=cursor_x
   str w10,[x11]
   //Setze cursor_y auf 0
   ldr x11,=cursor_y
   str w10,[x11]

ldp x10, x11, [sp], 16 ldp x29, x30, [sp], 16 ret

//void MoveCursor(u32 x, u32 y) //Setze den Cursor auf eine neue Position .globl MoveCursor MoveCursor: stp x29, x30, [sp, -16]! stp x10, x11, [sp, -16]! mov x29, sp

   //Setze cursor_x auf x

ldr x10,=cursor_x str w0,[x10]

   //Setze cursor_y auf y

ldr x10,=cursor_y str w1,[x10]

ldp x10, x11, [sp], 16 ldp x29, x30, [sp], 16 ret

//void DrawCharAtCursor(char c) //Zeichne den Char an die aktuelle Position in der Konsole //Berücksichtige auch Sonderzeichen .globl DrawCharAtCursor DrawCharAtCursor: stp x29, x30, [sp, -16]! mov x29, sp

   //Vergleiche auf Zeilenumbruch

cmp w0,#'\n'

   //Wenn nicht, weitere Abfrage

bne 1f

   //Setze den cursor_x auf 0

ldr x1,=cursor_x mov w2,#0 str w2,[x1]

   //Und den cursor_y um eins höher, für die Zeile

ldr x1,=cursor_y ldr w2,[x1] add w2,w2,#1 str w2,[x1]

b 7f 1:

   //Vergleiche auf Carriage Return

cmp w0,#'\r' bne 2f

   //Setzt den Cursor an den Anfang der aktuellen Zeile.

ldr x1,=cursor_x mov w2,#0 str w2,[x1]

b 7f 2:

   //Vergleiche, ob TAB angezeigt werden soll

cmp w0,#'\t' bne 3f

   //Erhöht den cursor_x um 4
   //DOTO: Fester Wert in allen Zeilen

ldr x1,=cursor_x ldr w2,[x1] add w2,w2,#4 str w2,[x1]

b 7f 3:

   //Vergleich auf Backspace

cmp w0,#'\b' bne 4f

   //Bewegt den Cursor um ein Zeichen nach links
   //nur wenn cursor_x > 0 ist

ldr x1,=cursor_x ldr w2,[x1] cmp w2,#0 ble 8f

   // cursor_x -1

sub w2,w2,#1 str w2,[x1] 8: b 7f 4:

   //Vergleich auf Form Feed)

cmp w0,#'\f' bne 5f

   // Neue Seite

bl ClearScreen

b 7f 5:

   //Vergleich auf ESC-Zeichen

cmp w0,#27 bne 6f

   // ESC-Zeichen erkannt, muss aber zuvor Abgefangen werden.

b 7f 6:

   //Wenn hier angelangt, müsste es sich um ein druckbares Zeichen handeln
   // Char in w0

mov w0,w0

   // Berechnung der x-Pos (cursor_x * CHAR_WIDTH)

ldr x1,=cursor_x ldr w1,[x1] mov w2,#CHAR_WIDTH mul w1,w1,w2

   // Berechnung der y-Pos (cursor_y * CHAR_HEIGHT)

ldr x2,=cursor_y ldr w2,[x2] mov w3,#CHAR_HEIGHT mul w2,w2,w3 bl DrawChar

   //Addiere cursor_x um 1

ldr x0,=cursor_x ldr w1,[x0] add w1,w1,#1 str w1,[x0]

   // Wenn cursor_x >= NUM_COLS ist

cmp w1,NUM_COLS blt 9f

   // dann cursor_x = 0

ldr x0,=cursor_x mov w1,#0 str w1,[x0]

   // und neue Zeile (cursor_y + 1)

ldr x0,=cursor_y ldr w1,[x0] add w1,w1,#1 str w1,[x0] 9:

7: //Für alle:

   //Wenn cursor_y >= max Anzahl Zeilen

ldr x0,=cursor_y ldr w1,[x0] cmp w1,NUM_ROWS blt 10f

   //Dann Scrolle den Bildscirm

bl ScrollScreen

   //Setze die Cursorposition auf Vorletzte Zeile (cursor_y = NUM_ROWS - 1)

mov w0,NUM_ROWS sub w0,w0,#1 ldr x1,=cursor_y str w0,[x1] 10: ldp x29, x30, [sp], 16 ret

// void ProcessEscSequence(const char* seq) // Bearbeite ESC-Funktionen .globl ProcessEscSequence ProcessEscSequence: stp x29, x30, [sp, -16]! mov x29, sp

// Beispiel: "\033[1m" -> Setzt die Vordergrundfarbe auf Rot

//DOTO: https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797 //Color Name Foreground Color Code Background Color Code //Black 30 40 //Red 31 41 //Green 32 42 //Yellow 33 43 //Blue 34 44 //Magenta 35 45 //Cyan 36 46 //White 37 47 //Default 39 49 //Reset 0 0 // //# Set style to bold, red foreground. //\033[1;31mHello //# Set style to dimmed white foreground with red background. //\033[2;37;41mWorld

// Unterstützung nur für Farben: ESC[xm -> x = Farbe

   // Nur wenn seq[0] = '[' und seq[2] = 'm' entspricht

ldrb w1,[x0] cmp w1,'[' bne 1f ldrb w1,[x0,2] cmp w1,'m' bne 1f

   //Werte seq[1] aus:

ldrb w1,[x0,1]

   // Wenn 0

cmp w1,'0' bne 2f

   //dann FrontColor = Schwarz

mov w0,#0 mov w1,#0 mov w2,#0 bl SetFrontColor b 1f 2:

   // Wenn 1

cmp w1,'1' bne 3f

   //dann FrontColor = Rot

mov w0,#0xFF mov w1,#0 mov w2,#0 bl SetFrontColor b 1f 3:

   // Wenn 2

cmp w1,'2' bne 4f

   //dann FrontColor = Grün

mov w0,#0 mov w1,#0xFF mov w2,#0 bl SetFrontColor b 1f 4:

   // Wenn 3

cmp w1,'3' bne 5f

   //dann FrontColor = Gelb

mov w0,#0xFF mov w1,#0xFF mov w2,#0 bl SetFrontColor b 1f 5:

   // Wenn 4

cmp w1,'4' bne 6f

   //dann FrontColor = Blau

mov w0,#0 mov w1,#0 mov w2,#0xFF bl SetFrontColor b 1f 6:

   // Wenn 5

cmp w1,'5' bne 7f

   //dann FrontColor = Magenta

mov w0,#0xFF mov w1,#0 mov w2,#0xFF bl SetFrontColor b 1f 7:

   // Wenn 6

cmp w1,'6' bne 8f

   //dann FrontColor = Cyan

mov w0,#0 mov w1,#0xFF mov w2,#0xFF bl SetFrontColor b 1f 8:

   // Wenn 7

cmp w1,'7' bne 1f

   //dann FrontColor = Weiß

mov w0,#0xFF mov w1,#0xFF mov w2,#0xFF bl SetFrontColor // b 1f

1: ldp x29, x30, [sp], 16 ret

//void ScrollScreen() // Schiebe den Inhalt des Screens um eine Zeichenzeile nach oben .globl ScrollScreen ScrollScreen: stp x29, x30, [sp, -16]! stp x10, x11, [sp, -16]! mov x29, sp //{ // for (u32 y = 1; y < NUM_ROWS; y++) mov x10,#1 1: cmp x10,#NUM_ROWS bge 2f // { // for (u32 x = 0; x < NUM_COLS; x++) mov x11,#0 3: cmp x11,#NUM_COLS bge 4f // { // DrawColor = GetPixel(x * CHAR_WIDTH, y * CHAR_HEIGHT); mov w0,w11 mov w2,#CHAR_WIDTH mul w0,w0,w2 mov w1,w10 mov w2,#CHAR_HEIGHT mul w1,w1,w2 bl GetPixel ldr x1,=DrawColor str w0,[x1] // DrawPixel(x * CHAR_WIDTH, (y - 1) * CHAR_HEIGHT); mov w0,w11 mov w2,#CHAR_WIDTH mul w0,w0,w2 mov w1,w10 sub w1,w1,#1 mov w2,#CHAR_HEIGHT mul w1,w1,w2 bl DrawPixel // } add x11,x11,#1 b 3b 4: // } add x10,x10,#1 b 1b 2: // // Clear the last line // for (u32 x = 0; x < NUM_COLS; x++) mov w10,#0 5: cmp w10,NUM_COLS bge 6f // { // DrawChar(' ', x * CHAR_WIDTH, (NUM_ROWS - 1) * CHAR_HEIGHT); mov w0,#' ' mov w1,w10 mov w3,#CHAR_WIDTH mul w1,w1,w3 mov w2,#NUM_ROWS sub w2,w2,#1 mov w3,#CHAR_HEIGHT mul w2,w2,w3 bl DrawChar // } add w10,w10,#1 b 5b 6: //} ldp x10, x11, [sp], 16 ldp x29, x30, [sp], 16 ret

//void DrawString(const char* str) { .globl DrawString DrawString: stp x29, x30, [sp, -16]! stp x10, x11, [sp, -16]! mov x29, sp

mov x10,x0 // while (*str) 2: ldrb w0,[x10] cmp w0,#0 beq 1f // { // if (*str == '\033') ToDo: Komplett nach DrawCharAtCursor verlegen (Flexibler) cmp w0,#27 bne 3f // { // ESC-Zeichen erkannt // const char* esc_seq = ++str; add x10,x10,#1 mov x0,x10 // ProcessEscSequence(esc_seq); bl ProcessEscSequence // str += 3; // Überspringen der ESC-Sequenz add x10,x10,#3 b 4f // } 3: // else // { // DrawCharAtCursor(*str++); //ldr w0,[x10] bl DrawCharAtCursor add x10,x10,#1 // } // } 4: b 2b //} 1: ldp x10, x11, [sp], 16 ldp x29, x30, [sp], 16 ret

//********************************************************** // Data //********************************************************** .section .data .align 16 pScreen: .int pScreen_end - pScreen .int CODE_REQUEST

.int PROPTAG_ALLOCATE_BUFFER .int 8 .int 4 m_nBufferPtr: .int 0 m_nBufferSize: .int 0

.int PROPTAG_END	

pScreen_end:

.align 2 graphicsAddress: .int 0 DrawColor: .int 0xFFFFFFFF FrontColor: .int 0xFFFFFFFF BackColor: .int 0

// Terminal cursor_x: .int 0 cursor_y: .int 0

.ltorg font: .include "ms8x8font.fon"