#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
int /*<<< orphan*/ asm_beep();
char asm_getdisppage();
int /*<<< orphan*/ asm_getpos(char *, char *, char);
int /*<<< orphan*/ asm_gotoxy(char, char, char);
int /*<<< orphan*/ asm_putchar(char const, char, char);
char getnumcols();
char getnumrows();
int /*<<< orphan*/ scrollup();
void csprint(const char *str, char attr) {
  char page = asm_getdisppage();
  char newattr = 0, cha, chb;
  char row, col;
  asm_getpos(&row, &col, page);
  while (*str) {
    switch (*str) {
    case '\b':
      --col;
      break;
    case '\n':
      ++row;
      break;
    case '\r':
      col = 0;
      break;
    case 0x07:
      asm_beep();
      break;
    case 14:
    case 15:
      cha = *(str + 1);
      chb = *(str + 2);
      if ((((cha >= '0') && (cha <= '9')) || ((cha >= 'A') && (cha <= 'F'))) &&
          (((chb >= '0') && (chb <= '9')) || ((chb >= 'A') && (chb <= 'F')))) {
        if ((cha >= 'A') && (cha <= 'F'))
          cha = cha - 'A' + 10;
        else
          cha = cha - '0';
        if ((chb >= 'A') && (chb <= 'F'))
          chb = chb - 'A' + 10;
        else
          chb = chb - '0';
        newattr = (cha << 4) + chb;
        attr = (*str == 15 ? newattr : attr ^ newattr);
        str += 2;
      }
      break;
    default:
      asm_putchar(*str, attr, page);
      ++col;
    }
    if (col > getnumcols()) {
      ++row;
      col = 0;
    }
    if (row > getnumrows()) {
      scrollup();
      row = getnumrows();
    }
    asm_gotoxy(row, col, page);
    str++;
  }
}


x86 assembly (clang, -O0):
<csprint>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %sil,%al
mov    %rdi,-0x8(%rbp)
mov    %al,-0x9(%rbp)
mov    $0x0,%al
call   1050 <asm_getdisppage@plt>
mov    %al,-0xa(%rbp)
movb   $0x0,-0xb(%rbp)
lea    -0xe(%rbp),%rdi
lea    -0xf(%rbp),%rsi
movsbl -0xa(%rbp),%edx
call   1060 <asm_getpos@plt>
mov    -0x8(%rbp),%rax
cmpb   $0x0,(%rax)
je     13f1 <csprint+0x271>
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
add    $0xfffffff9,%eax
mov    %eax,%ecx
mov    %rcx,-0x18(%rbp)
sub    $0x8,%eax
ja     1352 <csprint+0x1d2>
mov    -0x18(%rbp),%rax
lea    0xe1e(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
mov    -0xf(%rbp),%al
add    $0xff,%al
mov    %al,-0xf(%rbp)
jmp    1372 <csprint+0x1f2>
mov    -0xe(%rbp),%al
add    $0x1,%al
mov    %al,-0xe(%rbp)
jmp    1372 <csprint+0x1f2>
movb   $0x0,-0xf(%rbp)
jmp    1372 <csprint+0x1f2>
mov    $0x0,%al
call   1090 <asm_beep@plt>
jmp    1372 <csprint+0x1f2>
mov    -0x8(%rbp),%rax
mov    0x1(%rax),%al
mov    %al,-0xc(%rbp)
mov    -0x8(%rbp),%rax
mov    0x2(%rax),%al
mov    %al,-0xd(%rbp)
movsbl -0xc(%rbp),%eax
cmp    $0x30,%eax
jl     1248 <csprint+0xc8>
movsbl -0xc(%rbp),%eax
cmp    $0x39,%eax
jle    1262 <csprint+0xe2>
movsbl -0xc(%rbp),%eax
cmp    $0x41,%eax
jl     134d <csprint+0x1cd>
movsbl -0xc(%rbp),%eax
cmp    $0x46,%eax
jg     134d <csprint+0x1cd>
movsbl -0xd(%rbp),%eax
cmp    $0x30,%eax
jl     127c <csprint+0xfc>
movsbl -0xd(%rbp),%eax
cmp    $0x39,%eax
jle    1296 <csprint+0x116>
movsbl -0xd(%rbp),%eax
cmp    $0x41,%eax
jl     134d <csprint+0x1cd>
movsbl -0xd(%rbp),%eax
cmp    $0x46,%eax
jg     134d <csprint+0x1cd>
movsbl -0xc(%rbp),%eax
cmp    $0x41,%eax
jl     12c2 <csprint+0x142>
movsbl -0xc(%rbp),%eax
cmp    $0x46,%eax
jg     12c2 <csprint+0x142>
movsbl -0xc(%rbp),%eax
sub    $0x41,%eax
add    $0xa,%eax
mov    %al,-0xc(%rbp)
jmp    12cc <csprint+0x14c>
movsbl -0xc(%rbp),%eax
sub    $0x30,%eax
mov    %al,-0xc(%rbp)
movsbl -0xd(%rbp),%eax
cmp    $0x41,%eax
jl     12f8 <csprint+0x178>
movsbl -0xd(%rbp),%eax
cmp    $0x46,%eax
jg     12f8 <csprint+0x178>
movsbl -0xd(%rbp),%eax
sub    $0x41,%eax
add    $0xa,%eax
mov    %al,-0xd(%rbp)
jmp    1302 <csprint+0x182>
movsbl -0xd(%rbp),%eax
sub    $0x30,%eax
mov    %al,-0xd(%rbp)
movsbl -0xc(%rbp),%eax
shl    $0x4,%eax
movsbl -0xd(%rbp),%ecx
add    %ecx,%eax
mov    %al,-0xb(%rbp)
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
cmp    $0xf,%eax
jne    132e <csprint+0x1ae>
movsbl -0xb(%rbp),%eax
mov    %eax,-0x1c(%rbp)
jmp    133b <csprint+0x1bb>
movsbl -0x9(%rbp),%eax
movsbl -0xb(%rbp),%ecx
xor    %ecx,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
mov    %al,-0x9(%rbp)
mov    -0x8(%rbp),%rax
add    $0x2,%rax
mov    %rax,-0x8(%rbp)
jmp    1372 <csprint+0x1f2>
mov    -0x8(%rbp),%rax
mov    (%rax),%cl
mov    -0x9(%rbp),%al
movsbl %cl,%edi
movsbl %al,%esi
movsbl -0xa(%rbp),%edx
call   1070 <asm_putchar@plt>
mov    -0xf(%rbp),%al
add    $0x1,%al
mov    %al,-0xf(%rbp)
movsbl -0xf(%rbp),%eax
mov    %eax,-0x20(%rbp)
mov    $0x0,%al
call   10a0 <getnumcols@plt>
mov    %al,%cl
mov    -0x20(%rbp),%eax
movsbl %cl,%ecx
cmp    %ecx,%eax
jle    139c <csprint+0x21c>
mov    -0xe(%rbp),%al
add    $0x1,%al
mov    %al,-0xe(%rbp)
movb   $0x0,-0xf(%rbp)
movsbl -0xe(%rbp),%eax
mov    %eax,-0x24(%rbp)
mov    $0x0,%al
call   1030 <getnumrows@plt>
mov    %al,%cl
mov    -0x24(%rbp),%eax
movsbl %cl,%ecx
cmp    %ecx,%eax
jle    13cb <csprint+0x24b>
mov    $0x0,%al
call   1080 <scrollup@plt>
mov    $0x0,%al
call   1030 <getnumrows@plt>
mov    %al,-0xe(%rbp)
mov    -0xe(%rbp),%cl
mov    -0xf(%rbp),%al
movsbl %cl,%edi
movsbl %al,%esi
movsbl -0xa(%rbp),%edx
call   1040 <asm_gotoxy@plt>
mov    -0x8(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
jmp    11b1 <csprint+0x31>
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<csprint>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
push   %rax
mov    %esi,%r14d
mov    %rdi,%r15
xor    %eax,%eax
call   1050 <asm_getdisppage@plt>
movsbl %al,%r13d
lea    0x7(%rsp),%rdi
lea    0x6(%rsp),%rsi
mov    %r13d,%edx
call   1060 <asm_getpos@plt>
mov    (%r15),%al
test   %al,%al
je     12fb <csprint+0x17b>
lea    0xe40(%rip),%r12
jmp    1203 <csprint+0x83>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
xor    %eax,%eax
call   1080 <scrollup@plt>
xor    %eax,%eax
call   1030 <getnumrows@plt>
mov    %al,0x7(%rsp)
movsbl 0x6(%rsp),%esi
movsbl %al,%edi
mov    %r13d,%edx
call   1040 <asm_gotoxy@plt>
movzbl 0x1(%r15),%eax
add    $0x1,%r15
test   %al,%al
je     12fb <csprint+0x17b>
movsbl %al,%edi
lea    -0x7(%rdi),%ecx
cmp    $0x8,%ecx
ja     129d <csprint+0x11d>
movslq (%r12,%rcx,4),%rcx
add    %r12,%rcx
jmp    *%rcx
movzbl 0x1(%r15),%edx
movzbl 0x2(%r15),%ecx
lea    -0x30(%rdx),%esi
lea    -0x41(%rdx),%edi
cmp    $0xa,%sil
jb     123b <csprint+0xbb>
cmp    $0x5,%dil
ja     12c0 <csprint+0x140>
lea    -0x30(%rcx),%r8d
lea    -0x41(%rcx),%ebp
cmp    $0xa,%r8b
jb     124e <csprint+0xce>
cmp    $0x5,%bpl
ja     12c0 <csprint+0x140>
add    $0x2,%r15
add    $0x9,%dl
cmp    $0x6,%dil
movzbl %sil,%esi
movzbl %dl,%edx
cmovae %esi,%edx
add    $0xc9,%cl
cmp    $0x6,%bpl
movzbl %r8b,%esi
movzbl %cl,%ecx
cmovae %esi,%ecx
shl    $0x4,%dl
add    %cl,%dl
cmp    $0xf,%al
movzbl %r14b,%r14d
mov    $0x0,%eax
cmove  %eax,%r14d
xor    %dl,%r14b
jmp    12c0 <csprint+0x140>
xor    %eax,%eax
call   1090 <asm_beep@plt>
jmp    12c0 <csprint+0x140>
addb   $0xff,0x6(%rsp)
jmp    12c0 <csprint+0x140>
movsbl %r14b,%esi
mov    %r13d,%edx
call   1070 <asm_putchar@plt>
addb   $0x1,0x6(%rsp)
jmp    12c0 <csprint+0x140>
addb   $0x1,0x7(%rsp)
jmp    12c0 <csprint+0x140>
movb   $0x0,0x6(%rsp)
nopl   0x0(%rax)
movzbl 0x6(%rsp),%ebp
xor    %eax,%eax
call   10a0 <getnumcols@plt>
movzbl 0x7(%rsp),%ebx
cmp    %al,%bpl
jle    12e2 <csprint+0x162>
add    $0x1,%bl
mov    %bl,0x7(%rsp)
movb   $0x0,0x6(%rsp)
xor    %eax,%eax
call   1030 <getnumrows@plt>
cmp    %al,%bl
jg     11d0 <csprint+0x50>
movzbl 0x7(%rsp),%eax
jmp    11e2 <csprint+0x62>
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define void @csprint(i8* %0, i8 signext %1) {
%3 = alloca i8*
%4 = alloca i8
%5 = alloca i8
%6 = alloca i8
%7 = alloca i8
%8 = alloca i8
%9 = alloca i8
%10 = alloca i8
store i8* %0, i8** %3
store i8 %1, i8* %4
%11 = call signext i8 (...) @asm_getdisppage()
store i8 %11, i8* %5
store i8 0, i8* %6
%12 = load i8, i8* %5
%13 = call i32 @asm_getpos(i8* %9, i8* %10, i8 signext %12)
br label %14
14: ; preds = %160, %2
%15 = load i8*, i8** %3
%16 = load i8, i8* %15
%17 = icmp ne i8 %16, 0
br i1 %17, label %18, label %167
18: ; preds = %14
%19 = load i8*, i8** %3
%20 = load i8, i8* %19
%21 = sext i8 %20 to i32
switch i32 %21, label %134 [
i32 8, label %22
i32 10, label %25
i32 13, label %28
i32 7, label %29
i32 14, label %31
i32 15, label %31
]
22: ; preds = %18
%23 = load i8, i8* %10
%24 = add i8 %23, -1
store i8 %24, i8* %10
br label %142
25: ; preds = %18
%26 = load i8, i8* %9
%27 = add i8 %26, 1
store i8 %27, i8* %9
br label %142
28: ; preds = %18
store i8 0, i8* %10
br label %142
29: ; preds = %18
%30 = call i32 (...) @asm_beep()
br label %142
31: ; preds = %18, %18
%32 = load i8*, i8** %3
%33 = getelementptr inbounds i8, i8* %32, i64 1
%34 = load i8, i8* %33
store i8 %34, i8* %7
%35 = load i8*, i8** %3
%36 = getelementptr inbounds i8, i8* %35, i64 2
%37 = load i8, i8* %36
store i8 %37, i8* %8
%38 = load i8, i8* %7
%39 = sext i8 %38 to i32
%40 = icmp sge i32 %39, 48
br i1 %40, label %41, label %45
41: ; preds = %31
%42 = load i8, i8* %7
%43 = sext i8 %42 to i32
%44 = icmp sle i32 %43, 57
br i1 %44, label %53, label %45
45: ; preds = %41, %31
%46 = load i8, i8* %7
%47 = sext i8 %46 to i32
%48 = icmp sge i32 %47, 65
br i1 %48, label %49, label %133
49: ; preds = %45
%50 = load i8, i8* %7
%51 = sext i8 %50 to i32
%52 = icmp sle i32 %51, 70
br i1 %52, label %53, label %133
53: ; preds = %49, %41
%54 = load i8, i8* %8
%55 = sext i8 %54 to i32
%56 = icmp sge i32 %55, 48
br i1 %56, label %57, label %61
57: ; preds = %53
%58 = load i8, i8* %8
%59 = sext i8 %58 to i32
%60 = icmp sle i32 %59, 57
br i1 %60, label %69, label %61
61: ; preds = %57, %53
%62 = load i8, i8* %8
%63 = sext i8 %62 to i32
%64 = icmp sge i32 %63, 65
br i1 %64, label %65, label %133
65: ; preds = %61
%66 = load i8, i8* %8
%67 = sext i8 %66 to i32
%68 = icmp sle i32 %67, 70
br i1 %68, label %69, label %133
69: ; preds = %65, %57
%70 = load i8, i8* %7
%71 = sext i8 %70 to i32
%72 = icmp sge i32 %71, 65
br i1 %72, label %73, label %83
73: ; preds = %69
%74 = load i8, i8* %7
%75 = sext i8 %74 to i32
%76 = icmp sle i32 %75, 70
br i1 %76, label %77, label %83
77: ; preds = %73
%78 = load i8, i8* %7
%79 = sext i8 %78 to i32
%80 = sub nsw i32 %79, 65
%81 = add nsw i32 %80, 10
%82 = trunc i32 %81 to i8
store i8 %82, i8* %7
br label %88
83: ; preds = %73, %69
%84 = load i8, i8* %7
%85 = sext i8 %84 to i32
%86 = sub nsw i32 %85, 48
%87 = trunc i32 %86 to i8
store i8 %87, i8* %7
br label %88
88: ; preds = %83, %77
%89 = load i8, i8* %8
%90 = sext i8 %89 to i32
%91 = icmp sge i32 %90, 65
br i1 %91, label %92, label %102
92: ; preds = %88
%93 = load i8, i8* %8
%94 = sext i8 %93 to i32
%95 = icmp sle i32 %94, 70
br i1 %95, label %96, label %102
96: ; preds = %92
%97 = load i8, i8* %8
%98 = sext i8 %97 to i32
%99 = sub nsw i32 %98, 65
%100 = add nsw i32 %99, 10
%101 = trunc i32 %100 to i8
store i8 %101, i8* %8
br label %107
102: ; preds = %92, %88
%103 = load i8, i8* %8
%104 = sext i8 %103 to i32
%105 = sub nsw i32 %104, 48
%106 = trunc i32 %105 to i8
store i8 %106, i8* %8
br label %107
107: ; preds = %102, %96
%108 = load i8, i8* %7
%109 = sext i8 %108 to i32
%110 = shl i32 %109, 4
%111 = load i8, i8* %8
%112 = sext i8 %111 to i32
%113 = add nsw i32 %110, %112
%114 = trunc i32 %113 to i8
store i8 %114, i8* %6
%115 = load i8*, i8** %3
%116 = load i8, i8* %115
%117 = sext i8 %116 to i32
%118 = icmp eq i32 %117, 15
br i1 %118, label %119, label %122
119: ; preds = %107
%120 = load i8, i8* %6
%121 = sext i8 %120 to i32
br label %128
122: ; preds = %107
%123 = load i8, i8* %4
%124 = sext i8 %123 to i32
%125 = load i8, i8* %6
%126 = sext i8 %125 to i32
%127 = xor i32 %124, %126
br label %128
128: ; preds = %122, %119
%129 = phi i32 [ %121, %119 ], [ %127, %122 ]
%130 = trunc i32 %129 to i8
store i8 %130, i8* %4
%131 = load i8*, i8** %3
%132 = getelementptr inbounds i8, i8* %131, i64 2
store i8* %132, i8** %3
br label %133
133: ; preds = %128, %65, %61, %49, %45
br label %142
134: ; preds = %18
%135 = load i8*, i8** %3
%136 = load i8, i8* %135
%137 = load i8, i8* %4
%138 = load i8, i8* %5
%139 = call i32 @asm_putchar(i8 signext %136, i8 signext %137, i8 signext %138)
%140 = load i8, i8* %10
%141 = add i8 %140, 1
store i8 %141, i8* %10
br label %142
142: ; preds = %134, %133, %29, %28, %25, %22
%143 = load i8, i8* %10
%144 = sext i8 %143 to i32
%145 = call signext i8 (...) @getnumcols()
%146 = sext i8 %145 to i32
%147 = icmp sgt i32 %144, %146
br i1 %147, label %148, label %151
148: ; preds = %142
%149 = load i8, i8* %9
%150 = add i8 %149, 1
store i8 %150, i8* %9
store i8 0, i8* %10
br label %151
151: ; preds = %148, %142
%152 = load i8, i8* %9
%153 = sext i8 %152 to i32
%154 = call signext i8 (...) @getnumrows()
%155 = sext i8 %154 to i32
%156 = icmp sgt i32 %153, %155
br i1 %156, label %157, label %160
157: ; preds = %151
%158 = call i32 (...) @scrollup()
%159 = call signext i8 (...) @getnumrows()
store i8 %159, i8* %9
br label %160
160: ; preds = %157, %151
%161 = load i8, i8* %9
%162 = load i8, i8* %10
%163 = load i8, i8* %5
%164 = call i32 @asm_gotoxy(i8 signext %161, i8 signext %162, i8 signext %163)
%165 = load i8*, i8** %3
%166 = getelementptr inbounds i8, i8* %165, i32 1
store i8* %166, i8** %3
br label %14
167: ; preds = %14
ret void
}

LLVM IR (-O2):
define void @csprint(i8* nocapture %0, i8 signext %1) {
%3 = alloca i8
%4 = alloca i8
%5 = tail call signext i8 (...) @asm_getdisppage()
%6 = call i32 @asm_getpos(i8* %3, i8* %4, i8 signext %5)
%7 = load i8, i8* %0
%8 = icmp eq i8 %7, 0
br i1 %8, label %78, label %9
9: ; preds = %2, %71
%10 = phi i8 [ %76, %71 ], [ %7, %2 ]
%11 = phi i8* [ %75, %71 ], [ %0, %2 ]
%12 = phi i8 [ %54, %71 ], [ %1, %2 ]
%13 = sext i8 %10 to i32
switch i32 %13, label %49 [
i32 8, label %14
i32 10, label %17
i32 13, label %20
i32 7, label %21
i32 14, label %23
i32 15, label %23
]
14: ; preds = %9
%15 = load i8, i8* %4
%16 = add i8 %15, -1
store i8 %16, i8* %4
br label %53
17: ; preds = %9
%18 = load i8, i8* %3
%19 = add i8 %18, 1
store i8 %19, i8* %3
br label %53
20: ; preds = %9
store i8 0, i8* %4
br label %53
21: ; preds = %9
%22 = call i32 (...) @asm_beep()
br label %53
23: ; preds = %9, %9
%24 = getelementptr inbounds i8, i8* %11, i64 1
%25 = load i8, i8* %24
%26 = getelementptr inbounds i8, i8* %11, i64 2
%27 = load i8, i8* %26
%28 = add i8 %25, -48
%29 = icmp ult i8 %28, 10
%30 = add i8 %25, -65
%31 = icmp ult i8 %30, 6
%32 = or i1 %29, %31
br i1 %32, label %33, label %53
33: ; preds = %23
%34 = add i8 %27, -48
%35 = icmp ult i8 %34, 10
%36 = add i8 %27, -65
%37 = icmp ult i8 %36, 6
%38 = or i1 %35, %37
br i1 %38, label %39, label %53
39: ; preds = %33
%40 = add nuw nsw i8 %25, 9
%41 = select i1 %31, i8 %40, i8 %28
%42 = add nsw i8 %27, -55
%43 = select i1 %37, i8 %42, i8 %34
%44 = shl i8 %41, 4
%45 = add i8 %44, %43
%46 = icmp eq i8 %10, 15
%47 = select i1 %46, i8 0, i8 %12
%48 = xor i8 %45, %47
br label %53
49: ; preds = %9
%50 = call i32 @asm_putchar(i8 signext %10, i8 signext %12, i8 signext %5)
%51 = load i8, i8* %4
%52 = add i8 %51, 1
store i8 %52, i8* %4
br label %53
53: ; preds = %33, %23, %39, %49, %21, %20, %17, %14
%54 = phi i8 [ %12, %49 ], [ %48, %39 ], [ %12, %21 ], [ %12, %20 ], [ %12, %17 ], [ %12, %14 ], [ %12, %23 ], [ %12, %33 ]
%55 = phi i8* [ %11, %49 ], [ %26, %39 ], [ %11, %21 ], [ %11, %20 ], [ %11, %17 ], [ %11, %14 ], [ %11, %23 ], [ %11, %33 ]
%56 = load i8, i8* %4
%57 = call signext i8 (...) @getnumcols()
%58 = icmp sgt i8 %56, %57
%59 = load i8, i8* %3
br i1 %58, label %60, label %62
60: ; preds = %53
%61 = add i8 %59, 1
store i8 %61, i8* %3
store i8 0, i8* %4
br label %62
62: ; preds = %53, %60
%63 = phi i8 [ %61, %60 ], [ %59, %53 ]
%64 = call signext i8 (...) @getnumrows()
%65 = icmp sgt i8 %63, %64
br i1 %65, label %68, label %66
66: ; preds = %62
%67 = load i8, i8* %3
br label %71
68: ; preds = %62
%69 = call i32 (...) @scrollup()
%70 = call signext i8 (...) @getnumrows()
store i8 %70, i8* %3
br label %71
71: ; preds = %66, %68
%72 = phi i8 [ %67, %66 ], [ %70, %68 ]
%73 = load i8, i8* %4
%74 = call i32 @asm_gotoxy(i8 signext %72, i8 signext %73, i8 signext %5)
%75 = getelementptr inbounds i8, i8* %55, i64 1
%76 = load i8, i8* %75
%77 = icmp eq i8 %76, 0
br i1 %77, label %78, label %9
78: ; preds = %71, %2
ret void
}