#include #include #include "hedley.h" typedef enum : char { NONE = ' ', CROSS = 'X', NOT = 'O' } Cell; Cell* board = ((Cell*)0x7F00); 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) { __asm__ volatile ( "movl $0x8000, %esp\n" "ljmp $(0),$(start)\n" "start:\n" ); 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" ); }