bootsector_tictactoe/boot.c

129 lines
2.0 KiB
C

#include <stdbool.h>
#define BOARD ((Cell*)0x7F00)
typedef enum : char {
NONE = ' ',
CROSS = 'X',
NOT = 'O'
} Cell;
inline void putchar(char);
inline char readchar(void);
inline void printboard(void);
inline bool checkwin(Cell c);
void _start(void) {
Cell cur = CROSS;
for (char i = 0; i < 3; i++)
for (char j = 0; j < 3; j++)
*(BOARD + i * 3 + j) = NONE;
while (1) {
printboard();
char c;
switch (readchar()) {
case 0x47: // 7
c = 0;
break;
case 0x48: // 8
c = 1;
break;
case 0x49: // 9
c = 2;
break;
case 0x4B: // 4
c = 3;
break;
case 0x4C: // 5
c = 4;
break;
case 0x4D: // 6
c = 5;
break;
case 0x4F: // 1
c = 6;
break;
case 0x50: // 2
c = 7;
break;
case 0x51: // 3
c = 8;
break;
default:
continue;
}
if (*(BOARD + c) != NONE)
continue;
*(BOARD + c) = cur;
if (checkwin(cur))
break;
if (cur == CROSS)
cur = NOT;
else
cur = CROSS;
}
putchar(cur);
printboard();
while(1)
;
}
inline void printboard(void) {
__asm__ volatile (
"movb $0x02, %%ah;"
"movb $0x00, %%bh;"
"movw $0x0000, %%dx;"
"int $0x10;"
:
:
:"%ah","%bh","%dx"
);
for (char i = 0; i < 3; i++) {
for (char j = 0; j < 3; j++) {
putchar(*(BOARD + i * 3 + j));
}
putchar('\n');
putchar('\r');
}
}
inline bool checkwin(Cell c) {
for (char i = 0; i < 3; i++)
if ((*(BOARD + i) == c) && (*(BOARD + i + 3) == c) && (*(BOARD + i + 6) == c))
return true;
for (char i = 0; i < 3; i++)
if ((*(BOARD + 3*i) == c) && (*(BOARD + 3*i + 1) == c) && (*(BOARD + 3*i + 2) == c))
return true;
if (*(BOARD) == c && *(BOARD + 4) == c && *(BOARD + 8))
return true;
if (*(BOARD + 2) == c && *(BOARD + 4) == c && *(BOARD + 7))
return true;
return false;
}
inline char readchar(void) {
char out;
__asm__ volatile (
"movb $0x00, %%ah;"
"int $0x16;"
"movb %%ah, %0;"
:"=r"(out)
:
:"%ax"
);
return out;
}
inline void putchar(char out) {
__asm__ volatile (
"movb $0x0e, %%ah;"
"movb %0, %%al;"
"int $0x10;"
:
:"r"(out)
:"%ax"
);
}