/* showbinaer.c
Darstellung eines Bitmusters
unter Verwendung der portieren conio- Funktionen
*/

#include <conio.h>
#include <stdio.h>

/* Zeichen zum Zeichnen von Rahmenlinien im Textmode laut Codepage 850 */
#define Z_ELO  218  /* Ecke links oben   */
#define Z_ERO  191  /* Ecke rechts oben  */
#define Z_ELU  192  /* Ecke links unten  */
#define Z_ERU  217  /* Ecke rechts unten */
#define Z_AOB  194  /* Anschluss oben    */
#define Z_AUN  193  /* Anschluss unten   */
#define Z_LWA  196  /* Linie waagrecht   */
#define Z_LSE  179  /* Linie senkrecht   */
#define Z_FILL 219  /* voll ausfuellen   */

/*
Die Funktion showbinaer gibt size Bytes Speicherinhalte ab der Adresse p aus.
Die Darstellung beginnt in Zeile z0 und benoetigt 6 Zeilen.
Wird die Funktion verwendet, um Aenderungen eines Bitmusters anzuzeigen, so
duerfen dazwischen keine normalen Ausgaben auf die Konsole gemacht werden.
Die Ausgabe erfolgt immer an derselben Position am Bildschirm.
Ist init = 1, so werden die Rahmen der Darstellung gezeichnet.
*/

void showbinaer(void *p, unsigned size, int y0, int init)
{
  int i, j;
  int x0 = 8;
  int xpos;                     /* Position des aktuellen Bits  */
  int zahlxpos;                 /* Position des Bytewertes      */
  unsigned char mask = 0;       /* Maske fuer Pruefung der Bits */
  unsigned char *pb;            /* Zeiger auf ein Byte          */
  unsigned long int zwert = 0;  /* das Muster als Zahl (fuer size < sizeof(long)) */

  textbackground(WHITE);
  _setcursortype (_NOCURSOR);

  if (init) {    /* Rahmenlinien zeichnen */
    clrscr();
    textcolor(BLACK);
    /* 1. Zeile: Nummern der Bits */
    gotoxy(x0, y0);
    for (i = size * 8 - 1; i >= 0; i--) printf(" %1i", i % 8);
    /* 2. Zeile: Kasten obere Linie */
    gotoxy(x0, y0 + 1);
    putchar(Z_ELO);
    for (i = 0; i < size * 8 - 1 ; i++) {
      putchar(Z_LWA);
      putchar(Z_AOB);
    }
    putchar(Z_LWA);
    putchar(Z_ERO);
    /* 3. Zeile: Inhalt */
    gotoxy(x0, y0 + 2);
    for (i = 0; i < size * 8; i++) {
      putchar(Z_LSE);
      putchar(' ');
    }
    putchar(Z_LSE);
    /* 4. Zeile: Kasten untere Linie */
    gotoxy(x0, y0 + 3);
    putchar(Z_ELU);
    for (i = 0; i < size * 8 - 1; i++) {
      putchar(Z_LWA);
      putchar(Z_AUN);
    }
    putchar(Z_LWA);
    putchar(Z_ERU);
  }


  /* Ausgabe der einzelnen Bits */

  xpos = x0 + 1;      /* Position der einzelnen Bits */
  zahlxpos = x0;      /* Position des Zahlenwertes fuer die einzelnen Bytes */

  for (j = size-1; j >= 0; j--) {  /* vom hoechstwertigsten zum niederwertigsten Byte */
    pb = (unsigned char *) p + j;  /* aktuelles Byte */
    zwert += *pb << 8*j;           /* Zahlenwert des gesamten Musters berechnen */
    textcolor(BLACK);              /* Zahlenwert des Bytes ausgeben */
    gotoxy(zahlxpos, y0 + 5);
    printf("|      %4u     |", *pb);
    zahlxpos += 16;
    mask = 1 << 7;                 /* Beginn: Ausgabe der einzelnen Bits */
    for (i = 7; i >= 0; i--) {
      if (*pb & mask)
        textcolor(LIGHTGREEN);
      else
        textcolor(DARKGRAY);
      gotoxy(xpos, y0 + 2);
      putchar(Z_FILL);             /* aktuelles Bit ausgeben */
      xpos += 2;
      mask >>= 1;
    }
  }

  /* Zahlenwert des gesamten Musters anzeigen */
  gotoxy(x0, y0 + 7);
  textcolor(BLACK);
  printf("%-12u", zwert);

  textbackground(BLACK);
  textcolor(WHITE);
  _setcursortype (_NORMALCURSOR);
  gotoxy(1, y0 + 10);

}  /* end showbinaer */