bootsector_tictactoe/boot.c
2024-10-20 16:36:21 +05:00

123 lines
2.1 KiB
C

#include <stdlib.h>
#include <stdbool.h>
#include "hedley.h"
#define BOARD ((Cell*)0x7F00)
typedef enum : char {
NONE = ' ',
CROSS = 'X',
NOT = 'O'
} Cell;
HEDLEY_ALWAYS_INLINE char readchar(void);
HEDLEY_ALWAYS_INLINE bool checkwin(Cell c);
HEDLEY_NEVER_INLINE void putchar(char);
HEDLEY_NEVER_INLINE void printboard(void);
char numpadkeys[];
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 k = readchar();
char o;
if (k > 0x46)
o = 0x47;
else if (k < 0x13)
o = 0x10;
else if (k < 0x21)
o = (0x1E - 4);
else
o = (0x2C - 8);
size_t c = numpadkeys[k - o];
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)
;
HEDLEY_UNREACHABLE();
}
// numpadkeys[x - 0x47]
char numpadkeys[] = {0, 1, 2, false, 3, 4, 5, false, 6, 7, 8};
HEDLEY_NEVER_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');
}
}
HEDLEY_ALWAYS_INLINE
bool checkwin(Cell c) {
for (size_t i = 0; i <= 2; i++)
if ((BOARD[i] == c) && (BOARD[i + 3] == c) && (BOARD[i + 6] == c))
return true;
for (size_t i = 0; i <= 2; i++)
if ((BOARD[3*i] == c) && (BOARD[3*i + 1] == c) && (BOARD[3*i + 2] == c))
return true;
if (BOARD[0] == c && BOARD[4] == c && BOARD[8] == c)
return true;
if (BOARD[2] == c && BOARD[4] == c && BOARD[6] == c)
return true;
return false;
}
/*
* 012
* 345
* 678
*/
HEDLEY_ALWAYS_INLINE
char readchar(void) {
char out;
__asm__ volatile (
"movb $0x00, %%ah;"
"int $0x16;"
"movb %%ah, %0;"
:"=r"(out)
:
:"%ax"
);
return out;
}
HEDLEY_NEVER_INLINE
void putchar(char out) {
__asm__ volatile (
"movb $0x0e, %%ah;"
"movb %0, %%al;"
"int $0x10;"
:
:"r"(out)
:"%ax"
);
}