From 866a6ca0e749f4446b7fdc7579a6d553df85ec10 Mon Sep 17 00:00:00 2001 From: Christian Cunningham Date: Wed, 5 Jan 2022 14:27:09 -0800 Subject: Moved includes to its own directory --- include/cpu/atomic/swap.h | 40 ++ include/cpu/irq.h | 23 ++ include/drivers/uart.h | 15 + include/graphics/drawer.h | 27 ++ include/graphics/font.bin.h | 178 +++++++++ include/graphics/glyphs.h | 6 + include/graphics/homer.h | 400 +++++++++++++++++++ include/graphics/lfb.h | 28 ++ include/graphics/mbox.h | 27 ++ include/graphics/philosopher_toad.h | 764 ++++++++++++++++++++++++++++++++++++ include/lib/ll.h | 24 ++ include/lib/mem.h | 25 ++ include/lib/q.h | 30 ++ include/lib/strings.h | 10 + include/symbols.h | 101 +++++ include/sys/core.h | 55 +++ include/sys/kernel.h | 8 + include/sys/power.h | 6 + include/sys/timer.h | 10 + include/util/mutex.h | 17 + include/util/status.h | 6 + include/util/time.h | 26 ++ 22 files changed, 1826 insertions(+) create mode 100644 include/cpu/atomic/swap.h create mode 100644 include/cpu/irq.h create mode 100644 include/drivers/uart.h create mode 100644 include/graphics/drawer.h create mode 100644 include/graphics/font.bin.h create mode 100644 include/graphics/glyphs.h create mode 100644 include/graphics/homer.h create mode 100644 include/graphics/lfb.h create mode 100644 include/graphics/mbox.h create mode 100644 include/graphics/philosopher_toad.h create mode 100644 include/lib/ll.h create mode 100644 include/lib/mem.h create mode 100644 include/lib/q.h create mode 100644 include/lib/strings.h create mode 100644 include/symbols.h create mode 100644 include/sys/core.h create mode 100644 include/sys/kernel.h create mode 100644 include/sys/power.h create mode 100644 include/sys/timer.h create mode 100644 include/util/mutex.h create mode 100644 include/util/status.h create mode 100644 include/util/time.h (limited to 'include') diff --git a/include/cpu/atomic/swap.h b/include/cpu/atomic/swap.h new file mode 100644 index 0000000..cbed62c --- /dev/null +++ b/include/cpu/atomic/swap.h @@ -0,0 +1,40 @@ +#ifndef CPU_ATOMIC_SWAP_A_H +#define CPU_ATOMIC_SWAP_A_H +#include "../../util/mutex.h" + +/// https://stackoverflow.com/questions/16329123/use-of-strexeq-instead-of-strex-for-spinlock-implementation-in-arm +/// https://elixir.bootlin.com/linux/v4.9/source/arch/arm/include/asm/spinlock.h +/// https://elixir.bootlin.com/linux/v4.9/source/arch/arm/include/asm/spinlock_types.h#L23 +/// https://www.cs.uic.edu/~jbell/CourseNotes/OperatingSystems/3_Processes.html +/// https://developer.arm.com/documentation/dht0008/a/arm-synchronization-primitives/practical-uses/implementing-a-semaphore?lang=en + +// TODO: Once scheduling works, have a failed lock put thread in waiting state +static inline void atm_lock(unsigned long pid, unsigned long* addr) +{ + unsigned long tmp, current_lock_value; + asm volatile( +"1: ldrex %0, [%3]\n" +" cmp %0, #0\n" +" wfene\n" +" strexeq %1, %2, [%3]\n" +" teq %1, #0\n" +" bne 1b\n" +" dmb" + : "=&r" (current_lock_value), "=&r" (tmp) + : "r" (pid), "r" (addr) + : "cc"); +} + +static inline void atm_release(unsigned long* addr) +{ + unsigned long cleared = NULL_PID; + asm volatile( +" dmb\n" +" str %0, [%1]\n" +" dsb\n" +" sev" + :: "r" (cleared), "r" (addr) + : "cc"); +} + +#endif diff --git a/include/cpu/irq.h b/include/cpu/irq.h new file mode 100644 index 0000000..3b8f085 --- /dev/null +++ b/include/cpu/irq.h @@ -0,0 +1,23 @@ +#ifndef CPU_IRQ_H +#define CPU_IRQ_H + +static inline void enableirq(void) +{ + asm volatile("cpsie i"); +} +static inline void disableirq(void) +{ + asm volatile("cpsid i"); +} +static inline void enablefiq(void) +{ + asm volatile("cpsie f"); +} +static inline void disablefiq(void) +{ + asm volatile("cpsid f"); +} + +void c_irq_handler(void); + +#endif diff --git a/include/drivers/uart.h b/include/drivers/uart.h new file mode 100644 index 0000000..b83732f --- /dev/null +++ b/include/drivers/uart.h @@ -0,0 +1,15 @@ +#ifndef DRIVERS_UART_H +#define DRIVERS_UART_H + +#define PRINTS_DBG(X) uart_char('[');uart_string(__FILE__);uart_char(':');uart_10(__LINE__);uart_string("] ");uart_string(X);uart_char('\n'); +#define PRINTX_DBG(X) uart_char('[');uart_string(__FILE__);uart_char(':');uart_10(__LINE__);uart_string("] ");uart_hex((unsigned long)X);uart_char('\n'); +#define PRINTI_DBG(X) uart_char('[');uart_string(__FILE__);uart_char(':');uart_10(__LINE__);uart_string("] ");uart_10((unsigned long)X);uart_char('\n'); + +extern void uart_char(unsigned char c); +extern void uart_string(char* message); +extern void uart_hex(unsigned long data); + +void uart_10(unsigned long); +void uart_hexn(unsigned long); + +#endif diff --git a/include/graphics/drawer.h b/include/graphics/drawer.h new file mode 100644 index 0000000..6d97163 --- /dev/null +++ b/include/graphics/drawer.h @@ -0,0 +1,27 @@ +#ifndef GRAPHICS_DRAWER_H +#define GRAPHICS_DRAWER_H + +struct Drawer { + unsigned int x; + unsigned int y; +}; + +#ifndef GRAPHICS_DRAWER_C +extern struct Drawer g_Drawer; +#endif + +void write_cchar(struct Drawer* d, char s, unsigned int c); +void write_char(struct Drawer* d, char s); + +void write_cstring(struct Drawer* d, char* s, unsigned int c); +void write_string(struct Drawer* d, char* s); + +void write_chex32(struct Drawer* d, unsigned long val, unsigned int c); +void write_hex32(struct Drawer* d, unsigned long val); + +void write_c10(struct Drawer* d, unsigned long val, unsigned int c); +void write_10(struct Drawer* d, unsigned long val); + +void set_drawer(struct Drawer* d, unsigned int x, unsigned int y); + +#endif diff --git a/include/graphics/font.bin.h b/include/graphics/font.bin.h new file mode 100644 index 0000000..f883cda --- /dev/null +++ b/include/graphics/font.bin.h @@ -0,0 +1,178 @@ +enum { + GLYPH_X = 8, + GLYPH_Y = 16, +}; +unsigned char glyphs[] = { + 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, + 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, 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, 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, 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, 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, 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, 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, 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, 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, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14, 0x14, 0x14, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x48, + 0x68, 0xfe, 0x24, 0x24, 0x7f, 0x14, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x7c, 0x92, 0x12, 0x1c, 0x70, 0x90, 0x92, 0x7c, + 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 0x09, 0x46, 0x38, + 0x66, 0x90, 0x90, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, + 0x04, 0x04, 0x0c, 0x92, 0xb2, 0xa2, 0x46, 0xbc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x10, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x08, 0x08, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x92, 0x7c, 0x38, 0xd6, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x7f, + 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x08, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 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, 0x40, + 0x20, 0x20, 0x10, 0x10, 0x18, 0x08, 0x08, 0x04, 0x04, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x38, 0x44, 0x82, 0x82, 0x92, 0x82, 0x82, 0x44, 0x38, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, + 0xc2, 0x80, 0x80, 0x40, 0x30, 0x18, 0x04, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7c, 0x82, 0x80, 0xc0, 0x38, 0xc0, 0x80, 0xc2, 0x7c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x50, 0x58, 0x48, 0x44, + 0x42, 0xfe, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, + 0x02, 0x02, 0x3e, 0xc0, 0x80, 0x80, 0xc2, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x78, 0x84, 0x02, 0x7a, 0xc6, 0x82, 0x82, 0xc4, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x40, 0x40, 0x20, 0x20, + 0x10, 0x18, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, + 0x82, 0x82, 0x82, 0x7c, 0x82, 0x82, 0x86, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3c, 0x46, 0x82, 0x82, 0xc6, 0xbc, 0x80, 0x42, 0x3c, + 0x00, 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, 0x08, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x70, 0x0e, 0x0e, 0x70, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, + 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x1c, 0xe0, 0xe0, 0x1c, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1c, 0x22, 0x20, 0x10, 0x08, 0x08, 0x00, 0x08, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xcc, 0x84, 0xe2, 0x92, + 0x92, 0x92, 0xe2, 0x04, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x28, 0x28, 0x28, 0x44, 0x44, 0x7c, 0xc6, 0x82, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7e, 0x82, 0x82, 0x82, 0x7e, 0x82, 0x82, 0x82, 0x7e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x84, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, + 0x42, 0x82, 0x82, 0x82, 0x82, 0x82, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0x02, 0x02, 0x02, 0xfe, 0x02, 0x02, 0x02, 0xfe, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x02, 0x02, 0x02, 0xfe, + 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, + 0x84, 0x02, 0x02, 0xc2, 0x82, 0x82, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x82, 0x82, 0x82, 0x82, 0xfe, 0x82, 0x82, 0x82, 0x82, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x42, 0x22, 0x12, 0x0a, 0x0e, 0x12, 0x22, 0x22, 0x42, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, + 0xc6, 0xaa, 0xaa, 0xaa, 0x92, 0x82, 0x82, 0x82, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x86, 0x86, 0x8a, 0x8a, 0x92, 0xa2, 0xa2, 0xc2, 0xc2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x82, 0x82, 0x82, + 0x82, 0x82, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, + 0xc2, 0x82, 0x82, 0xc2, 0x7e, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x38, 0x44, 0x82, 0x82, 0x82, 0x82, 0x82, 0x44, 0x78, + 0x60, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xc2, 0x82, 0x82, 0x7e, + 0x42, 0x82, 0x82, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, + 0x86, 0x02, 0x06, 0x7c, 0xc0, 0x80, 0xc2, 0x7d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x82, 0x82, 0x82, 0x82, + 0x82, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, + 0xc6, 0x44, 0x44, 0x44, 0x28, 0x28, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x81, 0x81, 0x81, 0x5a, 0x5a, 0x5a, 0x66, 0x66, 0x66, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x44, 0x28, 0x38, 0x10, + 0x28, 0x6c, 0x44, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, + 0x22, 0x14, 0x14, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0xc0, 0x60, 0x20, 0x10, 0x08, 0x0c, 0x06, 0xfe, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x04, 0x04, 0x08, 0x08, 0x18, 0x10, 0x10, 0x20, 0x20, 0x40, 0x00, 0x00, + 0x00, 0x1c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x14, 0x22, 0x63, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, + 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x40, + 0x7c, 0x42, 0x62, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, + 0x02, 0x3e, 0x66, 0x42, 0x42, 0x42, 0x66, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x02, 0x02, 0x02, 0x44, 0x38, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x7c, 0x66, 0x42, + 0x42, 0x42, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3c, 0x66, 0x42, 0x7e, 0x02, 0x46, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x08, 0x08, 0x08, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x66, 0x42, + 0x42, 0x42, 0x66, 0x5c, 0x40, 0x44, 0x38, 0x00, 0x00, 0x02, 0x02, 0x02, + 0x02, 0x3a, 0x46, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x0e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1c, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0e, 0x00, 0x00, 0x02, 0x02, 0x02, + 0x02, 0x22, 0x12, 0x0a, 0x0e, 0x12, 0x22, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x92, 0x92, + 0x92, 0x92, 0x92, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3a, 0x46, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x42, 0x66, 0x3c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x66, 0x42, + 0x42, 0x42, 0x66, 0x3e, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7c, 0x66, 0x42, 0x42, 0x42, 0x66, 0x5c, 0x40, 0x40, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x4c, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x02, + 0x3c, 0x40, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x08, 0x7e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x62, 0x5c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x66, 0x24, + 0x24, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x81, 0x81, 0x5a, 0x5a, 0x5a, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x24, 0x18, 0x18, 0x18, 0x24, 0x66, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x44, 0x24, + 0x24, 0x28, 0x18, 0x10, 0x10, 0x08, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7e, 0x40, 0x20, 0x18, 0x04, 0x02, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x08, 0x08, 0x08, 0x08, 0x06, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x0e, 0x08, 0x08, + 0x08, 0x08, 0x30, 0x08, 0x08, 0x08, 0x08, 0x08, 0x06, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x62, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff +}; +unsigned int src_graphics_font_bin_len = 2048; diff --git a/include/graphics/glyphs.h b/include/graphics/glyphs.h new file mode 100644 index 0000000..1a9319d --- /dev/null +++ b/include/graphics/glyphs.h @@ -0,0 +1,6 @@ +#ifndef GRAPHICS_GLYPHS_H +#define GRAPHICS_GLYPHS_H + +#include "font.bin.h" + +#endif diff --git a/include/graphics/homer.h b/include/graphics/homer.h new file mode 100644 index 0000000..459bc3d --- /dev/null +++ b/include/graphics/homer.h @@ -0,0 +1,400 @@ +/* GIMP header image file format (RGB) */ + +static unsigned int homer_width = 96; +static unsigned int homer_height = 64; + +/* Call this macro repeatedly. After each use, the pixel data can be extracted */ + +#define HEADER_PIXEL(data,pixel) {\ +pixel[0] = (((data[0] - 33) << 2) | ((data[1] - 33) >> 4)); \ +pixel[1] = ((((data[1] - 33) & 0xF) << 4) | ((data[2] - 33) >> 2)); \ +pixel[2] = ((((data[2] - 33) & 0x3) << 6) | ((data[3] - 33))); \ +data += 4; \ +} + +static char *homer_data = + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!1)$!Q5*$2=C$\"9B#!U5%BUM'3R((#Z-%S%T#!Y7!A-&!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!#R-?$REJ%2YP%C%W'3F%$BAI$2AM*DJ:#B%7$\"%9%2YR(#^*!A-&" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!#B5A%B]Y$BMK\"1I0'4*+\"B)B!!!!\"1];$\"QV$3>#$C9`$2]T#R9F(D&1" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!#\"1D%S=\\!19,#B)A$B-?(C9N+CMI34Q=?'9>BWY>?75=75E7.T)I'\"E=" + ")4)]!!!\"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!1-%%S-X\"QY9#R)>(\"QD=6=FJHUHY\\-L`_1J`_E?`_9A`_AA`_IH`^YIVLM@" + "F9%O5&*#!1I9\"QQ3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!%3!\\'2=BFXEU:UU?QJ%VW;EI_^-B`^EA`^EA`^IB`^IB`^IA`^IB`^QA" + "`^EB\\^%^K*NK!QQC\"AI2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!$BUR'BI7P:1ZV+-I6IKV*UOT;%JL9!NU[=K`^QD`^I@`^IB`^IB`^IB`^IB`^IB`^IB`^IB" + "`^MA`^IC`N9<_^^3A(RD%2IG!!!!!!!!!!!!!!!!!!!#!!!!!!-*!!!%!!!!!!9," + "!!!$!!!'!!%\"!!5/$\"-=!!!%!!!!!!!!!!!&#\"!9!!5.!!!!!!!!!!%\"!!!$!!!$" + "!!%'!!!!!!!$!!!!!!=1#A]:!!!&!!!!!!!\"!!50#!Y8!!)*!!!!!!!$!!!+!!-*" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "#RANE7QKS*=NUJQOT;!LT:UM\\M1F`^M@`^I@`^IB`^IB`^IB`^IB`^IB`^IB`^IB" + "`^IB`^IB`^ED`NIH[>2V.%*/!!!!!!!!!!!!\"1A+=Y'.O<`$8WJ^DZGCP-,)3&NN" + "G;7MK\\;])$64I\\#ZQ]H-J\\#U(CU_$C-PH[KRR-P1LLH\"(DB0!!!!(#Y^I+WXL,;^" + ";(\"]OM$'=([/(D\"&KLD!QML/I[SR'3M['#M]JL+`R-H*K<3\\&SV&=Y?:PM@-78+(" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!QU:" + ".CU?WKAUT;%JU*YOTK!MTJQK_N-G`^E>`^IB`^IB`^IB`^IB`^IB`^IB`^IB`^IB" + "`^IB`^IB`NMA_^I?`_^)/9" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1%\"!R)G" + "FX5OV;)NTJYMTJ]LTJ]LT[%I_N5E`^IB`^IB`^IB`^IB`^IB`^IB`^IB`^IB`^IB" + "`^IB`^IB`^M@`^AC`.US`_W6%\"QO!!!!!!!!!Q5(?I3/`@\\_LL#Q[?@H````F*/4" + "````J[?HY?,B\\/XOH;#@```_R=D,P=$\"````J+;I\\O\\P[/PO!!U;'3)OX/,H_`PZ" + "HJ[?````F:C=X?$C]P,SH*[@_PL[S=L,Q-$%````G:K<\\O`OZ/DL>H[%````9XC1" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!-((31P" + "R*=QU*YJTJ]LTJ]LTJ]LU+)K_N5E`^EA`^IB`^IB`^IB`^IB`^IB`^IB`^IB`^IB" + "`^IB`^IB`^IB`^EC`>AB``/\"8&R1!AQ=!!!!!1)$9W^[_@L]S]X/^P^,T-+6$BAK!1)%!!!!0UJ6]@0V````Z/0DYO,B````" + "````6'W$ZO@G\\?XNHJ_B`P``RML,Q-0&````J+?I\\O\\PZOHM!!U<'#)NX?,G_PT[" + "E*#1````F*C\\_`O[?TM77S!^`4S+TV4" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!AA.4%=Y" + "TZUMT+!NTJ]LTJ]LTZ]LT*QI_.%H`NM?`NE@`^MA`_9@`_=B`_%9`NE?`^EC`^E>" + "`^AB`NAA`^Q:`_-=`_1B`^YA^.RCDIRO&2YJ!!!!,TF$Z?DH`P``R=<'R=8(````" + "`0PX7XS>PM@,_0HYT-\\/````N,X$M!!51'CEXX/0E_@P[" + "EZ+6````G*[HR]X0_PL[T=T/````NLX!L\\?`````S]T._@HVV.L>8X'+\\_\\J1V6N" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!-*1U9^" + "TJMKTZ]MTZ]LTJ]LTJ]KSZQJ[M)J`^I@_.ABW-%OE(IMAG]JO+%W^N5N_>A@`.I;" + "`.AC_>=CZ=9VIY]QG9-OS,)T_>ARS<6L+$2#!!!!(CEUU^D;^`DYJL3]GKCW_@LY" + "Y/4I0%60.6:N]@,V_@L[\\@$S2VJH0&\"=\\?`S_PPY_PX]4G;\"!!!!(#Z\"W>`@]P4T" + "DZ+4`0X^F+/T3GO%^P8V_PP[]0(R37\"W1&>K[OXQ_@LW_@H[06NZ>YG6```_5GC&" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!-(*#QO" + "S:ERTJ]KTJ]LTJ]LTJ]LT:QMY<=GPKAHD96EDYW;Q]84T.(&CAX!!%'!!!&&CE[0%F:(#V!!!)'!!!!\"1I0%2]N%\"]P" + "%\"QH%\"]P$2MH!!!$'CI\\15Z<&SI_!!!\"!!)'&S5W0%F8(#U_!A5+$\"EE&CA^#B5B" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)$#2-A" + "P:-YTK!ITJ]LTJ]LTJ]KWK=T?6I1%1^,C]C$\"%6!!)(!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\"\"!?" + "4$QCX+ERT:]MTJYNTJYJ=&UX]P,T``T_]P,T[OLK`````P\\_`P\\_`P\\^`@X\\````" + ">H:Y[?HK```_`P\\_`P\\_````\\?TNXN\\AV^45%#B#!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1)'&S-O4V&*8&F(" + "0%&\"#QY4!!%'!!-)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!)$!!E@,#5D,#UN-#]MOJ)VRZIIXM)EI:%J%BQL!!!#!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + ")C=QSJENU;!LUK%MRZ=KCY\"K_PL\\`@X^@8N^(2U>`````````P\\_`P\\_`P\\_````" + "L[_QR]@)```_`@X^`@X^````KKCK35J,_P8P#\"Q\\!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)$&C1QDH!WRJ9ISJIH" + "TK5P/$-J-4%O*#EN\"2-F!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!1-&%BQOFXYR]MEB^^EHD(9FAW!FY<%N_NAD`>I>C(QQ$29E!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "%#!TGX9FV+5TOI]JRZAOF)NY`@T^```_RM0'H*S=`````P\\_`P\\_`P\\_`P\\_````" + "L+SMR]@)`````@X^_`P\\`@X^^P4W^`8ZR=$!$SJ%!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\"AU2;6=YTK%OVK%I^>)G" + "DX=IE()NT:QMTZIO:65Q$REL!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!\"QU9=6MP]=1H`?!>`^A@``!G@W9EJH]MW\\5IY--?RKIH+T9^!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)$\"B%?" + "!AY>>6UKL)-M.3AAG8=GC8B7^@8W`0X^`````````@X^`P\\_`P\\_`P\\_`P\\^````" + ":72HM\\#UM<#KHZO1CY.SE)J`Q]8&````5FJI&3-R!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!QM3)3QX;&!A?W!KJI]DMJIL" + "A'!DW[=UZLUD^^-B_N-K5F%R!AA.!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!1E4!!UJ+SQM=F1DWK9O]N!A`^ME`NI7[=MX/#9:?W)EEXM>F(QH/DAM!!UB" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!A5*&3>\"" + "#S\"\"7V!Y>6ECL)5X;6!A@V]FT=L.`````@X_`P\\_`P\\_`P\\_`P\\``P\\`````KK?T" + "9VUXQL\"@TLB4X=B6]>FAZ^S';'&8AI;0(3E\\!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!AQ8/4=PLYAOV;]FX])FS;]B9V5A" + "FX-K[,QI`NM?`_1FK:-A9F)H%BQM!A]?!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!%%)35HQKEQ]MY@MZQI6U!BW+EO^^1D`^]O3DM9N:5K_>1D`^ED`^AB_^9S7V5Z" + "\"1QB!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!A5)#BUT" + "$#![04=U;6)FTZMR`^YWFY^E)#=Q#!Y3!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$RAEJ9!RV[5G`.AA`^EF`^I=_.5I" + ">'%HWLIJ_^AH8%Q9D7UORZ9PN)QX.T5Q!15-!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "$\");D8YI`^U=`^I@`_1DT\\9J75A:S+)Q9EU=Q:QR`^Y@`^IA`NI?`^M>`NI8Y-R4" + "\"1U=!!%$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1-'$2YX" + "$\"AJ%R5:85MHUZYNF8-EI8=LRZIS;FIUO=?`>AB`^AA`NIC`^AD[=-D:6MSI*2>%\"5;!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!11(,T!OR:=PYLUD^.%G`NI>`^EA`^Q@" + "X]-I@'YI?GAEK)%VY;]J[<]C_^-?W,MJ*#QL!!%$!!!!!!!!!!!!!!!!!!!!!!!!" + "'C%LMY]E`^MJ`.Q:`>EC`^YAV\\EM44I>FH)K_^9F`^M@`NE<`.MP]>-[_^=<\\^%[" + "/$U`!!%%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%#$\"MS" + "!A1(#B5E?7!FV*YNS*IOQJ-MT[!JX,-CR+QGIZ-_I9^3K*F0OK:&W`NE;" + "`_E^?WV.CGAIX,!F^N)D`^QA_.AEY]9F;'5Y!!)'!!!!!!!!!!!!!!!!!!!!!!!!" + "*C]XGGUJI9EP`^]D`^AB`>M=^N=>?W=GP:9E`^M?`N=<_^=LZNO\"B8!L_^A=]^5Y" + "3EJ#!!!\"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1%\"$\"Q[" + "!1-)#B%?EX%RV*]OT;!JTJ]LT:ULYL9J`^IC`^U;__%HP+-P8UQ41#]40SY@/SI>" + "/3E7-C1/.31:7U=TDX.;S;2]SL32?8\"G'#V&$R9>!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!-'5UIYU:QK_.=>RKAIB8-W`_:$`.9O" + "``6\\=WR,M9AH_MYI`NI>_NYH;FQAWLYKA(J(!!%'!!!!!!!!!!!!!!!!!!!!!!!!" + "(#-GIHYI*BA3J)MN^N)A`^EE`>I=FHYCJIQE^.=Z]NN=VM:\\:&9SX]=A`NE=^.J)" + "55V$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "\"QY:.DIN8UY@E8)LSZUOT[!LTJYKZA>_N^B" + "8V^7!Q=/!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!QU?" + "<7)MX\\]HZMIKT,!AS*MNTJ]KT:YKWKUN@GEH?&Z+M)ZHT;F[U+R\\U+Z_U;^_U+Z_" + "U+Z_U+^^UL\"_U\\'!U\\'!U\\\"_UL#\"U;^`WL7$R+O&2%.':':EC9*Y-DR+!A5)!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!-.(31OH(QNTJQK_-]D`^Q@\\^!E8&-=P+)G" + "T\\)BU,5J?71GL:5>MJEH>'-IN*MC]NJ3,TF#!A1'!!!!!!!!!!!!!!!!!!!!!!!!" + "!15)6EQMRJIQ955E9%I=@'!I2D)8CWYJ]=MI]=UMOK!>KJ)F`^]?`^I@`>M>_NR)" + "QLC#(3UY!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%#$2-D" + "P*-NV^%QJFMV,\"`UL##UL#!UL#!UL&_UL#!" + "UL#!UL#\"UL#\"UL#!UL#!UL#!UL#!UL#\"V,'!SKZ[P;6`V" + "`^AA`^ICZ]ADL:9SM:IJXI;" + "`_>GFZ\"K(T&)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%##R-?" + "QJAZD'AGH(1RDX%HW;1PU+!JNY]P3TALNZ&IU\\&_U,'\"UL\"`UL\"`UL\"`UL&^UL\"_" + "UL#!UL##UL##UL\"`UL'!UL#!UL#!U\\#\"U<'\"UL&YPJZTS[:[SL#\"4V\"3!Q=-!!!!" + "!!!!!!!!!!!!!!!!!!!!!AA0+4%VKI%LVK)NSZYKW[]I`NEA`NICKJ!LZ=9A`^MC" + "`NIA`.MC`^MC`_!<`^Y@`_1`T,^])S]_!!%%!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!9.(S1MMIAKW;EPU[-LU+!KT:QLY\\5J`^M@U\\9FZ]9F`^IA`^IB`NIC`NM?" + "`.IB`_BCHJ:R$BML!A-$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1Q:" + "6UINR*5QWK9XU;-WP*!IW+AN:UIEBGB2S[6XU<*^U<&`UL&`UL&_UL&_UL&_UL&_" + "UL\"`UL#!UL'!UL&_UL&_UL#!UL#!UL#\"UL3!O*>K3DQPPJNPIZ'\"$2AJ!!!!!!!!" + "!!!!!!!!!!!!!!!!!!97,D)RKY%MV+%OTZYMV;1K^M]B`^MB`^EA_>9C`>A>`^ID" + "`^IB`^IB`^A>_>II`_NHR\\FZ.U.-!A=0!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!19,+3YVMYALU+!MTJ]LTJUMW;IM`^Q<`^M@_^I@`^IB`^IB`^IB`^IC" + "`NIC_NA?`>Z2H*>Q%3!S!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "\"B!<,41W4$A72D-=#!5&R;7(&#-Q$2AE!A5*!!!!" + "!!!!!!!!!!!!!!=71$=OQ*5SUK!LSK%MU:YI^-QF`^IB`^IB`^ED`^I@`NMC`^EA" + "`^IB`^EA_^EM`_[*JJBS*$.\"\"1E0!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!A=.-$)PN)]NUZ]MTZ]NT:MH^]YI`^M?`^IA`^IB`^IB`^IB`^IB" + "`^IA`^M?`>AA`O.5EYRC)$\"%!!-'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!\"1M>&UKX;EKPJ)M54QKQ*:MT;R]UL&_UL&_UL'!UL#!UL#!UL#!UL#!" + "UL'!UL'!UL##UL#!UL#!UL#!UL#!UL#!V<3\"R+\"VNJ*ML*:U\"2%G!!!!!!!!!!!!" + "!!!!!!!!\"Q];4UI[QZEQUZ]LT:YMUK9H^-YD`^M@`^IB`^IB`^IB`^IB`^IB`^MA" + "`^ID_^M?`O:YA8BF!2-J!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!E90DAKVK-QU:]LU*UQV[AE`>=D`^IB`^IB`^IB`^IB`^IB" + "`^IB`^IB`^E?`>E@`_20M[FV*D%^!QE2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!1U=75ADX;IMOIYK75-TQ*BKU+Z\\UL&_UL&_UL&_UL&_UL&_UL#!UL#!" + "UL'!UL'!UL##UL#!UL#!UL#!U\\#\"KYZHK)VMXLO+[];56V2-$2QO!!!!!!!!!!!!" + "!!!%\"!YA;6=QS*ANUK!KTJQRV[MF^N%C`^QB`^IB`^IB`^EA`^IB`^IB`^IB`^IB" + "`>A=`_*>K;\"U&#-U!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!\"B-K651AW[ATT+%LU*]IZ\\QH`^IA`^ID`^IA`^IA`^IB" + "`^IA`^IB`^EB`^IB`^A?`^V!S\\^[+$6\"\"1M4!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!922DIAXKQOTK!Q0SUCQZNLT[V]UL#!UL\"`UL&`UL&^UL&_UL#!UL#!" + "UL#!UL#!UL'\"U<'!U<'!U<'\"U,*_U,##2$5P1%B11UF7(#Z$!!!!!!!!!!!!!!)&" + "&#%QDH!QUK%QTZ]KTJQPW+MF_^5E`^IB`^IB`^IB`^IB`^IB`^IB`^MA`NEE`NE;" + "_^Z%Z.33)T%_\"1Q0!1-&!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!%2YMCGIPT[%NTJYNU;)I]]EE`^IA`^I?`^IB`^IB" + "`^IB`^IB`^IB`^IB`^IB`NA<`_%[X=NS36.9#2-A!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!9/.3A7X[USV[=R7$]?GXRAU;N]UL#\"UL#!UL&`UL&_UL&_UL#!UL#!" + "UL#!UL#!UL'!U<'!U<'!U,'\"W,'#HY:E)T\"#!!!!!!!!!!!!!!!!!!!!!!9.)SUU" + "GX1HU[-ITJYLT:UMXA>`^]Q[N6C=(\"C#REM!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!AA2,C5;X[UWUK%KM)ET5T]RRK*VUL&`UL##UL&`UL&`UL&`UL\"`UL\"`" + "UL\"`UL\"`U\\&`UL'!U<'!XLS)KI^G,$-`!!)&!!!!!!!!!!!!!!!!\"21H4E9TN)IN" + "V[1PTZ]LT*UNYL=D`.9C`^EA`^EB`^IB`^IB`^IB`^IB`^IC`^I@`^E@`>IE_O:[" + "<'N9\"B%B!A1%!!!!!1)$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!50/3]CU;=WU*YNTZ]MU;-H]]UF`^I@`^IA" + "`^IC`^IB`^IB`^IB`^EA`^IB`^IB`^I@`>MA_/\"8F:\"H%35^#B%;!!!!!!!!!!!!" + "!!!!!!!!!AE2,C=;Y+UXTZ]NUK%OA'%MA'6-U\\/!UL&\\UL&`UL#!UL#!UL&_UL&_" + "UL&_UL&_U\\&_U,+\"YEC`^IB`^IB`^IB`^IB`^IB`^IB`^IA`NMC`^AE_^=B`/:GFJ\"Q" + "&SE\\!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!E<651BT[-LT[!LTJYOV+=J^]]G`^I?" + "`^IC`^IB`^IB`^IB`^IB`^IB`^IB`^IB`^EA`>A<`_6-P+VH*T%Z\"!I3!!!!!!%$" + "!!!!!!!!!!9//#M;X[QTT;!LTK!LTJ]M9UAABX\"7SKS!V,+#V,+\"U\\'!U\\&`U\\*`" + "V,*`V,.`U\\&`P*ZW9VB+%S1X!!!!!!!!!A9/%#%T\"R-C'S-MGH)GW+9RT;!KU*YM" + "U;!I\\-)F`^I?`^I@`^IB`^IB`^IB`^IB`^IB`^IB`^IB`>ED`>A=`_22R\\O('35Z" + "!!%#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!Y<=&UOU:]NTZ]JT*]MVK=I^]]D" + "`^QA`^IA`^IB`^IB`^IB`^IB`^IB`^IB`^IB`^IB`.E@`^]OVL^+6F5V#AU=)39T" + "!!M9!!!!!!E64$QCWKIOT:]JU;%LV+)NW;MOJI]B=&YWDH6:N*6TSKF]U\\#&S[NY" + "O*BXG9\"E?7B+9&F'#B5E!!!!!!!!!!1//U\".J+'E=(\"U6%IYH8AJU+%NTJULT[)M" + "\\=-E`^EB`^EB`^IC`^IB`^IB`^IB`^IB`^MB`^IA`^IB`N=>`_&-U-#!,$R+\"!Y7" + "!!%\"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%#$R5@H(ASU[!NTJ]OTJ]LV;9G" + "^^!C`^IA`^EB`^ID`^IB`^IB`^IB`^IB`^IB`^IB`NMA`^IB`^EC_>=BH9QI3%\"!" + ";WFN\"\"!I!1Y>;F1EZ\\1[V;9ZR:AQLY9KK))ER;IBP[5AC(5D7)]9%YU6UMQ" + "='1SI)I@XM:3T<[-!QA/!!!!!A1'-4Z0Q],#Y.@;Y^L8V=L(B9*`<6-KTK%L]MQE" + "`^IB`^IC`^IB`^IB`^IB`^IB`^IB`^IB`^MC`>MB`N=?`>MZZ^7,/52)\"QY7!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!))&\"9@LI9VV;)JU*]MTZUP" + "V[EF_>%E`^I=`^EB`^IB`^IB`^IB`^IB`^IB`^IB`^ID`^IA`^MB`NAB^>A>G:CAFZ/2@8W\"<7.(S,!M_NAE" + "`^U>`^Y?`?&0R\\K((SZ*.5JE.%.8A8R\\WN<4Y^82X>@7XND9Z.H:JKCL@W]^\\-QF" + "`^Q>`^IA`^IB`^IB`^IB`^IB`^IB`^IB`^IB`>E>_NQT]_/,87&8#2-B!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1.(#%EKI-OU;)LTJ]N" + "T:UMW;II_>%D`^M@`^IA`^ID`^IB`^IB`^IB`^IB`^IB`^IB`^IC`^MXY.T`>M[TM#,E9W.Q,KUWND7D)O/R,[]Y.<6Y.<5X.44Z?(C````V.4=?8*8" + "U,1=`^Q?`^M@`^IC`^IB`^IB`^IB`^IB`^EB`.QS`OG,=8\"@#B-H!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1-',CYFPZ%TTZ]L" + "TK!LTZQOV[=G_>%G`^I@`^IC`^IB`^IB`^IB`^IB`^IB`^IB`^EB`_)BCHEAQ]8+" + "`````0T\\Z?(A7665M[SLZ>P;XN85^`4R`P`_`P\\_`P\\_````GZK=K+?J^@D[559\\" + "Z]ML`^Q>`.AKV=;-F)_/;'2H````PLW_J+'>X^L8W^<5\\?LK`PX``P\\_`P\\_\\_`P" + "@H28Y--H`.MA`^MB`^IB`^IB`^IB`^EA`.AC`?K&>X:@%C!S!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1./D1HRZAO" + "U;!JTJ]LT:]LV[MI_>5A`^MC`^IB`^IB`^IB`^IB`^IB`^IB`^QC]>!A<72-_0DZ" + "`P\\_`@X^_`LYT]T*96R;V-\\,YN\\<`````P\\_`P\\_`P\\_````/DA\\````````\\/TQ" + "5%AA^>5A`>AEWMS&3%6&V^@9````^P\\E=7J+]N1B`^MA`^IB`^IB`NE?_^AD__:\\H:6S%3-[!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!95149F" + "QJ1OU+%LTJ]LT:YMW+UH_N1B`^MA`^IB`^IB`^IB`^IB`^EB`_!AIYQAL;WR````" + "`P\\_`P\\_````_@@VGZC7G:75^@,S`````P\\_`P\\_````XNX?='ZR`````@X^````" + "QM(\"H)=I_NA;W=G$6VB6R]@(````````5V25ZO4E`````P\\_`P\\_`P\\_`P\\_`P\\_" + "````V>0=EG`_VYK;*Y'CQ[!1)#!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!AE3" + "24IKSJIOTK%IT:]PT:YKW+MG_^5C`^M@`^IA`^IA`^EC`>M>\\-UGW]`,S``\\```X```X`````J+/EQM($`````P\\_`P\\_" + "_PP\\E)K!X=N#>'F(Z/8J8FV?\\OXO````N\\7WDI[1`````P\\_`P\\_`P\\_`P\\_`P\\_" + "`P\\_````S]X&FI-B`NQC`.E:`_FQJ*VV%S%R\"R%5!!%#!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!1I84$UJSJMTU;!JTJ]LT:UMW[QH_^5F`^IB`^IB`^I@`^IED(MKX.T=`````P`^" + "`P\\_`P\\_`P\\_`P\\__`PYC);&SMH*XN\\?W^PB)3'[OLK`P\\^`P\\_`P\\_" + "```_^PYM->>'N?_0@[`P\\_`P\\_`P\\_" + "`P\\_`P\\_`P\\_`P\\_``\\`````:W:I^`@X`````P\\``P\\_`P\\_`P\\_`P\\_`P\\_`P\\_" + "`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_\\/TNEZ+8\\/TM_`P\\`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_" + "`P\\_`P\\_`P\\_`P``<7RE*$B-\"QY4!!!\"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!=4.3]GPJ1PU+!MTJ]LTZUKT[IK;F]]Y_DH```^`P\\_`P\\_`P\\_" + "`P\\_`P\\_`P\\_`P\\_``\\`````O,;YO,GY`````P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_" + "`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`0T]GZK?XNTA``\\```\\_`P\\_`P\\_`P\\_`P\\_`P\\_" + "`P\\_`P\\_`P\\_````BY3($2QK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!92-CEEKI-PV;5PRZ=O:F)XS=H/`````@\\_`P\\_`P\\_`P\\_" + "`P\\_`P\\_`P\\_`P\\_`P\\_````[OHKQ=(\"`````P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_" + "`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_````O\\K]K;?K`````P\\_`P\\_`P\\_`P\\_`P\\_`P\\_" + "`P\\_`P\\``P\\]```]86\\/DH`PX^`P\\_`P\\_`P\\_" + "`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_" + "`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_````='ZQT-P-`````P\\_`P\\_`P\\_`P\\_`P\\_" + "````^P8VG:O?&39^!Q5)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!Q9)$\"9EIJW?[_$?X^H6Y.@6X><4Z_4B_`PZ`````P\\`" + "`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_" + "`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_````Z/0E76>;`````P\\_`P\\_```_``````\\\\" + "S-L*8':U#\"1H!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!$%\"IL?XK\"XN@2YNP:Y.<5X><5Y>P:^@8T`P``" + "`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_" + "`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_````3%6*```````````````_P\\[_=(K)" + "'35V!A9+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1/.4>#KK3EV>(0YNH7XND5X>H8\\/HG" + "`0T\\`P```P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_" + "`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_````\\/TMA9#$Q,`\"V>8:CIO30UJ9%3!R!!-*" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%&!!A4-DB%=H.]J:_CT-<%UMX-" + "W^87[/XO$&#-X\"A9'!1-&!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!%\"!A1'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!QQ>@8W$\\/8C" + "Z_(>^P0Q`````P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_" + "`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_```_````D:'5%CE\\!Q5&\"!M2!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!%\"!A5)!!!!!!!!!!%#!A1'!!%#!!!!!!!!!!!!!!9/15>6Y><5Y.85" + "Z.X=`@X]`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_" + "`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`@`_````LK[W'SE`#\"!;!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!%\"\"AQ4!!!!!!!!!!!!!A9+)T2.RLW_Y>D:W^85" + "^`4T`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_" + "`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`P\\_`@X^`@X\\G*_H&SI`!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + ""; diff --git a/include/graphics/lfb.h b/include/graphics/lfb.h new file mode 100644 index 0000000..a4eef2e --- /dev/null +++ b/include/graphics/lfb.h @@ -0,0 +1,28 @@ +#ifndef GRAPHICS_LFB_H +#define GRAPHICS_LFB_H + +#define GG_MAX_X 128 +#define GG_MAX_Y 46 + +#ifndef GRAPHICS_LFB_C +extern unsigned int width, height, pitch, isrgb; /* dimensions and channel order */ +#endif + +void lfb_init(void); +void lfb_showpicture(void); + +void clear_screen(void); + +void draw_cbyte(unsigned char lx, unsigned char ly, unsigned char letter, unsigned int c); +void draw_byte(unsigned char lx, unsigned char ly, unsigned char letter); + +void draw_cletter(unsigned char lx, unsigned char ly, unsigned char letter, unsigned int c); +void draw_letter(unsigned char lx, unsigned char ly, unsigned char letter); + +void draw_cstring(unsigned int lx, unsigned int ly, char* s, unsigned int c); +void draw_string(unsigned int lx, unsigned int ly, char* s); + +void draw_chex32(unsigned int lx, unsigned int ly, unsigned long val, unsigned int c); +void draw_hex32(unsigned int lx, unsigned int ly, unsigned long val); + +#endif diff --git a/include/graphics/mbox.h b/include/graphics/mbox.h new file mode 100644 index 0000000..fe021a2 --- /dev/null +++ b/include/graphics/mbox.h @@ -0,0 +1,27 @@ +#ifndef GRAPHICS_MBOX_H +#define GRAPHICS_MBOX_H + +/* a properly aligned buffer */ +extern volatile unsigned int mbox[36]; + +#define MBOX_REQUEST 0 + +/* channels */ +#define MBOX_CH_POWER 0 +#define MBOX_CH_FB 1 +#define MBOX_CH_VUART 2 +#define MBOX_CH_VCHIQ 3 +#define MBOX_CH_LEDS 4 +#define MBOX_CH_BTNS 5 +#define MBOX_CH_TOUCH 6 +#define MBOX_CH_COUNT 7 +#define MBOX_CH_PROP 8 + +/* tags */ +#define MBOX_TAG_SETPOWER 0x28001 +#define MBOX_TAG_SETCLKRATE 0x38002 +#define MBOX_TAG_LAST 0 + +int mbox_call(unsigned char ch); + +#endif diff --git a/include/graphics/philosopher_toad.h b/include/graphics/philosopher_toad.h new file mode 100644 index 0000000..c58d6b4 --- /dev/null +++ b/include/graphics/philosopher_toad.h @@ -0,0 +1,764 @@ +/* GIMP header image file format (RGB): philosopher_toad.h */ + +static unsigned int toad_width = 109; +static unsigned int toad_height = 110; + +/* Call this macro repeatedly. After each use, the pixel data can be extracted */ + +#define HEADER_PIXEL(data,pixel) {\ +pixel[0] = (((data[0] - 33) << 2) | ((data[1] - 33) >> 4)); \ +pixel[1] = ((((data[1] - 33) & 0xF) << 4) | ((data[2] - 33) >> 2)); \ +pixel[2] = ((((data[2] - 33) & 0x3) << 6) | ((data[3] - 33))); \ +data += 4; \ +} +static char *toad_data = + "P+[BP;_CO+K>N+;:O;O?QWFYJZG9R\\JJG)MK75G)N[EY:VH:\"`K:S,JJG)N[K:Q,3EP\\/FM[KUD(^MD(^ME).QBHJE" + "AX>BEI:QHZ*`='.18F%_=G63C(NI?GV;FINXMK?6L+32HZ;&K+'2M+G:L[C9L;79" + "L+38M[O?P<7IPL;JO,#DO<'EQ,CLQLKNQLKNRL[TS-#VR\\_US='WS-'XQ\\SSQLGQ" + "Q,?OQ,?OQ,?OQ,?OR,OSRLWUQLGSQRE)2ME)2MDY.LA(2=?7V6C8VFGY^X" + "#?7J6" + "E9*N<6Z*@X.>JZO&J:K'HJ.`IZO'I:G'F)RZG)^_K;#0M;C8L+/3L[;6P,/CQ,?I" + "O<#BO;W@O+_AP<3FP\\;HP,7FP,3HO,+EMKS?L+76L+76L[?;MKK>M[OAO<'GP\\?M" + "PL7MOL+FP,3JPL;LQNKW?O,'BO<+CM[W>L[C7M+G:M[S=N+S@M[O?O<'GP\\?MP\\?MQ]" + "K:N_MK3(P;_3Q,+8PL#7P\\'8P;[8M+'+>G>3@G^;D8ZL>721A'^>KZS*JZC&G)NY" + "G)NYGZ\"]FYRYH)^]I*/!J:C&KZ[.N+?7O;S=NKG:M+/4IZ;'J*?(K:W.L;'2L;36" + "MKG;M[S=L[C9MKO:M[S;N;[?N+W>L[?;MKK>N[_EN[_ENK[DOL'IP\\;NQ\\KRR,OS" + "R,OSR,OSRWIJ7%LK'1M;34MK76M+/4KJW.IZ;&K*O,KJS0J:G*JZS)LK/.L[?3LK;4" + "M+C6M;G7MKG9M;C8I:C*JJW/K:_4K*[3KK#5L++7M+C=G./?GN7E)&MFYBT@(\";?7V8@X.>CX^JF9BVF)>UH)^_" + "JJG)K*O+JJG)JJG*JJG*KZ[.K:S-JJC,J:C)K:[+L[7-L;+-K*W,LK/0MK?4M[C7" + "MK?6IJ;'J:G*JZO.JZO.J*O-J*O-JZ[0L;/8N;O@OL+HO\\/IO\\+JM;G?MKK@M+C>" + "M;G?N;WCN+SBN;WCP,3JR'61>WB4C(FEE)&M?7V8@(\";BHJEEY>RGYZ\\F9BVFIFWHJ&_I*/#H:\"`" + "I*/#JZK*LK'/K*O,J*?(JJG)L+#+LK++KK#(J:K'K:W(M+3/MK;1M+/1I*/!IJ7%" + "IZ;&J*?'I:3$I*/$I:7&JZO,LK+5MK;;LK39KK#5JZW2JZW2L++7M+;;L++7K:_4" + "L++7M+;;P,+IQ\\GPR':-<6Z(?GN5?7J4" + "?'F3BH>AE)&KA8*RG)NYH)^]H)^]HZ*`K*O)J*7#" + "I:'\"HZ+#J:C(K*S%JZO\"JJK!J:G$JJB_M++)M;+,L*W'H9ZZHZ\"\\I*&_IZ3\"HI^]" + "H9Z\\I*&_J:C(L*_0L;#1JZK+I*+&I*3'HZ/&KJ[1M;78K:W0JZO.L;'4L+#3M[?<" + "O+SAP\\/FQL;GQ<7FP<'DO+[CN[WBP\\+JQ\\;ORLGTRXI*&_" + "J:>^IZ6[I**XHZ\"ZJ*2[LZ_&L:W%JJ:^G9FSH9VWH9RYIJ&^H9RYH)NXH)VYI:*`" + "K*G'KJK+JZ?(I*/$GIV^GIV^JZK+L[+3K*O,KJW.M+/4L*_0KJS0KJW.MK76P<#@" + "P<+AN;G:L[/4M+37NKK?OKWEO[[GO+OFN[KEO[[IQ,/LQL7NQ<3LRLGQS\\[VSLWU" + "RI:.Z>7>.=G2+B8>>?WV4>':-@X&8CHRCA(\"8B86=B(2<" + "BH:>C8NBE9.JE)&KE)&KFYBRG)FSF)6QG)FUFI>SEI.QEI*SH)VYJJ:]J::ZH9ZR" + "FY>NI:&XL:W$K:F`I*\"XFI:NGIJTGYNUI:&[IZ.]I*\"ZHIVZHIVZHZ\"^I:*`IJ+#" + "IJ+#GYZ^H)^_JJG)K*O+I*/#J*?'KJW-I:3$HIZ`H)R]IJ+#KZ[,L[+0K*W,J:K)" + "K*S-LK+5M+39L;#8JJG1J:C1L;#9NKGAO;SDN[O@PL+GR\\OPSLWURLGQPL'JO+OD" + "N;CAN+?@OKWFQ,/LQL7NRLGRS,OTR\\KSR,?PQ\\;OR\\KSS,OTRLGTRLCVS,KZS,KZ" + "R\\GYSQN;G4P;[8O+G3" + "O+G3P\\#:L['(A(*9=G2+@'Z5=G2+='*)A(*9DI\"GB86=C8FAC(B@CHJBC(JADI\"G" + "CXVDD8^FFI>QEY2NDH^IFI>QH)VYG9JXG9JXHYZ[JJ:]J::XH9ZPFI6LHI^SKZO\"" + "J:6\\H9VUF96MGIJTG9FSHY^YIZ.]J*2^J:3!IJ._HZ\"^GYRZG9FZG)BYHI^]IZ3\"" + "K*G'I*&_FYBVH)V[I*&_FYBVFI6VF92UF9:TG)FUG9VXH*&^I:;%JJO*L;'4L[/6" + "KJ[3I:3,HZ+*JJG1L+#5LK+7KJ[1L[/6O+S?Q<7JR,?OP\\+JN;CAL*_8L*_7M;3<" + "N;C@N[KBO[[FQ<3LR,?OQL7MR,?ORLGQR7>-<&Z$=FY>NCXNBD(RCCXJAD8RCBHB>C(JAB8>>CHRCEY6L" + "DH^ICXRFG)FSH9ZZHI^]I*&_IZ.]IZ2XIJ&THIVPG9BMH9VTKJK!J*2[GYNSF96M" + "GIJTG)BRHIZXGIJTIJ*\\KZK'L*W)JJ?%H)V[F)2UD9\"PGINYIZ3\"JJ?%G9JXDY\"N" + "FYBVGYRZF)6SF92UFY:UEI.QCXRHC8VHF9BVHZ3!J:K)L;'2M+37L;'6J:G.IZ;." + "K:W2L+#5KJ[1J*C)J:G,KZ_2N[O@Q\\?LQ\\;NO+OCL;#9K:S4KZ[6KZ[6KJW5LK'9" + "O+OCP\\+JQ<3LR,?ORWF/" + "=7.)8CXVAF9>MCHRBE9.JEY6LF)6O" + "HI^YI:*\\IZ6\\IJ*ZI:&XI*\"WHZ\"TH9ZRJ*:\\K:O!JJB_GYVTF9>NG)FSH)VWH9ZX" + "FY:SG)FUH*&\\IZ?\"J*.`H9NXFI6TEI.QGYFRI)RUH9FRH9>QF8^IH9FRHYJVGYFT" + "HYZ[I)Z[F(^KAX&JFY:KFY:M" + "I*\"XIZ.]I)^\\I*&_HI^]G)FUI*&]O+G3PK_9NKC/B(:=>':,@'Z4=7.);&I^<6^#" + ">7:*_J:6\\IZ.ZI:&XHZ&WJ*:]J*:]I**YGYVTGIRSH)VWG9VVFIJSHIVZG)FUFYRW" + "H:&\\I)^\\I)Z[H)NXF9:RH:\"^HZ\"^G9JXFYBVE9*PHZ\"^J*7#IZ;&HZ\"\\H)RVDHRG" + "@W^7CHZED)*JD9&JE9*NFIFWJZK*KJW.J:?+K*K.L:_3KZ[/KJW.J:C&I*/!IJ7%" + "IZ;'K*K.OKS@RCD(VIL[#*Q<+_K:G!K*K!K*K!" + "J:F`IZ>^GY^VEI:MC(RCBHJCD)\"IFYNTHZ.\\IZ>`H9R[G9JVG9VXGINWF9.NG92P" + "HIRWGYRVH9RYIJ&^IJ&^IJ&^GIFVI:\"]I*\"ZH)RVGY^XF9:PAX.;=W6,@X6;@HF=" + "@XB?AXFAC(NKE92TFIFZGYZ_I:/'IJ3(I*/$IJ7&IJ7#H:\"^GYZ^G9R]GYZ_L['5" + "Q,+HQ,+HMK3:KZW3J*;,HZ''G)J`EY6[G9O!J:?-LK#8N;?=P\\'ERLCPRL?UQL+T" + "Q\\/URL;WR\\?XR\\?XR\\?XR\\?XR\\?XIY^UF9&IDHVDG9>PHY^YJZC$KJW+H:\"^AH.?" + "AX2@K*G#Q,';P+[5D(ZE@H\"6A(*87:(9F-U;FM]>7:(@G^/A'^4" + "B829D(N@EY*IF).JF92KF)*KF)*KEY&JG):OGYNSGYNSG9JTG)RUG9^WGJ\"XE9>O" + "C8^GAXFAB8NCCX^HE96NF9FRG9VVI:\"_H9ZZH:&\\GIFVEHVIF8^KGYFRG9FQJ)JR" + "K*\"WJ:\"VHYNQE8VCG92JHI:KI9>MDY\"JDHREB8&:?7B/B(F>A(:<@8.9@X.XI:/'MK;9N[O>NKC<" + "KZW1J*;*I*+&FYF]EI2XF9>[GYW!JJC.KZW1M[79P;_GR,7SR<7WQL3UQ'6'?WR.@G^1AH&6B829CHF@D(NB" + "DHVDCHF@B82;AH&8DHJBFI6LH)RTF9:PC(REAH>BBXRID)2PD9*MB(FD@X2?B8JE" + "DY.NF)BSF9FTFIJUGYRZF9:REI.OEY&NF8^KG9\"MF9\"LCHJDF(^KH)JUGYRXEY>R" + "A86@C(FCE8^HG)2LF)*MFI\"JDH.?A7F2C86=AX.;BX>?E8^JDXZMAX*AA8*@D8ZL" + "F96VEI6UE).SE).TE9*PFYBVH)R]G)BYE92UFYJ[JJG*M++6N[K;L*_0IZ;'H:#!" + "GIV^GYZ_H:#!H)^`JJ7,K:G+L*_0N+;WB,<&V!=W2(?'F-?7J,@GZ5A8&8B86WR9A(2?DY.NG9JVG9JV" + "FYBTCXRHCXRHD8ZJF9.PHI2TH9*RF8ZMDXZKC)&XE9W#DZ''BIS!=8>L>(:J?8:H" + "@(:GG).OG9\"MF(6BC7J7DH6@BX&;D8>CGY6QEI\"MD8NHCHBEBH6BAX*?B82CB(6C" + "@7V>CH>GEY*QGIFZG9BYF96VG9F[IZ;'LK'2N;76L:W.IZ/$H9V^HY^`IJ+#J*3%" + "JJ;'LJ[0L:W.LZ_0MK38O+GCO[WKPL#NQ,/NR?>W>.@W^6:&9]65=N" + ";VV#AH*9G>+@'R3@W^6AH*9AH*9E)\"GD8VDD8VDD8VDC8J>FY>N" + "I**YGYRVC8RJ@8*A@8&BAH:IB(FFAXBEBXJHDI&OG)FWFYBTDXZKBX:CCHNGF)6Q" + "GIFVIYZ^KY_\"HY.XF(VPG9:XF*#(E:'(B)K!>Y&Y;(*H=8>L>XBK?XBJAH\"=CX6A" + "EH6DF8:CHY2PEXJGD82AEHBHFY\"ODHBDCH:?C(2=A'Z7@WV8@'N8>723BH&ADXJJ" + "F9*TG9:XGIFZH9R]IZ/$L*S-KJK+K*C)IJ+#I*#!IZ/$HY^`HY^`K*C)M+#1J:;$" + "IZ3\"L*_0N;??N;CCN[KCP,+IR,?RR,?RQ\\;QQ\\7SQL3RC(JAGYVTJ*6_KZO%L*O(" + "K*;#JJ3!IIV]I)^\\IZ*_N+3.O;G3N[?/BH:>>G:-A8&89F1[44]F9&)Y?GJ2;&A_" + ":V=^G:-@H\"6@X&7A(*8@7^5DI\"FCXVCD(ZDDI\"FC8J>D8^EEI2KEI.MD9\"N" + "C8RMAX>J@X.FBXRKD9\"PEY:TFYBVFYBVFY:SFY:SFY6REY2PGINWGIFXI9R\\KI[#" + "G(JQAGJAB8&GEI*SD).SAH^O@H^P?(FHB9*PBX^IBXBB@X\"AH\"=A7J;C8*CE(JMFY&TH)F[" + "H)N\\HIV^J*/$HIZ_IJ+#IJ+#JJ;'JZ?(G9FZFI:WJJ;'JJ7$DY\"LCXRHI:3$N+;<" + "M[;?MKC@OL#EQ\\;OQL7PQL7PQL3RQL3RCXNCH9VUKZO#LZ_)KZO%IJ&^GYJWGYJY" + "I:&[L*S&M[/-P;W7M;')D(RD?WN3@W^78EYU3$A?85UT>W>.:F9]:&1[;6E`@'R3" + "@GZ5A(\"7@'R3BX>>GIJQB(2;@'R3?GJ1B(2;E)\"GGYNRCHRC@X.VBHJK" + "BXRIG9Z[G9Z[DY*PB8BFG)N[H:\"`GIV^F)2UDX^QE8^RDXVPI)V_F9*RC(:CCXFF" + "B(FHAH>DA(BBA8FCAHJDAXNEBXRICY\"MFY*RH):YBX2FB8*DB8*BB8.@FY6NGIFP" + "H)BPG9BOF).HGYJOBXBXFI:WJJ;'K*G'DH^MC8FJH)^`KZW1KZ[6MK7=P,+J" + "Q<3MQ\\;OQL7PQ<3OQ\\7SFI:NHIZVK:G!M+#*L*S&HYZ[G9BUHIV\\K:G#MK+,O+C2" + "P;W7MK+*D(RD@7V5@W^78EYU3DIA8U]V>G:-:V=^;&A_W>.>W>.?'B/@W^6BH:=EI*ICHRBBHJAF)BQEI6SB(FFB8FDF9FTF9BV" + "C(VJCH^ND9*QDI*SEI:WDI*UCHRPG9N_GIJ^F96WHYZ]JJ7\"I*\"ZI:.ZG9ZSE9:I" + "D)&DD)&DD)&FB(B?@'V7?7:8>W27?WF>;VN/:&2&>7:4?'B2G:-BH>;E9*D" + "C8J<@'V/>WB*@7Z2E(^DC8F@AH*9@W^9AH&>AX2BBH:GC(BIBXBFE)\"QGIJ[G)BY" + "E9&RG9FZH9V^I:'\"K*C)JZC&H)V[F96VG9R]J*;*KZ_4M;3'2+A8&8AH*9@GZ5B(2;C8F@AX.:?7F0" + "B(2;BX>>?'B0?GJ1C8F@DI\"DE)*HFYRQDY.JAH:?A(2=D)\"KD9\"NAXBGEI:WBXZP" + "BHVODI6WHJ3+G)[%EYF^DY.VCY\"ODI*MAH2;?GR2DHZ;IZ&NKJBSH)JCDXV8D8J:" + "C(68@'N2@7N@EB(6CAH.AD8ZLF9:TEI.QD(VKD(VKGINY" + "I*&_IJ/!JJ?%IJ/!FI:WE).TH)[\"JJK/KZ[6M+;=N[KBOKWEO[[GP+_HQ,/NK*B`" + "IZ.[K:G!M+#*K:G#HIVZI:\"]L*O*N+3.N;7/O+C2O;G3N[?/EI*JB86=B(2<:F9]" + "7UMR=W.*B(2;?WN2?'B/>76,@'R3C(B?D(RCD(RCB86<@GZ5@'R3B(2;BH:=>G:." + ">W>.C8J>F):JF9BIF9>KCY\"CA8:9?GN5@X\":AH6CC(NKGI[!GJ'#GJ#%GZ/'GZ+*" + "E9B`AHJP@XBI@(2@>WV3969Y9V9U*DX2&@G-Y=VEUAGF+GI\"FHY_#" + "IJ3*M[;>S,[VR,OSO;_DM+?7GI^\\='6045-K4E-H8%YRA8*4C(F;C(>;DX^I" + "EY*OCXJIBH6DD(RME)&OC8JHB(6ABH>ED(VKE)&OF)6SC8JHEI.QF9:TFYBVJJ?%" + "HZ\"^DH^MC8RLG9R]I:7(J:G.L;/8M;7:NKK?O+OCOKWEP\\+KM+#(L*S$L*S$JZ?!" + "GYNUGIFVJJ7\"LJW,N;7/MK+,M;'+O;G3O[O3G9FQC(B@BX>?<&R#9&!W>76,A(\"7" + "@'R3?'B/>G:-@'R3C(B?D8VDBX>>AH*9AX.:A(\"7?GJ1A8&8@GZ6@W^6E)&EG)FK" + "E).DD(^@C(N?WR6>WB6@X*BBHJMGI[!H*/%EYJ\\>GRD?8&GC9*SCY2R" + "BE(^NFI6TEI&RDXZO" + "G)BYH)V[E)&MBH>CA8*@D8ZLG9JXH9Z\\CXRJE)&OEY2REI.QH9ZZH9Z\\EI.QD9\"P" + "GIV^HZ/$IJ;)KK'3KZ_2M+39M[?TK:C%" + "KJG(LZ_)K*C\"IZ.]N[?1OKK2GYNSB(276,>G:->76,?'B/" + "AX.:@W^6@W^6?WN2AX.:DHZEC8F@?GJ1C8F@C8FACXNBGINOG)FKCHN=B8:8B8:8" + "C8J<>W>.=G*,?'F5D8VND9\"QGYZ_D(^PEQ3@F-?>%M>=UUIA&U^:%YW4$IE3$AJ2DIO6UV$9&2)'2," + ">721AH&BDXVPGYJ[F).R@WZ;B(.@M;+,S,K@RLG8W-KDQ+_\"AGY\\95I5=F):?65:" + "A6A7C&M9D&]?B&EC;U576$%*1#5(+R-!+\"9!,BY05%)X<6V1A'ZARL/ER<#>DXFE" + "A7F0=&9\\6TQB;5]WS" + "H)VYE)&MD8ZJF9:RH)VYF)6QD8ZJEI.OF9:TEY:TF9BXFYR[G9Z]G)^_I*3%J:G*" + "K:W0M+37O;WBN[?/N+3,M+#(IZ.]GIJTK:C%M[+/JZ;%J:6_G9FSDHZHO+C2O[O3" + "I:&Y@W^7A8&9;VN\"75EP;&A_<&R#='\"':F9]9V-Z<6V$AX.:AX.:B(2;@W^6@'R3" + "FY>NF96LE9&HD(RDF)2KJ::ZHZ\"TD8Z@BH>;@G^3>WB,?7F0>76-?WJ7B82EG9:X" + "E8ZN@WV:;FB#<&A`=&^&@'V/CXV9OKR`R<&`H9>/>FQD@&I723CHJNIZ'&LZG,PK?8GY6OB'J2B7J.;EUP6DE<" + ";E]U?GB=?7>CE)&M" + "F)6QHI^[H9ZZG)FUCHNGC8JFEY:TG)NYF9JYF9JYFIZ\\HZ/$J*C)K*S-L[/6O+S?" + "N;7-N+3,L*S$G9FSI*\"ZJJ:`L:W'JZ;#JJ7\"GIFVEI*LN+3.PK[6IJ*ZB8676-6E9M96%X;VN\"<6V$:&-Z9V)Y<&N\"?7F0?WN2>76,>W>.?GJ1DHZEDHZECHJA" + "@'Z5>WF-FYJKH:\"QIJ2ZA(*9;6N\"W>1@GV:CXFFDXVJEHVIEHRF=VM`0SA*" + ",2E!+21!0CI(:6!FAWU\\GI&)H9&#DH!QCW)AC6Q:BV92C61/CV93C6A7A6-8>UU4" + "D'AWMZ.CUL7,U\\O:TL;=T<3?P[7-K:\"S@G!]=V5P@FQW6T9.33E#8$Y=8U1H:EYU" + "A':6CH*G=&R4=G&:=W69AX.DEI&PC8:HAX2@@G^;@7Z:>G>1A(&;BXBBFYBRH)VW" + "F)6OB(6?B(6?BXNFGYZ\\F)FVE)6TG*\"^HZ/$J*C)J*C)J*C+O[_BMK+*M;')IJ*\\" + "DX^IH9VWHY^YI)^\\IJ&^L*O(I)^\\FI:PNK;0O[O3J:6]D8VDEI*I@'R37EIQ:65\\" + ";&A_8U]V8%QS:V=^M>G>1:VB\";6N\"<&R&C8BEF9.PF(^MBX&;F8NC>VZ!44-32#M$6$Q1;F!>" + "C'YTA75EC'IEA6]8A&Q3EWAEE7)?DVU7E&M6D6A5BV14AF19AF5=E7AUHH:$L9N<" + "NJ:PL9ZPHY\"DG(>7G(B3@FMR?&-H@&9J6T%#2C%!33A!33M(5D56=6I[?W:,7F0>'F.@7^5@'R3?GN5?'F3>G>1='&+=W2.?WR6CXRFF9:PFI>QC(FC@X\":" + "@8&REYBUEYBUFY^]GI^^H*#!H:'\"HJ+#N+C;M+#(LJ[(G9FSC8FCG9FSFI6R" + "EY*OH9RYLJW*IZ*_FY>QO+C2N;7-J*2\\E9&HGIJQAX.:8%QS:65\\:65\\7%AO7UMR" + ";VN\"<6V$='\"'=W.*=W.*>'2+=W.*BH:=D8VDBH:=:65\\2TE?;VV!B(:'.0DHRIG).QDXFEC7^9F8J>DX&0?VUZA7%SD7QZE(!TGHEUD'A?DWA<" + "DW-9GWUCEG9@DW!9DVU5EFQ5DFA3BV13D&I>EW5JE7!IC6QDD71MFW]_D79\\?&%I" + ">F!DB6UM@V1@?%U7>5M2:$I!94A#6D!!3CA!239!44=185EG9V-S7UUQ:6I_9&1[" + ":VE_<6^%=G.->7:0>'6/=G.-<6Z(>'6/AX2>EI.MFYBREY2NAX2>?7V8C8VHDY2Q" + "G)VZG*\"\\H:+!HJ/\"H:'\"HJ+#L[/6M[/-KZO%G9FSDX^IFI6REI&NE(^LG9BUJJ7\"" + "H9RYF96OOKK4M[/+HY^WD8VDGIJQAX.:7UMR96%X:65\\9F)Y9F)Z:VE`;6N\"?'B/" + "A(\"7AH*9?7F0?GJ1E9\"GE9\"G?7B/75EP4DYF=G**AH*9>W>.:VE`<6Z,=G*4<&F)" + "@'J7G)&PEHFDE(6;?VQ^B'1^CWI`FX.$E7YYD7ELB7!;CW-%M6=EA/>UY1?5Q," + ">EE'=E5#=E=$?F-3;%1)74E!54)!-RQ!2$!.759G3TMB34IF4DYO6U=X:&2%<6^&" + ">':->G>1?7J4'6/@G^9DY\"JG)BRH9VWC(FC>G>1>WN6A86@E)6PFINXFINX" + "FYR[FINZG)R]I:7&M[/-J:6_GYNUFY:SE9\"ME(^LE9\"ME9\"MG9BUF92QF96OO[O5" + "N[?/H9VUCHJAG9FP@7Z285YR9&!W;&A_76," + "A8\"7G9BOCHF@8EIR241;9%YWB(2>BX>>?WR0769F%,:%-!95-$9U5(0S9!2C]$85A>6U5B03M41T)A5$]N:F6\">GB/?WV4@'Z5A(*9" + ">G>1?'F3@G^9D8ZHI9^ZI)ZYB86?<&R&:VB\">'61A86@CX^JCHVKD9\"NDY*PF)>W" + "F9FZKZO%H9VWFI6RF92QC8BEDHVJDHVJB82CD8RIEY*OG9FSN[?1P;W5I*\"XDHZE" + "GYNR?GF.9&%U:65\\<&R#=G2*96-Z75UT=76,C(B@C8FA@GZ6=W&*C8>@G)2M?W>0" + "345>1T)9=&Z)D8NHB86%EJ=5)G?%9L@%EMA%MMBF%RD&ATC&1N" + "@5QD?V)1@&1/?V-,>5]'=EQ&=UQ(>5])>F!(')_>W>.>'2+=G**>G:.=G*,=G*,>W>1" + "A8\"=G92PCX:B=&N'75=R7%9Q:&1^:&1^=7&+D(NHD8ZLE)&OG)FWEY:VJ:6_HIVZ" + "EY*ODXZKC8BEEI&NCXJI@GVDGIFVI*\"ZL:W'P;W5IZ.[EY.JGYNR@WZ39V1X" + ";FM_<6^%<6^&8&!W75UV;V^(@W^7AH*:A8&9AH\"9F9.LC86>;&1]44=A7%1L?722" + "C(6EB(.:@H\",>WN&=W6+=W.5=W\":@7N@@7J<@'B1W)L;V5::5A/5TA\"" + "2SM!1S9!0C!!2#1!2S9!1S)!3S!!535!7#Q&941+<4]/>UI4?U]3?5U-?V-6@&53" + "@&1->U](=5E$<%1!;U-!;E)!<51%;$]!<59&;U5%=5Y-72+=W*)?7>0AH\"9A7^:B(*=C(:CEXJGAWJ7" + "?7./>&Z*>7\",?G619F![<6N&CHBEC8>DC8BGF92SE)\"QJJ7\"JZ;#F92QDHVJE9\"M" + "H)NZDHVLA8\"?C(>DI:\"]J*2^IZ.]O;G1IZ.[F96LG9FPBH6::&5Y;VQ`<6^%;6N\"" + "86%X8&!Y8V5]=7&)?GJ2C(B@F9.LI)RU?76.8%9P7%)L9EYV>7\".A7Z>CXJACHR6" + "B(>.?WV1=W.4>W2?>W6<>G.6;FB#;VAX@WU`@GMR95]033E!.BA!/BI$,Q]#-B%)" + "+QM!/RI,-R)!2\"I#1RE\"3\"Q\"43!\"5S9!7CY!9D=!;$]\";5%%=UI+?F)-@6).@&%." + "?U]/?%Q,=UA%;DU#:$I!<55)9TM!9DQ!:U!&;U=,;%1+:U-0=V%5<5Y/8D]*9%)?" + "54-<6TQB=&AW>W.);65];V=_>'\")C(2=BH&=C82@C(.AA'63>VR*B7R9E(>DE(JF" + "CH2@9EUY<6B$C82BB(*?B(*?EI&PE9\"OJJ7\"LJW*HYZ[AX*?E9\"MFI6RF92QE(^L" + "EY.MHY^YIZ.]KZO%LZ_'JJ:^E9&IH)RSC(J>;FE^;&=^:6=^7V1[86=^8FB!;7&+" + ">'B1>GJ1B8>>GIJRG)BP=6^(5E!I54]H:&1T;F9^?'2-@7V4C8^=AHR9@H2<=G66" + ">W:=?'B8=G\")54Y>;V9J>&]K9UU45$!!7$=#8DI'5D%!7$M$5$-!43Y!6T1!" + "8D9$9TE*9D9(83Y!8#Y!94-\"8T1!7T!!845!94E!%I/A61:@5Y7@%U8>E=2" + "*C86;B(\"6D(>=E8R@@76,:EUP?&M\\E(68E(N?A'^68%MRF).JD8NFCXJGH)NZM[+/M[+/HYZ[BH6BC(>DD(NHE(^LFI6RJ:6_H9VWJ*2^" + "N[?1N+3,K:G!FI:NG)BPCXVA:V9]9V)Y9&)Y7F-Z6V%Z9&J#;'\"*9VF!7&*=W.*=WF'G::>'25" + "=FEAAG%MAF]JB7!JA6YEBG9L?VU@?&A?5M:?5M:>%E5<5).8$1!9DA!:TU$;U%&<$]'5=4>UE6?5Y:" + "?F%>?F)??6%?<5A58DA(5#Y!84E*=5M;=%YA4T)+1SE%33]+9E9@8UAG7E-B9U]O" + ">'&\"@GN,=VY`B7Z0GY2E@G2*74YA74M::EQL?72&>W:+7%=J:6)SCXJ?DXZEB8.<" + "A8\"=EI&PO[K7NK72J:3!GIFVG)BRHY^YJJ:`M[/-MK+,IJ*\\IZ.]O;G1O;G1JZ>_" + "DX^GG9FQE9.I:&-Z6E1M:&9]9&E`96N$9FR%8F:\"8F9`<7:-AXFAF9NSEI:O?WV4" + "9F)Z7UMS9&%S=&R\">W.+>'.(:VQ]9FQ]8F=^86&\";&J0=G28>'>7>76/9E]P<69M" + "?6]MC'UWFH-^G8)\\GX-YF7UPEG]LCWIDD'IDDG=CEWMNEWEND7-JBFECAV5BB6=D" + "B&EEA69@?V!:@V5EE19T9!9D-!8CY!:$1%=E)2=E13>UE8?%Q<>EQ;>5U=" + "=%A8:E!08DE-7D1&;%)29%AC;F1P?'%`?7*!8%5D" + "95EF>&QY951E54-07TM67T]9=&EX<6U]5E1B9&!MB827AX*7?GF0>W>1BX:CP;S9" + "O+?4L*O(L*S&JJ:`KZO%KZO%M;'+MK+,LZ_)IZ.[MK+*PK[6IZ.[B(2O>WN49F1[9V-Z>72)" + "?W>-?72(>72':FM^:&V!96F#:FN*WN>?7R<>WB4AVI;@F)6@6!8A&-=AV9@A69@AF=A" + "B6IDAF5=@F%;=%--<$Q,;4E*<$Q/6YV?W-^@'1_8%-<5$1-3S](1S5!" + "8DU5@6QR=&-J@GA`>79`7%ID9V1L@7J+?WB+?'>.?7>0BH6BMK'.N[;3MK+,MK+," + "K*C\"KJK\"JJ:^K*B`L:W%M;')KZO#N[?/P;W5I:&YB(2>J*2^H)ZU:&)[7%9Q;VR&" + "9&B\"9FR':W\".8V>%9VZ)>'^:D9BUHJC#@86?8F)[65=M;&E]?WJ-?'.%=VQ]>W*$" + "?GN7=6V#DX>6II*:E7^\"DWAPG']RFWAEEG18" + "AFI&A&A\"C'!,BVU,BFQ1B&I1A692@F)2?V)5@%]5?EU5>UI2>5A2>5A0?%M3>EE1" + "?UQ7?%E6?%A8>E97>555>555?%I9=E96:$A(73]!6S]!7$!!6$!!845%:DY,=U]@" + ";UQA5D9/0S-!6DE.?&QUCX**BWZ&AWJ\"CX**@'%W=&-H74Q14CU%>V5IEH\"#?VQO" + "DH>,CXJ096)H9&)F?7:&?G>(A8\"3AX*9CXNEJ*.`M[+/NK;0M;'+KJK\"K:G!K:G!" + "M+#'KZO#JJ:^LZ_'Q<'9N[?/HY^YD(RFH)RVI**Y8EQW:6-^;FN':V^+9FR';7*0" + "7F)`5EMY;W:3BY*PE9RY:V^+555N7%AO>72)B8\"4?W2#=VEW>6Y]=W*%=76,<'**" + "<'*(965`9&6\">WR9A82B=W&*BGV0H8V8EG^&D79LE'1FC&A1E7)1D'!(A6A!AFE\"" + "B6A$AVA*@V-)?F!)>U]+>EU.>5Q/>5A.>%=->E=0=E-,>EA.>%9,@F!6?EM4?EM6" + ">%50?%E4>EE3?5M8>UQ86AM8U9>33U&" + "6TI1=FEQD(.+C8\"(A'=_BWZ&A79Z@W-U:59995!4C'9WEW]^>F9FE(B+EH^58EUB" + "6U99?WF&@GN+D8J=C8B=DHREHIVZLJW*N+3.LZ_)M+#(JZ>_J*2[KJK!L:W%HIZV" + "JZ>_P[_7NK;0I*\"ZCXNEF96OGYRV8%IU&IV?'.%G2/>FZ#@6]^>6-OC7)HF'AHCFI1FG93FGE/D7)'BVM%AF1!@V%$>UQ!" + "=5=!%A,>5E->59/>%9,>UE.?5M.@F!3@%Y1?EQ1>5=,65CE8:(EHV16U5885A^K*B_M;'(IZ.[H9VUN;7-P;W7" + "IZ.]B86?FY>QDY\"J95]Z>'*/=7*..CY:35)P6E]^0?FM_<5MIA6I@I(1TFW=UE!=EA!=UM&>5Q+" + "=UI+=U=+=U=+=U5+?%I0?%I-@F%1?%M+?%M+=%-#9E=;;&%I7U1<3#Q%5$92:EQH=VMVB7Z&DH6-" + "AG=]D8&#@&UO@6UMG(>#D7IU?&AFF8J,FY*68EE=;V9HB8*+C8>2GYBHDXZADXZE" + "G9BUI:\"]L*S&M+#*Q,#8P;W4J*2[I:&XL:W$GIJQF)2KO;G1P[_7J**]E(ZIF9.N" + "F96O;&B\";&B\":VB$24AF7U]`='27;FZ3=7>UQ(>UQ(?5Y*?%M(" + "?EU-?5Q,@6!.A&-1?E],=5A';5-#9TU!8D=!9DM#9$Q#:%!'7D=!94Y'95!,:%-1" + ":%)6:U56;%A6<5YA9E9B:EMN9%AG6U%;5$Q:2T-165%?>&YZC8&,C'R%E(.(AG-V" + "BG5YFH*#DWMX?VIHJ9N;D8B,;&-I:V)F@GN$AW^+CH:6CH>:E8VEE9\"MI:\"]JZ?!" + "K*C\"OKK2Q<'8KZO\"G9JNEY.JC8F@E)\"GQ\\/;P+S4J*2^DHZHHYZ[DHRG<6V'9%]\\" + "7%EU@G^=E).TI*+&GY_$C9\"REIF[>'N=2TYN45!N3$AB44A>9%AM<%MM?69O@&9J" + "BW)Y<%YM8E=I:V5R@7^#?'B%:VAX:6E`<&^/:62+=VR/?VV&=%UP@&9HGX1TF7M6" + "GWQ1I'Q7H7A;F7)4D6U,C&A/BFA.B6E3A&51?5Y+?5U-@6%1@&%.AF)1AF)1AV-2" + "@V)0?%U*=%=&:U%!8DM!:D]'9TQ$94U$84A\"7$5!7$=#8TU.9$Y1:U1=<%M?>F=I" + ">FEP=V9U=F=[?7\"\"@':\"'%Z>W-_@'B(AG^2CH:KD(RCAH*9EI*JP;W5P+S6K:G#DXZKF).PBX6B?GB5;&>$:&-`HZ\"^L:W/" + "R<7IU=#WR\\OLO+_A@X:H2$AI7EMY7UER;6%V@G6'DGJ'EWE`@&)C@&-HUQ)GEX^?>7&!8%AH:5YMA7F&BWZ'C7R%AG)ZBW9\\H8N,EW]^GHJ(I)67B8\"&" + "<&9N<6=O=F]X=6UY>G)`AG^0D(F_O;G1P+S6JJ:`GINWFYBT@WR721FI6TNK76R,+ETLSQTLSSS,SQ" + "R,?OMK7=EI:[HIZ`I)NYE(B?V!HA&5K@V9K;UIB:EIF=&9R@W9_=')\\" + "7EUK86)W=7248EV&8UB!:%=Z9U-O@VQGF'YND'-4DW%,G753J7UAJ'QBHW=>F7-=" + "FW=@G7IEE75?B6I6AF=3AVA5A693B6-/AF%-@UY*@%],?V!-=%I*:E1&9E)&:$])" + "9DU);%11:%)38TY474E38U%>9E5D<%UR?FR!C'N.DH.7I9>MIYNRHIFMGI>JG)6F" + "@'F*6E-D4$A88E=F:%QG;%QF<6!ICWR!G8F+DWY\\G(B(H)&5?7-[>&YX=VUW<&ER" + ";65QT72'8%MP6U=O;6B'" + "85I]5TQM5$5;5T54>6-5D'=BD'-4D&Y)EW%+JG]=JG]>HWA9G75:GWI>H7YAF'E<" + "C&]1BFQ1BFQ3AFA/BF51@V!+?UQ'@%],@&-2G!\\;V=U:F)R=&M]?'6(" + "A'R2LJK\"P+C0N[/+L:S#I)^VNK;-LZ_&CHJAI)ZWE)\"HC8FAN[?1P+W7GYRX%>'25GIJ[N[C6Q\\3BPKW>RL3GTLKPT,CPS6EUA'F!5I'>5Q+?&%1;55(7TM!8D]'95-064E(3T!$4D=/2T-1651G:69Z" + ">WF/D8ZHH9ZZHIV\\HY^YGIFNIJ*RG9BKEY*GGYVSE)*H;FQ`2$57/#A(1T%.2D!," + "6$Q7E(.*G8J-A'!PHY\"3E(>/B'Z*>W!_?'%`=FU_<6A\\@7B.@'B0BH*;MZ[$MJ[$" + "N+#&L:S#EY*IJJ:^JZ>_HIZVN;/,K:G!DX^IO+G3L:[*?GZ96UIX962\"8V2#F'=5F'5,I']3H'E1GG91E&Q'E6])E')-D7!,CG!-D715D7-8B6M2@613@613" + "=EM)%Y0<%I.8T]%8U!(6$U*2T%!24!&65->:&5U>7J/AHN@D)6JEYVTEIJV" + "DY>UDI.NDY*CG9NGHY^NI)^RHJ.XEYJN0D(64>W\"!?W*$=6R\"<&9_B'Z8@7B6DXJHP[K.M*N_MZ_%MJ[$B(.:" + "BX>?EI*LKJK$PKS5M[/+EI*LM+'+M[30A(2?=W:4A8:CA(2E96:%9VB'>GF9@GZ?" + "JJ3'N;/8NK3;Q+WHNK3AO;GKM[3HO[_PM[;AQ<#GR,/DRLC>QL'8MZ[\"CH201T%$" + "85A<9%EA6$=86TI=5$585TA;:5INC'N.7TI85#Y!?F=@E'ALD71ED&]5]/<5='>6%4" + ">F18;EQ1:UI185E83$9'3DE/8%YL@(&4CI.HFZ.YFJ6ZDY^TD9NWG:3\"FIZXE9>E" + "CX^8GIRHIJ&THJ2ZH*6ZAHF=6EUQ1$566%5E5U-@75=BB7I`CGM^?6EKE8*%E8B1" + "CH.2?G.%@'.&<6>!;6-_BX\"?@WJ:G9.VN+++NK++N[/,LZO$HIJR=7\"'AH*9P;_5" + "S\\OCKJK\"D8^FN;;0P+W7H9ZXFYNVK*S'JZO&A(.A962$>7B6>'B1@'V7>7:4@W^A" + "GYF^N;+P[W:N+++L::UM*RXPKB`N:VN?&AF:U9284M.84Y3" + ";%E>95%97$I584]<@&QW6T9.6T5&B7%NEX!OC71?CG);FGU?G'Y=F7A6E'91DW50" + "E'95FGQ;F7Q=E'=9DWA&5@<%Y;85).6TM*" + "5$E02T1+34=2;&IXCY\"CH:2XJ:O!I:J_G**[EYRSG9VTG)JPGYRPEI&DGIFLIJ&T" + "G)JNI::[FYRQ=7:+0#Y255%A65%?85=CBGJ#EX2)AW)VCWR!GI\".D8VDN[G-Q\\/;J:6]EI2K" + "L*[%PK_9K:K$F9FRH*\"YI*2]A86@>'>5AH:ADI*IAX6<<6Z*85U^>W68E)\"TGYK!" + "L*O2J*+'IZ\"`GY>PEHVCCH*-DXB0DH>,CW]^?&A@94U$749!<%I;>&1DF%>BG)ECG1FF7YLHH-OIH9NH(!FFWQ?DG-6DW5&1B@G!O?FYO9%A95TM,4$E07EAA@'R)" + "H:\"QIZB[KJ[%M+;,HZ6]GI^ZE)2MEI2KE9&HEI&FC8B;F92GJ*.VF):LHJ.XF9FP" + ">'B/2TE?4TYA3T=57%)>AG9_DG^$CGE]F(6*G8^;?W2%8EEK9EMM95MT:%YWA'N7" + "@WJ8DXRLL:O$M;#'OK;.L:G!GY>OF).HK:J^OKO/R\\?>P;W4N+;,N;?.OKS3L*[%" + "F)BOG9VTI*2[@H*;;&R'GB/<&V)='&/7.0>'\"(" + "=VQ^>&Q[?6QSE(6)DX.$?FIBF'YPG8!QG8%TCW1JB'%JEW]\\D'AY;%994#I!3#-!" + ":$Y.BG%NAF]JC'-MG(%WG(!TH(-TE'=FDG5DC&]>C7)BAFM;@6=7@VQ=AFYAA&UD" + "@&QD@6QGA&QIAW)PB'1TAG9XA79Z=&EP85=?:&%HCXN8I*\"OJJ>YK*J^KJ[%K*S%" + "JJ?!HI^YGYRVF96OEY&JDHVBDXNAC8B=FI6JIJ&VG9NQHJ*YFIJQA(2;:VE_8EUP" + "3D9664Y=>6ES@FYVD'M_GHN0EXF5NE(^FGIFPKZR`K:J^L*S#M[/*L[''O;O1N[G/L:_%G9ZSIZB]KJ_$" + "@X.:65ER7E]T969W<&]`;6N!>'6/@G^9;6J$5E-M2D9>:V-Y9UQM;F)M=FEQ?FIL" + "@&QL@W!K?V=0" + "<&N\"<&N\"=7&(;VN\"=7&(='\"'<6^%LK#&P+[4K*J`DY2IGI^TLK/(AH:=7U]V:&E^" + ";W\"!9V9U65=K8V%X=7.);VV#8EYU6%-H?'6&;&)N75!88U1:9$Y/6T=%8DU(;%)%" + "?5Y*@5Y'FGIBJ8MTDWAFFG]OHX=[H89^>F%=;U939DY-7DA)5D)\"6T=';5E9>65E" + "EX.#DGY\\D'QZBW9TAG1Q@G!M?F]K@G-OB7IVB'IZ?W!R=&5G85%:5DE28E9ARF)6QFY6RD(JEC(*=CHF@CXNBFI>QE)2MCX^JE)2OH9ZXEY*I=FV!?'&\"A'1`<5UGCGE_H8V5" + "F(J6;V1U3T984TA:3T5>6$YG;V:\"?W:4BX2D@'V77@7>#8U9?;V!F>&1D>65E=6%?:E))?6!/C6U7D7-<" + "E'ACH89TDG=EAFM;BW%DBW-JEH%]@&QL7$E+3CY!=V9KFHN/FX^4IIJ?H9*8FHN1" + "D8*(B'Q_AGI]@G9Y@'9XAWU_C8*'AWZ$?'-Y9EII7E-B=&Q\\AX\"3J*6YHZ&XHJ*[" + "I:6`IJ?\"J*G&H:*_GI^\\F9BVDY\"LD8NFC(.?B7^8@GB1@G:-C8&8BX*8B(\"8AX&:" + "D(RDB8:BA86@@X*@B8BFC(FEC8>@=&M_>W\"\"CGV,;5ECC'=_GHJ2FXV9.7E]T;W%_9F5S9&-T9&)X9&)X;6N!" + "?'J.CXR>BX>7CH:4A7N%F(V5GXR/?&QNAG-UC79QGX-WIH9VGH%PHXAXK9)`IXQ\\" + "F'YNC'1GAW!GC'ET?6UL:%E;?&]XK:\"IR;W*O;+!M:V]L*BXKJ.TJZ\"OIINJHIBD" + "FI\"&:U=BD'N#FX>1E(:2;6)S3$-55TQ>7E1M7U5N" + "9EUY=VZ,@'F9EI6SEY2RCHFHCXJGBH2ADXVJF).PI:\"]I:\"]@GV:D(VGKZS&P;[8" + "L*[%IZ>^IZ>^H*\"WFIJQ>WN48F-X9FAV;VY];6Q];FR\":VE_7%IP<&Z\">WB,;VM[" + ";VAX>W!_B7V*D8\"%4D-)H" + "HYRMJZ2WKZ>]K:B]KZJ_LZ[%K*B`IZ.]J:;\"IZ2`JJ?%I:;%G9Z]EYBWD)&P@X*@" + "BH>CEI*JBH6C(.9AGV3?'2*BH*:C(:?C(BBC8JFBXJHCXZNFIFYC8JF" + "H9NTBH&7?G*'@G%`;EIEG(>/G8F3BWV+8UAI3416:5YP;6-\\:5]X:%][>&^-?WB8" + "HIZ_FYBTFI:PFI2QEY\"RHYR_G)6WI9Z^F92UA8\"AI)^`KJG(HYZ]JZC$JZC$JZO$" + "FIRTBXVE@(\"7VO;3&K*2\\L*K%JZ;#J:6_L*S#M;##M;')L*S#HI^SG)FKH)VOHZ\"RJZB\\L*W!" + "L;'*KZ_(JZO$J::`J*7!J:;\"IJ._HI^[F9BXCY\"OC8ZMBXRKAH6CC8JFCXNEA'Z7" + "A7V5DXNAC86;@WJ0:F)Z@7N4BH:@C(>DA8&BD(^PF9BYE).SFYBVH9NVB'R39UEO" + ";5MP>&-SI(Z9J)25>W24>G:7>7:4?'>4" + "?WB8@GN>BH*HAG^BA8\"A;6B)75AY@'N<@7R;:VB&>'61AX2@>7:2@(*:>'J2=76." + ";FZ'8%YU7EQS9F)Z;FJ\"?W^:@X.>?7V6;V^&;VV$<&R#BX:;;F9\\=&M_6$U?=6AZ" + "AGB(A')]@FYVAW)VA&YOCWEZEH)`G(F$BWETBWQXB'Q]>G%WA7Z'M[+%Q,#7L[#," + "L[+2KZ_0K:[-K:[)JZW%KK#(K*[$H:2XG:\"RHZ:XJ:R^KK'%L;3(JZW%K[')KZ_*" + "J:G$IJ._HZ\"\\H)VYFYBTD9*QCH^ND9*QD)&PBHNHB8:BA(\":>'2.A'^4C(2:?'2*" + ":6%W755M=W&*@W^9A'^AWF%2C]03$%395IL:6%W=FZ&>'\")@WJ8AX\"@9V:';&B):F6$9F&\":V.+;&6/" + "<6N2:F2)85M^:6.&<&N,:&2%;6J(;VR*='&/#9&%[75ES" + "8U]Y;&B\"='.1?'N9>'>5:&B#965`;FN'BX>A=&Z)=VZ*;V:\"=&J$=FB\"=69\\<%]P" + ";EQI95->6TA*9%)1<&%=<&%=BG]\\B7]_@7I`DXV6KJ['N[O6L+/3M+CK;/6" + "JK#1J*_-JK+*K;7-IZ_%H:F]HZN_I:W!H:F]GJ:\\I*C$J*S(IJ?\"FYNVDY.NF)6Q" + "G9JVH)NXF)FVDY2QC)\"NB(RJAH>DAH:AB8:@C(BBC8B=B829;&%SD8JJD9\"QEY.TD(NLAH\"CBH.MB(&LD(NUA'^HBH2I" + "D8VQCHJLE92UEY:VEY.TG9JXHI^]=G636%=U4D]M;&F%8EUZ75AU7%9S6U5P96&\"" + ":&>':&>'86!`7%M[6EEY=G*3<&N,;VJ+:V2$:%]_?722G9.MJY^VHI6HA'B'9UQ9" + "6U!+54M#4$9!6U),6%-09&!@A(*&HZ.^M;;5M[K_FJ*ZG*\"\\I*C$IZC%G)VZE)2OE9*NEI.OE9\"MDI.N" + "D9*OC9&MC9&MCH^LAH>B@H*;A8*<@G^3>'.(8UYS4TMC8UMS;VF$>G21>W:5?WN<" + "AX:FB(BIC8VNC(NKFI6RFY.K9%MQ:EAM>61TF(*.JY>B?G!^1#Q,7U9H72;DI\"T@X.FDY.V" + "FYN\\F9FZEI6UJZ?(GINY<&V+55)P<6R+651Q75=T6U5R4TUJ4$MJ5E)S75EZ7UY^" + "6UIZ5E5U:V>);6F+<&V+:F6$8UY]>G21CXFDGY>OG)2J?G6)?G=^;6-K7%-93D5+" + ".C-!1#Y'7UQF@7^-EY2PM+/1PL/BN[[@M;C:K*_1K*_/K;#0NKO:N;K7M+70IJB`" + "I*:^IZG!G)VXF)FTGJ*\\I:;!I*6`F9FTCX^JCXRHC8JFBH6BB8FDB(FDB(FFBXRI" + "BXRI@X.>>7F2>'6/;FJ\"8EYU6E5L5T]G;&1];VF$>G21@7R9?WZFB(FH" + "@(&>D(VGEI&H95US8E%DWJC8F&)<'\"5;6^4='BWGIZ_" + "B8BIEY2R$65-P75=T8EEW6U)P85IZ:&&!:&.\"8V!^6UIX6EEW:&6#" + "9V2\";6J$;VR&:6:\"9F-_4T]I3TMC5E%H241;1#Y;/#93.\"]+.3!,,\"I%2D1A7UIY" + "96&\"@7R9IZ*_N[C6KJW-K:S,L*W+M+'-M;#-K*?&JJ7\"K:G#J:6_L:W%M[/-I:&[" + "GYJWH:&ZH:&ZG)RUE)&KCHNGCHNGCHNGC(FEDH^IB(6A>GJ5;W\"-9F6#75UX659P" + "5E-M2TAB1$!:2$);3DAA8%IS8UUV<6N&?'B2A(2?A(2?A(6B@X>C?X\";C8VDD8ZB" + "8UYQ7U!C=F1SF822L)ZK@'.%2T)4751F8UMK95YQ?W>-;F9^=&R%?GB3EY>PDY.J" + "CXVDBH>CAH2HAH2LWC9*SAXJJ?W^@CHFF?'>4" + "5U)O6%)O5U%N5DUI7%-O751P95MW:6!\\95]Z8U]Y9&%[;6J$='&+<&V'7EQS;&F#" + "7:2EY.JFY>N" + "H)RSH)RTF9:PC8JF@7Z:>7:496%[7UMU7%EU5E9Q34QJ3DMG34ID1T-=14)@0T!<" + "34EC5U%J85QS9V)Y=W&*?GJ2@H*9?X&9@X>A@X>A?X2;D)\"GC8J>9V-S85)E?VU\\" + "GHF7II2C=6AZ4$=;8UIL:V-S;VAY?WB+L;W&8;&Z3866+G2/@'B1EXVGGIBSAX&:?WJ1?7B/DXZCI:\"WE(^FD(JCEH^BEI&FF92IEI*IB86?" + "='&-85YZ5U1R85MT6U=Q7%=T55)N2$5A1T1@2D9@03U71T9F3$EG651Q85MT8EUT" + ";&=^>72+>W>.>GN0>7N1A8JA@XB??8*9BXRA@X*39F-S6DM>@&Y]H(N9G(J9:UYP" + "4DE=9%UN;&1T:F-T?G>(@'F,F9&GE(^F='&+@'N0HINLJ:6UB(:<>7J5>W^==G>6" + "9&:->'NCEYK$EYS'C9*]:&N3;6^6>7F>BXFOA(.C7%EU.S=144MH3D5C7U5Q;6-\\" + "95]\\7EAU7EAU:&-`;FF&8EUZ7EMW;&F%EY6LKJO%M[3.J:;\"HI^[K*G'L[#.L*S-" + "IJ/!GINYHI^]IZ3\"JJ?%F)6SC8JHAX2B?WR:'.0;6B%;&:!>7.." + ">G:0;6F#655O2D9@9V-[=7&);VN#:&1\\;VI_;FE^='\"'X\"7@H>>>X\"5B(F>@'N085IM4D58>&=XGHR9C'N*:%UN6%%D:6)S<&AX" + "=F^\"?'6(@GJ0DXZEDHRE;VV#<&Q\\AX&.C8F6AH64<72(_A8BP6UZ&86.(='29@7^CA82D8%UW/#A23TEF44MH7E5Q:5]Y9%Y[6U5R75AU" + "9%]\\9F%^=&^,D8ZJJJ?#O;K4P+W7M;+,H9ZZFI>SHI^]IJ/!H)R]FI>UDY\"NF)6S" + "GINYK:K(J:;$I*&_G)FWG)FWE)&OF)6SBXBFDXZKAX*?A8\"=?7B5>W>19F)\\2D9@" + "/3E34$QD85UU4$QD2D9>3DM?7%EM;FJ!<6V%7:0=W20>'61;FN':F>#:&6!" + ":6:\"<6Z*>WB4=W20:6:\"8%UW:6:\"'*+?GF.A'R4?W:2=W>0?X&9@8:=" + "A(F@@H2:C(J@@GV27E=J34!3'&$=V^%=FZ&" + "A'Z7@WV6;VU[<&IW>W1]<6QRWR9FYZ^EIB]@8.J5UE`" + "65M`<'\"5=725@H&?8%UW.SE01#]<24)B44MH85ER8EUZ8%MXDH)VY" + "M[30N;;2L:[(LJ_)K:K&IZ2`JZC$L:[,KZS*IJ/!GYRZG)FWH)V[HZ\"^L:[,KJO)" + "HZ\"^DY\"NFI>UG9JXG)FWB8:DF).PF).PEY*OA8\"=@GZ8=7&+8EYX5%!J7%AR=7&)" + ":&1\\;VN#=7*&@'R3C8F@B86=@X\":@G^9>'61<6Z*:6:\";6J&=7*.?'F5@G^;B8:B" + "BXBDA8*>=7*,='&-=G.1>721?'B0A'^4@GV4>7..='2-?'Z6@X6=@8.;@H*9BXF?" + "A'^4759I13I,W.)=&R$@GR5@7N4>'5]" + "=W!Y>7!V:V5H:FAH75]?8&%E7EQH7EQR?7J4GIV[F9>[@8\"H5E5]34QT8&\"%>GF9" + "@8&<7UUT/SU414)>2T9E2D5B6%1N:62!=7\"-CXJGI:\"]L:[*P;[:Q<+>MK//KZS(" + "K:K&JJ?#IZ2`IJ/!I:*`H9Z\\G9JXEY2RF)6SHI^]J:;$NK?5N;;4L[#.IJ/!H)V[" + "IJ/!FYBVD8ZLD8ZLEY2RF)6SDY\"NCHFF?GF6<&R&7UMU:65_B(2>B(2B(6AB8:B@X\":" + "?7J6>WB6?7B5?WN3@G^3?WJ1=&Z)=G:/?W^8A8>??GZ7@H*9C8F@C8B=9V!S13I," + ":F5J:6!F<&1I;&)B" + "6E9,3T]$6E947UA>7UIM=&^$F)*MI)^`E)\"T8EV$1T5K7UV#@H*=A(2;8F!V/3M1" + "03Y:3TQJ3TQJ5U1P96)^AH.?I*&]L:[*N+71OKO7O+G5M[30JZC$JJ?#JZC$KZS*" + "L*W+K:K(J:;$J*7#H9Z\\GYRZI*&_IJ/!KJO)J:;$J:;$I:*`I*&_I*&_FI>UFYBV" + "EI.QE)&OI*&_L:[,G9JV=G./9F-_8E]Y?7J4D(VGCHNEE9*LH)ZUF):ME)*IC8JD" + "B(6?AH.?@'V9@7Z:AH.?AX2@C8JFD8ZJC8JFBH>CB(6A@X\"" + "A(\"8@X\"4?WN2=W.->'B1@(\"9A86>?'F3?WV4BH6W.)=&R\"BHB>;F^\"/#U2-S=24E%Q:VJ*" + ">7B6CHVKL:[,QL/AQL/AQ,'?P+W;NK?5NK74KZS*K*G'K*G'L:[,LJ_-K*G'I*&_" + "H)V[FYBVFI>UH)V[H9Z\\IZ3\"HZ\"^I:*`I:*`EI.QCXRJDY\"NEI.QFYJZD9\"PL*_/" + "N+?7BH>C:6:\";&F%AX2@J::`I*&[H)VWHI^YI*2[GIZUF)BQC(REC8JDDY\"LCXRH" + "C(FEC(FEB8:BBXBDCXRHD8ZJDY\"LDY\"LC8JFB8:@AX2@B8:DBXBDB(:=A8.7A(*8" + "@GZ8?GZ7@X.@'1W;EUF8TU88D]1;6%2;651;F1;;U]A8U=87E)7" + ";5]K@G6'C(\"5;F5[3TI?:F=[>':-WK*O+EY:V:&6!;&F%" + "@X\"SEY2PBXBBAX2@B(6CBXBDB8>>B(::BHB>B8:@B8FBBXBB" + "@X\":@GZ8?WF2BH*:>W.)4TQ?1#U->6Y]BGR*8E9E4DE=6E)J8UERBH2?D8*&FX>1E7V*>6-FA'1F?7)=@')H@&UP;6!9:%I89%577T]8:5MG" + "8UEE2$)/6%5?65=M/CQ02$E:65IMAH>BIJ?&P,'@QUE9*PFIFYFIFYIJ7%I*3%=766;VR*CXRHH)VYM+'-JZC$" + "J::`L:[(JZC\"IZG!FIRTG)RUI*2]IZ?\"H)VYDY\"LE)&ME)&MCXRHBXBDB(6ABH>C" + "E)&MF9:RE)&MCXRFB(6AAX2BBH>CBHB?BXF=CHRBCHNEB8FBA8*<>'2.>W60=W&*" + "A7V57E5I8%AP7U5N8E9O;F9\\=&R$>7&*B8.>AX&<" + "<5Y8LK;4NKO:Q,7DP\\+BQ<3DO;G:N+35J*/$" + "H9V^G)BYE9\"QGYJ[G)>VE(^NA'^>A8\"?C(FGE9*PGINYH)V[GINYH9Z\\H9Z\\F9:T" + "DH^MEY2RGYRZFYBVF)6SHI^]CXZL8F%_AH6CL*_-I:3\"J*?%F9FTEI:QG)RWGY^Z" + "G)ZVF9NSG)RUI*2]IJ._GINWEI&NDXZKDH^KCHNGCHNGD(VIC8JFCHNGD8ZJDH^K" + "BXNFCXRHCXNECXRFBXVC@H69A(*8DXZEB(6?>G:0;&B\"'*+>G**9%MO4D=9" + ";&%RAW^+>G-\\8EIH6E%E7U5O5DQF75-M95UU=6V&>7&*A7R8@WV83SI!6$%(:5!5" + "?6-GD75UF7YXDWMPBG)EB'%BC'5DC79EAW%BAG1GA7=O@G5P=6II>'9`55)<>'2#" + "E)6JIJO)M+K;Q6?GN9CHNIH)V[IJ/!I*&_I:*`H)V[E9*PE)&OE9*PG9JX" + "GIV[FYJZE).S>'>745!P=W:6JJG)J*?%K:S*H)^]F9FTEY>RF)BSG)ZVG9^WG)RU" + "F9FRG)FUGINWG9BUF).PCXRHD(VIF)6QGINWFYBTE9*NDY\"LD(VIE96PFI>SFI:P" + "E)&KBHRB@H2:A(*8BX:=AH.=?7J4;&B\";FB#3AH\";>F-NA6YYCW1^D7-ZE79ZFGMY" + "E'5OB&IAAVQ8C'):D7==C75:BW=??VY;@G1J;6!9=W1\\7%9?C8>4IJ2ZL[?3M[W>" + "P<;ERLOJQLKHP,3BN+G8L;+1MK75HZ+\"FI:WH)R]CXFL;VJ+96&\";6F*85U^;&F'" + "=7*0;&F'DY\"NEY2REI.QG)FWG9JXE9*PEI.QFYBVG9RZGYZ^GIV]DY2S" + ">7J97EY_@X2CHZ3#FYR[JJO(K*W*H*&^EI>TFINXGI^ZG9ZYF9FTDI*ME)&KFI>Q" + "G9FSFY>QE)&MEI.OGYRXI*&]G)FUDH^KC8JFBXBDE)2OF)6OFI:PD8ZHA(:=BH6G:0>G2/&I@?'5[;F5KI9VIM+'#O+W8NK_>N\\#>O+W:O\\#=" + "O\\#=N[S9KJ_,K:S,HZ+\"C(NK?GV=9F\"#44MN2$1F14%B/3E:44YL9F.!8V!^9&.!" + ">WB6D8ZLFI>UG)FWH9Z\\H)V[EY*QEI.QI:*`I:3\"G9R\\G)V\\EYBW@8*A;&^/@X2C" + "IZC'HZ3#JJO*IJ?&EYBUD)&NFINXGZ\"[F9JUE96PE)2OEI.MEI.MFI:PGIJTEY2P" + "EY2PG)FUGINWEY2PDY\"LEI.OF)6QD8ZHD(RFD8VGC(FC@H2:A(F>C8VDC(B?B8:@" + "@GZ8=W&,;F6!4TEC3$);7U5N?W:,B'V.C8./=VUW54U;8UIN<&A`<6F!9U]U:6%Z" + ":V-\\9F![;&:!A'Z;95!494]2;E59?6-CC7!MEG5OFGANGWIPF'ICEG9&99=&AI=FIMK*&HL:JZL+#'L[?3M+C4LK+-M+3/L;',L*_-HZ*`" + "F9BVE).S>7667UM\\3TEN7%9[8EY`6E9X5E)S6UIX8%]]65AV7%MY:FF'>GF7A(&?" + "BXBFF92SHIV\\GYJYI)^^K:K(JZC&H)^]G9RZC8ZK<'&.6U][>7J7G)VZG9Z[GZ\"]" + "I*7\"HJ.`FYRYFINXG)VXEI>RDI*MDI*ME)&KDY\"JEI*LF)2NEY*OEY*OFY:SG)>T" + "EY*OEY*OFI6RFY:SDY\"JCHJDCXNECHRCAHB>A8J?BHJAB(2<@GZ8>G2/<6F\"7U5N" + "035.3D);G!\\7%1B9EUQ;&1\\;65]9EYV<&J#<&J#<&J%>G2/" + "DHRI6TE(:%95=&!>>V9BA6YIDG=OF'IQEG5KD'!@CFU:DG!6E7-7G7MADG9?F7]O" + "AW%C<&%=?VULK)VAN:^[L[#$M;7.M[?0M;/*J:;\"H9ZZHZ\"\\GYRZE)&OBX>H:&2%" + "5E)S;FB-CHBMGIJ^DHZPC8RL@8\">;VZ,7E]\\4U)P7UY\\?@(*:D)&LBHNF>GN6@X2?E)6REYBUF)FV" + "H*&^HZ3!HZ3!G9VXDY.NE9*LFYBRG)BPE9&IE)\"JF96OH9VWHIZXH)RVHIZXH)RV" + "F)2NBXBBB(2>B8.X\"5>GJ1=W.+>G2->'\"(;F)[6DQD1C9/9%1M@G*+" + "AWF1BWV3AWJ-\"61?>F5@" + "E(!`LJ6NKZBYJ*:]I:.ZHIZUK*C\"J:3!I)^\\GIFVF92SAX*C7%=X75AYC8>NH)K!" + "IJ+&F96WFYJZDY*PAXBE>WR9:6J'8V)`86!^9V2\";6J(>G64A'^>AX\"@E(JMC8:F" + "C8:FEI&NFYBRDI*ICY\"EEIFKHZ.\\C(RE>7F2>GJ5=W>2;V^*?W^:EY:THJ.`HJ.`" + "G)RWE)2OF9:PHI^YHIZVFI:NE9&IFY>OH9VUH9VUI*\"XK*B`J:6]G)BPDHZFEY&J" + "DXVFBHB?A(:<@8:;?H\"6?7N2>G**<&=]5DA>13-*02Y#7$A@=6-ZA'2-F8NECH\"6" + ";&%S4TA:5$IC:%][;FB#;FB!=6^*;&:!=&Z)CHFFD(NH:%I88%)09UQ;@')RA75T" + ">6=F?FEGE'QYB&UECF]IEG-LE6YHD&EAD6QCD')GG8%UAF]FKJ:V" + "J:6\\IJ*YIJ&VJJ2_LZW(HYVZE8^LF)&QBH.E7UAZ<6J,HIS#J*+)KJK.JJ;(L;#0" + "JZS)HJ.`D9*MAH>DW24?7.6A7N>BX2DCHBCBX>?" + "C(J>E)6FH*&RF9FPDY.JBXND@X.'*->7..W%[;V5O;V-H=&1F" + ";518@&9HDG9TB&MHAFEFBV]MB&YPE'M_B71X;EM@8U-ZHZ&WFYNR" + "I*\"XHY^WFY>QDHZHC(>DCXJI:V:'>G66J:7'H9N^H9J\\OKG:N;K9K+#,GZ\"]G)FW" + "C(NIC(NI?GN9>7:46%5S9V2\"7*4;FB%=7\"%:65U;FIZ'2,AH*9B(2;>W>.D8VEDX^IA(\":?'>.:V9]>G6,CXJA@GR5>'2,@GZ6B(2<" + "EI*JFY>OEI*JAH*:@GZ6BX>?B(2<=7&)=&N'VR\">V=_9U%I54%94CY6<5]VBWR2;&-W24190#M02$!89UUV@WN4>'*+" + "=W&,?':1?WF4A'Z;=W*1?'2\"6U%=5$A3<6=S@'F)>W>&=&QX:%UE8DY6=V)HB&]S" + "@&9H?F1FAFQN@6MO>V9L@&QT=&-L:EIDO" + "EY.MCHFFAH&@9F%`@'N7.0;6B'BX.99%UP3T9:9V)WA(*9C8VDAX.:<6I]8%5D9%9D:%AD6=T?&MZ<6-S95IK6%%B<6Q_CHR@I:.WJJ:]J:6\\HY^WGIJRCHJD=7\"-" + "55!M>'.2LZ_0L:S-K:;(NK76L[31I*C$F9JWE)&ODI&OD(^MC8JHBH>EE)&OBH>E" + "E9\"OB82C6E5T1#]@44IL7%9S9%]T5$U>5D]@8UQO;&1Z95YQ:6)U:V1W@WR/@GJ0" + "=V^%<6F!:6%Y9EYV5T]G1#]6@7N4=&Z'<&J#=W.+@GZ6?'B0>G:.>'2,<6V%;6F!" + ";VN#;VN#7UET6%)K7EIQ=W.+BX:CC8>DDXNDI)NQL**ZL*\"YLJ\"WL)VRJ)*HI9*G" + "F8J>G(ZDCX:<96!U/#I.,C!&44QC8EAR<6F\";&9_:F1_@7N6AX&<=&Z+;VJ)D8RI" + ";&:!3DID8F%_?X*BB(VNA(>G<&^-96%Y2T9=24!46M[8E-G" + ":%MN:5UR8UIN5$U@:F5Z@G^3F):JKJK!KJK!I:&XFI:NA8&;9&!Z2$-@;VJ'JJ?%" + "L:S+LZS,NK74MK?4J:W)GZ\"]F)6SCHVKBXJHBXBFAX2BC8JH@'V;AX*AW.)?W:(?G6'?G6)A7R.>W*$<&AX>'!`GI:FG).EC828EXZBGY6N" + "GI2MEX^GDXNCGIBQEY&JDXVFFI2MG):OCHBAA'Z7?WF2>7.,>G2-@WV6BH2=BH2?" + "D8NDF92KHIRUJ)^]I9J[I9BUJYVWL*\"YJIBOJ)6JIY&FJI2IK9ROH9*FF(J@BH*8" + "9V1X0T19-#)(4TYE7E1N;&1];6=`:6-^@WV8BX6@>'*/>G64BXJK:V>)3TMM:&B-" + "@XBO@HJR?8*I:V^37V!_/3Q<03Y:>7..G)2LGY:LFHZE@76,6DUH54ME8UER:V-[" + "7EEP9&!W:V=^>':,CXNBF96LE9&IA(\"8;&B\"4DYH245?=&^,G9JXKZK)MJ_/M[+1" + "M;;3IJK&FYRYD8ZLAX:DA(.AA(&?@X\">>7:4>G>5@7R;85Q[,BU,1T)C>'&3AGV;" + "C(.9DXB:CX26C7^5CX25>F]`=6IYA7J)D(64G9*CHYBJM:J\\M*C!M*C!L*:_LZG\"" + "IIZWJJ2]JJ2]J**[FI2MD8NDBH2=B(*;BX6>EI\"IH9NTHYVVH9BTJ:2[KJF`JZ6`" + "JZ+\"JYV_JIN[K9VYJIBQJ96MJY6JI9\"BII&CG8R=AWB,=VM`=FZ&7EIQ24I?-S5+" + "3DE@6U%K<&B!>'*+;VF$@GR7BH2?@7N8B82CAH6M:6>-3DQR<'*:D)?\"BY2`@8BS" + ";W*:4U5Z/S]B2$=H'2,>W>/9F)\\34EC0#Q634AE>G62GINWM[+/O[G6N+/0M;;3I*C$F)FV" + "BXBFB(>EAH6C@X\">A(&?=G.1A(&?C(>F:62#.S95241EEI\"IFI2MD8NDG)2MFI*JE(^FDXJFD8BHC8*ED(&A" + "EXBDDH\"9CWN3AW&&=V)R@FU]?FM]959I54==-\"I#+RE\"0D!724=>6U5N9UUW<&B!" + ";&9_>'*-?WF4@WV8A'Z;C(>FD)*Z=72<551\\=7:AEIW*CI?#@XBS;&Z63U%X04-H" + "3T]T:&:*@7V?EY*SE(VM@7J:7UAZ3$5E9V*!=&^.?'>4E@GV<6E5T+RQ*+2A)0#E;1SY<5DIA9EEL959J>FA_A7F(9EII" + "9EIIA'B%H)2CL:6TJIVOH92GH)*LFXVGJY^XM*C!KJ2^H9FRG):OD8ND?GB1?GB1" + "?7>0>'*+>G2-@7N4?':/;FB!=&R%'*-?'.3>F^2@7.5C8\"=>VF\"?6M`" + "G2/>G2/" + ">W60@GR9@GV7BA551\\<7*=D9C%C).`A(FR;6^63TYV1$-K555Z:VF/A(*F" + "FY>YDHVN@GV>7UI[2T9G;FF*?'>6E(^ND8RI>7215E%N0#M803Q90SY;/CE6/#=4" + "2$-@:&-`B(.@H)VWP+S6Q\\'>M;#-M+70J:W)I*7\"F9:TDI&OE92RAX2B@'V;@G^=" + "@X\">>G646E5T,2Y,+BE*.C-5.\"U,0#1+3C]32CA-8$YE9EII95EH6DY=:5UJJY^N" + "L:6TH92FLZ:YFXNF" + "CI\"W;&Z54U5\\:VV5BHRTD)*ZA(:N;G\"85%=_2$MS6%J!;FV5U" + "K:C'O[S:O[S:KJO)M[;4L*_-HJ.`F)FVE)&OC(FGAX2B@GV<=7\"/A8\"?>W:55E-Q" + ".C=5/#=60SI:13I933Y<4D1>3S]87$UC95AJDK:&PK)^QLZ:Y" + "EXFC75!M4T5G:UU];F%\\7E1M3T5>34-?0SI644AD=&R%@7F2@'B1;65^13U603E2" + "55!G95US;F1]65!N5E%R44MN0CE98%%O2SE0>69Z@6Q\\?VEUAG!\\J92DL)VOFHB=" + ":UQR/2Y*1#96449E7E9O;65^K=7.77%^!3DYQ6EI]:VN.:FB,@H&BBX>I?WN=6E5V1#]@9%]`" + ">W:7DHROFY6XA'ZA6U5X.S17.C17/3=:.S971D%B655V>766I:*`N+/4O[K9O+G7" + "KZS*M;32K:S*H:*_F)FVEI6SE9*PDY\"NC8JH?7J8BH6D?WJ97%=V03Y<.C54/S96" + "449E75!M64ME5TEA85-I:5YO>&U\\7U5A=VUYK**NMZR[L::XL:6ZG9&J9EEV4T5G" + "13=93D%>3T5>4DAB5$IF3D9?4TMD?G:/CH:?B8&:=6V&345>.C)+5$QD64]H6$YG" + "3$-A4$ML3DAK0CE954AE23I0?&M^@FU]=V%MBG)_JI2BKYJLFH>;9E1M0C).3T!@" + "5TQK65%J8EIR<&B!$4DHVJBHZL:6V+7E]^=G>6DI&OBXBF" + "CXRJ@GV:9V:$44YL6%5S;&B):V>(@W^@BX>HA8&B9F*#34EJ:V>)@GZ@CHJLG)B\\" + "B86I655Y.#)7-S%4/3=:.S582D1G7EI[B86FM;'2PKW>OKG:NK;7M+#1M+/1K*O)" + "HJ.^F)FTDI&OD(^MCHVKC8JH@G^=CHNI@'N:6E5T/#E7-\"].-\"U-3$%@5$=D23Q7" + "5$AA6DYE;6)T>6Y_8UAGAGR(L:>SN[\"_K*&SI)BMD82?9%9V6$IL1SE;34-?6E!I" + "5TUG85=S75-M54ME@':0BX&;B7^9>W&+7U5O1#I44DIC6$YG5DED341B2T5H1T-E" + "1T!@5$IF33]5?W\"#@W%`;UEEB'!]IHZ=JY2GG(:;:U=S2SA76TIK:5M[:F!Z:6%Y" + ":F)Z95QX:6-^;FB#?7>4E(ZKHIVZ@86CUBH6BD(JGBH2AG644$EI.S95/CE80#=73D-D23Y=/\"],44=@4$9?;F-U" + "<&5V859EDHB4L::UM:J[I)FKF8VDB'N87E!R44-G54IM4$9B75-M2#Y88UEU8%9O" + "5DQE?'*+?G2.@GB2>6^)9EQV3$)<4DAB7E%L5TIG3D5E14%C04!A2T9E341@3D)7" + "?&U`BGB'7F<7%M\\:&2&FY6XC8:HBH.EB7^B<6J-4TQO6E1W=W&4" + "=W.7AH*FBXFOB8>M<6V.44UN1T%D" + "44MN@GR?N++5P[W@NK/6M*[1LZ[/LZ_0KJK+L*_-KJW+HZ*`H*\"[G9VXE)6PD)&L" + "B8FDCHNG;FF&0#I7-S!0/SA80SE<4$5F2T!A.\"Y*4TEC44=@VKZ2UI)BMFX^F=VF)3T%C2#QA5TQO4TAG6$YH/35.65!L54MD64]H@':/?7.," + "@WF3>&Z(7%)L03=1341@64]K3T5A1SY>0#Q@0#YB2$-D.3-./C))95AKAW:'?6=U" + "AV]\\HHJ9L)>KGH6;=%UX1S)21#!21C=723]93$1<54UF7E5Q85MV8%IU9%YY'.0?WVA?GR@5E1X8U^#G):]D8NRB8&I@GJB8ER!2D1I65-Z=6^6;FF0>G6<@H\"F" + "AH2J=G*34T]P='\"2BX>ID(RNG)B\\HI[\"9F*&.#180#Q>-S-524-F54]RH)N\\O;C9" + "KZK+P[S>O+77M;#1M*_0JZ?(KZO,JJG)H:\"`FIJUGI^ZFYRWDY>QAXBCAH.?8UY[" + ".S)0,BE),B=*,29)0S593#Y@/\"Y.6$YJ7E1N@7.)&V,5DMN6$QS4$1I4$5D345>/C9/0SI62D%77%-IAGR5@7>0A'J3?W6/7E1N" + "/S5/1SY<5TYL4TAG1T!B0#Q@0#YB1D%B.S)..2U&6DQBAG.'C'6&D'B'IHZ?JY*F" + "EG^4=F)Z23930S)31CA834-=345>4DIC6U)P2D1=3DAC8%IU8%IU?GR@" + "7UM_='\"4G9B_D(JQB8*L@'FC8%N\"2$-J5U)YG::A8&EBX>K?7R<5U9V" + "=724@H&AB8BICHVNHZ+#;VZ/4$QN55%S/#A:4$ML=&^0L:S-N[;7KZC(QK_?N[34" + "L*O,M*_0JZ?)JJ;(G9R]F):ZD9&LF)FTE)BRCY.MAH>BB(6A:F2!1CU;1#E:1#9:" + "0S-83#QA74UR44-E:EQ\\;V6!C'R5?6Z$B7J.MZB[LJ.VI)6IKIZWHI*M/BH*;<6F\"3$-?03Q;54QJ" + "5DUM349H14%E0S]C1#]@1#I61C=574UH?FM`CG>*F(\"1K92HJ)&FG86<@6^$4D)=" + "3T!>7%%P;F6!:6%Z6U)N5TYN4DQE65-L766?7F::F:(BH:JGIJ^" + "BH6LAX*K?WJC;VV144]S6EA\\=725=G*4A8&BCHJKCXNLBHFI8F&!?WZ>AH6ECHVM" + "D9\"PL;#0AH6E9F*#8%Q]2$1E6E5VG9BYN+/2PKO;P[SRFINVDI:PC9&KBHZHDI*M>7.05TYL7E!T:EI_;5V\":5=]=66*" + ":%A[`J)BSAWR=?W.8@G:==FJ/:V*\"" + ">7\",=VZ*9%MW1C]25DYDAW^5B8&9?'2,E(RE@GJ35$MG0SY=2D-C2T)B1T!C2$-J" + "14%E/C=9/C101#534T-?9%!H=E]TBW*&IHVAGH:=H(JBAG>*6$IB54AE95IY>W*." + "=FV):%]]8UE\\;FB!8EQU8EQUBX6@D8VG@GVFBX:M9V6)>WF=EI6U@H&A?7R:@8&<" + "='2/555P5E9Q:FJ%;&N)=722AH6CB8BF?'V88V1_>'F6BXRID9*QE96VIJ;)AH:I" + "75M_4$YR4E!TABXJH=7*03DEJ34)E855\\;F&+:EZ%:EQ^95AU<&-`=6>'" + "AWF1@'\")G(VCN:>^P*[%KY^XM:6`J)JTAGN<<6:%=FV)9EUY65!L" + "0#A.7E9L@GJ0G**;V=`4DEE2$)?3$-C5$IM6U1W:F:(9F*$5E%P6E%O" + "?&Z(B7F2=&%V<5IMAV]`H8BGF9<7*/4E-P;F^,@8*A@8&BB8FJFYN^>GJ=3$IN/#I>5U9W" + "BHFJL*S.K:G+LJ[0N[?9J:3%HYZ_GYJ[GIJ[G9FZFI>UFI>UG)FWEI>TEYNUBX^I" + "A(BBA8:AD)\"KA8*@96\"!3$)E34-I4$5N3D)I5$EJ5TUI:EUZ<&*\"@G2,?FZ'HY2J" + "NZF`Q++)NZO$NJK%H9.MB7Z?C(\"EB'RC;F*':E]^/?W>0;61`;VF&?'.3A'J=A7ZABH:HB86FAX*ACX:DK)ZXH)\"IB'6*" + ">F-VD'B)G866H(F7B8" + "BHFI@8\"@=W:73DUN;FV.@8\"AAH2HDY&UG)J^>7>;2DEJ.CE:9F*$GYN]K:G*I*#!" + "KZK+M*_0J:3#HYZ]GIFXG)>VFI6TEI.OEY2PFYBTFINVFYVUE9>OC8^GC8^GE)2O" + "D(VKG\",B'J2@G*+KZ\"VNZF`NZF`N*C!" + "OZ_*K9ZZD8:GC8*ECH*I@'29CX2CE(REFI*KFI&M?G:,AGZ4G)2JCH:@?G61A7^ID8VNE(^NDHFGF8NE?FZ':59K:%%DC'2%KI:G" + "J9*EI(ZCD7^69E=M74]I9EET9UUY9EUY:%][9V%\\5$YG9F!Y>'*+<&J#'F8:VR+<&^/=725XCXZO?WVC" + "44]U9F2*=7.9AX6KDY&UBXFM:6>+3$AJ1T-E<6V.GIJ[I)^`HYZ]JJ7$I)^^JJ3!" + "HIRYG):SG)>TG9FSFI:PDX^ICHJDD)\"GDY.JDI*IB8F@@H*;A86@B(6C;VN,.SI;" + ".#183TIS6%)W3TAH3$-?:5]YA'J6DX6=@W.,M*2]O*K!MZ6^L:&ZO:W(LJ._C(&@" + "AWR?D(2IBW^DHI>VEHZGF)\"IEHVIBX.9C86;GY>MC86;@'B.?'2,=6V&;&-_9F!]" + "9EU]7%)U8EM^9F*$<6V.=W*/&%T>V-TJI*CI(V@I(^AD7^4" + ";E]U7U%I851O:5][:%][;&-_;6>\"95]X8EQU:6-\\(55%R8%Q]" + "@H&AEYBWGI^^A8:E:FJ+75U^:6F*>'::=W69@7^CCHJNA8&E=&^83$=P3DER4$MR" + ";&>.<6V17EI^2D9J-3%31$!ARHYVXG9>RFY6NGIBQ" + "H)JSFY>OCXNBAH*9CHRBDI\"FCXVCA(*8=W6,@G^9CXZL@H&A3DYO-C9;1$)J44MP" + "44IJ44EB;6-]C(*>C7^9@'\")MJ:_O:O$P*['NJK%MZ?#F8JF8E=V7U1W:EZ#:E^\"" + "B'V<>G*+A7V6BX*>@GJ0>W.)A'R2<&A^85EO7E9N7%1M6$]K6%)O6E%Q4TEL4TQO" + "0CY?0C]=1T-=4$AA7U%I>VR\"FH>;E'V.?F9WHXNG27;VF,5E)T44UO>7B9CHZOE96V" + "='>75E9Y2DIM7EZ!>7>=>7>=>W:=@'NB=W*;9%^)1D%K/#=@-3!944QS4$QP14%C" + "/SM=.C56/#=83TII9F%`7EAU65-N8EQW'.(@7Z0B8:8AX26?GN/:65\\?7J4CXZLAX:F8&.%04%F2$9N4DYR65)R7%1M=FR&" + "G9\"K=FB\"@G*-O:W&NZG\"P:_(O:W(MJ;\"A'617E-R75)U7U-X6$UP;V6!7%1L:V-[" + "=FZ'9U]U8UMQ=&R\":V-Y:&!V:6%Y8UMT6E%M8%IW9EU]9UU`95Y`44UN5%%O5%!J" + ":V-\\(CW>&IHZ?M9ZOHXZ@BWJ-=F=[74]E5DIC:V%[7E5Q7U9R" + "85MV;&9_;6=`;FB!?GB1?7F3"; diff --git a/include/lib/ll.h b/include/lib/ll.h new file mode 100644 index 0000000..ab4148d --- /dev/null +++ b/include/lib/ll.h @@ -0,0 +1,24 @@ +#ifndef LIB_LL_H +#define LIB_LL_H + +struct LL { + struct LL* prev; + struct LL* next; + void* data; +}; + +struct LL* new_ll(void* val); +void push_ll(struct LL* l, void* val); +void remove_ll(struct LL* l, unsigned long idx); + +#define show_ll(L, TYPE) { \ + struct LL* t = L; \ + do { \ + uart_hex(*(TYPE*)t->data); \ + t = t->next; \ + if (t != l) \ + uart_char(' '); \ + } while (t != l); \ +} + +#endif diff --git a/include/lib/mem.h b/include/lib/mem.h new file mode 100644 index 0000000..5c5cc94 --- /dev/null +++ b/include/lib/mem.h @@ -0,0 +1,25 @@ +#ifndef LIB_MEM_H +#define LIB_MEM_H + +struct MemTab { + unsigned char size; + unsigned char in_use; + void* data; +} __attribute__((packed)); + +void memcpy(unsigned char* src, unsigned char* dest, unsigned int n); +unsigned char memcmp(unsigned char* a, unsigned char* b, unsigned int n); + +void memshow32(unsigned long* addr, unsigned int n); +void memcpy32(unsigned long* src, unsigned long* dest, unsigned int n); +unsigned char memcmp32(unsigned long* a, unsigned long* b, unsigned int n); + +void* malloc(unsigned char size); +void* malloca(unsigned char size, unsigned char amnt); +void free(void* memloc); +void* heap_base(void); +void* heap_top(void); +void heap_info(void); +void heap_info_u(void); + +#endif diff --git a/include/lib/q.h b/include/lib/q.h new file mode 100644 index 0000000..cf75c6d --- /dev/null +++ b/include/lib/q.h @@ -0,0 +1,30 @@ +#ifndef LIB_Q_H +#define LIB_Q_H + +struct Q_base { + struct Q* next; + struct Q* last; +}; + +struct Q { + struct Q* next; + void* data; +}; + +struct Q_base* new_q(); +void push_q(struct Q_base* qb, void* val); +void pop_q(struct Q_base* qb); + +#define show_q(QQ, TYPE) { \ + if (QQ->next != 0) { \ + struct Q* t = QQ->next; \ + while (t->next != 0) { \ + uart_hex(*(TYPE*)t->data); \ + t = t->next; \ + uart_char(' '); \ + } \ + uart_hex(*(TYPE*)t->data); \ + } \ +} + +#endif diff --git a/include/lib/strings.h b/include/lib/strings.h new file mode 100644 index 0000000..1bbcac8 --- /dev/null +++ b/include/lib/strings.h @@ -0,0 +1,10 @@ +#ifndef LIB_STRINGS_H +#define LIB_STRINGS_H + +#define string_t char* + +unsigned long strlen(string_t s); +unsigned char strcmp(string_t a, string_t b); +unsigned char strcmpn(string_t a, string_t b, unsigned int n); + +#endif diff --git a/include/symbols.h b/include/symbols.h new file mode 100644 index 0000000..dda0f27 --- /dev/null +++ b/include/symbols.h @@ -0,0 +1,101 @@ +#ifndef SYMBOLS_H +#define SYMBOLS_H + +enum +{ + // The offset for the MMIO area +#ifdef BSP23 + MMIO_BASE = 0x3F000000, // For Raspberry Pi 2 and 3 +#else + MMIO_BASE = 0xFE000000, +#endif + + // The offsets for reach register. + GPIO_BASE = (MMIO_BASE + 0x200000), + + // Controls actuation of pull up/down to ALL GPIO pins. + GPPUD = (GPIO_BASE + 0x94), + + // Controls actuation of pull up/down for specific GPIO pin. + GPPUDCLK0 = (GPIO_BASE + 0x98), + + // The base address for UART. + UART0_BASE = (GPIO_BASE + 0x1000), // for raspi4 0xFE201000, raspi2 & 3 0x3F201000, and 0x20201000 for raspi1 + + // The offsets for reach register for the UART. + UART0_DR = (UART0_BASE + 0x00), + UART0_RSRECR = (UART0_BASE + 0x04), + UART0_FR = (UART0_BASE + 0x18), + UART0_ILPR = (UART0_BASE + 0x20), + UART0_IBRD = (UART0_BASE + 0x24), + UART0_FBRD = (UART0_BASE + 0x28), + UART0_LCRH = (UART0_BASE + 0x2C), + UART0_CR = (UART0_BASE + 0x30), + UART0_IFLS = (UART0_BASE + 0x34), + UART0_IMSC = (UART0_BASE + 0x38), + UART0_RIS = (UART0_BASE + 0x3C), + UART0_MIS = (UART0_BASE + 0x40), + UART0_ICR = (UART0_BASE + 0x44), + UART0_DMACR = (UART0_BASE + 0x48), + UART0_ITCR = (UART0_BASE + 0x80), + UART0_ITIP = (UART0_BASE + 0x84), + UART0_ITOP = (UART0_BASE + 0x88), + UART0_TDR = (UART0_BASE + 0x8C), + + // IRQ REGISTERS + IRQ_BASE = (MMIO_BASE + 0xB000), + IRQ_BASIC_PENDING = (IRQ_BASE + 0x200), + IRQ_PENDING1 = (IRQ_BASE + 0x204), + IRQ_PENDING2 = (IRQ_BASE + 0x208), + FIQ_CONTROL = (IRQ_BASE + 0x20C), + IRQ_ENABLE1 = (IRQ_BASE + 0x210), + IRQ_ENABLE2 = (IRQ_BASE + 0x214), + IRQ_BASIC_ENABLE = (IRQ_BASE + 0x218), + IRQ_DISABLE1 = (IRQ_BASE + 0x21C), + IRQ_DISABLE2 = (IRQ_BASE + 0x220), + IRQ_BASIC_DISABLE = (IRQ_BASE + 0x224), + + // Peripherals Interrupts + UART_IRQ = 57, + GPIO_IRQ_0 = 49, + GPIO_IRQ_1 = 50, + GPIO_IRQ_2 = 51, + GPIO_IRQ_3 = 52, + + FIQ_ENABLE_FLAG = 1<<7, + + // ARM Peripheral Interrupts + TIMER_ARM_IRQ = 0, + MAILBOX_ARM_IRQ = 1, + DOORBELL0_ARM_IRQ = 2, + DOORBELL1_ARM_IRQ = 3, + GPU0HALT_ARM_IRQ = 4, + GPU1HALT_ARM_IRQ = 5, + + // The offsets for Mailbox registers + MBOX_BASE = 0xB880, + MBOX_READ = (MBOX_BASE + 0x00), + MBOX_STATUS = (MBOX_BASE + 0x18), + MBOX_WRITE = (MBOX_BASE + 0x20), + + GPU_INTERRUPTS_ROUTING = 0x4000000C, + + CORE0_TIMER_IRQCNTL = 0x40000040, + CORE0_IRQ_SOURCE = 0x40000060, + + /* Power Management, Reset controller and Watchdog registers */ + //BCM2835_PERI_BASE = 0x3F000000, + BCM2835_PERI_BASE = 0x20000000, + PM_BASE = (BCM2835_PERI_BASE + 0x100000), + PM_RSTC = (PM_BASE+0x1c), + PM_WDOG = (PM_BASE+0x24), + PM_WDOG_RESET = 0x00000000, + PM_PASSWORD = 0x5a000000, + PM_WDOG_TIME_SET = 0x000fffff, + PM_RSTC_WRCFG_CLR = 0xffffffcf, + PM_RSTC_WRCFG_SET = 0x00000030, + PM_RSTC_WRCFG_FULL_RESET = 0x00000020, + PM_RSTC_RESET = 0x00000102, +}; + +#endif diff --git a/include/sys/core.h b/include/sys/core.h new file mode 100644 index 0000000..2d611b3 --- /dev/null +++ b/include/sys/core.h @@ -0,0 +1,55 @@ +#ifndef SYS_CORE_H +#define SYS_CORE_H + +#ifndef SYS_CORE_C +extern char* os_info_v; +#endif + +static inline unsigned long load32(unsigned long addr) +{ + return *(volatile unsigned long*)addr; +} + +static inline void store32(unsigned long value, unsigned long addr) +{ + *(volatile unsigned long*)addr = value; +} + +static inline void delay(unsigned long cycles) +{ + asm volatile("__delay_%=: subs %[cycles], %[cycles], #1;bne __delay_%=\n" + : "=r"(cycles): [cycles]"0"(cycles) : "cc"); +} + +static inline void preserveregs(void) +{ + asm volatile("push {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11}"); +} + +static inline void restoreregs(void) +{ + asm volatile("pop {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11}"); +} + +static inline void* getsp(void) +{ + void* out; + asm volatile ("mov %0, sp" : "=r"(out)); + return out; +} + +static inline void setsp(void* in) +{ + asm volatile ("mov sp, %0" :: "r"(in)); +} + +static inline void* heap_end(void) +{ + unsigned long value; + asm volatile ("ldr %0, =__bss_end": "=r"(value)); + return (void*)value; +} + +void sysinit(void); + +#endif diff --git a/include/sys/kernel.h b/include/sys/kernel.h new file mode 100644 index 0000000..e724513 --- /dev/null +++ b/include/sys/kernel.h @@ -0,0 +1,8 @@ +#ifndef SYS_KERNEL_H +#define SYS_KERNEL_H + +extern unsigned long cntfrq; +extern unsigned long cmdidx; +extern char cmd[2048]; + +#endif diff --git a/include/sys/power.h b/include/sys/power.h new file mode 100644 index 0000000..711842b --- /dev/null +++ b/include/sys/power.h @@ -0,0 +1,6 @@ +#ifndef SYS_POWER_H +#define SYS_POWER_H + +void reboot(void); + +#endif diff --git a/include/sys/timer.h b/include/sys/timer.h new file mode 100644 index 0000000..29dc2dd --- /dev/null +++ b/include/sys/timer.h @@ -0,0 +1,10 @@ +#ifndef SYS_TIMER_H +#define SYS_TIMER_H + +#ifndef SYS_TIMER_C +extern struct Mutex exe_cnt_m; +#endif + +void c_timer(void); + +#endif diff --git a/include/util/mutex.h b/include/util/mutex.h new file mode 100644 index 0000000..524a461 --- /dev/null +++ b/include/util/mutex.h @@ -0,0 +1,17 @@ +#ifndef UTIL_MUTEX_H +#define UTIL_MUTEX_H + +#define NULL_PID 0 +#define SYS_PID 1 +#define SCHED_PID 2 + +struct Mutex { + void* addr; + unsigned long pid; +} __attribute__((packed, aligned(4)));; + +unsigned char lock_mutex(struct Mutex*, unsigned long); +unsigned char release_mutex(struct Mutex*, unsigned long); +struct Mutex* create_mutex(void* addr); + +#endif diff --git a/include/util/status.h b/include/util/status.h new file mode 100644 index 0000000..f6966dd --- /dev/null +++ b/include/util/status.h @@ -0,0 +1,6 @@ +#ifndef UTIL_STATUS_H +#define UTIL_STATUS_H + +void status(void); + +#endif diff --git a/include/util/time.h b/include/util/time.h new file mode 100644 index 0000000..f6dacb0 --- /dev/null +++ b/include/util/time.h @@ -0,0 +1,26 @@ +#ifndef UTIL_TIME_H +#define UTIL_TIME_H + +void routing_core0cntv_to_core0irq(void); +unsigned long read_core0timer_pending(void); +unsigned long long read_cntvct(void); +unsigned long long read_cntvoff(void); +unsigned long read_cntv_tval(void); +void write_cntv_tval(unsigned long val); +unsigned long read_cntfrq(void); + +static inline void enablecntv(void) +{ + unsigned long cntv_ctl; + cntv_ctl = 1; + asm volatile ("mcr p15, 0, %0, c14, c3, 1" :: "r"(cntv_ctl) ); // write CNTV_CTL +} + +static inline void disablecntv(void) +{ + unsigned long cntv_ctl; + cntv_ctl = 0; + asm volatile ("mcr p15, 0, %0, c14, c3, 1" :: "r"(cntv_ctl) ); // write CNTV_CTL +} + +#endif -- cgit v1.2.1