#include #include #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) { __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" ); }