#import "../lib/styles.typ" : *
#import "../lib/common_rewrite.typ" : *
#import "../lib/bit_fields.typ" : *
#import "@preview/cetz:0.4.2"

#set page(
  paper: "a4", 
  margin: (
    bottom: 10mm,
    top: 5mm,
    left: 5mm,
    right: 5mm
  ),
  flipped:true,
  numbering: "— 1 —",
  number-align: center
)

#set text(size: 8pt)

#place(top+center, scope: "parent", float: true, heading(
  [Computer Technik/Programmierpraktikum EI]
))

#let Allgemein = color.hsl(105.13deg, 92.13%, 75.1%)
#let colorProgramming = color.hsl(330.19deg, 100%, 68.43%)
#let colorNumberSystems = color.hsl(202.05deg, 92.13%, 75.1%)
#let colorMMIX = color.hsl(280deg, 92.13%, 75.1%)
#let colorRandomShit = color.hsl(356.92deg, 92.13%, 75.1%)
// #let colorGruppen = color.hsl(34.87deg, 92.13%, 75.1%)


#let SeperatorLine = line(length: 100%, stroke: (paint: black, thickness: 0.3mm))
#let MathAlignLeft(e) = {
  align(left, block(e))
}
#columns(2, gutter: 2mm)[
  #bgBlock(fill: colorNumberSystems)[
    #subHeading(fill: colorNumberSystems)[ASCII Ranges]

    #table(
      columns: (1fr, 1fr, 1fr),
      [Range], [Hex], [Bits],
      [Upper Case], raw("0x41-0x5A"), [#raw("010XXXXX") (bit 6)],
      [Lower Case], raw("0x61-0x7A"), [#raw("011XXXXX") (bit 6)],
      [Numbers (0-9)], raw("0x30-0x39"), [#raw("0011XXXX")],
      [Ganz ASCII], raw("0x00-0x7F"), [#raw("0XXXXXXX")],
    )
  ]

  #bgBlock(fill: colorNumberSystems)[
    #subHeading(fill: colorNumberSystems)[Fixed Point]

    #table(
      columns: 17,
      fill: (x, y) => if calc.rem(x, 2) == 1 { tableFillLow } else { tableFillHigh },

      .. for i in range(0,17) {
        ([$2^#i$],)
      },
      .. for i in range(0,17) {
        ($#calc.pow(2,i)$,)
      }
    )

    #columns(2, [
      *Vorzeichen und Betrag:*

      #grid(
        columns: (2fr, 1fr),
        [
          $x = (-1)^"sign-bit" dot "Betrag"$

          $0 -> "positiv", 1 -> "negativ"$

          Range: \ $(-2^(n-1) - 1) dot 2^r$ bis $(2^(n-1) - 1) dot 2^r$

          Achtung: $plus.minus 0$
        ],
        image("../images/ct/betragUndVorzeich.png", width: 2cm)
      )

      #line(length: 100%, stroke: (thickness: 0.2mm))

      *Einer-Komplement*
      
      #grid(
        columns: (2fr, 1fr),
        [
          $x = (-1)^"sign-bit" dot "Betrag"$

          $0 -> "positiv normaler Betrag"$

          $1 -> "negativ INVERT. Betrag"$

          Range: \ 
          $(-2^(n-1) - 1) dot 2^r$ bis $(2^(n-1) - 1) dot 2^r$

          Achtung: $plus.minus 0$
        ],
        image("../images/ct/einerKomplement.png", width: 2cm)
      )
      #colbreak()

      *Zweier-Komplement*

      #grid(
        columns: (2fr, 1fr),
        [
          $x = (-1)^"sign-bit" dot "Betrag"$

          $0 -> "positiv"$

          $1 -> "negativ"$

          Range: \ $(-2^(n-1)) dot 2^r$ bis $(2^(n-1) - 1) dot 2^r$

          Positiv: Normal Binär Kodierung

          Negativ: #raw("Invertiert(Binär) + 1")

        ],
        image("../images/ct/zweierKomplement.png", width: 2cm)
      )

      #line(length: 100%, stroke: (thickness: 0.2mm))
      
      *Radix / Fixed Point*

      $r = 0$ Normal Falle, nix änder sich

      $r > 0$ : Komma nach Rechts und Nullen auffüllen \
      Bsp. $r = 3 quad ->$  #raw("xxxxxxx000.")

      $r < 0$ : Komma nach Links verschieben \
      Bsp: $r = -4 quad ->$ #raw("xxxxx.xxxx")

    ])
  ]

  #colbreak()
  #bgBlock(fill: colorNumberSystems)[
    #subHeading(fill: colorNumberSystems)[Float (IEEE 754)]

    *Float (IEEE 754)*

    #cetz.canvas({
      import cetz.draw : *
      let cell_size = 0.3;
      
      let manntise_stop = 22;
      let exponent_start = 23;
      let exponent_stop = 30;
      let sign_bit = 31;
      let total_bits = sign_bit + 1;


      for i in range(total_bits) {
        let bit = 31 - i;

        rect((i*cell_size, 0), (i*cell_size+cell_size, 0.5),
          fill: if bit == sign_bit { rgb("#8fff57") } else { 
            if ( bit >= exponent_start and bit <= exponent_stop) { rgb("#ffe057") } else { if (bit <= manntise_stop) {rgb("#57a5ff")} else { white } }
          },
          stroke: (thickness: 0.2mm)
        )
  
        content((i*cell_size + 0.5*cell_size, 0.25), raw(str(0)))
      }

      content((cell_size, 0.7), [sign], anchor: "east")
      content((5*cell_size, 0.7), [Exponent (#str(exponent_stop - exponent_start + 1) bit)])
      content((20*cell_size, 0.7), [Mantisse/Wert (#str(manntise_stop+1) bit)])

      rect((0,0), (32*cell_size, 0.5))

      content((cell_size*(total_bits - sign_bit), -0.2), anchor: "south", raw(str(sign_bit)), angle: 90deg)

      content((cell_size*(total_bits - exponent_stop), -0.2), anchor: "south", raw(str(exponent_stop)), angle: 90deg)

      content((cell_size*(total_bits - exponent_start), -0.2), anchor: "south", raw(str(exponent_start)), angle: 90deg)

      content((cell_size*(total_bits - manntise_stop), -0.2), anchor: "south", raw(str(manntise_stop)), angle: 90deg)

      content((cell_size*(total_bits), -0.2), anchor: "south", raw(str(0)), angle: 90deg)
    })

    #cetz.canvas({
      import cetz.draw : *
      let cell_size = 0.21;
      
      let manntise_stop = 51;
      let exponent_start = 52;
      let exponent_stop = 62;
      let sign_bit = 63;
      let total_bits = sign_bit + 1;


      for i in range(total_bits) {
        let bit = sign_bit - i;

        rect((i*cell_size, 0), (i*cell_size+cell_size, 0.5),
          fill: if bit == sign_bit { rgb("#8fff57") } else { 
            if ( bit >= exponent_start and bit <= exponent_stop) { rgb("#ffe057") } else { if (bit <= manntise_stop) {rgb("#57a5ff")} else { white } }
          },
          stroke: (thickness: 0.2mm)
        )
  
        content((i*cell_size + 0.5*cell_size, 0.25), raw(str(0)))
      }

      content((cell_size, 0.7), [sign], anchor: "east")
      content((7*cell_size, 0.7), [Exponent (#str(exponent_stop - exponent_start + 1) bit)])
      content((20*cell_size, 0.7), [Mantisse/Wert (#str(manntise_stop+1) bit)])

      rect((0,0), (total_bits*cell_size, 0.5))

      content((cell_size*(total_bits - sign_bit), -0.2), anchor: "south", raw(str(sign_bit)), angle: 90deg)

      content((cell_size*(total_bits - exponent_stop), -0.2), anchor: "south", raw(str(exponent_stop)), angle: 90deg)

      content((cell_size*(total_bits - exponent_start), -0.2), anchor: "south", raw(str(exponent_start)), angle: 90deg)

      content((cell_size*(total_bits - manntise_stop), -0.2), anchor: "south", raw(str(manntise_stop)), angle: 90deg)

      content((cell_size*(total_bits), -0.2), anchor: "south", raw(str(0)), angle: 90deg)
    })

    $x = (-1)^"sign" dot #raw("1.[mantisse]")  dot 2^(("exponent" - k))$

    #grid(
      columns: (auto, auto),
      column-gutter: 5mm,
      row-gutter: 2mm,
      $"float32"&, k = 127 &= #raw("    111 1111") "(7 x Einser)" \
       "float64"&, k = 1023 &= #raw("11 1111 1111") "(10 x Einser)"$
    )

    *Spezial Cases* 
    #table(
      columns: (auto, auto),
      [$0$], [exponent = 0 \ mantisse = 0],
      [$plus.minus infinity$], [exponent = alle 1 \ mantisse = 0],
      [NaN], [exponent = alle 1 \ mantisse > 0],
      [denormalisierte Float], [exponent = 0 \ mantisse > 0],
      [normalisierter Float], [0 < exponent < 255/2047]
    )
  ]

  #bgBlock(fill: colorProgramming)[
    #subHeading(fill: colorProgramming)[C]

    #table(
      columns: (auto, auto, auto),
      fill: (x, y) => if calc.rem(y, 2) == 0 { tableFillLow } else { tableFillHigh },

      [*C-Type*], [*min size*], [*typ. size*],
      raw("char"), raw("1 byte"), raw("1 byte"),
      raw("short (int)"), raw("2 byte"), raw("2 byte"),
      raw("int"), raw("2 byte"), raw("4 byte"),
      raw("long (int)"), raw("4 byte"), raw("8 byte"),
      raw("long long"), raw("4 byte"), raw("8 byte"),
      raw("float"), raw("4 byte"), raw("4 byte"),
      raw("double"), raw("8 byte"), raw("8 byte"),

    )

    #table(
      columns: (auto, 1fr),
      fill: white,
      raw("restrict", lang: "c"), [
        Funktions Argument modifier

        Gibt compiler den hint, das eine Pointer nur in der Funktion verwedent wird. Kann besser optimiert werden
      ],
      raw("volatile", lang: "c"), [
        Zwingt Compiler den Funktion/Variable nicht wegzuoptimieren
      ]
    )
  ]

  #bgBlock(fill: colorProgramming)[
    #subHeading(fill: colorProgramming)[#raw("scanf/printf") Format Specifier]

    #columns(2)[
      *printf* 
      #table(
        columns: (auto, auto),
        fill: (x, y) => if calc.rem(y, 2) == 0 { tableFillLow } else { tableFillHigh },
        raw("%s"), [*String*],
        raw("%d"), [*Decimal: #raw("int/short/long"))*],
        raw("%f"), [*Float*],
        raw("%f"), [*Float*],
        raw("%lf"), [*Double*],
        raw("%x"), [* Hexdecimal #raw("int/short/long")*],
      )

      Allgemeiner Syntax: #raw("%[flags][width][.precision]type")

      Flags:
      - #raw("0") Prepend With left aligned
      - #raw("-") Left-aligned

      #table(columns: (auto, auto),
        fill: (x, y) => if calc.rem(y, 2) == 0 { tableFillLow } else {  tableFillHigh },
        raw("\\n"), [New Line],
        raw("\\t"), [Tab],
        raw("\\0"), [Null Terminator],
        raw("\\\\"), [#raw("\\")],
        raw("\\\""), [#raw("\"")],
      )

      #colbreak()

      *scanf*
      #table(
        columns: (auto, auto),
        fill: (x, y) => if calc.rem(y, 2) == 0 { tableFillLow } else { tableFillHigh },
        raw("%[size of String]s"), [*String* \ Size of String (without the #raw("\\0")) \ Terminates with Whitespace],
        raw("%i"), [*#raw("int")*],
        raw("%f"), [*#raw("float")*],
        raw("%lf"), [*#raw("double")*],
        raw("%x"), [*#raw("int")* als Hexadezimal],
        raw("%c"), [*#raw("char")* ],
      )

      #raw("fgets(char * s, int count, stdin)")
    ]
  ]

  #bgBlock(fill: colorMMIX)[
    #subHeading(fill: colorMMIX)[MMIX]
    - $32$ Speziel Register
    - $256$ Allzwickregister
    - $2^64$ Speicher

    Wort: $64$ Bit
    
    *Calling Convensions*

    #cetz.canvas({
      import cetz.draw : *

      let cellHeight = 0.4
      let cellWidth = 2

      let c(y, c, x: 0, number: "") = {
        rect((x, cellHeight*y), (x + cellWidth,  cellHeight*(y+1)), fill: white)
        content((x+ cellWidth/2, cellHeight*(y+0.5)), c)
        content((x - 0.2, cellHeight*(y+0.5)), number, anchor: "mid-east")
      }

      c(0, "3.Param", number: raw("0x3FFFFFFFFFFFFFF8"))
      c(1, "2.Param", number: raw("0x3FFFFFFFFFFFFFF0"))
      c(2, "1.Param", number: raw("0x3FFFFFFFFFFFFFE8"))
      c(3, "Sicherung $1", number: raw("0x3FFFFFFFFFFFFFE0"))
      c(4, "Sicherung $2", number: raw("0x3FFFFFFFFFFFFFD8"))

      c(0, "Rückgabe wert", x: cellWidth)
    })

    #colbreak()

#text(rgb("#1a00aa"))[
*1. (Aufrufer) Parameter auf Stack ablegen*\
#raw("SUB :SP,:SP,n*8
STO $x0,:SP,0*8
STO $x1,:SP,1*8
...
STO $xn,:SP,n*8")

*2. (Aufrufer) Funktions Aufruf*\
#raw("GO $0,:Fkt")
]

#text(rgb("#aa0000"))[
*3. (Funktion) Sicherung der Register*\
#raw("SUB :SP,:SP,n*8
STO $y0,:SP,0*8
STO $y1,:SP,1*8
...
STO $yn,:SP,n*8")

*4. (Funktion) Funktions Code*\

*5. (Funktion) Schreiben des Rückgabewerts*\
#raw("
STO $r,:SP,m*8
")

*6. (Funktion) Wiederherstellung der Register*\
#raw("LDO $x0,:SP, 0*8 + k
LDO $x1,:SP, 1*8 + k
...
LDO $xn,:SP, n*8 + k
")

*7. (Funktion) Rücksprung*\
]

#text(rgb("#1a00aa"))[
*8. (Aufrufer) Lesen des Rückgabewerts*\


]
]

  #bgBlock(fill: colorRandomShit)[
    #subHeading(fill: colorRandomShit)[Register Register Magista]

    *Zwei-Address-Maschine:* $quad X <-- X dot.o Y$, Parameter: $(X,Y)$ \
    *Drei-Address-Maschine:* $quad X <-- Y dot.o Z$, Parameter: $(X,Y,Z)$ \
    *Ein-Address-Maschine:* $quad "ACC" <-- X$, Parameter: $(X)$

    *Register-Speicher-Architekture:* \
    Operanden können Register und Addressen sein
    
    *Register-Register-Archiektur/Load-Store-Architektur* \
    Operanden nur Register. Extra Befehle fürs Laden aus Speicher


    *CISC*: Complex Instruction Set Architecture
    - Eine Befehl kann viel $->$ Wenige Befehle
    - Befehlslänge Variable (meistens)
    - z.B. x86

    *RISC*: Reduced Instruction Set Architecture
    - Eine Befehl kann wenig $->$ Viel Befehle
    - Befehlslänge fix (meistens)
    - z.B. Arm, RISC, MMIX

    *Universal Rechner*
    
    - M1: Ergebnis Qulle
      - Input a,b,c oder ALU
    - M2: ALU Operation 
    - M3,M4: Operanden
      - R0-R7
    - D: Ergebnis Register
      - R0-R7
    - K: Konstante für Operanden 
  ]
]