Whoops, I think I just accidentally (no) foramtted the entire project with clang

This commit is contained in:
Андреев Григорий 2026-04-07 23:07:51 +03:00
parent d76095ca85
commit 1794df45f4
50 changed files with 1953 additions and 1324 deletions

6
.clang-format Normal file
View File

@ -0,0 +1,6 @@
BasedOnStyle: LLVM
IndentWidth: 4
ContinuationIndentWidth: 4
TabWidth: 4
UseTab: Never
BreakBeforeBraces: Attach

View File

@ -5,74 +5,66 @@
// bootmain() loads an ELF kernel image from the disk starting at // bootmain() loads an ELF kernel image from the disk starting at
// sector 3 and then jumps to the kernel entry routine. // sector 3 and then jumps to the kernel entry routine.
#include "elf.h"
#include "drivers/port.h" #include "drivers/port.h"
#include "elf.h"
#define SECTSIZE 512 #define SECTSIZE 512
typedef unsigned char uchar; typedef unsigned char uchar;
typedef unsigned int uint; typedef unsigned int uint;
void readseg(uchar*, uint, uint); void readseg(uchar *, uint, uint);
inline void stosb(uchar* addr, uchar byte, uint count) { inline void stosb(uchar *addr, uchar byte, uint count) {
asm volatile("cld; rep stosb" : "+D"(addr), "+a"(byte) : "c"(count) : "cc"); asm volatile("cld; rep stosb" : "+D"(addr), "+a"(byte) : "c"(count) : "cc");
} }
void void bootmain(void) {
bootmain(void)
{
Elf32_Ehdr *elf; Elf32_Ehdr *elf;
Elf32_Phdr *ph, *eph; Elf32_Phdr *ph, *eph;
void (*entry)(void); void (*entry)(void);
uchar* pa; uchar *pa;
elf = (Elf32_Ehdr*)0x30000; // scratch space elf = (Elf32_Ehdr *)0x30000; // scratch space
// Read 1st page off disk // Read 1st page off disk
readseg((uchar*)elf, 4096, 0); readseg((uchar *)elf, 4096, 0);
// Is this an ELF executable? // Is this an ELF executable?
if(elf->magic != ELF_MAGIC) if (elf->magic != ELF_MAGIC)
return; // let bootasm.S handle error return; // let bootasm.S handle error
// Load each program segment (ignores ph flags). // Load each program segment (ignores ph flags).
ph = (Elf32_Phdr*)((uchar*)elf + elf->e_phoff); ph = (Elf32_Phdr *)((uchar *)elf + elf->e_phoff);
eph = ph + elf->e_phnum; eph = ph + elf->e_phnum;
for(; ph < eph; ph++) { for (; ph < eph; ph++) {
pa = (uchar*)(ph->p_paddr & 0x0fffffff); pa = (uchar *)(ph->p_paddr & 0x0fffffff);
readseg(pa, ph->p_filesz, ph->p_offset); readseg(pa, ph->p_filesz, ph->p_offset);
if(ph->p_memsz > ph->p_filesz) if (ph->p_memsz > ph->p_filesz)
stosb(pa + ph->p_filesz, 0, ph->p_memsz - ph->p_filesz); stosb(pa + ph->p_filesz, 0, ph->p_memsz - ph->p_filesz);
} }
// Call the entry point from the ELF header. // Call the entry point from the ELF header.
// Does not return! // Does not return!
entry = (void(*)(void))(elf->e_entry & 0x0fffffff); entry = (void (*)(void))(elf->e_entry & 0x0fffffff);
entry(); entry();
} }
void void waitdisk(void) {
waitdisk(void)
{
// Wait for disk ready. // Wait for disk ready.
while((port_byte_in(0x1F7) & 0xC0) != 0x40) while ((port_byte_in(0x1F7) & 0xC0) != 0x40)
; ;
} }
static inline void static inline void insl(int port, void *addr, int cnt) {
insl(int port, void *addr, int cnt) asm volatile("cld; rep insl"
{ : "=D"(addr), "=c"(cnt)
asm volatile("cld; rep insl" : : "d"(port), "0"(addr), "1"(cnt)
"=D" (addr), "=c" (cnt) : : "memory", "cc");
"d" (port), "0" (addr), "1" (cnt) :
"memory", "cc");
} }
// Read a single sector at offset into dst. // Read a single sector at offset into dst.
void void readsect(void *dst, uint offset) {
readsect(void *dst, uint offset)
{
// Issue command. // Issue command.
waitdisk(); waitdisk();
port_byte_out(0x1F2, 1); // count = 1 port_byte_out(0x1F2, 1); // count = 1
@ -84,15 +76,13 @@ readsect(void *dst, uint offset)
// Read data. // Read data.
waitdisk(); waitdisk();
insl(0x1F0, dst, SECTSIZE/4); insl(0x1F0, dst, SECTSIZE / 4);
} }
// Read 'count' bytes at 'offset' from kernel into physical address 'pa'. // Read 'count' bytes at 'offset' from kernel into physical address 'pa'.
// Might copy more than asked. // Might copy more than asked.
void void readseg(uchar *pa, uint count, uint offset) {
readseg(uchar* pa, uint count, uint offset) uchar *epa;
{
uchar* epa;
epa = pa + count; epa = pa + count;
@ -105,6 +95,6 @@ readseg(uchar* pa, uint count, uint offset)
// If this is too slow, we could read lots of sectors at a time. // If this is too slow, we could read lots of sectors at a time.
// We'd write more to memory than asked, but it doesn't matter -- // We'd write more to memory than asked, but it doesn't matter --
// we load in increasing order. // we load in increasing order.
for(; pa < epa; pa += SECTSIZE, offset++) for (; pa < epa; pa += SECTSIZE, offset++)
readsect(pa, offset); readsect(pa, offset);
} }

View File

@ -1,15 +1,15 @@
#include "console.h" #include "console.h"
#include "drivers/vga.h"
#include "drivers/uart.h" #include "drivers/uart.h"
#include "drivers/vga.h"
void printk(const char* msg) { void printk(const char *msg) {
vga_print_string(msg); vga_print_string(msg);
for (; *msg; ++msg) { for (; *msg; ++msg) {
uartputc(*msg); uartputc(*msg);
} }
} }
void panic(const char* msg) { void panic(const char *msg) {
printk("\nKernel panic: "); printk("\nKernel panic: ");
printk(msg); printk(msg);
asm("cli"); asm("cli");

View File

@ -1,6 +1,10 @@
#pragma once #pragma once
void printk(const char* msg); void printk(const char *msg);
_Noreturn void panic(const char* msg); _Noreturn void panic(const char *msg);
#define check(expr) if (!(expr)) { panic("Assertion failed at " __FILE__ " : " " : " #expr "\n"); } #define check(expr) \
if (!(expr)) { \
panic("Assertion failed at " __FILE__ " : " \
" : " #expr "\n"); \
}

View File

@ -1,8 +1,8 @@
#include "gdt.h" #include "gdt.h"
#include "x86.h"
#include "memlayout.h"
#include "../lib/string.h" #include "../lib/string.h"
#include "kernel/mem.h" #include "kernel/mem.h"
#include "memlayout.h"
#include "x86.h"
#include <stdint.h> #include <stdint.h>
@ -22,27 +22,47 @@ struct seg_desc_t {
uint8_t base_31_24; // High bits of segment base address uint8_t base_31_24; // High bits of segment base address
} __attribute__((packed)); } __attribute__((packed));
#define SEG(type, base, lim, dpl) (struct seg_desc_t) \ #define SEG(type, base, lim, dpl) \
{ ((lim) >> 12) & 0xffff, (uint)(base) & 0xffff, \ (struct seg_desc_t){((lim) >> 12) & 0xffff, \
((uint)(base) >> 16) & 0xff, type, 1, dpl, 1, \ (uint)(base) & 0xffff, \
(uint)(lim) >> 28, 0, 0, 1, 1, (uint)(base) >> 24 } ((uint)(base) >> 16) & 0xff, \
#define SEG16(type, base, lim, dpl) (struct seg_desc_t) \ type, \
{ (lim) & 0xffff, (uint)(base) & 0xffff, \ 1, \
((uint)(base) >> 16) & 0xff, type, 1, dpl, 1, \ dpl, \
(uint)(lim) >> 16, 0, 0, 1, 0, (uint)(base) >> 24 } 1, \
(uint)(lim) >> 28, \
0, \
0, \
1, \
1, \
(uint)(base) >> 24}
#define SEG16(type, base, lim, dpl) \
(struct seg_desc_t){(lim) & 0xffff, \
(uint)(base) & 0xffff, \
((uint)(base) >> 16) & 0xff, \
type, \
1, \
dpl, \
1, \
(uint)(lim) >> 16, \
0, \
0, \
1, \
0, \
(uint)(base) >> 24}
struct seg_desc_t seg_desc[6]; struct seg_desc_t seg_desc[6];
void init_seg_desc() { void init_seg_desc() {
seg_desc[SEG_KCODE] = SEG(STA_X|STA_R, 0, 0xffffffff, 0); seg_desc[SEG_KCODE] = SEG(STA_X | STA_R, 0, 0xffffffff, 0);
seg_desc[SEG_KDATA] = SEG(STA_W, 0, 0xffffffff, 0); seg_desc[SEG_KDATA] = SEG(STA_W, 0, 0xffffffff, 0);
seg_desc[SEG_UCODE] = SEG(STA_X|STA_R, 0, 0xffffffff, DPL_USER); seg_desc[SEG_UCODE] = SEG(STA_X | STA_R, 0, 0xffffffff, DPL_USER);
seg_desc[SEG_UDATA] = SEG(STA_W, 0, 0xffffffff, DPL_USER); seg_desc[SEG_UDATA] = SEG(STA_W, 0, 0xffffffff, DPL_USER);
} }
struct gdt_desc_t { struct gdt_desc_t {
uint16_t size; uint16_t size;
void* ptr; void *ptr;
} __attribute__((packed)); } __attribute__((packed));
void load_gdt() { void load_gdt() {
@ -51,20 +71,20 @@ void load_gdt() {
struct gdt_desc_t gdt_desc; struct gdt_desc_t gdt_desc;
gdt_desc.size = sizeof(seg_desc) - 1; gdt_desc.size = sizeof(seg_desc) - 1;
gdt_desc.ptr = seg_desc; gdt_desc.ptr = seg_desc;
asm("lgdt %0": : "m"(gdt_desc)); asm("lgdt %0" : : "m"(gdt_desc));
} }
void switchuvm(struct taskstate *tss, void* esp, pde_t *pgdir) { void switchuvm(struct taskstate *tss, void *esp, pde_t *pgdir) {
memset(tss, 0, sizeof(*tss)); memset(tss, 0, sizeof(*tss));
seg_desc[SEG_TSS] = SEG16(STS_T32A, tss, sizeof(*tss)-1, 0); seg_desc[SEG_TSS] = SEG16(STS_T32A, tss, sizeof(*tss) - 1, 0);
seg_desc[SEG_TSS].s = 0; seg_desc[SEG_TSS].s = 0;
tss->ss0 = SEG_KDATA << 3; tss->ss0 = SEG_KDATA << 3;
tss->esp0 = (uint)esp; tss->esp0 = (uint)esp;
// setting IOPL=0 in eflags *and* iomb beyond the tss segment limit // setting IOPL=0 in eflags *and* iomb beyond the tss segment limit
// forbids I/O instructions (e.g., inb and outb) from user space // forbids I/O instructions (e.g., inb and outb) from user space
tss->iomb = (ushort) 0xFFFF; tss->iomb = (ushort)0xFFFF;
asm("ltr %0": : "r"((ushort)(SEG_TSS << 3))); asm("ltr %0" : : "r"((ushort)(SEG_TSS << 3)));
lcr3(V2P(pgdir)); lcr3(V2P(pgdir));
} }

View File

@ -19,9 +19,9 @@
#define SEG_UDATA 4 #define SEG_UDATA 4
#define SEG_TSS 5 #define SEG_TSS 5
#define SEG_ASM(type,base,lim) \ #define SEG_ASM(type, base, lim) \
.word (((lim) >> 12) & 0xffff), ((base) & 0xffff); \ .word(((lim) >> 12) & 0xffff), ((base) & 0xffff); \
.byte (((base) >> 16) & 0xff), (0x90 | (type)), \ .byte(((base) >> 16) & 0xff), (0x90 | (type)), \
(0xC0 | (((lim) >> 28) & 0xf)), (((base) >> 24) & 0xff) (0xC0 | (((lim) >> 28) & 0xf)), (((base) >> 24) & 0xff)
#define USER_BASE 0x400000 // 4 MB #define USER_BASE 0x400000 // 4 MB
@ -74,5 +74,5 @@ struct taskstate {
}; };
void load_gdt(); void load_gdt();
void switchuvm(struct taskstate *tss, void* esp, pde_t *pgdir); void switchuvm(struct taskstate *tss, void *esp, pde_t *pgdir);
#endif #endif

View File

@ -1,13 +1,13 @@
#include "isr.h"
#include "gdt.h"
#include "memlayout.h"
#include "../syscall.h"
#include "../proc.h"
#include "../drivers/keyboard.h"
#include "../drivers/port.h"
#include "../drivers/pit.h"
#include "../drivers/vga.h"
#include "../console.h" #include "../console.h"
#include "../drivers/keyboard.h"
#include "../drivers/pit.h"
#include "../drivers/port.h"
#include "../drivers/vga.h"
#include "../proc.h"
#include "../syscall.h"
#include "gdt.h"
#include "isr.h"
#include "memlayout.h"
enum { enum {
IDT_HANDLERS = 256, IDT_HANDLERS = 256,
@ -17,10 +17,10 @@ typedef struct {
uint16_t low_offset; uint16_t low_offset;
uint16_t selector; uint16_t selector;
uint8_t always0; uint8_t always0;
uint8_t type: 4; uint8_t type : 4;
uint8_t s: 1; uint8_t s : 1;
uint8_t dpl: 2; uint8_t dpl : 2;
uint8_t p: 1; uint8_t p : 1;
uint16_t high_offset; uint16_t high_offset;
} __attribute__((packed)) idt_gate_t; } __attribute__((packed)) idt_gate_t;
@ -56,7 +56,7 @@ void init_idt() {
set_idt_gate(T_SYSCALL, 1, default_handlers[T_SYSCALL], DPL_USER); set_idt_gate(T_SYSCALL, 1, default_handlers[T_SYSCALL], DPL_USER);
} }
const char * const exception_messages[] = { const char *const exception_messages[] = {
[0] = "Division By Zero", [0] = "Division By Zero",
[1] = "Debug", [1] = "Debug",
[2] = "Non Maskable Interrupt", [2] = "Non Maskable Interrupt",
@ -105,7 +105,7 @@ void trap(registers_t *r) {
} }
if (r->int_no < 32) { if (r->int_no < 32) {
const char* msg = "Reserved"; const char *msg = "Reserved";
if (r->int_no < ARRLEN(exception_messages)) { if (r->int_no < ARRLEN(exception_messages)) {
msg = exception_messages[r->int_no]; msg = exception_messages[r->int_no];
} }
@ -141,7 +141,7 @@ bool is_userspace_ptr_mapped(uint32_t ptr) {
return 0; return 0;
} }
pte_t *table = (pte_t*)P2V(PTE_ADDR(pde)); pte_t *table = (pte_t *)P2V(PTE_ADDR(pde));
pte_t pte = table[PTX(ptr)]; pte_t pte = table[PTX(ptr)];
if ((pte & (PTE_P | PTE_U)) != (PTE_P | PTE_U)) { if ((pte & (PTE_P | PTE_U)) != (PTE_P | PTE_U)) {
return 0; return 0;
@ -179,13 +179,13 @@ static bool is_userspace_cstr(uint32_t ptr) {
if (addr == 0 || !is_userspace_ptr_mapped(addr)) { if (addr == 0 || !is_userspace_ptr_mapped(addr)) {
return 0; return 0;
} }
if (*(const char*)addr == '\0') { if (*(const char *)addr == '\0') {
return (void*)ptr; return (void *)ptr;
} }
} }
} }
static _Noreturn void userspace_panic(const char* msg) { static _Noreturn void userspace_panic(const char *msg) {
if (!vga_is_text_mode()) { if (!vga_is_text_mode()) {
switch_to_text_mode(); switch_to_text_mode();
vga_clear_screen(); vga_clear_screen();
@ -198,7 +198,7 @@ static void handle_puts(uintptr_t s) {
if (!is_userspace_cstr(s)) { if (!is_userspace_cstr(s)) {
userspace_panic("SYS_puts panic: page fault\n"); userspace_panic("SYS_puts panic: page fault\n");
} }
printk((const char*)s); printk((const char *)s);
} }
static void require_text_mode_for_userspace_text_syscall() { static void require_text_mode_for_userspace_text_syscall() {
@ -219,8 +219,8 @@ static void handle_swap_frame(uintptr_t frame) {
userspace_panic("SYS_swap_frame panic: page fault\n"); userspace_panic("SYS_swap_frame panic: page fault\n");
} }
uint8_t *video = (uint8_t*)(KERNBASE + 0xA0000); uint8_t *video = (uint8_t *)(KERNBASE + 0xA0000);
uint8_t *user = (uint8_t*)frame; uint8_t *user = (uint8_t *)frame;
for (uint32_t i = 0; i < VGA_GRAPHICS_FRAME_SIZE; i++) { for (uint32_t i = 0; i < VGA_GRAPHICS_FRAME_SIZE; i++) {
video[i] = user[i]; video[i] = user[i];
} }
@ -253,7 +253,7 @@ static int handle_getc(void) {
return kbd_take_from_copy_buffer(); return kbd_take_from_copy_buffer();
} }
static void handle_syscall(registers_t* r) { static void handle_syscall(registers_t *r) {
switch (r->eax) { switch (r->eax) {
case SYS_exit: case SYS_exit:
if (r->ebx == 0) { if (r->ebx == 0) {
@ -335,7 +335,7 @@ static void init_pic() {
typedef struct { typedef struct {
uint16_t limit; uint16_t limit;
void* base; void *base;
} __attribute__((packed)) idt_register_t; } __attribute__((packed)) idt_register_t;
static idt_register_t idt_reg; static idt_register_t idt_reg;
@ -352,10 +352,6 @@ void load_idt() {
register_interrupt_handler(T_SYSCALL, handle_syscall); register_interrupt_handler(T_SYSCALL, handle_syscall);
} }
void cli() { void cli() { asm("cli"); }
asm("cli");
}
void sti() { void sti() { asm("sti"); }
asm("sti");
}

View File

@ -30,8 +30,10 @@ enum {
typedef struct { typedef struct {
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; /* Pushed by pusha. */ uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; /* Pushed by pusha. */
uint32_t gs, fs, es, ds; /* Data segment selector */ uint32_t gs, fs, es, ds; /* Data segment selector */
uint32_t int_no, err_code; /* Interrupt number and error code (if applicable) */ uint32_t int_no,
uint32_t eip, cs, eflags, useresp, ss; /* Pushed by the processor automatically */ err_code; /* Interrupt number and error code (if applicable) */
uint32_t eip, cs, eflags, useresp,
ss; /* Pushed by the processor automatically */
} registers_t; } registers_t;
void isr_install(); void isr_install();

View File

@ -4,8 +4,8 @@
#define PGSIZE 0x1000 #define PGSIZE 0x1000
#define PHYSTOP 0x8000000 // 128 Mib #define PHYSTOP 0x8000000 // 128 Mib
#define PGROUNDUP(sz) (((sz)+PGSIZE-1) & ~(PGSIZE-1)) #define PGROUNDUP(sz) (((sz) + PGSIZE - 1) & ~(PGSIZE - 1))
#define PGROUNDDOWN(a) (((a)) & ~((uintptr_t)(PGSIZE-1))) #define PGROUNDDOWN(a) (((a)) & ~((uintptr_t)(PGSIZE - 1)))
#define NPDENTRIES 1024 // # directory entries per page directory #define NPDENTRIES 1024 // # directory entries per page directory
#define NPTENTRIES 1024 // # PTEs per page table #define NPTENTRIES 1024 // # PTEs per page table
@ -17,8 +17,8 @@
#ifndef __ASSEMBLER__ #ifndef __ASSEMBLER__
#include <stdint.h> #include <stdint.h>
#define V2P(a) (((uintptr_t) (a)) - KERNBASE) #define V2P(a) (((uintptr_t)(a)) - KERNBASE)
#define P2V(a) ((void *)(((uintptr_t) (a)) + KERNBASE)) #define P2V(a) ((void *)(((uintptr_t)(a)) + KERNBASE))
// page directory index // page directory index
#define PDX(va) (((uintptr_t)(va) >> PDXSHIFT) & PXMASK) #define PDX(va) (((uintptr_t)(va) >> PDXSHIFT) & PXMASK)

View File

@ -1,20 +1,20 @@
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
static inline void static inline void stosl(void *addr, int data, int cnt) {
stosl(void *addr, int data, int cnt) asm volatile("cld; rep stosl"
{ :
asm volatile("cld; rep stosl" : : "D"(addr), "c"(cnt), "a"(data) : "memory"); : "D"(addr), "c"(cnt), "a"(data)
: "memory");
} }
static inline void static inline void stosb(void *addr, unsigned char data, int cnt) {
stosb(void *addr, unsigned char data, int cnt) asm volatile("cld; rep stosb"
{ :
asm volatile("cld; rep stosb" : : "D"(addr), "c"(cnt), "a"(data) : "memory"); : "D"(addr), "c"(cnt), "a"(data)
: "memory");
} }
static inline void static inline void lcr3(uint32_t val) {
lcr3(uint32_t val) asm volatile("mov %0,%%cr3" : : "r"(val));
{
asm volatile("mov %0,%%cr3" : : "r" (val));
} }

View File

@ -19,8 +19,8 @@
static void ATA_wait_BSY(); static void ATA_wait_BSY();
static void ATA_wait_RDY(); static void ATA_wait_RDY();
void read_sectors_ATA_PIO(void* target_address, uint32_t LBA, uint8_t sector_count) void read_sectors_ATA_PIO(void *target_address, uint32_t LBA,
{ uint8_t sector_count) {
ATA_wait_BSY(); ATA_wait_BSY();
port_byte_out(0x1F6, 0xE0 | ((LBA >> 24) & 0xF)); port_byte_out(0x1F6, 0xE0 | ((LBA >> 24) & 0xF));
port_byte_out(0x1F2, sector_count); port_byte_out(0x1F2, sector_count);
@ -31,8 +31,7 @@ void read_sectors_ATA_PIO(void* target_address, uint32_t LBA, uint8_t sector_cou
uint16_t *target = (uint16_t *)target_address; uint16_t *target = (uint16_t *)target_address;
for (int j = 0; j < sector_count; j++) for (int j = 0; j < sector_count; j++) {
{
ATA_wait_BSY(); ATA_wait_BSY();
ATA_wait_RDY(); ATA_wait_RDY();
for (int i = 0; i < 256; i++) for (int i = 0; i < 256; i++)
@ -41,8 +40,8 @@ void read_sectors_ATA_PIO(void* target_address, uint32_t LBA, uint8_t sector_cou
} }
} }
void write_sectors_ATA_PIO(uint32_t LBA, uint8_t sector_count, uint32_t *bytes) void write_sectors_ATA_PIO(uint32_t LBA, uint8_t sector_count,
{ uint32_t *bytes) {
ATA_wait_BSY(); ATA_wait_BSY();
port_byte_out(0x1F6, 0xE0 | ((LBA >> 24) & 0xF)); port_byte_out(0x1F6, 0xE0 | ((LBA >> 24) & 0xF));
port_byte_out(0x1F2, sector_count); port_byte_out(0x1F2, sector_count);
@ -51,12 +50,10 @@ void write_sectors_ATA_PIO(uint32_t LBA, uint8_t sector_count, uint32_t *bytes)
port_byte_out(0x1F5, (uint8_t)(LBA >> 16)); port_byte_out(0x1F5, (uint8_t)(LBA >> 16));
port_byte_out(0x1F7, 0x30); // Send the write command port_byte_out(0x1F7, 0x30); // Send the write command
for (int j = 0; j < sector_count; j++) for (int j = 0; j < sector_count; j++) {
{
ATA_wait_BSY(); ATA_wait_BSY();
ATA_wait_RDY(); ATA_wait_RDY();
for (int i = 0; i < 256; i++) for (int i = 0; i < 256; i++) {
{
port_long_out(0x1F0, bytes[i]); port_long_out(0x1F0, bytes[i]);
} }
} }

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
void read_sectors_ATA_PIO(void* target_address, uint32_t LBA, uint8_t sector_count); void read_sectors_ATA_PIO(void *target_address, uint32_t LBA,
uint8_t sector_count);

View File

@ -4,304 +4,420 @@
borrowed bits from http://files.osdev.org/mirrors/geezer/osd/graphics/modes.c borrowed bits from http://files.osdev.org/mirrors/geezer/osd/graphics/modes.c
*/ */
#include "vga.h"
#include "cpu/x86.h"
#include "cpu/memlayout.h" #include "cpu/memlayout.h"
#include "cpu/x86.h"
#include "port.h" #include "port.h"
#include "vga.h"
static vga_display_mode_t current_display_mode = VGA_DISPLAY_MODE_TEXT; static vga_display_mode_t current_display_mode = VGA_DISPLAY_MODE_TEXT;
static inline char inb(int port) { static inline char inb(int port) { return port_byte_in(port); }
return port_byte_in(port);
}
static inline void outb(int port, char data) { static inline void outb(int port, char data) { port_byte_out(port, data); }
port_byte_out(port, data);
}
/* This is the standard 256-color palette, in 0xRRGGBB format. Of course the VGA registers want 6 bits, not 8 per channel, so we do a bit /* This is the standard 256-color palette, in 0xRRGGBB format. Of course the VGA
of shifting when setting the registers: much easier than writing down the values in 6-bit form! registers want 6 bits, not 8 per channel, so we do a bit of shifting when
setting the registers: much easier than writing down the values in 6-bit
form!
*/ */
int vga256_24bit[256] = { 0x000000, 0x0000a8, 0x00a800, 0x00a8a8, 0xa80000, 0xa800a8, 0xa85400, 0xa8a8a8, 0x545454, 0x5454fc, 0x54fc54, 0x54fcfc, 0xfc5454, 0xfc54fc, 0xfcfc54, 0xfcfcfc, 0x000000, 0x141414, 0x202020, 0x2c2c2c, 0x383838, 0x444444, 0x505050, 0x606060, 0x707070, 0x808080, 0x909090, 0xa0a0a0, 0xb4b4b4, 0xc8c8c8, 0xe0e0e0, 0xfcfcfc, 0x0000fc, 0x4000fc, 0x7c00fc, 0xbc00fc, 0xfc00fc, 0xfc00bc, 0xfc007c, 0xfc0040, 0xfc0000, 0xfc4000, 0xfc7c00, 0xfcbc00, 0xfcfc00, 0xbcfc00, 0x7cfc00, 0x40fc00, 0x00fc00, 0x00fc40, 0x00fc7c, 0x00fcbc, 0x00fcfc, 0x00bcfc, 0x007cfc, 0x0040fc, 0x7c7cfc, 0x9c7cfc, 0xbc7cfc, 0xdc7cfc, 0xfc7cfc, 0xfc7cdc, 0xfc7cbc, 0xfc7c9c, 0xfc7c7c, 0xfc9c7c, 0xfcbc7c, 0xfcdc7c, 0xfcfc7c, 0xdcfc7c, 0xbcfc7c, 0x9cfc7c, 0x7cfc7c, 0x7cfc9c, 0x7cfcbc, 0x7cfcdc, 0x7cfcfc, 0x7cdcfc, 0x7cbcfc, 0x7c9cfc, 0xb4b4fc, 0xc4b4fc, 0xd8b4fc, 0xe8b4fc, 0xfcb4fc, 0xfcb4e8, 0xfcb4d8, 0xfcb4c4, 0xfcb4b4, 0xfcc4b4, 0xfcd8b4, 0xfce8b4, 0xfcfcb4, 0xe8fcb4, 0xd8fcb4, 0xc4fcb4, 0xb4fcb4, 0xb4fcc4, 0xb4fcd8, 0xb4fce8, 0xb4fcfc, 0xb4e8fc, 0xb4d8fc, 0xb4c4fc, 0x000070, 0x1c0070, 0x380070, 0x540070, 0x700070, 0x700054, 0x700038, 0x70001c, 0x700000, 0x701c00, 0x703800, 0x705400, 0x707000, 0x547000, 0x387000, 0x1c7000, 0x007000, 0x00701c, 0x007038, 0x007054, 0x007070, 0x005470, 0x003870, 0x001c70, 0x383870, 0x443870, 0x543870, 0x603870, 0x703870, 0x703860, 0x703854, 0x703844, 0x703838, 0x704438, 0x705438, 0x706038, 0x707038, 0x607038, 0x547038, 0x447038, 0x387038, 0x387044, 0x387054, 0x387060, 0x387070, 0x386070, 0x385470, 0x384470, 0x505070, 0x585070, 0x605070, 0x685070, 0x705070, 0x705068, 0x705060, 0x705058, 0x705050, 0x705850, 0x706050, 0x706850, 0x707050, 0x687050, 0x607050, 0x587050, 0x507050, 0x507058, 0x507060, 0x507068, 0x507070, 0x506870, 0x506070, 0x505870, 0x000040, 0x100040, 0x200040, 0x300040, 0x400040, 0x400030, 0x400020, 0x400010, 0x400000, 0x401000, 0x402000, 0x403000, 0x404000, 0x304000, 0x204000, 0x104000, 0x004000, 0x004010, 0x004020, 0x004030, 0x004040, 0x003040, 0x002040, 0x001040, 0x202040, 0x282040, 0x302040, 0x382040, 0x402040, 0x402038, 0x402030, 0x402028, 0x402020, 0x402820, 0x403020, 0x403820, 0x404020, 0x384020, 0x304020, 0x284020, 0x204020, 0x204028, 0x204030, 0x204038, 0x204040, 0x203840, 0x203040, 0x202840, 0x2c2c40, 0x302c40, 0x342c40, 0x3c2c40, 0x402c40, 0x402c3c, 0x402c34, 0x402c30, 0x402c2c, 0x40302c, 0x40342c, 0x403c2c, 0x40402c, 0x3c402c, 0x34402c, 0x30402c, 0x2c402c, 0x2c4030, 0x2c4034, 0x2c403c, 0x2c4040, 0x2c3c40, 0x2c3440, 0x2c3040, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000 }; int vga256_24bit[256] = {
0x000000, 0x0000a8, 0x00a800, 0x00a8a8, 0xa80000, 0xa800a8, 0xa85400,
0xa8a8a8, 0x545454, 0x5454fc, 0x54fc54, 0x54fcfc, 0xfc5454, 0xfc54fc,
/* VGA fonts aren't actually stored in the graphics card, they disappear when you change modes, 0xfcfc54, 0xfcfcfc, 0x000000, 0x141414, 0x202020, 0x2c2c2c, 0x383838,
so we have to keep one here to restore when we switch back to text mode. */ 0x444444, 0x505050, 0x606060, 0x707070, 0x808080, 0x909090, 0xa0a0a0,
static unsigned char g_8x16_font[4096] = 0xb4b4b4, 0xc8c8c8, 0xe0e0e0, 0xfcfcfc, 0x0000fc, 0x4000fc, 0x7c00fc,
{ 0xbc00fc, 0xfc00fc, 0xfc00bc, 0xfc007c, 0xfc0040, 0xfc0000, 0xfc4000,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc7c00, 0xfcbc00, 0xfcfc00, 0xbcfc00, 0x7cfc00, 0x40fc00, 0x00fc00,
0x00, 0x00, 0x7E, 0x81, 0xA5, 0x81, 0x81, 0xBD, 0x99, 0x81, 0x81, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00fc40, 0x00fc7c, 0x00fcbc, 0x00fcfc, 0x00bcfc, 0x007cfc, 0x0040fc,
0x00, 0x00, 0x7E, 0xFF, 0xDB, 0xFF, 0xFF, 0xC3, 0xE7, 0xFF, 0xFF, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x7c7cfc, 0x9c7cfc, 0xbc7cfc, 0xdc7cfc, 0xfc7cfc, 0xfc7cdc, 0xfc7cbc,
0x00, 0x00, 0x00, 0x00, 0x6C, 0xFE, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0xfc7c9c, 0xfc7c7c, 0xfc9c7c, 0xfcbc7c, 0xfcdc7c, 0xfcfc7c, 0xdcfc7c,
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbcfc7c, 0x9cfc7c, 0x7cfc7c, 0x7cfc9c, 0x7cfcbc, 0x7cfcdc, 0x7cfcfc,
0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0xE7, 0xE7, 0xE7, 0x99, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x7cdcfc, 0x7cbcfc, 0x7c9cfc, 0xb4b4fc, 0xc4b4fc, 0xd8b4fc, 0xe8b4fc,
0x00, 0x00, 0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x7E, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0xfcb4fc, 0xfcb4e8, 0xfcb4d8, 0xfcb4c4, 0xfcb4b4, 0xfcc4b4, 0xfcd8b4,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfce8b4, 0xfcfcb4, 0xe8fcb4, 0xd8fcb4, 0xc4fcb4, 0xb4fcb4, 0xb4fcc4,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xb4fcd8, 0xb4fce8, 0xb4fcfc, 0xb4e8fc, 0xb4d8fc, 0xb4c4fc, 0x000070,
0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c0070, 0x380070, 0x540070, 0x700070, 0x700054, 0x700038, 0x70001c,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x700000, 0x701c00, 0x703800, 0x705400, 0x707000, 0x547000, 0x387000,
0x00, 0x00, 0x1E, 0x0E, 0x1A, 0x32, 0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00, 0x1c7000, 0x007000, 0x00701c, 0x007038, 0x007054, 0x007070, 0x005470,
0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x003870, 0x001c70, 0x383870, 0x443870, 0x543870, 0x603870, 0x703870,
0x00, 0x00, 0x3F, 0x33, 0x3F, 0x30, 0x30, 0x30, 0x30, 0x70, 0xF0, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x703860, 0x703854, 0x703844, 0x703838, 0x704438, 0x705438, 0x706038,
0x00, 0x00, 0x7F, 0x63, 0x7F, 0x63, 0x63, 0x63, 0x63, 0x67, 0xE7, 0xE6, 0xC0, 0x00, 0x00, 0x00, 0x707038, 0x607038, 0x547038, 0x447038, 0x387038, 0x387044, 0x387054,
0x00, 0x00, 0x00, 0x18, 0x18, 0xDB, 0x3C, 0xE7, 0x3C, 0xDB, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x387060, 0x387070, 0x386070, 0x385470, 0x384470, 0x505070, 0x585070,
0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFE, 0xF8, 0xF0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x605070, 0x685070, 0x705070, 0x705068, 0x705060, 0x705058, 0x705050,
0x00, 0x02, 0x06, 0x0E, 0x1E, 0x3E, 0xFE, 0x3E, 0x1E, 0x0E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x705850, 0x706050, 0x706850, 0x707050, 0x687050, 0x607050, 0x587050,
0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x507050, 0x507058, 0x507060, 0x507068, 0x507070, 0x506870, 0x506070,
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x505870, 0x000040, 0x100040, 0x200040, 0x300040, 0x400040, 0x400030,
0x00, 0x00, 0x7F, 0xDB, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x400020, 0x400010, 0x400000, 0x401000, 0x402000, 0x403000, 0x404000,
0x00, 0x7C, 0xC6, 0x60, 0x38, 0x6C, 0xC6, 0xC6, 0x6C, 0x38, 0x0C, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x304000, 0x204000, 0x104000, 0x004000, 0x004010, 0x004020, 0x004030,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x004040, 0x003040, 0x002040, 0x001040, 0x202040, 0x282040, 0x302040,
0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x7E, 0x00, 0x00, 0x00, 0x382040, 0x402040, 0x402038, 0x402030, 0x402028, 0x402020, 0x402820,
0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x403020, 0x403820, 0x404020, 0x384020, 0x304020, 0x284020, 0x204020,
0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x204028, 0x204030, 0x204038, 0x204040, 0x203840, 0x203040, 0x202840,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c2c40, 0x302c40, 0x342c40, 0x3c2c40, 0x402c40, 0x402c3c, 0x402c34,
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x402c30, 0x402c2c, 0x40302c, 0x40342c, 0x403c2c, 0x40402c, 0x3c402c,
0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34402c, 0x30402c, 0x2c402c, 0x2c4030, 0x2c4034, 0x2c403c, 0x2c4040,
0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6C, 0xFE, 0x6C, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c3c40, 0x2c3440, 0x2c3040, 0x000000, 0x000000, 0x000000, 0x000000,
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7C, 0x7C, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x000000, 0x000000, 0x000000, 0x000000};
0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x7C, 0x7C, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x3C, 0x3C, 0x3C, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x6C, 0x6C, 0xFE, 0x6C, 0x6C, 0x6C, 0xFE, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x7C, 0xC6, 0xC2, 0xC0, 0x7C, 0x06, 0x86, 0xC6, 0x7C, 0x18, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xC2, 0xC6, 0x0C, 0x18, 0x30, 0x60, 0xC6, 0x86, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xCE, 0xD6, 0xD6, 0xE6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0xC6, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06, 0x3C, 0x06, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0C, 0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x0C, 0x0C, 0x1E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFE, 0xC0, 0xC0, 0xC0, 0xFC, 0x0E, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x38, 0x60, 0xC0, 0xC0, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFE, 0xC6, 0x06, 0x06, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x06, 0x0C, 0x78, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x0C, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xDE, 0xDE, 0xDE, 0xDC, 0xC0, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xC0, 0xC0, 0xC2, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xDE, 0xC6, 0xC6, 0x66, 0x3A, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xE6, 0x66, 0x6C, 0x6C, 0x78, 0x78, 0x6C, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xF0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xC6, 0xE6, 0xF6, 0xFE, 0xDE, 0xCE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xDE, 0x7C, 0x0C, 0x0E, 0x00, 0x00,
0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x60, 0x38, 0x0C, 0x06, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7E, 0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xD6, 0xFE, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xC6, 0xC6, 0x6C, 0x6C, 0x38, 0x38, 0x6C, 0x6C, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFE, 0xC6, 0x86, 0x0C, 0x18, 0x30, 0x60, 0xC2, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C, 0x00, 0x00, 0x00, 0x00,
0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xE0, 0x60, 0x60, 0x78, 0x6C, 0x66, 0x66, 0x66, 0x66, 0xDC, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1C, 0x0C, 0x0C, 0x3C, 0x6C, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x38, 0x6C, 0x64, 0x60, 0xF0, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xCC, 0x78, 0x00,
0x00, 0x00, 0xE0, 0x60, 0x60, 0x6C, 0x76, 0x66, 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x06, 0x06, 0x00, 0x0E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3C, 0x00,
0x00, 0x00, 0xE0, 0x60, 0x60, 0x66, 0x6C, 0x78, 0x78, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xEC, 0xFE, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0x0C, 0x1E, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x76, 0x62, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x60, 0x38, 0x0C, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x10, 0x30, 0x30, 0xFC, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xD6, 0xD6, 0xFE, 0x6C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x38, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x0C, 0xF8, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xCC, 0x18, 0x30, 0x60, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0E, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0E, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xC0, 0xC2, 0x66, 0x3C, 0x0C, 0x06, 0x7C, 0x00, 0x00,
0x00, 0x00, 0xCC, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0C, 0x18, 0x30, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0x38, 0x6C, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xCC, 0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x38, 0x6C, 0x38, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x60, 0x60, 0x66, 0x3C, 0x0C, 0x06, 0x3C, 0x00, 0x00, 0x00,
0x00, 0x10, 0x38, 0x6C, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xC6, 0xC6, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x60, 0x30, 0x18, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x66, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x18, 0x3C, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
0x00, 0xC6, 0xC6, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x38, 0x6C, 0x38, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x18, 0x30, 0x60, 0x00, 0xFE, 0x66, 0x60, 0x7C, 0x60, 0x60, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x76, 0x36, 0x7E, 0xD8, 0xD8, 0x6E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3E, 0x6C, 0xCC, 0xCC, 0xFE, 0xCC, 0xCC, 0xCC, 0xCC, 0xCE, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0x38, 0x6C, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xC6, 0xC6, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x60, 0x30, 0x18, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x30, 0x78, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x60, 0x30, 0x18, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xC6, 0xC6, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x0C, 0x78, 0x00,
0x00, 0xC6, 0xC6, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00,
0x00, 0xC6, 0xC6, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x18, 0x18, 0x3C, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3C, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x38, 0x6C, 0x64, 0x60, 0xF0, 0x60, 0x60, 0x60, 0x60, 0xE6, 0xFC, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18, 0x7E, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0xF8, 0xCC, 0xCC, 0xF8, 0xC4, 0xCC, 0xDE, 0xCC, 0xCC, 0xCC, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0E, 0x1B, 0x18, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0x70, 0x00, 0x00,
0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0C, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x18, 0x30, 0x60, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x18, 0x30, 0x60, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x76, 0xDC, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
0x76, 0xDC, 0x00, 0xC6, 0xE6, 0xF6, 0xFE, 0xDE, 0xCE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xC0, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xC0, 0xC0, 0xC2, 0xC6, 0xCC, 0x18, 0x30, 0x60, 0xCE, 0x93, 0x06, 0x0C, 0x1F, 0x00, 0x00,
0x00, 0xC0, 0xC0, 0xC2, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xCE, 0x9A, 0x3F, 0x06, 0x0F, 0x00, 0x00,
0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3C, 0x3C, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x06, 0xF6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x36, 0x36, 0x36, 0x36, 0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0xD8, 0xD8, 0xD8, 0xDC, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xC6, 0xFC, 0xC6, 0xC6, 0xFC, 0xC0, 0xC0, 0xC0, 0x00, 0x00,
0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x80, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFE, 0xC6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0x70, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xC0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7E, 0x18, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, 0x6C, 0x6C, 0x6C, 0xEE, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1E, 0x30, 0x18, 0x0C, 0x3E, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0xDB, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x06, 0x7E, 0xCF, 0xDB, 0xF3, 0x7E, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1C, 0x30, 0x60, 0x60, 0x7C, 0x60, 0x60, 0x60, 0x30, 0x1C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0xD8, 0x70, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0x00, 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0F, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x6C, 0x3C, 0x1C, 0x00, 0x00, 0x00, 0x00,
0x00, 0xD8, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x70, 0x98, 0x30, 0x60, 0xC8, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
/* VGA fonts aren't actually stored in the graphics card, they disappear when
you change modes, so we have to keep one here to restore when we switch back
to text mode. */
static unsigned char g_8x16_font[4096] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x81, 0xA5, 0x81, 0x81, 0xBD,
0x99, 0x81, 0x81, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xFF,
0xDB, 0xFF, 0xFF, 0xC3, 0xE7, 0xFF, 0xFF, 0x7E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x6C, 0xFE, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7C, 0xFE,
0x7C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
0x3C, 0x3C, 0xE7, 0xE7, 0xE7, 0x99, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x7E, 0x18, 0x18, 0x3C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C,
0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0x99, 0xBD,
0xBD, 0x99, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x1E, 0x0E,
0x1A, 0x32, 0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x33, 0x3F, 0x30, 0x30, 0x30,
0x30, 0x70, 0xF0, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x63,
0x7F, 0x63, 0x63, 0x63, 0x63, 0x67, 0xE7, 0xE6, 0xC0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x18, 0x18, 0xDB, 0x3C, 0xE7, 0x3C, 0xDB, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFE, 0xF8,
0xF0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0E,
0x1E, 0x3E, 0xFE, 0x3E, 0x1E, 0x0E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xDB,
0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00, 0x00, 0x00,
0x00, 0x7C, 0xC6, 0x60, 0x38, 0x6C, 0xC6, 0xC6, 0x6C, 0x38, 0x0C, 0xC6,
0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFE, 0xFE, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C,
0x7E, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x7E, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x7E, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0,
0xC0, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x28, 0x6C, 0xFE, 0x6C, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7C, 0x7C, 0xFE, 0xFE, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x7C, 0x7C,
0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x3C, 0x3C, 0x3C, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C,
0x6C, 0xFE, 0x6C, 0x6C, 0x6C, 0xFE, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x7C, 0xC6, 0xC2, 0xC0, 0x7C, 0x06, 0x86, 0xC6, 0x7C, 0x18,
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC2, 0xC6, 0x0C, 0x18,
0x30, 0x60, 0xC6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6C,
0x6C, 0x38, 0x76, 0xDC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18,
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E,
0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xCE, 0xD6, 0xD6, 0xE6, 0xC6, 0xC6, 0x7C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6,
0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06, 0x3C, 0x06, 0x06, 0x06, 0xC6, 0x7C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x1C, 0x3C, 0x6C, 0xCC, 0xFE,
0x0C, 0x0C, 0x0C, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC0,
0xC0, 0xC0, 0xFC, 0x0E, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x38, 0x60, 0xC0, 0xC0, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC6, 0x06, 0x06, 0x0C, 0x18,
0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6,
0xC6, 0xC6, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x06, 0x0C, 0x78,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0x06,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00,
0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x0C, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xDE, 0xDE,
0xDE, 0xDC, 0xC0, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38,
0x6C, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xC0,
0xC0, 0xC2, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x6C,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68,
0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66,
0xC2, 0xC0, 0xC0, 0xDE, 0xC6, 0xC6, 0x66, 0x3A, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xE6, 0x66, 0x6C, 0x6C, 0x78, 0x78, 0x6C, 0x66, 0x66, 0xE6,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x60, 0x60, 0x60, 0x60, 0x60,
0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xEE,
0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xC6, 0xE6, 0xF6, 0xFE, 0xDE, 0xCE, 0xC6, 0xC6, 0xC6, 0xC6,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0xC6,
0xC6, 0xC6, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x66,
0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xDE, 0x7C,
0x0C, 0x0E, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x6C,
0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6,
0xC6, 0x60, 0x38, 0x0C, 0x06, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7E, 0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6,
0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6,
0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xD6, 0xFE, 0x6C, 0x6C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0x6C, 0x6C, 0x38, 0x38,
0x6C, 0x6C, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66,
0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFE, 0xC6, 0x86, 0x0C, 0x18, 0x30, 0x60, 0xC2, 0xC6, 0xFE,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C,
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x7C,
0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x60,
0x60, 0x78, 0x6C, 0x66, 0x66, 0x66, 0x66, 0xDC, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC0, 0xC0, 0xC6, 0x7C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x0C, 0x0C, 0x3C, 0x6C, 0xCC,
0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x38, 0x6C, 0x64, 0x60, 0xF0, 0x60, 0x60, 0x60, 0x60, 0xF0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xCC, 0xCC,
0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xCC, 0x78, 0x00, 0x00, 0x00, 0xE0, 0x60,
0x60, 0x6C, 0x76, 0x66, 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0E, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x00, 0xE0, 0x60,
0x60, 0x66, 0x6C, 0x78, 0x78, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEC, 0xFE, 0xD6,
0xD6, 0xD6, 0xD6, 0xD6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66,
0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x76, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0x0C, 0x1E, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x76, 0x62, 0x60, 0x60, 0x60, 0xF0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x60,
0x38, 0x0C, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30,
0x30, 0xFC, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66,
0x66, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xC6, 0xC6, 0xC6, 0xD6, 0xD6, 0xFE, 0x6C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x38, 0x38, 0x6C, 0xC6,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6,
0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x0C, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xFE, 0xCC, 0x18, 0x30, 0x60, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0E, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0E,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18,
0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18,
0x18, 0x18, 0x0E, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6,
0xC6, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66,
0xC2, 0xC0, 0xC0, 0xC0, 0xC2, 0x66, 0x3C, 0x0C, 0x06, 0x7C, 0x00, 0x00,
0x00, 0x00, 0xCC, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x00, 0x7C, 0xC6, 0xFE,
0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6C,
0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xCC, 0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76,
0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0C, 0x7C,
0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6C, 0x38,
0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x60, 0x60, 0x66, 0x3C, 0x0C, 0x06,
0x3C, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6C, 0x00, 0x7C, 0xC6, 0xFE,
0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6,
0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x60, 0x30, 0x18, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC0, 0xC6, 0x7C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x38, 0x18, 0x18,
0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x66,
0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C,
0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0x10, 0x38, 0x6C, 0xC6, 0xC6,
0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6C, 0x38, 0x00,
0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x18, 0x30, 0x60, 0x00, 0xFE, 0x66, 0x60, 0x7C, 0x60, 0x60, 0x66, 0xFE,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x76, 0x36,
0x7E, 0xD8, 0xD8, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x6C,
0xCC, 0xCC, 0xFE, 0xCC, 0xCC, 0xCC, 0xCC, 0xCE, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0x38, 0x6C, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0x00, 0x7C, 0xC6, 0xC6,
0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18,
0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x30, 0x78, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76,
0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xCC, 0xCC, 0xCC,
0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6,
0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x0C, 0x78, 0x00,
0x00, 0xC6, 0xC6, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x38,
0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0x00, 0xC6, 0xC6, 0xC6, 0xC6,
0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x3C,
0x66, 0x60, 0x60, 0x60, 0x66, 0x3C, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x38, 0x6C, 0x64, 0x60, 0xF0, 0x60, 0x60, 0x60, 0x60, 0xE6, 0xFC,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18,
0x7E, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xCC, 0xCC,
0xF8, 0xC4, 0xCC, 0xDE, 0xCC, 0xCC, 0xCC, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0E, 0x1B, 0x18, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18,
0xD8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0C, 0x7C,
0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x18, 0x30,
0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x18, 0x30, 0x60, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xCC, 0xCC, 0xCC,
0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC,
0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
0x76, 0xDC, 0x00, 0xC6, 0xE6, 0xF6, 0xFE, 0xDE, 0xCE, 0xC6, 0xC6, 0xC6,
0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6C, 0x6C,
0x38, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xC0, 0xC6, 0xC6, 0x7C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC0,
0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFE, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xC0, 0xC0, 0xC2, 0xC6, 0xCC, 0x18, 0x30, 0x60, 0xCE, 0x93, 0x06,
0x0C, 0x1F, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC2, 0xC6, 0xCC, 0x18, 0x30,
0x66, 0xCE, 0x9A, 0x3F, 0x06, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
0x00, 0x18, 0x18, 0x18, 0x3C, 0x3C, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x66, 0x33,
0x66, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44,
0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
0x55, 0xAA, 0x55, 0xAA, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77,
0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0xF8,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0xF8,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x06, 0xF6,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0xF8,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xF7, 0x00, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36,
0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3F,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0,
0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x76, 0xDC, 0xD8, 0xD8, 0xD8, 0xDC, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xC6, 0xFC, 0xC6, 0xC6, 0xFC, 0xC0,
0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC0, 0xC0, 0xC0,
0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFE, 0xC6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xC6, 0xFE,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xD8, 0xD8,
0xD8, 0xD8, 0xD8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xC0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x18, 0x3C, 0x66, 0x66,
0x66, 0x3C, 0x18, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
0x6C, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, 0x6C, 0x6C, 0x6C, 0xEE,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x30, 0x18, 0x0C, 0x3E, 0x66,
0x66, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x7E, 0xDB, 0xDB, 0xDB, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x06, 0x7E, 0xCF, 0xDB, 0xF3, 0x7E, 0x60, 0xC0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x30, 0x60, 0x60, 0x7C, 0x60,
0x60, 0x60, 0x30, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C,
0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18,
0x18, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0x00, 0x7E,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0xD8, 0x70, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x18, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0x00,
0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6C, 0x6C,
0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x6C, 0x3C, 0x1C, 0x00, 0x00, 0x00, 0x00,
0x00, 0xD8, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x98, 0x30, 0x60, 0xC8, 0xF8, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00};
#define VGA 0x3C0 #define VGA 0x3C0
void write3C0(unsigned char index, unsigned char value) { void write3C0(unsigned char index, unsigned char value) {
// get VGA port into index mode // get VGA port into index mode
inb(VGA+0x1A); inb(VGA + 0x1A);
outb(0x3C0, index); outb(0x3C0, index);
outb(0x3C0, value); outb(0x3C0, value);
} }
void write3C2(unsigned char value) { void write3C2(unsigned char value) { outb(0x3C2, value); }
outb(0x3C2, value);
}
void write3C4(unsigned char index, unsigned char value) { void write3C4(unsigned char index, unsigned char value) {
outb(0x3C4, index); outb(0x3C4, index);
@ -318,9 +434,7 @@ void write3D4(unsigned char index, unsigned char value) {
outb(0x3D5, value); outb(0x3D5, value);
} }
void write3C6(unsigned char value) { void write3C6(unsigned char value) { outb(0x3C6, value); }
outb(0x3C6,value);
}
void vgaSetPalette(int index, int r, int g, int b) { void vgaSetPalette(int index, int r, int g, int b) {
outb(0x3C8, index); outb(0x3C8, index);
@ -330,12 +444,10 @@ void vgaSetPalette(int index, int r, int g, int b) {
} }
void setdefaultVGApalette() { void setdefaultVGApalette() {
for(int index=0;index<256;index++) { for (int index = 0; index < 256; index++) {
int value = vga256_24bit[index]; int value = vga256_24bit[index];
vgaSetPalette(index, vgaSetPalette(index, (value >> 18) & 0x3f, (value >> 10) & 0x3f,
(value>>18)&0x3f, (value >> 2) & 0x3f);
(value>>10)&0x3f,
(value>>2)&0x3f);
} }
} }
@ -354,7 +466,6 @@ void vgaMode13() {
// see http://www.osdever.net/FreeVGA/vga/crtcreg.htm#11 // see http://www.osdever.net/FreeVGA/vga/crtcreg.htm#11
write3D4(0x11, 0x0E); write3D4(0x11, 0x0E);
write3D4(0x00, 0x5F); write3D4(0x00, 0x5F);
write3D4(0x01, 0x4F); write3D4(0x01, 0x4F);
write3D4(0x02, 0x50); write3D4(0x02, 0x50);
@ -409,7 +520,7 @@ void vgaMode13() {
write3C0(0x14, 0x00); write3C0(0x14, 0x00);
// enable display?? // enable display??
inb(VGA+0x1A); inb(VGA + 0x1A);
outb(0x3C0, 0x20); outb(0x3C0, 0x20);
setdefaultVGApalette(); setdefaultVGApalette();
@ -439,7 +550,6 @@ void vgaMode3() {
write3D4(0x06, 0xBF); write3D4(0x06, 0xBF);
write3D4(0x07, 0x1F); write3D4(0x07, 0x1F);
write3D4(0x08, 0x00); write3D4(0x08, 0x00);
write3D4(0x09, 0x4F); write3D4(0x09, 0x4F);
write3D4(0x0A, 0x20); write3D4(0x0A, 0x20);
@ -469,7 +579,7 @@ void vgaMode3() {
write3CE(0x07, 0x00); write3CE(0x07, 0x00);
write3CE(0x08, 0xFF); write3CE(0x08, 0xFF);
inb(VGA+0x1A); inb(VGA + 0x1A);
write3C0(0x00, 0x00); write3C0(0x00, 0x00);
write3C0(0x01, 0x01); write3C0(0x01, 0x01);
@ -493,7 +603,6 @@ void vgaMode3() {
write3C0(0x13, 0x08); write3C0(0x13, 0x08);
write3C0(0x14, 0x00); write3C0(0x14, 0x00);
write3C4(0x00, 0x01); // seq reset write3C4(0x00, 0x01); // seq reset
write3C4(0x02, 0x04); // image plane 2 write3C4(0x02, 0x04); // image plane 2
write3C4(0x04, 0x07); // disable odd/even in sequencer write3C4(0x04, 0x07); // disable odd/even in sequencer
@ -504,9 +613,9 @@ void vgaMode3() {
write3CE(0x05, 0x00); // odd/even disabled write3CE(0x05, 0x00); // odd/even disabled
write3CE(0x06, 0x00); // memory map select A0000h-BFFFFh write3CE(0x06, 0x00); // memory map select A0000h-BFFFFh
for(int i=0;i<4096;i+=16) for (int i = 0; i < 4096; i += 16)
for(int j=0;j<16;j++) for (int j = 0; j < 16; j++)
((char*)KERNBASE+0xa0000)[2*i+j] = g_8x16_font[i+j]; ((char *)KERNBASE + 0xa0000)[2 * i + j] = g_8x16_font[i + j];
write3C4(0x00, 0x01); // seq reset write3C4(0x00, 0x01); // seq reset
write3C4(0x02, 0x03); // image planes 0 and 1 write3C4(0x02, 0x03); // image planes 0 and 1
@ -520,22 +629,16 @@ void vgaMode3() {
write3CE(0x05, 0x10); // odd/even enable write3CE(0x05, 0x10); // odd/even enable
write3CE(0x06, 0x0E); // memory map select: 0xb8000 write3CE(0x06, 0x0E); // memory map select: 0xb8000
inb(VGA+0x1A); inb(VGA + 0x1A);
outb(0x3C0, 0x20); outb(0x3C0, 0x20);
current_display_mode = VGA_DISPLAY_MODE_TEXT; current_display_mode = VGA_DISPLAY_MODE_TEXT;
} }
void switch_to_graphics_mode() { void switch_to_graphics_mode() { vgaMode13(); }
vgaMode13();
}
void switch_to_text_mode() { void switch_to_text_mode() { vgaMode3(); }
vgaMode3();
}
vga_display_mode_t vga_get_display_mode() { vga_display_mode_t vga_get_display_mode() { return current_display_mode; }
return current_display_mode;
}
bool vga_is_text_mode() { bool vga_is_text_mode() {
return current_display_mode == VGA_DISPLAY_MODE_TEXT; return current_display_mode == VGA_DISPLAY_MODE_TEXT;

View File

@ -1,9 +1,9 @@
#include "keyboard.h" #include "keyboard.h"
#include "console.h"
#include "cpu/isr.h" #include "cpu/isr.h"
#include "cpu/memlayout.h" #include "cpu/memlayout.h"
#include "console.h"
#include "port.h"
#include "kernel/mem.h" #include "kernel/mem.h"
#include "port.h"
keyboard_interrupt_shared_t kbd_state_shrd; keyboard_interrupt_shared_t kbd_state_shrd;
@ -14,12 +14,11 @@ static void kbd_interrupt_handler(registers_t *r) {
} }
} }
void init_keyboard() { void init_keyboard() {
kbd_state_shrd.len = 0; kbd_state_shrd.len = 0;
kbd_state_shrd.buf = (uint8_t*)kalloc(); kbd_state_shrd.buf = (uint8_t *)kalloc();
kbd_state_shrd.copy_len = 0; kbd_state_shrd.copy_len = 0;
kbd_state_shrd.copy_buf = (uint8_t*)kalloc(); kbd_state_shrd.copy_buf = (uint8_t *)kalloc();
/* 128/8 actually we need only 16 bytes for that */ /* 128/8 actually we need only 16 bytes for that */
memset(kbd_state_shrd.copy_pressed, 0, 16); memset(kbd_state_shrd.copy_pressed, 0, 16);
@ -32,16 +31,17 @@ uint8_t kbd_take_from_copy_buffer() {
uint8_t key_event_code = kbd_state_shrd.copy_buf[--kbd_state_shrd.copy_len]; uint8_t key_event_code = kbd_state_shrd.copy_buf[--kbd_state_shrd.copy_len];
uint8_t keycode = (key_event_code & 0x7f); uint8_t keycode = (key_event_code & 0x7f);
if (key_event_code & 0x80) { if (key_event_code & 0x80) {
kbd_state_shrd.copy_pressed[keycode >> 3] = kbd_state_shrd.copy_pressed[keycode >> 3] & (~(1u << (keycode & 0x7))); kbd_state_shrd.copy_pressed[keycode >> 3] =
kbd_state_shrd.copy_pressed[keycode >> 3] &
(~(1u << (keycode & 0x7)));
} else { } else {
kbd_state_shrd.copy_pressed[keycode >> 3] = kbd_state_shrd.copy_pressed[keycode >> 3] | (1u << (keycode & 0x7)); kbd_state_shrd.copy_pressed[keycode >> 3] =
kbd_state_shrd.copy_pressed[keycode >> 3] | (1u << (keycode & 0x7));
} }
return key_event_code; return key_event_code;
} }
bool kbd_can_take_from_copy_buffer() { bool kbd_can_take_from_copy_buffer() { return kbd_state_shrd.copy_len > 0; }
return kbd_state_shrd.copy_len > 0;
}
bool kbd_is_pressed(uint8_t code) { bool kbd_is_pressed(uint8_t code) {
check(code < 128); check(code < 128);
return kbd_state_shrd.copy_pressed[code >> 3] & (1u << (code & 0x7)); return kbd_state_shrd.copy_pressed[code >> 3] & (1u << (code & 0x7));

View File

@ -20,22 +20,22 @@ typedef struct {
/* decoding */ /* decoding */
static const char keysym_mapped_ascii_lower[] = { static const char keysym_mapped_ascii_lower[] = {
0 , 0 , '1', '2', '3', '4', '5', '6', 0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0,
'7', '8', '9', '0', '-', '=', 0 , 0 , 'q', 'w', 'e', 'r', 't', 'y', 0, 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', 0,
'u', 'i', 'o', 'p', '[', ']', '\n', 0 , 'a', 's', 'd', 'f', 'g', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, '\\', 'z',
'h', 'j', 'k', 'l', ';', '\'', '`', 0 , '\\', 'z', 'x', 'c', 'v', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, 0, 0, ' ',
'b', 'n', 'm', ',', '.', '/', 0 , 0 , 0 , ' ',
}; };
static const char keysym_mapped_ascii_upper[] = { static const char keysym_mapped_ascii_upper[] = {
0 , 0 , '!', '@', '#', '$', '%', '^', 0, 0, '!', '@', '#', '$', '%', '^', '&',
'&', '*', '(', ')', '_', '+', 0 , 0 , 'Q', 'W', 'E', 'R', 'T', 'Y', '*', '(', ')', '_', '+', 0, 0, 'Q', 'W',
'U', 'I', 'O', 'P', '{', '}', '\n', 0 , 'A', 'S', 'D', 'F', 'G', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{',
'H', 'J', 'K', 'L', ':', '"', '~', 0 , '\\', 'Z', 'X', 'C', 'V', '}', '\n', 0, 'A', 'S', 'D', 'F', 'G', 'H',
'B', 'N', 'M', '<', '>', '?' /* an actual question mark */, 0 , 0 , 0 , ' ', 'J', 'K', 'L', ':', '"', '~', 0, '\\', 'Z',
'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?' /* an actual question mark */,
0, 0, 0, ' ',
}; };
extern keyboard_interrupt_shared_t kbd_state_shrd; extern keyboard_interrupt_shared_t kbd_state_shrd;
void init_keyboard(); void init_keyboard();

View File

@ -1,8 +1,7 @@
#pragma once #pragma once
#include "port.h" #include "port.h"
__attribute__((noreturn)) __attribute__((noreturn)) static inline void qemu_shutdown() {
static inline void qemu_shutdown() {
port_word_out(0x604, 0x2000); port_word_out(0x604, 0x2000);
__builtin_unreachable(); __builtin_unreachable();
} }

View File

@ -1,6 +1,6 @@
#include "pit.h" #include "pit.h"
#include "port.h"
#include "../cpu/isr.h" #include "../cpu/isr.h"
#include "port.h"
enum { enum {
PIT_CRYSTAL_HZ = 1193182, PIT_CRYSTAL_HZ = 1193182,
@ -30,7 +30,6 @@ enum {
PC_SPEAKER_PORT = 0x61, PC_SPEAKER_PORT = 0x61,
}; };
// Wtf is that O_o // Wtf is that O_o
static timer_callback callbacks[100]; static timer_callback callbacks[100];
static int registered_callbacks = 0; static int registered_callbacks = 0;
@ -78,9 +77,7 @@ static void timer_int_callback(void) {
sleep_counter--; sleep_counter--;
} }
uint32_t get_uptime_ms(void) { uint32_t get_uptime_ms(void) { return uptime_ms; }
return uptime_ms;
}
void set_beep_frequency_hz(uint32_t frequency_hz) { void set_beep_frequency_hz(uint32_t frequency_hz) {
if (frequency_hz == 0) { if (frequency_hz == 0) {
@ -117,9 +114,7 @@ void disable_beep(void) {
speaker_frequency_hz = 0; speaker_frequency_hz = 0;
} }
uint32_t get_beep_frequency_hz(void) { uint32_t get_beep_frequency_hz(void) { return speaker_frequency_hz; }
return speaker_frequency_hz;
}
void msleep(int ms) { void msleep(int ms) {
sleep_counter = ms / 10; sleep_counter = ms / 10;

View File

@ -2,25 +2,25 @@
static inline unsigned char port_byte_in(unsigned short port) { static inline unsigned char port_byte_in(unsigned short port) {
unsigned char result; unsigned char result;
asm volatile("in %%dx, %%al" : "=a" (result) : "d" (port)); asm volatile("in %%dx, %%al" : "=a"(result) : "d"(port));
return result; return result;
} }
static inline unsigned short port_word_in(unsigned short port) { static inline unsigned short port_word_in(unsigned short port) {
unsigned short result; unsigned short result;
asm volatile("in %%dx, %%ax" : "=a" (result) : "d" (port)); asm volatile("in %%dx, %%ax" : "=a"(result) : "d"(port));
return result; return result;
} }
static inline void port_byte_out(unsigned short port, unsigned char data) { static inline void port_byte_out(unsigned short port, unsigned char data) {
asm volatile("outb %%al, %%dx" : : "a" (data), "d" (port)); asm volatile("outb %%al, %%dx" : : "a"(data), "d"(port));
} }
static inline void port_word_out(unsigned short port, unsigned short data) { static inline void port_word_out(unsigned short port, unsigned short data) {
asm volatile("outw %%ax, %%dx" : : "a" (data), "d" (port)); asm volatile("outw %%ax, %%dx" : : "a"(data), "d"(port));
} }
/* assembler-long, not c-long */ /* assembler-long, not c-long */
static inline void port_long_out(unsigned short port, unsigned int data) { static inline void port_long_out(unsigned short port, unsigned int data) {
asm volatile("outl %%eax, %%dx" : : "a" (data), "d" (port)); asm volatile("outl %%eax, %%dx" : : "a"(data), "d"(port));
} }

View File

@ -9,37 +9,35 @@ enum {
void uartinit() { void uartinit() {
// Turn off the FIFO // Turn off the FIFO
port_byte_out(COM1+2, 0); port_byte_out(COM1 + 2, 0);
// 9600 baud, 8 data bits, 1 stop bit, parity off. // 9600 baud, 8 data bits, 1 stop bit, parity off.
port_byte_out(COM1+3, 0x80); // Unlock divisor port_byte_out(COM1 + 3, 0x80); // Unlock divisor
port_byte_out(COM1+0, 115200/9600); port_byte_out(COM1 + 0, 115200 / 9600);
port_byte_out(COM1+1, 0); port_byte_out(COM1 + 1, 0);
port_byte_out(COM1+3, 0x03); // Lock divisor, 8 data bits. port_byte_out(COM1 + 3, 0x03); // Lock divisor, 8 data bits.
port_byte_out(COM1+4, 0); port_byte_out(COM1 + 4, 0);
port_byte_out(COM1+1, 0x01); // Enable receive interrupts. port_byte_out(COM1 + 1, 0x01); // Enable receive interrupts.
// If status is 0xFF, no serial port. // If status is 0xFF, no serial port.
if(port_byte_in(COM1+5) == 0xFF) if (port_byte_in(COM1 + 5) == 0xFF)
return; return;
uart = 1; uart = 1;
// Acknowledge pre-existing interrupt conditions; // Acknowledge pre-existing interrupt conditions;
// enable interrupts. // enable interrupts.
port_byte_in(COM1+2); port_byte_in(COM1 + 2);
port_byte_in(COM1+0); port_byte_in(COM1 + 0);
} }
void void uartputc(char c) {
uartputc(char c)
{
int i; int i;
if (!uart) if (!uart)
return; return;
/* What is that *skeleton emoji*? */ /* What is that *skeleton emoji*? */
for (i = 0; i < 128 && !(port_byte_in(COM1+5) & 0x20); i++) { for (i = 0; i < 128 && !(port_byte_in(COM1 + 5) & 0x20); i++) {
asm("pause"); asm("pause");
} }
port_byte_out(COM1+0, c); port_byte_out(COM1 + 0, c);
} }

View File

@ -1,9 +1,9 @@
#include "vga.h" #include "vga.h"
#include "port.h"
#include "../lib/string.h" #include "../lib/string.h"
#include "cpu/memlayout.h" #include "cpu/memlayout.h"
#include "port.h"
static char* const video_memory = (char*) (KERNBASE + 0xb8000); static char *const video_memory = (char *)(KERNBASE + 0xb8000);
enum colors16 : unsigned char { enum colors16 : unsigned char {
black = 0, black = 0,
@ -32,15 +32,13 @@ unsigned vga_get_offset(unsigned col, unsigned row) {
return row * VGA_COLS + col; return row * VGA_COLS + col;
} }
unsigned vga_get_row_from_offset(unsigned offset) { unsigned vga_get_row_from_offset(unsigned offset) { return offset / VGA_COLS; }
return offset / VGA_COLS;
}
void vga_set_cursor(unsigned offset) { void vga_set_cursor(unsigned offset) {
port_byte_out(VGA_CTRL_REGISTER, VGA_OFFSET_HIGH); port_byte_out(VGA_CTRL_REGISTER, VGA_OFFSET_HIGH);
port_byte_out(VGA_DATA_REGISTER, (unsigned char) (offset >> 8)); port_byte_out(VGA_DATA_REGISTER, (unsigned char)(offset >> 8));
port_byte_out(VGA_CTRL_REGISTER, VGA_OFFSET_LOW); port_byte_out(VGA_CTRL_REGISTER, VGA_OFFSET_LOW);
port_byte_out(VGA_DATA_REGISTER, (unsigned char) (offset & 0xff)); port_byte_out(VGA_DATA_REGISTER, (unsigned char)(offset & 0xff));
} }
unsigned vga_get_cursor() { unsigned vga_get_cursor() {
@ -64,14 +62,15 @@ void vga_clear_screen() {
} }
static unsigned scroll() { static unsigned scroll() {
kmemmove(video_memory, video_memory + 2 * VGA_COLS, 2 * VGA_COLS * (VGA_ROWS-1)); kmemmove(video_memory, video_memory + 2 * VGA_COLS,
2 * VGA_COLS * (VGA_ROWS - 1));
for (int col = 0; col < VGA_COLS; col++) { for (int col = 0; col < VGA_COLS; col++) {
vga_set_char(vga_get_offset(col, VGA_ROWS - 1), ' '); vga_set_char(vga_get_offset(col, VGA_ROWS - 1), ' ');
} }
return vga_get_offset(0, VGA_ROWS - 1); return vga_get_offset(0, VGA_ROWS - 1);
} }
void vga_print_string(const char* s) { void vga_print_string(const char *s) {
unsigned offset = vga_get_cursor(); unsigned offset = vga_get_cursor();
while (*s != 0) { while (*s != 0) {
if (*s == '\n') { if (*s == '\n') {

View File

@ -13,8 +13,6 @@ enum {
VGA_OFFSET_HIGH = 0x0e, VGA_OFFSET_HIGH = 0x0e,
}; };
unsigned vga_get_cursor(); unsigned vga_get_cursor();
unsigned vga_get_row_from_offset(unsigned offset); unsigned vga_get_row_from_offset(unsigned offset);
unsigned vga_get_offset(unsigned col, unsigned row); unsigned vga_get_offset(unsigned col, unsigned row);
@ -22,7 +20,7 @@ void vga_set_cursor(unsigned offset);
void vga_clear_screen(); void vga_clear_screen();
void vga_set_char(unsigned offset, char c); void vga_set_char(unsigned offset, char c);
void vga_print_string(const char* s); void vga_print_string(const char *s);
#define VGA_GRAPHICS_WIDTH 320 #define VGA_GRAPHICS_WIDTH 320
#define VGA_GRAPHICS_HEIGHT 200 #define VGA_GRAPHICS_HEIGHT 200

View File

@ -1,12 +1,12 @@
#include "fs.h" #include "fs.h"
#include "../lib/string.h"
#include "../drivers/ata.h" #include "../drivers/ata.h"
#include "../lib/string.h"
enum { enum {
fs_start = 1, // sector where the FS starts fs_start = 1, // sector where the FS starts
}; };
int stat(const char* name, struct stat *buf) { int stat(const char *name, struct stat *buf) {
struct dir dir; struct dir dir;
read_sectors_ATA_PIO(&dir, fs_start, 1); read_sectors_ATA_PIO(&dir, fs_start, 1);
for (int i = 0; i < ents_in_dir; ++i) { for (int i = 0; i < ents_in_dir; ++i) {
@ -23,7 +23,7 @@ int stat(const char* name, struct stat *buf) {
/* Find file by name and read it into buffer with size bufsize. /* Find file by name and read it into buffer with size bufsize.
* At most (bufsize & -512) bytes will be read. * At most (bufsize & -512) bytes will be read.
* Return number of bytes read or -1 on failure. */ * Return number of bytes read or -1 on failure. */
int read_file(const struct stat *statbuf, void* buf, uint32_t bufsize) { int read_file(const struct stat *statbuf, void *buf, uint32_t bufsize) {
uint32_t sector = fs_start + statbuf->start_sector; uint32_t sector = fs_start + statbuf->start_sector;
uint32_t bytes_read = 0; uint32_t bytes_read = 0;
uint32_t file_sectors = (statbuf->size + sector_size - 1) / sector_size; uint32_t file_sectors = (statbuf->size + sector_size - 1) / sector_size;

View File

@ -45,9 +45,9 @@ struct stat {
/* Find file by name and fill information in buf. /* Find file by name and fill information in buf.
* Returns zero on success, nonzero on failure. */ * Returns zero on success, nonzero on failure. */
int stat(const char* name, struct stat *buf); int stat(const char *name, struct stat *buf);
/* Find file by name and read it into buffer with size bufsize. /* Find file by name and read it into buffer with size bufsize.
* At most (bufsize & ~511) bytes will be read. * At most (bufsize & ~511) bytes will be read.
* Return number of bytes read or -1 on failure. */ * Return number of bytes read or -1 on failure. */
int read_file(const struct stat *statbuf, void* buf, uint32_t bufsize); int read_file(const struct stat *statbuf, void *buf, uint32_t bufsize);

View File

@ -1,20 +1,20 @@
#include "console.h" #include "console.h"
#include "cpu/isr.h"
#include "cpu/gdt.h" #include "cpu/gdt.h"
#include "cpu/isr.h"
#include "cpu/memlayout.h" #include "cpu/memlayout.h"
#include "drivers/keyboard.h"
#include "drivers/vga.h"
#include "drivers/ata.h" #include "drivers/ata.h"
#include "drivers/keyboard.h"
#include "drivers/misc.h" #include "drivers/misc.h"
#include "drivers/pit.h" #include "drivers/pit.h"
#include "drivers/uart.h" #include "drivers/uart.h"
#include "drivers/vga.h"
#include "fs/fs.h" #include "fs/fs.h"
#include "kernel/mem.h"
#include "lib/string.h" #include "lib/string.h"
#include "proc.h" #include "proc.h"
#include "kernel/mem.h"
void vga_set_pixel(int x, int y, int color) { void vga_set_pixel(int x, int y, int color) {
unsigned char* pixel = (unsigned char*) (KERNBASE + 0xA0000 + 320 * y + x); unsigned char *pixel = (unsigned char *)(KERNBASE + 0xA0000 + 320 * y + x);
*pixel = color; *pixel = color;
} }
@ -22,7 +22,7 @@ void graphtest() {
switch_to_graphics_mode(); switch_to_graphics_mode();
for (int i = 0; i < 320; ++i) { for (int i = 0; i < 320; ++i) {
for (int j = 0; j < 200; ++j) { for (int j = 0; j < 200; ++j) {
vga_set_pixel(i, j, (i+j)/2); vga_set_pixel(i, j, (i + j) / 2);
} }
} }
msleep(5000); msleep(5000);
@ -30,7 +30,7 @@ void graphtest() {
vga_clear_screen(); vga_clear_screen();
} }
void read_line_input(char* buf, size_t* ret_len, size_t cap) { void read_line_input(char *buf, size_t *ret_len, size_t cap) {
size_t len = 0; size_t len = 0;
while (1) { while (1) {
while (kbd_can_take_from_copy_buffer()) { while (kbd_can_take_from_copy_buffer()) {
@ -50,8 +50,8 @@ void read_line_input(char* buf, size_t* ret_len, size_t cap) {
len--; len--;
} }
} else if (keycode < keycodes) { } else if (keycode < keycodes) {
char ch = shift_pressed ? keysym_mapped_ascii_upper[keycode] : char ch = shift_pressed ? keysym_mapped_ascii_upper[keycode]
keysym_mapped_ascii_lower[keycode]; : keysym_mapped_ascii_lower[keycode];
if (ch != 0) { if (ch != 0) {
char haha[2] = {ch, 0}; char haha[2] = {ch, 0};
printk(haha); printk(haha);
@ -76,16 +76,15 @@ void read_line_input(char* buf, size_t* ret_len, size_t cap) {
sti(); sti();
} }
} }
end: end:
printk("\n"); printk("\n");
*ret_len = len; *ret_len = len;
} }
void kmain() { void kmain() {
freerange(P2V(3u<<20), P2V(4u<<20)); freerange(P2V(3u << 20), P2V(4u << 20));
kvmalloc(); // map all of physical memory at KERNBASE kvmalloc(); // map all of physical memory at KERNBASE
freerange(P2V(4u<<20), P2V(PHYSTOP)); freerange(P2V(4u << 20), P2V(PHYSTOP));
load_gdt(); load_gdt();
init_keyboard(); init_keyboard();
@ -119,7 +118,7 @@ void kmain() {
} else if (cstr_equal(input, "graphtest")) { } else if (cstr_equal(input, "graphtest")) {
graphtest(); graphtest();
} else if (cstr_starts_with(input, "run ")) { } else if (cstr_starts_with(input, "run ")) {
const char* cmd = input + 4; const char *cmd = input + 4;
run_elf(cmd); run_elf(cmd);
} else { } else {
printk("unknown command, try: halt | run CMD\n"); printk("unknown command, try: halt | run CMD\n");

View File

@ -2,11 +2,11 @@
// memory for user processes, kernel stacks, page table pages, // memory for user processes, kernel stacks, page table pages,
// and pipe buffers. Allocates 4096-byte pages. // and pipe buffers. Allocates 4096-byte pages.
#include <stdint.h>
#include "mem.h" #include "mem.h"
#include "console.h" #include "console.h"
#include "cpu/memlayout.h" #include "cpu/memlayout.h"
#include "cpu/x86.h" #include "cpu/x86.h"
#include <stdint.h>
struct run { struct run {
struct run *next; struct run *next;
@ -16,21 +16,17 @@ struct {
struct run *freelist; struct run *freelist;
} kmem; } kmem;
void void freerange(void *vstart, void *vend) {
freerange(void *vstart, void *vend)
{
char *p; char *p;
p = (char*)PGROUNDUP((uintptr_t)vstart); p = (char *)PGROUNDUP((uintptr_t)vstart);
for(; p + PGSIZE <= (char*)vend; p += PGSIZE) for (; p + PGSIZE <= (char *)vend; p += PGSIZE)
kfree(p); kfree(p);
} }
void* void *memset(void *dst, unsigned c, uint64_t n) {
memset(void *dst, unsigned c, uint64_t n) if ((uintptr_t)dst % 4 == 0 && n % 4 == 0) {
{
if ((uintptr_t)dst%4 == 0 && n%4 == 0){
c &= 0xFF; c &= 0xFF;
stosl(dst, (c<<24)|(c<<16)|(c<<8)|c, n/4); stosl(dst, (c << 24) | (c << 16) | (c << 8) | c, n / 4);
} else } else
stosb(dst, c, n); stosb(dst, c, n);
return dst; return dst;
@ -40,12 +36,10 @@ memset(void *dst, unsigned c, uint64_t n)
// which normally should have been returned by a // which normally should have been returned by a
// call to kalloc(). (The exception is when // call to kalloc(). (The exception is when
// initializing the allocator; see kinit above.) // initializing the allocator; see kinit above.)
void void kfree(void *v) {
kfree(void *v)
{
struct run *r; struct run *r;
if((uintptr_t)v % PGSIZE || V2P(v) >= PHYSTOP) if ((uintptr_t)v % PGSIZE || V2P(v) >= PHYSTOP)
panic("kfree"); panic("kfree");
// Fill with junk to catch dangling refs. // Fill with junk to catch dangling refs.
@ -59,12 +53,11 @@ kfree(void *v)
// Allocate one 4096-byte page of physical memory. // Allocate one 4096-byte page of physical memory.
// Returns a pointer that the kernel can use. // Returns a pointer that the kernel can use.
// Returns 0 if the memory cannot be allocated. // Returns 0 if the memory cannot be allocated.
void* kalloc(void) void *kalloc(void) {
{
struct run *r; struct run *r;
r = kmem.freelist; r = kmem.freelist;
if(r) if (r)
kmem.freelist = r->next; kmem.freelist = r->next;
return (char*)r; return (char *)r;
} }

View File

@ -5,11 +5,11 @@
typedef uintptr_t pde_t; typedef uintptr_t pde_t;
typedef uintptr_t pte_t; typedef uintptr_t pte_t;
void* memset(void *dst, unsigned c, uint64_t n); void *memset(void *dst, unsigned c, uint64_t n);
void freerange(void *vstart, void *vend); void freerange(void *vstart, void *vend);
void* kalloc(void); void *kalloc(void);
void kfree(void*); void kfree(void *);
pde_t *setupkvm(); pde_t *setupkvm();
void kvmalloc(); void kvmalloc();

View File

@ -1,7 +1,7 @@
#include "mem.h" #include "console.h"
#include "cpu/memlayout.h" #include "cpu/memlayout.h"
#include "cpu/x86.h" #include "cpu/x86.h"
#include "console.h" #include "mem.h"
pde_t *kvm; pde_t *kvm;
@ -22,8 +22,7 @@ void kvmalloc() {
switchkvm(); switchkvm();
} }
void switchkvm(void) void switchkvm(void) {
{
lcr3(V2P(kvm)); // switch to the kernel page table lcr3(V2P(kvm)); // switch to the kernel page table
} }
@ -33,9 +32,7 @@ void switchkvm(void)
// Return the address of the PTE in page table pgdir // Return the address of the PTE in page table pgdir
// that corresponds to virtual address va. If alloc!=0, // that corresponds to virtual address va. If alloc!=0,
// create any required page table pages. // create any required page table pages.
static pte_t * static pte_t *walkpgdir(pde_t *pgdir, const void *va, int alloc) {
walkpgdir(pde_t *pgdir, const void *va, int alloc)
{
pde_t *pde; pde_t *pde;
pte_t *pgtab; pte_t *pgtab;
@ -65,13 +62,13 @@ walkpgdir(pde_t *pgdir, const void *va, int alloc)
// Create PTEs for virtual addresses starting at va that refer to // Create PTEs for virtual addresses starting at va that refer to
// physical addresses starting at pa. // physical addresses starting at pa.
// size might not be page-aligned. // size might not be page-aligned.
static int static int mappages(pde_t *pgdir, void *va, uintptr_t size, uintptr_t pa,
mappages(pde_t *pgdir, void *va, uintptr_t size, uintptr_t pa, int perm){ int perm) {
if ((uintptr_t)va % PGSIZE != 0) if ((uintptr_t)va % PGSIZE != 0)
panic("Why??"); panic("Why??");
char* a = va; char *a = va;
char* last = (char *)PGROUNDDOWN(((uintptr_t)va) + size - 1); char *last = (char *)PGROUNDDOWN(((uintptr_t)va) + size - 1);
for (;;){ for (;;) {
pte_t *pte = walkpgdir(pgdir, a, 1); pte_t *pte = walkpgdir(pgdir, a, 1);
if (pte == 0) if (pte == 0)
return -1; return -1;
@ -96,7 +93,7 @@ int allocuvm(pde_t *pgdir, uintptr_t base, uintptr_t top) {
return -1; return -1;
} }
memset(pa, 0, PGSIZE); memset(pa, 0, PGSIZE);
if (mappages(pgdir, (void*)a, PGSIZE, V2P(pa), PTE_W | PTE_U) < 0) { if (mappages(pgdir, (void *)a, PGSIZE, V2P(pa), PTE_W | PTE_U) < 0) {
kfree(pa); kfree(pa);
return -1; return -1;
} }
@ -107,16 +104,16 @@ int allocuvm(pde_t *pgdir, uintptr_t base, uintptr_t top) {
static void freept(pte_t *pt) { static void freept(pte_t *pt) {
for (int i = 0; i < NPTENTRIES; i++) { for (int i = 0; i < NPTENTRIES; i++) {
if (pt[i] & PTE_P) { if (pt[i] & PTE_P) {
kfree((char*)P2V(PTE_ADDR(pt[i]))); kfree((char *)P2V(PTE_ADDR(pt[i])));
} }
} }
kfree((char*)pt); kfree((char *)pt);
} }
void freevm(pde_t *pgdir) { void freevm(pde_t *pgdir) {
for (int i = 0; i < NPDENTRIES / 2; i++) { for (int i = 0; i < NPDENTRIES / 2; i++) {
if (pgdir[i] & PTE_P) { if (pgdir[i] & PTE_P) {
freept((pte_t*)P2V(PTE_ADDR(pgdir[i]))); freept((pte_t *)P2V(PTE_ADDR(pgdir[i])));
} }
} }
kfree(pgdir); kfree(pgdir);

View File

@ -1,28 +1,28 @@
#include "string.h" #include "string.h"
void memcpy(void *dst, const void *src, size_t size) {
void memcpy(void*dst, const void *src, size_t size) {
for (size_t i = 0; i < size; i++) { for (size_t i = 0; i < size; i++) {
((char*)dst)[i] = ((const char*)src)[i]; ((char *)dst)[i] = ((const char *)src)[i];
} }
} }
void kmemmove(char* dst, char* src, size_t size) { void kmemmove(char *dst, char *src, size_t size) {
if (dst == src) return; if (dst == src)
if (dst > src && dst < src + size) { // s d return;
// copy right-to-left if (dst > src && dst < src + size) { // s d
for (; size != 0; size--) { // copy right-to-left
for (; size != 0; size--) {
dst[size - 1] = src[size - 1]; dst[size - 1] = src[size - 1];
} }
} else { } else {
// copy left-to-right // copy left-to-right
for (size_t i = 0; i < size; ++i) { for (size_t i = 0; i < size; ++i) {
dst[i] = src[i]; dst[i] = src[i];
} }
} }
} }
int strncmp(const char* s1, const char* s2, size_t size) { int strncmp(const char *s1, const char *s2, size_t size) {
while (size && *s1 && *s2 && *s1 == *s2) { while (size && *s1 && *s2 && *s1 == *s2) {
size--; size--;
s1++; s1++;
@ -34,7 +34,7 @@ int strncmp(const char* s1, const char* s2, size_t size) {
return (unsigned char)(*s1) - (unsigned char)(*s2); return (unsigned char)(*s1) - (unsigned char)(*s2);
} }
bool cstr_equal(const char* s1, const char* s2) { bool cstr_equal(const char *s1, const char *s2) {
while (*s1 && *s2 && *s1 == *s2) { while (*s1 && *s2 && *s1 == *s2) {
s1++; s1++;
s2++; s2++;
@ -42,7 +42,6 @@ bool cstr_equal(const char* s1, const char* s2) {
return *s1 == 0 && *s2 == 0; return *s1 == 0 && *s2 == 0;
} }
bool cstr_starts_with(const char *A, const char *B) { bool cstr_starts_with(const char *A, const char *B) {
while (*A && *B) { while (*A && *B) {
if (*A != *B) if (*A != *B)

View File

@ -4,8 +4,8 @@
typedef unsigned size_t; typedef unsigned size_t;
void memcpy(void*dst, const void *src, size_t size); void memcpy(void *dst, const void *src, size_t size);
void kmemmove(char* dst, char* src, size_t size); void kmemmove(char *dst, char *src, size_t size);
int strncmp(const char* s1, const char* s2, size_t size); int strncmp(const char *s1, const char *s2, size_t size);
bool cstr_equal(const char* s1, const char* s2); bool cstr_equal(const char *s1, const char *s2);
bool cstr_starts_with(const char *A, const char *B); bool cstr_starts_with(const char *A, const char *B);

19
proc.c
View File

@ -27,7 +27,7 @@ struct vm {
} vm; } vm;
void trapret(); void trapret();
void swtch(void** oldstack, void* newstack); void swtch(void **oldstack, void *newstack);
pde_t *get_user_proc_page_directory() { pde_t *get_user_proc_page_directory() {
if (!vm.user_task) { if (!vm.user_task) {
@ -36,7 +36,7 @@ pde_t *get_user_proc_page_directory() {
return vm.user_task->pgdir; return vm.user_task->pgdir;
} }
void run_elf(const char* name) { void run_elf(const char *name) {
struct stat statbuf; struct stat statbuf;
if (stat(name, &statbuf) != 0) { if (stat(name, &statbuf) != 0) {
printk(name); printk(name);
@ -47,24 +47,27 @@ void run_elf(const char* name) {
vm.user_task = kalloc(); vm.user_task = kalloc();
} }
// todo: this code contains 9999 memory leaks but I don't care // todo: this code contains 9999 memory leaks but I don't care
// todo: yabloko is fucking shit made my monkeys, I want to forget this fucking nightmare // todo: yabloko is fucking shit made my monkeys, I want to forget this
// fucking nightmare
vm.user_task->pgdir = setupkvm(); vm.user_task->pgdir = setupkvm();
if (allocuvm(vm.user_task->pgdir, USER_BASE, USER_BASE + statbuf.size)) { if (allocuvm(vm.user_task->pgdir, USER_BASE, USER_BASE + statbuf.size)) {
printk("Fail: out of memory\n"); printk("Fail: out of memory\n");
return; return;
} }
if (allocuvm(vm.user_task->pgdir, USER_STACK_BASE - 2 * PGSIZE, USER_STACK_BASE)) { if (allocuvm(vm.user_task->pgdir, USER_STACK_BASE - 2 * PGSIZE,
USER_STACK_BASE)) {
printk("Fail: out of memory\n"); printk("Fail: out of memory\n");
return; return;
} }
switchuvm(&vm.user_task->tss, vm.user_task->stack.bottom, vm.user_task->pgdir); switchuvm(&vm.user_task->tss, vm.user_task->stack.bottom,
vm.user_task->pgdir);
if (read_file(&statbuf, (void*)USER_BASE, 100 << 20) <= 0) { if (read_file(&statbuf, (void *)USER_BASE, 100 << 20) <= 0) {
printk(name); printk(name);
printk(": file not found\n"); printk(": file not found\n");
return; return;
} }
Elf32_Ehdr *hdr = (void*)USER_BASE; Elf32_Ehdr *hdr = (void *)USER_BASE;
struct kstack *u = &vm.user_task->stack; struct kstack *u = &vm.user_task->stack;
memset(u, 0, sizeof(*u)); memset(u, 0, sizeof(*u));
@ -88,7 +91,7 @@ void run_elf(const char* name) {
} }
_Noreturn void killproc() { _Noreturn void killproc() {
void* task_stack; void *task_stack;
disable_beep(); disable_beep();
if (!vga_is_text_mode()) { if (!vga_is_text_mode()) {
switch_to_text_mode(); switch_to_text_mode();

11
proc.h
View File

@ -1,16 +1,15 @@
#pragma once #pragma once
#include "elf.h" #include "console.h"
#include "fs/fs.h"
#include "cpu/gdt.h" #include "cpu/gdt.h"
#include "cpu/isr.h" #include "cpu/isr.h"
#include "cpu/memlayout.h" #include "cpu/memlayout.h"
#include "elf.h"
#include "fs/fs.h"
#include "kernel/mem.h" #include "kernel/mem.h"
#include "lib/string.h" #include "lib/string.h"
#include "console.h"
pde_t *get_user_proc_page_directory();
pde_t* get_user_proc_page_directory(); void run_elf(const char *name);
void run_elf(const char* name);
_Noreturn void killproc(); _Noreturn void killproc();

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h>
/* We still have beef with keyboard, even in userspace */ /* We still have beef with keyboard, even in userspace */
#define KEYCODE_SHIFT 42 #define KEYCODE_SHIFT 42

View File

@ -2,183 +2,713 @@
#include "maps.h" #include "maps.h"
static const MapList map_list = { static const MapList
.maps = { map_list = {.maps =
{
/* CLUSTERTRACT.png */ /* CLUSTERTRACT.png */
[0] = { [0] =
{
.name = "CLUSTERTRACT", .name = "CLUSTERTRACT",
.map = { .map =
[0] = { tile_wall_t, tile_wall_lr, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall_lr, tile_wall_b }, {
[1] = { tile_wall_rb, tile_wall_lt, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall_lb, tile_wall_rt }, [0] = {tile_wall_t, tile_wall_lr,
[2] = { tile_wall_lr, tile_wall_rb, tile_wall_lt, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lb, tile_wall_rt, tile_wall_lr }, tile_wall_lr, tile_empty,
[3] = { tile_wall_lr, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall_lr }, tile_empty, tile_empty,
[4] = { tile_wall_lr, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall_lr }, tile_empty, tile_wall_lr,
[5] = { tile_wall_lr, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_b, tile_wall_lrt, tile_wall_lr }, tile_wall_lr, tile_wall_b},
[6] = { tile_wall_lr, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall_lr }, [1] = {tile_wall_rb, tile_wall_lt,
[7] = { tile_wall_lr, tile_wall_lrb, tile_wall_rt, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall_lr }, tile_wall_lr, tile_empty,
[8] = { tile_wall_lr, tile_wall_lrb, tile_wall_lt, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_rb, tile_wall_lrt, tile_wall_lr }, tile_empty, tile_empty,
[9] = { tile_wall_lr, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lb, tile_wall_lrt, tile_wall_lr }, tile_empty, tile_wall_lr,
[10] = { tile_wall_lr, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall_lr }, tile_wall_lb, tile_wall_rt},
[11] = { tile_wall_lr, tile_wall_lrb, tile_wall_t, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall_lr }, [2] =
[12] = { tile_wall_lr, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall_lr }, {tile_wall_lr,
[13] = { tile_wall_lr, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall_lr }, tile_wall_rb, tile_wall_lt, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lb, tile_wall_rt, tile_wall_lr},
[14] = { tile_wall_lr, tile_wall_lb, tile_wall_rt, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_rb, tile_wall_lt, tile_wall_lr }, [3] =
[15] = { tile_wall_lb, tile_wall_rt, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall_rb, tile_wall_lt }, {tile_wall_lr,
tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall_lr},
[4] =
{tile_wall_lr,
tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall_lr},
[5] =
{tile_wall_lr,
tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_b, tile_wall_lrt, tile_wall_lr},
[6] =
{tile_wall_lr,
tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall_lr},
[7] =
{tile_wall_lr,
tile_wall_lrb, tile_wall_rt, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall_lr},
[8] =
{tile_wall_lr,
tile_wall_lrb, tile_wall_lt, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_rb, tile_wall_lrt, tile_wall_lr},
[9] =
{tile_wall_lr,
tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lb, tile_wall_lrt, tile_wall_lr},
[10] =
{tile_wall_lr,
tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr,
tile_wall_lr},
[11] =
{tile_wall_lr,
tile_wall_lrb, tile_wall_t, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr,
tile_wall_lr},
[12] =
{tile_wall_lr, tile_wall_lr,
tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr,
tile_wall_lr},
[13] =
{tile_wall_lr, tile_wall_lr,
tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr,
tile_wall_lr},
[14] =
{tile_wall_lr, tile_wall_lb,
tile_wall_rt,
tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_rb,
tile_wall_lt, tile_wall_lr},
[15] =
{tile_wall_lb, tile_wall_rt,
tile_wall_lr,
tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr,
tile_wall_rb, tile_wall_lt},
}, },
}, },
/* EMPTY.png */ /* EMPTY.png */
[1] = { [1] =
{
.name = "EMPTY", .name = "EMPTY",
.map = { .map =
[0] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, {
[1] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, [0] = {tile_empty, tile_empty,
[2] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty,
[3] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty,
[4] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty,
[5] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty},
[6] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, [1] = {tile_empty, tile_empty,
[7] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty,
[8] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty,
[9] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty,
[10] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty},
[11] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, [2] = {tile_empty, tile_empty,
[12] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty,
[13] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty,
[14] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty,
[15] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty},
[3] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty},
[4] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty},
[5] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty},
[6] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty},
[7] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty},
[8] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty},
[9] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty},
[10] =
{tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty},
[11] =
{tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty},
[12] =
{tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty},
[13] =
{tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty},
[14] =
{tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty},
[15] =
{tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty},
}, },
}, },
/* GREEN DAYS.png */ /* GREEN DAYS.png */
[2] = { [2] =
{
.name = "GREEN DAYS", .name = "GREEN DAYS",
.map = { .map =
[0] = { tile_wall_rb, tile_wall_tb, tile_wall_tb, tile_wall_t, tile_empty, tile_empty, tile_wall_b, tile_wall_tb, tile_wall_tb, tile_wall_rt }, {
[1] = { tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr }, [0] = {tile_wall_rb, tile_wall_tb,
[2] = { tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr }, tile_wall_tb, tile_wall_t,
[3] = { tile_wall_l, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_l }, tile_empty, tile_empty,
[4] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_wall_b, tile_wall_tb,
[5] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_wall_tb, tile_wall_rt},
[6] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, [1] = {tile_wall_lr, tile_empty,
[7] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty,
[8] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty,
[9] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty,
[10] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_wall_lr},
[11] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, [2] = {tile_wall_lr, tile_empty,
[12] = { tile_wall_r, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_r }, tile_empty, tile_empty,
[13] = { tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr }, tile_empty, tile_empty,
[14] = { tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr }, tile_empty, tile_empty,
[15] = { tile_wall_lb, tile_wall_tb, tile_wall_tb, tile_wall_t, tile_empty, tile_empty, tile_wall_b, tile_wall_tb, tile_wall_tb, tile_wall_lt }, tile_empty, tile_wall_lr},
[3] = {tile_wall_l, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_wall_l},
[4] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty},
[5] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty},
[6] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty},
[7] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty},
[8] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty},
[9] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty},
[10] =
{tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty},
[11] =
{tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty},
[12] =
{tile_wall_r, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty, tile_wall_r},
[13] =
{tile_wall_lr, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty, tile_wall_lr},
[14] =
{tile_wall_lr, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty, tile_wall_lr},
[15] =
{tile_wall_lb, tile_wall_tb,
tile_wall_tb, tile_wall_t,
tile_empty, tile_empty,
tile_wall_b, tile_wall_tb,
tile_wall_tb, tile_wall_lt},
}, },
}, },
/* QUARTERHOUSE.png */ /* QUARTERHOUSE.png */
[3] = { [3] =
{
.name = "QUARTERHOUSE", .name = "QUARTERHOUSE",
.map = { .map =
[0] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, {
[1] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, [0] = {tile_empty, tile_empty,
[2] = { tile_empty, tile_empty, tile_empty, tile_wall_b, tile_wall_rtb, tile_wall_tb, tile_wall_t, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty,
[3] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty,
[4] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty,
[5] = { tile_wall_rt, tile_empty, tile_empty, tile_empty, tile_wall_lb, tile_wall_rt, tile_empty, tile_empty, tile_empty, tile_wall_rb }, tile_empty, tile_empty},
[6] = { tile_wall_lrt, tile_empty, tile_empty, tile_empty, tile_wall, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_wall_lrb }, [1] = {tile_empty, tile_empty,
[7] = { tile_wall_lrt, tile_wall, tile_wall_rb, tile_wall_tb, tile_wall_rtb, tile_wall_lrtb, tile_wall_tb, tile_wall_rt, tile_wall, tile_wall_lrb }, tile_empty, tile_empty,
[8] = { tile_wall_lrtb, tile_wall_tb, tile_wall_lt, tile_wall, tile_wall_lrb, tile_wall_lt, tile_wall, tile_wall_lb, tile_wall_tb, tile_wall_lrtb }, tile_empty, tile_empty,
[9] = { tile_wall_lrt, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall, tile_empty, tile_empty, tile_empty, tile_wall_lrb }, tile_empty, tile_empty,
[10] = { tile_wall_lt, tile_empty, tile_empty, tile_empty, tile_wall_lb, tile_wall_rt, tile_empty, tile_empty, tile_empty, tile_wall_lb }, tile_empty, tile_empty},
[11] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_wall, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty }, [2] = {tile_empty, tile_empty,
[12] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_wall, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_wall_b,
[13] = { tile_empty, tile_empty, tile_empty, tile_wall_b, tile_wall_tb, tile_wall_ltb, tile_wall_t, tile_empty, tile_empty, tile_empty }, tile_wall_rtb, tile_wall_tb,
[14] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_wall_t, tile_empty,
[15] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty},
[3] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_wall_lr,
tile_wall, tile_empty,
tile_empty, tile_empty,
tile_empty},
[4] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_wall_lr,
tile_wall, tile_empty,
tile_empty, tile_empty,
tile_empty},
[5] = {tile_wall_rt, tile_empty,
tile_empty, tile_empty,
tile_wall_lb, tile_wall_rt,
tile_empty, tile_empty,
tile_empty, tile_wall_rb},
[6] = {tile_wall_lrt, tile_empty,
tile_empty, tile_empty,
tile_wall, tile_wall_lr,
tile_empty, tile_empty,
tile_empty, tile_wall_lrb},
[7] = {tile_wall_lrt,
tile_wall, tile_wall_rb,
tile_wall_tb, tile_wall_rtb,
tile_wall_lrtb, tile_wall_tb,
tile_wall_rt,
tile_wall, tile_wall_lrb},
[8] = {tile_wall_lrtb, tile_wall_tb,
tile_wall_lt,
tile_wall, tile_wall_lrb,
tile_wall_lt,
tile_wall, tile_wall_lb,
tile_wall_tb, tile_wall_lrtb},
[9] = {tile_wall_lrt, tile_empty,
tile_empty, tile_empty,
tile_wall_lr,
tile_wall, tile_empty,
tile_empty, tile_empty,
tile_wall_lrb},
[10] =
{tile_wall_lt, tile_empty,
tile_empty, tile_empty,
tile_wall_lb, tile_wall_rt,
tile_empty, tile_empty, tile_empty,
tile_wall_lb},
[11] =
{tile_empty, tile_empty, tile_empty,
tile_empty, tile_wall,
tile_wall_lr, tile_empty,
tile_empty, tile_empty,
tile_empty},
[12] =
{tile_empty, tile_empty, tile_empty,
tile_empty, tile_wall,
tile_wall_lr, tile_empty,
tile_empty, tile_empty,
tile_empty},
[13] =
{tile_empty, tile_empty, tile_empty,
tile_wall_b, tile_wall_tb,
tile_wall_ltb, tile_wall_t,
tile_empty, tile_empty,
tile_empty},
[14] =
{tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty},
[15] =
{tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty},
}, },
}, },
/* SERPENTINE STRUTS.png */ /* SERPENTINE STRUTS.png */
[4] = { [4] =
{
.name = "SERPENTINE STRUTS", .name = "SERPENTINE STRUTS",
.map = { .map =
[0] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, {
[1] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_r, tile_empty, tile_empty, tile_wall_r, tile_empty, tile_empty }, [0] = {tile_empty, tile_empty,
[2] = { tile_empty, tile_empty, tile_empty, tile_wall_b, tile_wall_lrtb, tile_wall_tb, tile_wall_tb, tile_wall_lrtb, tile_wall_t, tile_empty }, tile_empty, tile_empty,
[3] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_l, tile_empty, tile_empty, tile_wall_l, tile_empty, tile_empty }, tile_empty, tile_empty,
[4] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty,
[5] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty},
[6] = { tile_empty, tile_empty, tile_empty, tile_wall_r, tile_empty, tile_empty, tile_wall_r, tile_empty, tile_empty, tile_empty }, [1] = {tile_empty, tile_empty,
[7] = { tile_empty, tile_empty, tile_wall_b, tile_wall_lrtb, tile_wall_tb, tile_wall_tb, tile_wall_lrtb, tile_wall_t, tile_empty, tile_empty }, tile_empty, tile_empty,
[8] = { tile_empty, tile_empty, tile_empty, tile_wall_l, tile_empty, tile_empty, tile_wall_l, tile_empty, tile_empty, tile_empty }, tile_wall_r, tile_empty,
[9] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_wall_r,
[10] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty},
[11] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, [2] = {tile_empty, tile_empty,
[12] = { tile_empty, tile_empty, tile_wall_r, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_r, tile_empty, tile_empty }, tile_empty, tile_wall_b,
[13] = { tile_empty, tile_wall_b, tile_wall_lrtb, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_lrtb, tile_wall_t, tile_empty }, tile_wall_lrtb, tile_wall_tb,
[14] = { tile_empty, tile_empty, tile_wall_l, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_l, tile_empty, tile_empty }, tile_wall_tb, tile_wall_lrtb,
[15] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_wall_t, tile_empty},
[3] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_wall_l, tile_empty,
tile_empty, tile_wall_l,
tile_empty, tile_empty},
[4] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty},
[5] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty},
[6] = {tile_empty, tile_empty,
tile_empty, tile_wall_r,
tile_empty, tile_empty,
tile_wall_r, tile_empty,
tile_empty, tile_empty},
[7] = {tile_empty, tile_empty,
tile_wall_b, tile_wall_lrtb,
tile_wall_tb, tile_wall_tb,
tile_wall_lrtb, tile_wall_t,
tile_empty, tile_empty},
[8] = {tile_empty, tile_empty,
tile_empty, tile_wall_l,
tile_empty, tile_empty,
tile_wall_l, tile_empty,
tile_empty, tile_empty},
[9] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty},
[10] =
{tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty},
[11] =
{tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty},
[12] =
{tile_empty, tile_empty,
tile_wall_r, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_wall_r, tile_empty,
tile_empty},
[13] = {tile_empty, tile_wall_b,
tile_wall_lrtb, tile_wall_tb,
tile_wall_tb, tile_wall_tb,
tile_wall_tb, tile_wall_lrtb,
tile_wall_t, tile_empty},
[14] =
{tile_empty, tile_empty,
tile_wall_l, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_wall_l, tile_empty,
tile_empty},
[15] =
{tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty},
}, },
}, },
/* SHEER GIRTH.png */ /* SHEER GIRTH.png */
[5] = { [5] =
{
.name = "SHEER GIRTH", .name = "SHEER GIRTH",
.map = { .map =
[0] = { tile_empty, tile_wall_rb, tile_wall_rtb, tile_wall_rtb, tile_wall_rtb, tile_wall_rtb, tile_wall_rtb, tile_wall_rtb, tile_wall_rt, tile_empty }, {
[1] = { tile_empty, tile_wall_lrb, tile_wall_lrtb, tile_wall_lrtb, tile_wall_lrtb, tile_wall_lrtb, tile_wall_lrtb, tile_wall_lrtb, tile_wall_lrt, tile_empty }, [0] = {tile_empty, tile_wall_rb,
[2] = { tile_empty, tile_wall_lb, tile_wall_ltb, tile_wall_ltb, tile_wall_ltb, tile_wall_ltb, tile_wall_ltb, tile_wall_ltb, tile_wall_lt, tile_empty }, tile_wall_rtb, tile_wall_rtb,
[3] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_wall_rtb, tile_wall_rtb,
[4] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_wall_rtb, tile_wall_rtb,
[5] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_wall_rt, tile_empty},
[6] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, [1] = {tile_empty, tile_wall_lrb,
[7] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_wall_lrtb, tile_wall_lrtb,
[8] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_wall_lrtb, tile_wall_lrtb,
[9] = { tile_empty, tile_wall_rb, tile_wall_rtb, tile_wall_rt, tile_empty, tile_empty, tile_wall_rb, tile_wall_rtb, tile_wall_rt, tile_empty }, tile_wall_lrtb, tile_wall_lrtb,
[10] = { tile_empty, tile_wall_lrb, tile_wall_lrtb, tile_wall_lrt, tile_empty, tile_empty, tile_wall_lrb, tile_wall_lrtb, tile_wall_lrt, tile_empty }, tile_wall_lrt, tile_empty},
[11] = { tile_empty, tile_wall_lrb, tile_wall_lrtb, tile_wall_lrt, tile_empty, tile_empty, tile_wall_lrb, tile_wall_lrtb, tile_wall_lrt, tile_empty }, [2] = {tile_empty, tile_wall_lb,
[12] = { tile_empty, tile_wall_lrb, tile_wall_lrtb, tile_wall_lrt, tile_empty, tile_empty, tile_wall_lrb, tile_wall_lrtb, tile_wall_lrt, tile_empty }, tile_wall_ltb, tile_wall_ltb,
[13] = { tile_empty, tile_wall_lb, tile_wall_ltb, tile_wall_lt, tile_empty, tile_empty, tile_wall_lb, tile_wall_ltb, tile_wall_lt, tile_empty }, tile_wall_ltb, tile_wall_ltb,
[14] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_wall_ltb, tile_wall_ltb,
[15] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_wall_lt, tile_empty},
[3] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty},
[4] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty},
[5] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty},
[6] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty},
[7] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty},
[8] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty},
[9] = {tile_empty, tile_wall_rb,
tile_wall_rtb, tile_wall_rt,
tile_empty, tile_empty,
tile_wall_rb, tile_wall_rtb,
tile_wall_rt, tile_empty},
[10] =
{tile_empty, tile_wall_lrb,
tile_wall_lrtb, tile_wall_lrt,
tile_empty, tile_empty,
tile_wall_lrb, tile_wall_lrtb,
tile_wall_lrt, tile_empty},
[11] =
{tile_empty, tile_wall_lrb,
tile_wall_lrtb, tile_wall_lrt,
tile_empty, tile_empty,
tile_wall_lrb, tile_wall_lrtb,
tile_wall_lrt, tile_empty},
[12] =
{tile_empty, tile_wall_lrb,
tile_wall_lrtb, tile_wall_lrt,
tile_empty, tile_empty,
tile_wall_lrb, tile_wall_lrtb,
tile_wall_lrt, tile_empty},
[13] =
{tile_empty, tile_wall_lb,
tile_wall_ltb, tile_wall_lt,
tile_empty, tile_empty,
tile_wall_lb, tile_wall_ltb,
tile_wall_lt, tile_empty},
[14] =
{tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty},
[15] =
{tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty},
}, },
}, },
/* VAULT.png */ /* VAULT.png */
[6] = { [6] =
{
.name = "VAULT", .name = "VAULT",
.map = { .map =
[0] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, {
[1] = { tile_empty, tile_empty, tile_empty, tile_wall_rb, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_rt, tile_empty }, [0] = {tile_empty, tile_empty,
[2] = { tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_empty }, tile_empty, tile_empty,
[3] = { tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_empty }, tile_empty, tile_empty,
[4] = { tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_empty }, tile_empty, tile_empty,
[5] = { tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_empty }, tile_empty, tile_empty},
[6] = { tile_empty, tile_empty, tile_empty, tile_wall_lb, tile_wall_t, tile_empty, tile_empty, tile_wall_b, tile_wall_lrt, tile_empty }, [1] = {tile_empty, tile_empty,
[7] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_empty }, tile_empty, tile_wall_rb,
[8] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_empty }, tile_wall_tb, tile_wall_tb,
[9] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_empty }, tile_wall_tb, tile_wall_tb,
[10] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_empty }, tile_wall_rt, tile_empty},
[11] = { tile_empty, tile_empty, tile_wall_rb, tile_wall_t, tile_empty, tile_empty, tile_wall_b, tile_wall_tb, tile_wall_lrt, tile_empty }, [2] = {tile_empty, tile_empty,
[12] = { tile_empty, tile_empty, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_empty }, tile_empty, tile_wall_lr,
[13] = { tile_empty, tile_empty, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_empty }, tile_empty, tile_empty,
[14] = { tile_empty, tile_empty, tile_wall_lb, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_lt, tile_empty }, tile_empty, tile_empty,
[15] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_wall_lr, tile_empty},
[3] = {tile_empty, tile_empty,
tile_empty, tile_wall_lr,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_wall_lr, tile_empty},
[4] = {tile_empty, tile_empty,
tile_empty, tile_wall_lr,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_wall_lr, tile_empty},
[5] = {tile_empty, tile_empty,
tile_empty, tile_wall_lr,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_wall_lr, tile_empty},
[6] = {tile_empty, tile_empty,
tile_empty, tile_wall_lb,
tile_wall_t, tile_empty,
tile_empty, tile_wall_b,
tile_wall_lrt, tile_empty},
[7] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_wall_lr, tile_empty},
[8] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_wall_lr, tile_empty},
[9] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_wall_lr, tile_empty},
[10] =
{tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty,
tile_wall_lr, tile_empty},
[11] =
{tile_empty, tile_empty,
tile_wall_rb, tile_wall_t,
tile_empty, tile_empty,
tile_wall_b, tile_wall_tb,
tile_wall_lrt, tile_empty},
[12] =
{tile_empty, tile_empty,
tile_wall_lr, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty, tile_wall_lr,
tile_empty},
[13] =
{tile_empty, tile_empty,
tile_wall_lr, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty, tile_wall_lr,
tile_empty},
[14] =
{tile_empty, tile_empty,
tile_wall_lb, tile_wall_tb,
tile_wall_tb, tile_wall_tb,
tile_wall_tb, tile_wall_tb,
tile_wall_lt, tile_empty},
[15] =
{tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty},
}, },
}, },
/* WALLS.png */ /* WALLS.png */
[7] = { [7] =
{
.name = "WALLS", .name = "WALLS",
.map = { .map =
[0] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, {
[1] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, [0] = {tile_empty, tile_empty,
[2] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty,
[3] = { tile_wall_tb, tile_wall_t, tile_empty, tile_empty, tile_wall_b, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_tb }, tile_empty, tile_empty,
[4] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty,
[5] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty},
[6] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, [1] = {tile_empty, tile_empty,
[7] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty,
[8] = { tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_t, tile_empty, tile_empty, tile_wall_b, tile_wall_tb, tile_wall_tb }, tile_empty, tile_empty,
[9] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty,
[10] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty},
[11] = { tile_wall_t, tile_empty, tile_empty, tile_wall_b, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_tb }, [2] = {tile_empty, tile_empty,
[12] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty,
[13] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty,
[14] = { tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_t, tile_empty, tile_empty, tile_wall_b }, tile_empty, tile_empty,
[15] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty }, tile_empty, tile_empty},
[3] = {tile_wall_tb, tile_wall_t,
tile_empty, tile_empty,
tile_wall_b, tile_wall_tb,
tile_wall_tb, tile_wall_tb,
tile_wall_tb, tile_wall_tb},
[4] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty},
[5] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty},
[6] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty},
[7] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty},
[8] = {tile_wall_tb, tile_wall_tb,
tile_wall_tb, tile_wall_tb,
tile_wall_t, tile_empty,
tile_empty, tile_wall_b,
tile_wall_tb, tile_wall_tb},
[9] = {tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty,
tile_empty, tile_empty},
[10] =
{tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty},
[11] =
{tile_wall_t, tile_empty,
tile_empty, tile_wall_b,
tile_wall_tb, tile_wall_tb,
tile_wall_tb, tile_wall_tb,
tile_wall_tb, tile_wall_tb},
[12] =
{tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty},
[13] =
{tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty},
[14] =
{tile_wall_tb, tile_wall_tb,
tile_wall_tb, tile_wall_tb,
tile_wall_tb, tile_wall_tb,
tile_wall_t, tile_empty,
tile_empty, tile_wall_b},
[15] =
{tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty, tile_empty, tile_empty,
tile_empty},
}, },
}, },
} }};
};

View File

@ -61,7 +61,7 @@ typedef enum {
#define WORLD_HEIGHT 10 #define WORLD_HEIGHT 10
typedef struct { typedef struct {
const char* name; const char *name;
tile_t map[WORLD_WIDTH][WORLD_HEIGHT]; tile_t map[WORLD_WIDTH][WORLD_HEIGHT];
} MapConfig; } MapConfig;

View File

@ -4,30 +4,33 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
void _Noreturn panic(const char* message) { void _Noreturn panic(const char *message) {
syscall(SYS_switch_to_text, 0); // ??? syscall(SYS_switch_to_text, 0); // ???
syscall(SYS_puts, (uintptr_t)message); syscall(SYS_puts, (uintptr_t)message);
syscall(SYS_exit, 1); syscall(SYS_exit, 1);
__builtin_unreachable(); __builtin_unreachable();
} }
#define check(expr) if (!(expr)){ panic( "Assertion failed at " __FILE__ ": " #expr "\n"); } #define check(expr) \
if (!(expr)) { \
panic("Assertion failed at " __FILE__ ": " #expr "\n"); \
}
typedef struct { typedef struct {
int x, y; int x, y;
} ivec2; } ivec2;
void* memcpy(void* dst, const void* src, uint32_t size) { void *memcpy(void *dst, const void *src, uint32_t size) {
uint8_t* d = (uint8_t*)dst; uint8_t *d = (uint8_t *)dst;
const uint8_t* s = (const uint8_t*)src; const uint8_t *s = (const uint8_t *)src;
for (uint32_t i = 0; i < size; i++) { for (uint32_t i = 0; i < size; i++) {
d[i] = s[i]; d[i] = s[i];
} }
return dst; return dst;
} }
void* memset(void* dst, int value, uint32_t size) { void *memset(void *dst, int value, uint32_t size) {
uint8_t* d = (uint8_t*)dst; uint8_t *d = (uint8_t *)dst;
uint8_t byte = (uint8_t)value; uint8_t byte = (uint8_t)value;
for (uint32_t i = 0; i < size; i++) { for (uint32_t i = 0; i < size; i++) {
d[i] = byte; d[i] = byte;
@ -42,20 +45,20 @@ typedef struct {
int len; int len;
} StringBuilder; } StringBuilder;
void StringBuilder_putc(StringBuilder* self, char ch) { void StringBuilder_putc(StringBuilder *self, char ch) {
if (self->len + 1 > STRING_BUILDER_CAPACITY) { if (self->len + 1 > STRING_BUILDER_CAPACITY) {
panic("string builder\n"); panic("string builder\n");
} }
self->buf[self->len++] = ch; self->buf[self->len++] = ch;
} }
void StringBuilder_append_cstr(StringBuilder* self, const char* str) { void StringBuilder_append_cstr(StringBuilder *self, const char *str) {
for (const char* p = str; *p; p++) { for (const char *p = str; *p; p++) {
StringBuilder_putc(self, *p); StringBuilder_putc(self, *p);
} }
} }
void StringBuilder_append_u32(StringBuilder* self, uint32_t x) { void StringBuilder_append_u32(StringBuilder *self, uint32_t x) {
char b[11]; char b[11];
int len = 0; int len = 0;
@ -80,11 +83,9 @@ void StringBuilder_append_u32(StringBuilder* self, uint32_t x) {
StringBuilder_append_cstr(self, b); StringBuilder_append_cstr(self, b);
} }
const char* StringBuilder_get_cstr(StringBuilder* self) { const char *StringBuilder_get_cstr(StringBuilder *self) {
StringBuilder_putc(self, 0); StringBuilder_putc(self, 0);
return self->buf; return self->buf;
} }
uint32_t time_ms(void) { uint32_t time_ms(void) { return (uint32_t)syscall(SYS_time_ms, 0); }
return (uint32_t)syscall(SYS_time_ms, 0);
}

View File

@ -3,24 +3,20 @@
#include <stdint.h> #include <stdint.h>
static const uint8_t VGA_GRAY_LUT[256] = { static const uint8_t VGA_GRAY_LUT[256] = {
16, 17, 23, 24, 20, 21, 23, 27, 22, 23, 28, 29, 25, 27, 30, 31, 16, 17, 23, 24, 20, 21, 23, 27, 22, 23, 28, 29, 25, 27, 30, 31, 16, 17, 18,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 18, 19, 21, 22, 23, 23,
18, 19, 21, 22, 23, 23, 23, 22, 22, 24, 26, 28, 30, 29, 28, 27, 23, 22, 22, 24, 26, 28, 30, 29, 28, 27, 26, 27, 27, 27, 28, 26, 23, 21, 26,
26, 27, 27, 27, 28, 26, 23, 21, 26, 26, 27, 27, 28, 28, 27, 27, 26, 27, 27, 28, 28, 27, 27, 27, 28, 29, 30, 30, 30, 30, 29, 29, 29, 29, 29,
27, 28, 29, 30, 30, 30, 30, 29, 29, 29, 29, 29, 30, 29, 28, 27, 30, 29, 28, 27, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 31, 30, 30,
28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 31, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 29, 29, 17, 17, 18, 18, 19, 19, 19, 18, 18, 19,
30, 30, 30, 30, 30, 30, 29, 29, 17, 17, 18, 18, 19, 19, 19, 18, 21, 22, 23, 23, 22, 21, 21, 21, 21, 22, 22, 21, 19, 18, 20, 21, 21, 21, 22,
18, 19, 21, 22, 23, 23, 22, 21, 21, 21, 21, 22, 22, 21, 19, 18, 22, 22, 21, 21, 22, 23, 23, 24, 23, 23, 23, 22, 23, 23, 23, 23, 22, 22, 21,
20, 21, 21, 21, 22, 22, 22, 21, 21, 22, 23, 23, 24, 23, 23, 23, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 23, 23, 23, 23, 23,
22, 23, 23, 23, 23, 22, 22, 21, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 22, 16, 17, 17, 17, 18, 17, 17, 17, 17, 18, 18, 19, 20, 20,
23, 23, 23, 23, 24, 24, 23, 23, 23, 23, 23, 23, 23, 23, 23, 22, 19, 19, 18, 19, 19, 19, 19, 18, 17, 17, 18, 18, 19, 19, 19, 19, 19, 19, 19,
16, 17, 17, 17, 18, 17, 17, 17, 17, 18, 18, 19, 20, 20, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 19, 19, 19, 19, 19, 19, 20,
18, 19, 19, 19, 19, 18, 17, 17, 18, 18, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 19, 20, 20, 20, 21, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 19, 19, 19, 19, 16, 16, 16, 16, 16, 16, 16, 16,
19, 19, 19, 20, 20, 20, 20, 20, 19, 20, 20, 20, 21, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 19, 16, 16, 16, 16, 16, 16, 16, 16,
}; };
static inline uint8_t vga_to_gray(uint8_t color){ static inline uint8_t vga_to_gray(uint8_t color) { return VGA_GRAY_LUT[color]; }
return VGA_GRAY_LUT[color];
}

View File

@ -1,17 +1,15 @@
#pragma once #pragma once
#include <stdint.h>
#include "misc_utils.h" #include "misc_utils.h"
#include <stdint.h>
typedef struct { typedef struct {
uint32_t state; uint32_t state;
} RandomEngine; } RandomEngine;
static void RandomEngine_init(RandomEngine* self) { static void RandomEngine_init(RandomEngine *self) { self->state = 0x6d2b79f5u; }
self->state = 0x6d2b79f5u;
}
static uint32_t RandomEngine_rnd(RandomEngine* self) { static uint32_t RandomEngine_rnd(RandomEngine *self) {
uint32_t x = self->state; uint32_t x = self->state;
if (x == 0) { if (x == 0) {
@ -27,8 +25,8 @@ static uint32_t RandomEngine_rnd(RandomEngine* self) {
return x; return x;
} }
static uint32_t RandomEngine_rnd_interval( static uint32_t RandomEngine_rnd_interval(RandomEngine *self, uint32_t from,
RandomEngine* self, uint32_t from, uint32_t until) { uint32_t until) {
check(from < until); check(from < until);
return from + RandomEngine_rnd(self) % (until - from); return from + RandomEngine_rnd(self) % (until - from);
} }

View File

@ -1,17 +1,16 @@
#include "../drivers/vga.h" #include "../drivers/vga.h"
#include "../syscall.h" #include "../syscall.h"
#include "keymapping.h"
#include "map_data.h"
#include "maps.h"
#include "misc_utils.h"
#include "pause_effect.h"
#include "random.h"
#include "sprite_data.h"
#include "sprites.h" #include "sprites.h"
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "misc_utils.h"
#include "keymapping.h"
#include "pause_effect.h"
#include "random.h"
#include "sprites.h"
#include "sprite_data.h"
#include "maps.h"
#include "map_data.h"
#define FRAME_SIZE (VGA_GRAPHICS_WIDTH * VGA_GRAPHICS_HEIGHT) #define FRAME_SIZE (VGA_GRAPHICS_WIDTH * VGA_GRAPHICS_HEIGHT)
@ -22,7 +21,7 @@
#define FONT_DIGIT_BASE 1 #define FONT_DIGIT_BASE 1
#define FONT_LETTER_BASE (FONT_DIGIT_BASE + 10) #define FONT_LETTER_BASE (FONT_DIGIT_BASE + 10)
uint8_t frame[FRAME_SIZE] = { 1 }; uint8_t frame[FRAME_SIZE] = {1};
#define SNAKE_GAMEMODE_MAX_APPLES 10 #define SNAKE_GAMEMODE_MAX_APPLES 10
#define SNAKE_GAMEMODE_DEFAULT_APPLES 5 #define SNAKE_GAMEMODE_DEFAULT_APPLES 5
@ -34,7 +33,6 @@ typedef enum {
game_screen_select_apple_count, game_screen_select_apple_count,
} game_screen_t; } game_screen_t;
#define SNAKE_START_Y 2 #define SNAKE_START_Y 2
#define SNAKE_START_HEAD_X 4 #define SNAKE_START_HEAD_X 4
#define SNAKE_START_PUPA_X 6 #define SNAKE_START_PUPA_X 6
@ -77,7 +75,8 @@ struct Snake {
bool have_game; bool have_game;
/* from 0 to PLAYABLE_MAPS_COUNT - 1 */ /* from 0 to PLAYABLE_MAPS_COUNT - 1 */
int selected_map_index; int selected_map_index;
/* from 1 to SNAKE_GAMEMODE_MAX_APPLES, default is SNAKE_GAMEMODE_DEFAULT_APPLES */ /* from 1 to SNAKE_GAMEMODE_MAX_APPLES, default is
* SNAKE_GAMEMODE_DEFAULT_APPLES */
int gamemode_apples_count; int gamemode_apples_count;
RandomEngine r_eng; RandomEngine r_eng;
@ -90,11 +89,11 @@ struct Snake {
/* If we are about to make a step into a wall, we start dying, /* If we are about to make a step into a wall, we start dying,
* we enter into dying mode, where we keep making steps, but the head * we enter into dying mode, where we keep making steps, but the head
* just disappears after walking, moving back. * just disappears after walking, moving back.
* When the pupa disappears this way, we enter 'awaiting postmortum' state, where * When the pupa disappears this way, we enter 'awaiting postmortum' state,
* nothing moves. * where nothing moves. If we are about to hit ourselves, we don't even
* If we are about to hit ourselves, we don't even move, * move, we immediately draw one small splash and enter 'awaiting
* we immediately draw one small splash and enter 'awaiting postmortum' state. * postmortum' state. There is no winning state, you just raise your score
* There is no winning state, you just raise your score until you are dead. * until you are dead.
*/ */
bool is_dying; bool is_dying;
int score; int score;
@ -102,7 +101,6 @@ struct Snake {
int puddle_sprite; int puddle_sprite;
ivec2 puddle_center; ivec2 puddle_center;
/* This stuff regulates game flow and animation progress */ /* This stuff regulates game flow and animation progress */
waiting_reason_t waiting_reason; waiting_reason_t waiting_reason;
uint32_t waiting_time; // Measures how much time we already accumulated uint32_t waiting_time; // Measures how much time we already accumulated
@ -124,7 +122,8 @@ void init_snake() {
bool place_random_apple() { bool place_random_apple() {
for (int t = 0; t < 50; t++) { for (int t = 0; t < 50; t++) {
uint32_t i = RandomEngine_rnd_interval(&snake.r_eng, 0, WORLD_WIDTH * WORLD_HEIGHT); uint32_t i = RandomEngine_rnd_interval(&snake.r_eng, 0,
WORLD_WIDTH * WORLD_HEIGHT);
if ((&snake.world[0][0])[i] == tile_empty) { if ((&snake.world[0][0])[i] == tile_empty) {
(&snake.world[0][0])[i] = tile_apple; (&snake.world[0][0])[i] = tile_apple;
return true; return true;
@ -143,8 +142,9 @@ bool place_random_apple() {
void start_snake_game() { void start_snake_game() {
snake.have_game = true; snake.have_game = true;
snake.game_screen = game_screen_gaming; snake.game_screen = game_screen_gaming;
const MapConfig* map_config = &map_list.maps[snake.selected_map_index]; const MapConfig *map_config = &map_list.maps[snake.selected_map_index];
memcpy(&snake.world[0][0], &map_config->map[0][0], sizeof(tile_t) * WORLD_WIDTH * WORLD_HEIGHT); memcpy(&snake.world[0][0], &map_config->map[0][0],
sizeof(tile_t) * WORLD_WIDTH * WORLD_HEIGHT);
memset(&snake.ghost_apples, 0, sizeof(snake.ghost_apples)); memset(&snake.ghost_apples, 0, sizeof(snake.ghost_apples));
for (int tx = SNAKE_START_HEAD_X; tx < SNAKE_START_PUPA_X; tx++) { for (int tx = SNAKE_START_HEAD_X; tx < SNAKE_START_PUPA_X; tx++) {
snake.world[tx][SNAKE_START_Y] = tile_snake_l; snake.world[tx][SNAKE_START_Y] = tile_snake_l;
@ -155,7 +155,8 @@ void start_snake_game() {
for (int app = 0; app < snake.gamemode_apples_count; app++) { for (int app = 0; app < snake.gamemode_apples_count; app++) {
place_random_apple(); place_random_apple();
} }
snake.new_snake_direction = snake.cur_snake_direction = snake_direction_left; snake.new_snake_direction = snake.cur_snake_direction =
snake_direction_left;
snake.is_dying = false; snake.is_dying = false;
snake.score = 0; snake.score = 0;
@ -166,12 +167,14 @@ void start_snake_game() {
} }
void set_tile(ivec2 pos, tile_t val) { void set_tile(ivec2 pos, tile_t val) {
check(0 <= pos.x && pos.x < WORLD_WIDTH && 0 <= pos.y && pos.y < WORLD_HEIGHT); check(0 <= pos.x && pos.x < WORLD_WIDTH && 0 <= pos.y &&
pos.y < WORLD_HEIGHT);
snake.world[pos.x][pos.y] = val; snake.world[pos.x][pos.y] = val;
} }
tile_t get_tile(ivec2 pos) { tile_t get_tile(ivec2 pos) {
check(0 <= pos.x && pos.x < WORLD_WIDTH && 0 <= pos.y && pos.y < WORLD_HEIGHT); check(0 <= pos.x && pos.x < WORLD_WIDTH && 0 <= pos.y &&
pos.y < WORLD_HEIGHT);
return snake.world[pos.x][pos.y]; return snake.world[pos.x][pos.y];
} }
@ -364,9 +367,8 @@ void put_pixel(int x, int y, uint8_t color) {
frame[y * VGA_GRAPHICS_WIDTH + x] = color; frame[y * VGA_GRAPHICS_WIDTH + x] = color;
} }
void draw_sprite( void draw_sprite(int dst_x, int dst_y, int sprite_width, int sprite_height,
int dst_x, int dst_y, int sprite_width, int sprite_height, const uint8_t *sprite) {
const uint8_t* sprite) {
for (int x = 0; x < sprite_width; x++) { for (int x = 0; x < sprite_width; x++) {
for (int y = 0; y < sprite_height; y++) { for (int y = 0; y < sprite_height; y++) {
uint8_t color = sprite[x * sprite_height + y]; uint8_t color = sprite[x * sprite_height + y];
@ -396,16 +398,17 @@ bool font_index_for_char(char ch, int *out_index) {
void draw_hud(const char *text) { void draw_hud(const char *text) {
// int lines_count = 1; // int lines_count = 1;
int y0 = HUD_OFFSET; int y0 = HUD_OFFSET;
for (const char* line_start = text; *line_start;) { for (const char *line_start = text; *line_start;) {
int glyph_count = 0; int glyph_count = 0;
const char* p = line_start; const char *p = line_start;
for (; *p != '\n' && *p != 0; p++) { for (; *p != '\n' && *p != 0; p++) {
glyph_count++; glyph_count++;
} }
if (glyph_count > 0) { if (glyph_count > 0) {
const int text_width = glyph_count * FONT_WIDTH + (glyph_count - 1) * GLYPH_SPACING; const int text_width =
glyph_count * FONT_WIDTH + (glyph_count - 1) * GLYPH_SPACING;
int x0 = VGA_GRAPHICS_WIDTH - HUD_OFFSET - text_width; int x0 = VGA_GRAPHICS_WIDTH - HUD_OFFSET - text_width;
for (const char* q = line_start; q != p; q++) { for (const char *q = line_start; q != p; q++) {
int glyph_index; int glyph_index;
check(font_index_for_char(*q, &glyph_index)); check(font_index_for_char(*q, &glyph_index));
draw_sprite(x0, y0, FONT_WIDTH, FONT_HEIGHT, draw_sprite(x0, y0, FONT_WIDTH, FONT_HEIGHT,
@ -484,7 +487,8 @@ void draw_game_world() {
continue; continue;
check((uint8_t)tt < TILE_SPRITES); check((uint8_t)tt < TILE_SPRITES);
draw_sprite(TILE_WIDTH * tx, TILE_WIDTH * ty - TILE_HEIGHT_OFFSET, draw_sprite(TILE_WIDTH * tx, TILE_WIDTH * ty - TILE_HEIGHT_OFFSET,
TILE_WIDTH, TILE_HEIGHT, &sprite_data.tile[tt].tex[0][0]); TILE_WIDTH, TILE_HEIGHT,
&sprite_data.tile[tt].tex[0][0]);
} }
} }
if (snake.game_screen != game_screen_gaming) { if (snake.game_screen != game_screen_gaming) {
@ -495,7 +499,7 @@ void draw_game_world() {
} }
void draw_game_text() { void draw_game_text() {
StringBuilder hud = { 0 }; StringBuilder hud = {0};
if (snake.game_screen == game_screen_gaming) { if (snake.game_screen == game_screen_gaming) {
if (snake.waiting_reason == waiting_reason_postmortum) { if (snake.waiting_reason == waiting_reason_postmortum) {
StringBuilder_append_cstr(&hud, "YOU DIED "); StringBuilder_append_cstr(&hud, "YOU DIED ");
@ -517,9 +521,11 @@ void draw_game_text() {
} else if (snake.game_screen == game_screen_select_map) { } else if (snake.game_screen == game_screen_select_map) {
StringBuilder_append_cstr(&hud, "SELECT LEVEL\nCURRENTLY SELECTED\n"); StringBuilder_append_cstr(&hud, "SELECT LEVEL\nCURRENTLY SELECTED\n");
check(snake.selected_map_index < PLAYABLE_MAPS_COUNT); check(snake.selected_map_index < PLAYABLE_MAPS_COUNT);
StringBuilder_append_cstr(&hud, map_list.maps[snake.selected_map_index].name); StringBuilder_append_cstr(&hud,
map_list.maps[snake.selected_map_index].name);
} else if (snake.game_screen == game_screen_select_apple_count) { } else if (snake.game_screen == game_screen_select_apple_count) {
StringBuilder_append_cstr(&hud, "SELECT DIFFICULTY\n" StringBuilder_append_cstr(&hud,
"SELECT DIFFICULTY\n"
"HOW MANY APPLES\nCURRENTLY SELECTED\n"); "HOW MANY APPLES\nCURRENTLY SELECTED\n");
StringBuilder_append_u32(&hud, snake.gamemode_apples_count); StringBuilder_append_u32(&hud, snake.gamemode_apples_count);
} }
@ -528,11 +534,10 @@ void draw_game_text() {
void draw_game_puddles() { void draw_game_puddles() {
if (snake.puddle_sprite >= 0) { if (snake.puddle_sprite >= 0) {
const PuddleSprite* sprite = &sprite_data.puddle[snake.puddle_sprite]; const PuddleSprite *sprite = &sprite_data.puddle[snake.puddle_sprite];
draw_sprite( draw_sprite(snake.puddle_center.x - PUDDLE_WIDTH / 2,
snake.puddle_center.x - PUDDLE_WIDTH / 2, snake.puddle_center.y - PUDDLE_WIDTH / 2, PUDDLE_WIDTH,
snake.puddle_center.y - PUDDLE_WIDTH / 2, PUDDLE_WIDTH, (&sprite->tex[0][0]));
PUDDLE_WIDTH, PUDDLE_WIDTH, (&sprite->tex[0][0]));
} }
} }
@ -585,7 +590,8 @@ int handle_incoming_keycode_after_halt(uint8_t keycode) {
if (snake.game_screen == game_screen_gaming) { if (snake.game_screen == game_screen_gaming) {
handle_gaming_keycode(keycode); handle_gaming_keycode(keycode);
} else if (snake.game_screen == game_screen_pause) { } else if (snake.game_screen == game_screen_pause) {
if (keycode == KEYCODE_1 || (keycode == KEYCODE_ENTER && !snake.have_game)) { if (keycode == KEYCODE_1 ||
(keycode == KEYCODE_ENTER && !snake.have_game)) {
snake.game_screen = game_screen_select_map; snake.game_screen = game_screen_select_map;
} else if (keycode == KEYCODE_ESCAPE && snake.have_game) { } else if (keycode == KEYCODE_ESCAPE && snake.have_game) {
snake.game_screen = game_screen_gaming; snake.game_screen = game_screen_gaming;
@ -675,38 +681,45 @@ void handle_time_difference(uint32_t time_diff) {
/* Step 1 */ /* Step 1 */
ivec2 old_head_pos = snake.snake_head; ivec2 old_head_pos = snake.snake_head;
if (tile_ahead == tile_empty || tile_ahead == tile_apple) { if (tile_ahead == tile_empty || tile_ahead == tile_apple) {
set_tile(tile_pos_ahead, set_tile(tile_pos_ahead, construct_straight_snake_tile(
construct_straight_snake_tile(snake.new_snake_direction)); snake.new_snake_direction));
snake.snake_head = tile_pos_ahead; snake.snake_head = tile_pos_ahead;
} }
/* Step 2 */ /* Step 2 */
set_tile(old_head_pos, construct_snake_tile( set_tile(old_head_pos,
get_opposite_direction(snake.cur_snake_direction), snake.new_snake_direction)); construct_snake_tile(
get_opposite_direction(snake.cur_snake_direction),
snake.new_snake_direction));
snake.cur_snake_direction = snake.new_snake_direction; snake.cur_snake_direction = snake.new_snake_direction;
/* Steps 3... */ /* Steps 3... */
if (is_tile_pupa(get_tile(snake.snake_tail))) { if (is_tile_pupa(get_tile(snake.snake_tail))) {
/* Step 3a */ /* Step 3a */
snake_direction_t pupa_dir = get_zero_pupa_destination(get_tile(snake.snake_tail)); snake_direction_t pupa_dir =
ivec2 penultimate_pos = world_walk_direction(snake.snake_tail, pupa_dir); get_zero_pupa_destination(get_tile(snake.snake_tail));
ivec2 penultimate_pos =
world_walk_direction(snake.snake_tail, pupa_dir);
set_tile(snake.snake_tail, tile_empty); set_tile(snake.snake_tail, tile_empty);
/* Step 4a */ /* Step 4a */
snake_direction_t penultimate_part_dir = get_snake_destination(get_tile(penultimate_pos)); snake_direction_t penultimate_part_dir =
set_tile(penultimate_pos, construct_zero_pupa(penultimate_part_dir)); get_snake_destination(get_tile(penultimate_pos));
set_tile(penultimate_pos,
construct_zero_pupa(penultimate_part_dir));
snake.snake_tail = penultimate_pos; snake.snake_tail = penultimate_pos;
/* WARNING: we updated snake_tail by moving pupa forward, we /* WARNING: we updated snake_tail by moving pupa forward, we
* WARNING: should check if we moved onto a ghost apple */ * WARNING: should check if we moved onto a ghost apple */
// check, this is important. This is the only place where we move pupa to a new pos // check, this is important. This is the only place where we
// we check for ghost apples. Clear ghost apples and enter // move pupa to a new pos we check for ghost apples. Clear ghost
// p1-waiting state (instead of remaining in step awaiting state) // apples and enter p1-waiting state (instead of remaining in
// step awaiting state)
if (snake.snake_tail.x == snake.snake_head.x && if (snake.snake_tail.x == snake.snake_head.x &&
snake.snake_tail.y == snake.snake_head.y snake.snake_tail.y == snake.snake_head.y) {
) {
snake.waiting_reason = waiting_reason_postmortum; snake.waiting_reason = waiting_reason_postmortum;
return; return;
} }
if (snake.ghost_apples[penultimate_pos.x][penultimate_pos.y]) { if (snake.ghost_apples[penultimate_pos.x][penultimate_pos.y]) {
snake.ghost_apples[penultimate_pos.x][penultimate_pos.y] = 0; snake.ghost_apples[penultimate_pos.x][penultimate_pos.y] =
0;
syscall(SYS_set_beep, WEIRD_SOUND); syscall(SYS_set_beep, WEIRD_SOUND);
snake.waiting_reason = waiting_reason_p1; snake.waiting_reason = waiting_reason_p1;
@ -716,7 +729,8 @@ void handle_time_difference(uint32_t time_diff) {
} }
} else { } else {
snake_direction_t tail_dir = get_snake_destination(get_tile(snake.snake_tail)); snake_direction_t tail_dir =
get_snake_destination(get_tile(snake.snake_tail));
set_tile(snake.snake_tail, construct_zero_pupa(tail_dir)); set_tile(snake.snake_tail, construct_zero_pupa(tail_dir));
syscall(SYS_set_beep, WEIRD_SOUND); syscall(SYS_set_beep, WEIRD_SOUND);
@ -737,7 +751,8 @@ void handle_time_difference(uint32_t time_diff) {
snake.waiting_reason = waiting_reason_cross; snake.waiting_reason = waiting_reason_cross;
} else if (snake.waiting_reason == waiting_reason_cross) { } else if (snake.waiting_reason == waiting_reason_cross) {
/* Finished pupa hatching */ /* Finished pupa hatching */
snake_direction_t tail_dir = get_zero_pupa_destination(get_tile(snake.snake_tail)); snake_direction_t tail_dir =
get_zero_pupa_destination(get_tile(snake.snake_tail));
set_tile(snake.snake_tail, construct_straight_snake_tile(tail_dir)); set_tile(snake.snake_tail, construct_straight_snake_tile(tail_dir));
syscall(SYS_set_beep, 0); syscall(SYS_set_beep, 0);
snake.waiting_reason = waiting_reason_step; snake.waiting_reason = waiting_reason_step;
@ -764,8 +779,9 @@ int main(void) {
uint32_t prev_time = time_ms(); uint32_t prev_time = time_ms();
while (1) { while (1) {
/* Returned from halt, we can enjoy keyboard input and animation progress*/ /* Returned from halt, we can enjoy keyboard input and animation
for (int ch;(ch = syscall(SYS_getc, 0)) >= 0;) { * progress*/
for (int ch; (ch = syscall(SYS_getc, 0)) >= 0;) {
int ret = handle_incoming_keycode_after_halt((uint8_t)ch); int ret = handle_incoming_keycode_after_halt((uint8_t)ch);
if (ret == 1) if (ret == 1)
goto quit; goto quit;
@ -783,9 +799,8 @@ int main(void) {
prev_time = current_time; prev_time = current_time;
syscall(SYS_halt, 0); syscall(SYS_halt, 0);
} }
quit: quit:
syscall(SYS_switch_to_text, 0); syscall(SYS_switch_to_text, 0);
syscall(SYS_puts, (uintptr_t)"Quit from game\n"); syscall(SYS_puts, (uintptr_t)"Quit from game\n");
return 0; return 0;

View File

@ -2,7 +2,6 @@
#include "sprites.h" #include "sprites.h"
static const SpriteData sprite_data = { static const SpriteData sprite_data = {
.tile = { .tile = {
[0] = { /* slot 0: zero-filled */ [0] = { /* slot 0: zero-filled */

View File

@ -27,7 +27,7 @@ typedef struct {
} PuddleSprite; } PuddleSprite;
#define TILE_SPRITES 50 #define TILE_SPRITES 50
#define FONT_SPRITES (1+10+26) #define FONT_SPRITES (1 + 10 + 26)
#define PUDDLE_SPRITES 5 #define PUDDLE_SPRITES 5
typedef struct { typedef struct {
@ -35,4 +35,3 @@ typedef struct {
FontSprite font[FONT_SPRITES]; FontSprite font[FONT_SPRITES];
PuddleSprite puddle[PUDDLE_SPRITES]; PuddleSprite puddle[PUDDLE_SPRITES];
} SpriteData; } SpriteData;

View File

@ -1,19 +1,19 @@
#include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdio.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h>
#include <unistd.h>
enum { enum {
MBR_END = 510, MBR_END = 510,
}; };
int main(int argc, char* argv[]) { int main(int argc, char *argv[]) {
if (argc != 3) { if (argc != 3) {
fprintf(stderr, "Usage: %s mbr.bin fs.img\n", argv[0]); fprintf(stderr, "Usage: %s mbr.bin fs.img\n", argv[0]);
return 1; return 1;
} }
const char* filename = argv[1]; const char *filename = argv[1];
const char* fsimg_path = argv[2]; const char *fsimg_path = argv[2];
int fd = open(filename, O_RDWR); int fd = open(filename, O_RDWR);
off_t length = lseek(fd, 0, SEEK_END); off_t length = lseek(fd, 0, SEEK_END);
if (length > MBR_END) { if (length > MBR_END) {

View File

@ -3,15 +3,15 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
char* basename(char* path) { char *basename(char *path) {
char* c = strrchr(path, '/'); char *c = strrchr(path, '/');
if (c && *c) { if (c && *c) {
return c + 1; return c + 1;
} }
return path; return path;
} }
int main(int argc, char* argv[]) { int main(int argc, char *argv[]) {
char sector[sector_size]; char sector[sector_size];
struct dir dir = {{0}}; struct dir dir = {{0}};
@ -20,7 +20,7 @@ int main(int argc, char* argv[]) {
return 1; return 1;
} }
FILE* image = fopen(argv[1], "wb"); FILE *image = fopen(argv[1], "wb");
if (!image) { if (!image) {
perror(argv[1]); perror(argv[1]);
return 1; return 1;
@ -33,12 +33,12 @@ int main(int argc, char* argv[]) {
uint32_t sector_offset = 1; uint32_t sector_offset = 1;
for (int i = 2; i < argc; ++i) { for (int i = 2; i < argc; ++i) {
char* name = argv[i]; char *name = argv[i];
struct dirent *dirent = &dir.entries[i-2]; struct dirent *dirent = &dir.entries[i - 2];
dirent->offset_sectors = sector_offset; dirent->offset_sectors = sector_offset;
dirent->size_bytes = 0; dirent->size_bytes = 0;
FILE* file = fopen(name, "rb"); FILE *file = fopen(name, "rb");
if (!file) { if (!file) {
perror(name); perror(name);
return 1; return 1;

View File

@ -2,7 +2,7 @@
#include <stdint.h> #include <stdint.h>
int main() { int main() {
const char* message = "I hope the kernel does not panic...\n"; const char *message = "I hope the kernel does not panic...\n";
syscall(SYS_puts, (uint32_t)message); syscall(SYS_puts, (uint32_t)message);
syscall(SYS_puts, 0x1bad1dea); syscall(SYS_puts, 0x1bad1dea);
return 0; return 0;

View File

@ -3,16 +3,13 @@
int main(); int main();
int syscall(int call, uintptr_t arg) { int syscall(int call, uintptr_t arg) {
asm volatile("int $0x84": "+a"(call) : "b"(arg)); asm volatile("int $0x84" : "+a"(call) : "b"(arg));
return call; return call;
} }
_Noreturn _Noreturn void _exit(int exit_status) {
void _exit(int exit_status) {
syscall(SYS_exit, exit_status); syscall(SYS_exit, exit_status);
__builtin_unreachable(); __builtin_unreachable();
} }
void _start() { void _start() { _exit(main()); }
_exit(main());
}

View File

@ -1,3 +1 @@
int main() { int main() { return 1; }
return 1;
}

View File

@ -1,9 +1,7 @@
#include "../syscall.h" #include "../syscall.h"
#include <stdint.h> #include <stdint.h>
static uint32_t time_ms(void) { static uint32_t time_ms(void) { return (uint32_t)syscall(SYS_time_ms, 0); }
return (uint32_t)syscall(SYS_time_ms, 0);
}
static void wait_ms(uint32_t duration_ms) { static void wait_ms(uint32_t duration_ms) {
uint32_t start = time_ms(); uint32_t start = time_ms();

View File

@ -1,7 +1,7 @@
#include "../syscall.h" #include "../syscall.h"
#include <stdint.h> #include <stdint.h>
void userspace_puts(const char* s) { void userspace_puts(const char *s) {
char c; char c;
while ((c = *s++)) { while ((c = *s++)) {
syscall(SYS_putc, c); syscall(SYS_putc, c);
@ -9,9 +9,9 @@ void userspace_puts(const char* s) {
} }
int main() { int main() {
const char* spell = "cra cra trif traf not sgnieflet\n"; const char *spell = "cra cra trif traf not sgnieflet\n";
const char* spell2 = "Pam pam pam pam parapapapapam\n"; const char *spell2 = "Pam pam pam pam parapapapapam\n";
const char* spell3 = "Zhopu podotri\n"; const char *spell3 = "Zhopu podotri\n";
// userspace_puts(spell); // userspace_puts(spell);
syscall(SYS_puts, (uintptr_t)spell); syscall(SYS_puts, (uintptr_t)spell);
syscall(SYS_puts, (uint32_t)spell2); syscall(SYS_puts, (uint32_t)spell2);