diff options
Diffstat (limited to 'Source/Kernel')
-rw-r--r-- | Source/Kernel/Core/Sys.ns.cpp | 2 | ||||
-rw-r--r-- | Source/Kernel/Core/cppsupport.wtf.cpp | 11 | ||||
-rw-r--r-- | Source/Kernel/Core/kmain.wtf.cpp | 10 | ||||
-rw-r--r-- | Source/Kernel/Devices/Display/Display.proto.h | 8 | ||||
-rw-r--r-- | Source/Kernel/Devices/Display/GraphicDisplay.proto.cpp | 64 | ||||
-rw-r--r-- | Source/Kernel/Devices/Display/GraphicDisplay.proto.h | 24 | ||||
-rw-r--r-- | Source/Kernel/Devices/Display/VESADisplay.class.cpp | 127 | ||||
-rw-r--r-- | Source/Kernel/Devices/Display/VESADisplay.class.h | 65 | ||||
-rw-r--r-- | Source/Kernel/Devices/Display/VGATextOutput.class.cpp | 16 | ||||
-rw-r--r-- | Source/Kernel/Devices/Display/VGATextOutput.class.h | 6 | ||||
-rw-r--r-- | Source/Kernel/Devices/Display/vga-vesa.wtf.asm | 11 | ||||
-rw-r--r-- | Source/Kernel/Makefile | 2 | ||||
-rw-r--r-- | Source/Kernel/Ressources/ConsoleFont.cd | 258 | ||||
-rw-r--r-- | Source/Kernel/TaskManager/V86/V86.ns.cpp | 13 | ||||
-rw-r--r-- | Source/Kernel/TaskManager/V86/V86.ns.h | 6 | ||||
-rw-r--r-- | Source/Kernel/TaskManager/V86/V86Thread.class.cpp | 25 |
16 files changed, 614 insertions, 34 deletions
diff --git a/Source/Kernel/Core/Sys.ns.cpp b/Source/Kernel/Core/Sys.ns.cpp index 30d9755..5d4a1ab 100644 --- a/Source/Kernel/Core/Sys.ns.cpp +++ b/Source/Kernel/Core/Sys.ns.cpp @@ -96,7 +96,7 @@ void panic(char *message, char *file, u32int line) { void panic(char *message, registers_t *regs, char *file, u32int line) { asm volatile("cli"); - SimpleVT vt(21, 70, 7, 1); + SimpleVT vt(12, 70, 7, 1); vt.map(); vt.write("\n"); diff --git a/Source/Kernel/Core/cppsupport.wtf.cpp b/Source/Kernel/Core/cppsupport.wtf.cpp index 2cefc39..06ef1b9 100644 --- a/Source/Kernel/Core/cppsupport.wtf.cpp +++ b/Source/Kernel/Core/cppsupport.wtf.cpp @@ -1,11 +1,22 @@ //This file just contains a few methods required for some C++ things to work #include <types.h> +namespace CMem { + u8int* memcpy(u8int*, const u8int*, int); +}; + +using namespace CMem; + extern "C" void __cxa_pure_virtual() {} //Required when using abstract classes void *__dso_handle; //Required when using global objects extern "C" int __cxa_atexit(void (*f)(void*), void *p, void *d) { return 0; } +extern "C" void * memmove(void* dst, const void* src, size_t len) { + memcpy((u8int*)dst, (const u8int*)src, len); + return dst; +} + //Functions for quad divisions/modulo. Taken and arranged from klibc include/asm/div64.h //These only work with 32-bit divisors and only return 32-bit remainder. //TODO : think of some correct quad div/mod algorithms diff --git a/Source/Kernel/Core/kmain.wtf.cpp b/Source/Kernel/Core/kmain.wtf.cpp index 9ecc9d7..2324857 100644 --- a/Source/Kernel/Core/kmain.wtf.cpp +++ b/Source/Kernel/Core/kmain.wtf.cpp @@ -4,6 +4,7 @@ #include <Core/multiboot.wtf.h> #include <Devices/Display/VGATextOutput.class.h> +#include <Devices/Display/VESADisplay.class.h> #include <Devices/Keyboard/PS2Keyboard.class.h> #include <Devices/Floppy/FloppyDrive.class.h> #include <Devices/Timer.class.h> @@ -91,8 +92,9 @@ void selectVideoMode(SimpleVT& v) { } else { v << "No graphics"; } - v.setCursorCol(40); - v << m.device->getName() << "\n"; + //v.setCursorCol(40); + //v << m.device->getName() << "\n"; + v << "\n"; } while (1) { @@ -161,6 +163,8 @@ void kmain(multiboot_info_t* mbd, u32int magic) { Dev::registerDevice(vgaout); Log::log(KL_STATUS, "kmain : Registered textual VGA output"); + Dev::registerDevice(new VESADisplay()); + Log::log(KL_STATUS, "kmain : Created VESA display"); Dev::registerDevice(new PS2Keyboard()); //Initialize keyboard driver if (!Kbd::loadKeymap("fr")) Log::log(KL_ERROR, "kmain : could not load french keymap."); @@ -183,6 +187,8 @@ void kmain(multiboot_info_t* mbd, u32int magic) { Usr::load(); Log::log(KL_STATUS, "kmain : User list loaded"); + //PANIC("Good, this works !"); + Process* p = Process::run("/System/Applications/PaperWork.app", 0); if (p == 0) { PANIC("Could not launch PaperWork !"); diff --git a/Source/Kernel/Devices/Display/Display.proto.h b/Source/Kernel/Devices/Display/Display.proto.h index e1775bd..8401e0b 100644 --- a/Source/Kernel/Devices/Display/Display.proto.h +++ b/Source/Kernel/Devices/Display/Display.proto.h @@ -19,7 +19,13 @@ class Display : public Device { virtual void putChar(u16int line, u16int col, WChar c, u8int color) = 0; //Color : <bg 4bits><fg 4bits> virtual void moveCursor(u16int line, u16int col) = 0; - //Graphic functions + //Graphic functions, can stay unimplemented for textual displays + virtual void putPix(u16int x, u16int y, u32int color) {} + virtual u32int getPix(u16int x, u16int y) { return 0; } + //Advanced graphic functions. These have a simple implementation in GraphicDisplay, + //and should have an optimized version in each individual driver. This is also the + //case of the graphical putChar and moveCursor. + //drawLine, drawCircle, ... }; #endif diff --git a/Source/Kernel/Devices/Display/GraphicDisplay.proto.cpp b/Source/Kernel/Devices/Display/GraphicDisplay.proto.cpp new file mode 100644 index 0000000..636a64c --- /dev/null +++ b/Source/Kernel/Devices/Display/GraphicDisplay.proto.cpp @@ -0,0 +1,64 @@ +#include "GraphicDisplay.proto.h" + +#include <Ressources/ConsoleFont.cd> + +u32int consoleColor[16] = { + 0x00000000, // 0 == black + 0x00000077, // 1 == dark blue + 0x00007700, // 2 == dark green + 0x00007777, // 3 == dark cyan + 0x00770000, // 4 == dark red + 0x00770077, // 5 == dark magenta + 0x00777700, // 6 == dark orange + 0x00777777, // 7 == light grey + 0x00444444, // 8 == dark grey + 0x000000FF, // 9 == bright blue + 0x0000FF00, // A == bright green + 0x0000FFFF, // B == bright cyan + 0x00FF0000, // C == bright red + 0x00FF00FF, // D == bright yellow + 0x00FFFF00, // E == bright orange + 0x00FFFFFF, // F == white +}; + +void GraphicDisplay::putChar(u16int line, u16int col, WChar c, u8int color) { + u8int ch = c.toAscii(); + if (ch == 0) return; + + u16int sx = col * C_FONT_WIDTH, sy = line * C_FONT_HEIGHT; + u32int fgcolor = consoleColor[color & 0xF], bgcolor = consoleColor[(color >> 4) & 0xF]; + + for (int y = 0; y < C_FONT_HEIGHT; y++) { + u8int pixs = consoleFont[ch][y]; + for (int x = C_FONT_WIDTH - 1; x >= 0; x--) { + putPix(sx + x, sy + y, ((pixs & 1) != 0 ? fgcolor : bgcolor)); + pixs = pixs >> 1; + } + } +} + +void GraphicDisplay::moveCursor(u16int line, u16int col) { + //If the current cursor position is correct, write there what is supposed to be there + if (m_csrbuff.x >= 0 and m_csrbuff.y >= 0) { + for (int x = 0; x < C_FONT_WIDTH; x++) { + for (int y = 0; y < C_FONT_HEIGHT; y++) { + putPix(m_csrbuff.x + x, m_csrbuff.y + y, m_csrbuff.buff[x][y]); + } + } + } + + //Save the current stuff to the buffer + m_csrbuff.x = col * C_FONT_WIDTH; + m_csrbuff.y = line * C_FONT_HEIGHT; + for (int x = 0; x < C_FONT_WIDTH; x++) { + for (int y = 0; y < C_FONT_HEIGHT; y++) { + m_csrbuff.buff[x][y] = getPix(m_csrbuff.x + x, m_csrbuff.y + y); + } + } + + //draw some cursor + for (int x = 0; x < C_FONT_WIDTH; x++) { + putPix(m_csrbuff.x + x, m_csrbuff.y + 14, 0x00FFFFFF); + putPix(m_csrbuff.x + x, m_csrbuff.y + 15, 0x00777777); + } +} diff --git a/Source/Kernel/Devices/Display/GraphicDisplay.proto.h b/Source/Kernel/Devices/Display/GraphicDisplay.proto.h new file mode 100644 index 0000000..2f4be98 --- /dev/null +++ b/Source/Kernel/Devices/Display/GraphicDisplay.proto.h @@ -0,0 +1,24 @@ +#ifndef DEF_GRAPHICDISPLAY_PROTO_H +#define DEF_GRAPHICDISPLAY_PROTO_H + +#include <Devices/Display/Display.proto.h> + +extern char consoleFont[256][16]; +extern u32int consoleColor[16]; + +#define C_FONT_WIDTH 9 //This is width of one character ON SCREEN, real width is 8px (1px padding) +#define C_FONT_HEIGHT 16 + +class GraphicDisplay : public Display { + struct { + int x, y; + u32int buff[C_FONT_WIDTH][C_FONT_HEIGHT]; + } m_csrbuff; + + public: + GraphicDisplay() { m_csrbuff.x = -1; m_csrbuff.y = -1; } + virtual void putChar(u16int line, u16int col, WChar c, u8int color); + virtual void moveCursor(u16int line, u16int col); +}; + +#endif diff --git a/Source/Kernel/Devices/Display/VESADisplay.class.cpp b/Source/Kernel/Devices/Display/VESADisplay.class.cpp new file mode 100644 index 0000000..a1dc7c1 --- /dev/null +++ b/Source/Kernel/Devices/Display/VESADisplay.class.cpp @@ -0,0 +1,127 @@ +#include "VESADisplay.class.h" +#include <DeviceManager/Disp.ns.h> + +extern v86_function_t vesa_int; //in vga-vesa.wtf.asm + +using namespace Disp; + +String VESADisplay::getClass() { + return "display.vesa"; +} + +String VESADisplay::getName() { + return "Standard VESA display"; +} + +vbe_controller_info_t VESADisplay::getCtrlrInfo() { + vbe_controller_info_t *info = (vbe_controller_info_t*)V86::alloc(sizeof(vbe_controller_info_t)); + info->signature[0] = 'V'; info->signature[1] = 'B'; info->signature[2] = 'E'; info->signature[3] = '2'; + info->videomodes = 0; + registers_t regs; + regs.eax = 0x00004F00; + regs.esi = LIN_SEG(info); + regs.edi = LIN_OFF(info); + V86::run(vesa_int, regs, 0); + if (regs.eax != 0x004F) PANIC("Something went wrong in detecting VBE modes."); + if (info->signature[3] != 'A') PANIC("No vesa sinature"); + return *info; +} + +vbe_mode_info_t VESADisplay::getModeInfo(u16int id) { + vbe_mode_info_t *mode = (vbe_mode_info_t*)V86::alloc(sizeof(vbe_mode_info_t)); + CMem::memset((u8int*)mode, 0, sizeof(vbe_mode_info_t)); + registers_t regs; + regs.eax = 0x00004F01; + regs.ecx = id; + regs.esi = LIN_SEG(mode); + regs.edi = LIN_OFF(mode); + V86::run(vesa_int, regs, 0); + return *mode; +} + +void VESADisplay::getModes(Vector<mode_t> &to) { + vbe_controller_info_t info = getCtrlrInfo(); + + u16int *modes = (u16int*)(((info.videomodes & 0xFFFF0000) >> 12) | ((info.videomodes) & 0x0000FFFF)); + for (int i = 0; i < 64; i++) { + if (modes[i] == 0xFFFF) break; + vbe_mode_info_t mode = getModeInfo(modes[i]); + + if ((mode.attributes & 0x19) != 0x19) continue; + if (mode.planes != 1) continue; + mode_t m; m.device = this; + m.textCols = mode.Xres / C_FONT_WIDTH; m.textRows = mode.Yres / C_FONT_HEIGHT; + m.identifier = modes[i]; + m.graphWidth = mode.Xres; m.graphHeight = mode.Yres; m.graphDepth = mode.bpp; + to.push(m); + } +} + +bool VESADisplay::setMode(mode_t &mode) { + if (mode.device != this) return false; + m_currMode = getModeInfo(mode.identifier); + registers_t regs; + regs.eax = 0x00004F02; + regs.ebx = mode.identifier; + V86::run(vesa_int, regs, 0); + return true; +} + +u8int* VESADisplay::memPos(u16int x, u16int y) { + u32int addr = y * m_currMode.pitch + x * (m_currMode.bpp / 8); + + u8int *base = (u8int*)(((m_currMode.physbase & 0xFFFF0000) >> 12) | (m_currMode.physbase & 0x0000FFFF)); + + return base + addr; +} + +void VESADisplay::clear() { + for (u16int y = 0; y < m_currMode.Yres; y++) { + for (u16int x = 0; x < m_currMode.Xres; x++) { + putPix(x, y, 0x77777777); + } + } +} + +void VESADisplay::putPix(u16int x, u16int y, u32int c) { + u32int addr = y * m_currMode.pitch + x * (m_currMode.bpp / 8); + int banksize = m_currMode.granularity*1024; + int banknumber = addr / banksize; + int bankoffset = addr % banksize; + + if (banknumber != b) { + registers_t r; + r.eax = 0x4F05; + r.ebx = 0; + r.edx = banknumber; + V86::run(vesa_int, r, 0); + b = banknumber; + } + + u8int* a = (u8int*)(0xA0000 + bankoffset); + a[2] = (c >> 16) & 0xFF; + a[1] = (c >> 8) & 0xFF; + a[0] = c & 0xFF; +} + +u32int VESADisplay::getPix(u16int x, u16int y) { + u32int addr = y * m_currMode.pitch + x * (m_currMode.bpp / 8); + int banksize = m_currMode.granularity*1024; + int banknumber = addr / banksize; + int bankoffset = addr % banksize; + + if (banknumber != b) { + registers_t r; + r.eax = 0x4F05; + r.ebx = 0; + r.edx = banknumber; + V86::run(vesa_int, r, 0); + b = banknumber; + } + + u32int ret; + + u8int* a = (u8int*)(0xA0000 + bankoffset); + ret = (a[2] << 16) | (a[1] << 8) | a[0]; + return ret; +} diff --git a/Source/Kernel/Devices/Display/VESADisplay.class.h b/Source/Kernel/Devices/Display/VESADisplay.class.h new file mode 100644 index 0000000..9daf1b9 --- /dev/null +++ b/Source/Kernel/Devices/Display/VESADisplay.class.h @@ -0,0 +1,65 @@ +#ifndef DEF_VESADISPLAY_CLASS_H +#define DEF_VESADISPLAY_CLASS_H + +#include <Devices/Display/GraphicDisplay.proto.h> +#include <TaskManager/V86/V86.ns.h> + +struct vbe_controller_info_t { + char signature[4]; // == "VESA" + s16int version; // == 0x0300 for VBE 3.0 + //s16int oemString[2]; // isa vbeFarPtr + FARPTR oemString; + u8int capabilities[4]; + FARPTR videomodes; + s16int totalMemory; // as # of 64KB blocks +} __attribute__((packed)); + +struct vbe_mode_info_t { + u16int attributes; + u8int winA, winB; + u16int granularity; + u16int winsize; + u16int segmentA, segmentB; + FARPTR realFctPtr; + u16int pitch; // bytes per scanline + + u16int Xres, Yres; + u8int Wchar, Ychar, planes, bpp, banks; + u8int memory_model, bank_size, image_pages; + u8int reserved0; + + u8int red_mask, red_position; + u8int green_mask, green_position; + u8int blue_mask, blue_position; + u8int rsv_mask, rsv_position; + u8int directcolor_attributes; + + u32int physbase; // your LFB address ;) + u32int reserved1; + u16int reserved2; +} __attribute__ ((packed)); + +class VESADisplay : public GraphicDisplay { + private: + vbe_controller_info_t getCtrlrInfo(); + vbe_mode_info_t getModeInfo(u16int mode); + + u8int* memPos(u16int x, u16int y); + + vbe_mode_info_t m_currMode; + + int b; + + public: + String getClass(); + String getName(); + + void getModes(Vector<Disp::mode_t> &to); + bool setMode(Disp::mode_t& mode); + + void clear(); + void putPix(u16int x, u16int y, u32int color); + u32int getPix(u16int x, u16int y); +}; + +#endif diff --git a/Source/Kernel/Devices/Display/VGATextOutput.class.cpp b/Source/Kernel/Devices/Display/VGATextOutput.class.cpp index 3265a7d..d307f60 100644 --- a/Source/Kernel/Devices/Display/VGATextOutput.class.cpp +++ b/Source/Kernel/Devices/Display/VGATextOutput.class.cpp @@ -21,19 +21,23 @@ String VGATextOutput::getName() { void VGATextOutput::getModes(Vector<mode_t> &to) { mode_t m; - m.textCols = 80; + m.textCols = 40; m.textRows = 25; - m.identifier = 3; + m.identifier = 1; m.graphWidth = 0; m.graphHeight = 0; m.device = this; to.push(m); + m.textCols = 80; + m.identifier = 3; //3 = text 80x25 16color, just what we want + to.push(m); } bool VGATextOutput::setMode(mode_t& mode) { - if (mode.device == this && mode.identifier == 3) { + if (mode.device == this && (mode.identifier == 3 or mode.identifier == 1)) { registers_t r; - r.eax = 3; //3 = text 80x25 16color, just what we want + r.eax = mode.identifier; + m_cols = mode.textCols; V86::run(setvgamode, r, 0); clear(); return true; @@ -43,11 +47,11 @@ bool VGATextOutput::setMode(mode_t& mode) { void VGATextOutput::putChar(u16int line, u16int col, WChar c, u8int color) { u16int* where = (u16int*)RAM_ADDR; - where[(80 * line) + col] = (color << 8) | c.toAscii(); + where[(m_cols * line) + col] = (color << 8) | c.toAscii(); } void VGATextOutput::moveCursor(u16int line, u16int col) { - u16int csrLoc = (line * 80) + col; + u16int csrLoc = (line * m_cols) + col; outb(0x3D4, 14); outb(0x3D5, csrLoc >> 8); outb(0x3D4, 15); diff --git a/Source/Kernel/Devices/Display/VGATextOutput.class.h b/Source/Kernel/Devices/Display/VGATextOutput.class.h index 1ced227..2c72d40 100644 --- a/Source/Kernel/Devices/Display/VGATextOutput.class.h +++ b/Source/Kernel/Devices/Display/VGATextOutput.class.h @@ -4,15 +4,17 @@ #include <Devices/Display/Display.proto.h> class VGATextOutput : public Display { + int m_cols; + public: + VGATextOutput() : m_cols(80) {} + String getClass(); String getName(); void getModes(Vector<Disp::mode_t> &to); bool setMode(Disp::mode_t& mode); - u16int textCols(); - u16int textRows(); void putChar(u16int line, u16int col, WChar c, u8int color); void moveCursor(u16int line, u16int col); void clear(); diff --git a/Source/Kernel/Devices/Display/vga-vesa.wtf.asm b/Source/Kernel/Devices/Display/vga-vesa.wtf.asm index c7b6bb5..4a6a1d6 100644 --- a/Source/Kernel/Devices/Display/vga-vesa.wtf.asm +++ b/Source/Kernel/Devices/Display/vga-vesa.wtf.asm @@ -9,3 +9,14 @@ setvgamode_start: int 3 setvgamode_end: db 0 + +[GLOBAL vesa_int] +vesa_int: + dw vesa_int_end - vesa_int_start +vesa_int_start: + int 60 + mov es, si + int 10h + int 3 +vesa_int_end: + db 0 diff --git a/Source/Kernel/Makefile b/Source/Kernel/Makefile index 636968d..0126c43 100644 --- a/Source/Kernel/Makefile +++ b/Source/Kernel/Makefile @@ -70,6 +70,8 @@ Objects = Core/loader.wtf.o \ SyscallManager/Res.ns.o \ SyscallManager/IDT.wtf.o \ Devices/Display/VGATextOutput.class.o \ + Devices/Display/GraphicDisplay.proto.o \ + Devices/Display/VESADisplay.class.o \ Devices/Display/vga-vesa.wtf.o \ Devices/Keyboard/PS2Keyboard.class.o \ Devices/Floppy/FloppyController.class.o \ diff --git a/Source/Kernel/Ressources/ConsoleFont.cd b/Source/Kernel/Ressources/ConsoleFont.cd new file mode 100644 index 0000000..23fb1b9 --- /dev/null +++ b/Source/Kernel/Ressources/ConsoleFont.cd @@ -0,0 +1,258 @@ +char consoleFont[256][16] = { +/* 0x00 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0x01 */ {0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00}, +/* 0x02 */ {0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00}, +/* 0x03 */ {0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00}, +/* 0x04 */ {0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0x05 */ {0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00}, +/* 0x06 */ {0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00}, +/* 0x07 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0x08 */ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, +/* 0x09 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0x0a */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0x0b */ {0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00}, +/* 0x0c */ {0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00}, +/* 0x0d */ {0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00}, +/* 0x0e */ {0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00}, +/* 0x0f */ {0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00}, +/* 0x10 */ {0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00}, +/* 0x11 */ {0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00}, +/* 0x12 */ {0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0x13 */ {0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00}, +/* 0x14 */ {0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00}, +/* 0x15 */ {0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00}, +/* 0x16 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00}, +/* 0x17 */ {0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00}, +/* 0x18 */ {0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00}, +/* 0x19 */ {0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00}, +/* 0x1a */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0x1b */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0x1c */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0x1d */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0x1e */ {0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0x1f */ {0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0x20 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0x21 */ {0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00}, +/* 0x22 */ {0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0x23 */ {0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00}, +/* 0x24 */ {0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00}, +/* 0x25 */ {0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00}, +/* 0x26 */ {0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00}, +/* 0x27 */ {0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0x28 */ {0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00}, +/* 0x29 */ {0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00}, +/* 0x2a */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0x2b */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0x2c */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00}, +/* 0x2d */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0x2e */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00}, +/* 0x2f */ {0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00}, +/* 0x30 */ {0x00, 0x00, 0x3c, 0x66, 0xc3, 0xc3, 0xdb, 0xdb, 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00}, +/* 0x31 */ {0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00}, +/* 0x32 */ {0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00}, +/* 0x33 */ {0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00}, +/* 0x34 */ {0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00}, +/* 0x35 */ {0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00}, +/* 0x36 */ {0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00}, +/* 0x37 */ {0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00}, +/* 0x38 */ {0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00}, +/* 0x39 */ {0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00}, +/* 0x3a */ {0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0x3b */ {0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00}, +/* 0x3c */ {0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00}, +/* 0x3d */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0x3e */ {0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00}, +/* 0x3f */ {0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00}, +/* 0x40 */ {0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00}, +/* 0x41 */ {0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00}, +/* 0x42 */ {0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00}, +/* 0x43 */ {0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00}, +/* 0x44 */ {0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00}, +/* 0x45 */ {0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00}, +/* 0x46 */ {0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00}, +/* 0x47 */ {0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00}, +/* 0x48 */ {0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00}, +/* 0x49 */ {0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00}, +/* 0x4a */ {0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00}, +/* 0x4b */ {0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00}, +/* 0x4c */ {0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00}, +/* 0x4d */ {0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00}, +/* 0x4e */ {0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00}, +/* 0x4f */ {0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00}, +/* 0x50 */ {0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00}, +/* 0x51 */ {0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00}, +/* 0x52 */ {0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00}, +/* 0x53 */ {0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00}, +/* 0x54 */ {0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00}, +/* 0x55 */ {0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00}, +/* 0x56 */ {0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00}, +/* 0x57 */ {0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00}, +/* 0x58 */ {0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00}, +/* 0x59 */ {0x00, 0x00, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00}, +/* 0x5a */ {0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x00}, +/* 0x5b */ {0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00}, +/* 0x5c */ {0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00}, +/* 0x5d */ {0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00}, +/* 0x5e */ {0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0x5f */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00}, +/* 0x60 */ {0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0x61 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00}, +/* 0x62 */ {0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00}, +/* 0x63 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00}, +/* 0x64 */ {0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00}, +/* 0x65 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00}, +/* 0x66 */ {0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00}, +/* 0x67 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00}, +/* 0x68 */ {0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00}, +/* 0x69 */ {0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00}, +/* 0x6a */ {0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00}, +/* 0x6b */ {0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00}, +/* 0x6c */ {0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00}, +/* 0x6d */ {0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00}, +/* 0x6e */ {0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00}, +/* 0x6f */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00}, +/* 0x70 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00}, +/* 0x71 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00}, +/* 0x72 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00}, +/* 0x73 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00}, +/* 0x74 */ {0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00}, +/* 0x75 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00}, +/* 0x76 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00}, +/* 0x77 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00}, +/* 0x78 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00}, +/* 0x79 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00}, +/* 0x7a */ {0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00}, +/* 0x7b */ {0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, +/* 0x7c */ {0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00}, +/* 0x7d */ {0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00}, +/* 0x7e */ {0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0x7f */ {0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0x80 */ {0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00}, +/* 0x81 */ {0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00}, +/* 0x82 */ {0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00}, +/* 0x83 */ {0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00}, +/* 0x84 */ {0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00}, +/* 0x85 */ {0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00}, +/* 0x86 */ {0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00}, +/* 0x87 */ {0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, 0x00}, +/* 0x88 */ {0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00}, +/* 0x89 */ {0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00}, +/* 0x8a */ {0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00}, +/* 0x8b */ {0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00}, +/* 0x8c */ {0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00}, +/* 0x8d */ {0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00}, +/* 0x8e */ {0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00}, +/* 0x8f */ {0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00}, +/* 0x90 */ {0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00}, +/* 0x91 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, 0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00}, +/* 0x92 */ {0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00}, +/* 0x93 */ {0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00}, +/* 0x94 */ {0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00}, +/* 0x95 */ {0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00}, +/* 0x96 */ {0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00}, +/* 0x97 */ {0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00}, +/* 0x98 */ {0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00}, +/* 0x99 */ {0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00}, +/* 0x9a */ {0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00}, +/* 0x9b */ {0x00, 0x18, 0x18, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00}, +/* 0x9c */ {0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00}, +/* 0x9d */ {0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00}, +/* 0x9e */ {0x00, 0xfc, 0x66, 0x66, 0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00}, +/* 0x9f */ {0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00}, +/* 0xa0 */ {0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00}, +/* 0xa1 */ {0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00}, +/* 0xa2 */ {0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00}, +/* 0xa3 */ {0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00}, +/* 0xa4 */ {0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00}, +/* 0xa5 */ {0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00}, +/* 0xa6 */ {0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xa7 */ {0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xa8 */ {0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00}, +/* 0xa9 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xaa */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xab */ {0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, 0x0c, 0x1f, 0x00, 0x00}, +/* 0xac */ {0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00}, +/* 0xad */ {0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00}, +/* 0xae */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xaf */ {0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xb0 */ {0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44}, +/* 0xb1 */ {0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa}, +/* 0xb2 */ {0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77}, +/* 0xb3 */ {0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, +/* 0xb4 */ {0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, +/* 0xb5 */ {0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, +/* 0xb6 */ {0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}, +/* 0xb7 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}, +/* 0xb8 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, +/* 0xb9 */ {0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}, +/* 0xba */ {0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}, +/* 0xbb */ {0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}, +/* 0xbc */ {0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xbd */ {0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xbe */ {0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xbf */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, +/* 0xc0 */ {0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xc1 */ {0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xc2 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, +/* 0xc3 */ {0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, +/* 0xc4 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xc5 */ {0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, +/* 0xc6 */ {0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, +/* 0xc7 */ {0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}, +/* 0xc8 */ {0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xc9 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}, +/* 0xca */ {0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xcb */ {0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}, +/* 0xcc */ {0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}, +/* 0xcd */ {0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xce */ {0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}, +/* 0xcf */ {0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xd0 */ {0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xd1 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, +/* 0xd2 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}, +/* 0xd3 */ {0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xd4 */ {0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xd5 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, +/* 0xd6 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}, +/* 0xd7 */ {0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}, +/* 0xd8 */ {0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, +/* 0xd9 */ {0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xda */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, +/* 0xdb */ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, +/* 0xdc */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, +/* 0xdd */ {0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0}, +/* 0xde */ {0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f}, +/* 0xdf */ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xe0 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00}, +/* 0xe1 */ {0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00}, +/* 0xe2 */ {0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00}, +/* 0xe3 */ {0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00}, +/* 0xe4 */ {0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00}, +/* 0xe5 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00}, +/* 0xe6 */ {0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00}, +/* 0xe7 */ {0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00}, +/* 0xe8 */ {0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00}, +/* 0xe9 */ {0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00}, +/* 0xea */ {0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00}, +/* 0xeb */ {0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00}, +/* 0xec */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xed */ {0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00}, +/* 0xee */ {0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00}, +/* 0xef */ {0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00}, +/* 0xf0 */ {0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xf1 */ {0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00}, +/* 0xf2 */ {0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00}, +/* 0xf3 */ {0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00}, +/* 0xf4 */ {0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, +/* 0xf5 */ {0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00}, +/* 0xf6 */ {0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xf7 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xf8 */ {0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xf9 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xfa */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xfb */ {0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00}, +/* 0xfc */ {0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xfd */ {0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xfe */ {0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00}, +/* 0xff */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +}; diff --git a/Source/Kernel/TaskManager/V86/V86.ns.cpp b/Source/Kernel/TaskManager/V86/V86.ns.cpp index 11a1626..bd16e06 100644 --- a/Source/Kernel/TaskManager/V86/V86.ns.cpp +++ b/Source/Kernel/TaskManager/V86/V86.ns.cpp @@ -12,18 +12,25 @@ void run(v86_function_t& entry, registers_t ®s, u32int data) { while (!ret.finished) Task::currThread()->sleep(10); } -u16int allocSeg(u16int length) { +u16int allocSeg(u16int length, Process* p) { + if (p == 0) p = Task::currProcess(); if (length & 0xF) length = (length & 0xFFFF0) + 0x10; u16int segments = length / 16; if (seg < V86_ALLOC_START) seg = V86_ALLOC_START; if (seg + segments > V86_ALLOC_END) seg = V86_ALLOC_START; u16int ret = seg; seg += segments; + + void* ptr = FP_TO_LINEAR(ret, 0); + for (u32int i = (u32int)ptr & 0xFFFFF000; i < (u32int)ptr + length; i += 0x1000) { + p->getPagedir()->allocFrame(i, true, true); + } + return ret; } -void* alloc(u32int length) { - return FP_TO_LINEAR(allocSeg(length), 0); +void* alloc(u16int length, Process* p) { + return FP_TO_LINEAR(allocSeg(length, p), 0); } } diff --git a/Source/Kernel/TaskManager/V86/V86.ns.h b/Source/Kernel/TaskManager/V86/V86.ns.h index 98f3ead..cdeef25 100644 --- a/Source/Kernel/TaskManager/V86/V86.ns.h +++ b/Source/Kernel/TaskManager/V86/V86.ns.h @@ -8,7 +8,7 @@ typedef u32int FARPTR; #define MK_FP(seg, off) ((FARPTR)(((u32int)(seg) << 16) | (u16int) (off))) #define FP_SEG(fp) (((FARPTR)fp) >> 16) #define FP_OFF(fp) (((FARPTR)fp) & 0xFFFF) -#define LIN_SEG(ptr) (((size_t) ptr - ((size_t) ptr & 0xF)) / 16) +#define LIN_SEG(ptr) (((size_t) ptr >> 4) & 0xFFFF) #define LIN_OFF(ptr) (((size_t) ptr) & 0xF) #define FP_TO_LINEAR(seg, off) ((void*)((((u16int)(seg)) << 4) + ((u16int)(off)))) inline FARPTR LINEAR_TO_FP(void* ptr) { @@ -25,8 +25,8 @@ inline FARPTR LINEAR_TO_FP(void* ptr) { namespace V86 { void run(v86_function_t& entry, registers_t ®s, u32int data); - u16int allocSeg(u16int size); - void* alloc(u16int size); + u16int allocSeg(u16int size, Process* p = 0); + void* alloc(u16int size, Process* p = 0); } #endif diff --git a/Source/Kernel/TaskManager/V86/V86Thread.class.cpp b/Source/Kernel/TaskManager/V86/V86Thread.class.cpp index 7eab887..4b07e98 100644 --- a/Source/Kernel/TaskManager/V86/V86Thread.class.cpp +++ b/Source/Kernel/TaskManager/V86/V86Thread.class.cpp @@ -60,23 +60,16 @@ V86Thread::V86Thread(v86_function_t* entry, v86_retval_t* ret, u32int data) : Th m_process->getPagedir()->switchTo(); - m_process->getPagedir()->allocFrame(0, true, true); //Map IVT frame - for (u32int i = 0xA0000; i < 0xFFFFF; i += 0x1000) { //Map BDA frames + //Map all lower memory + for (u32int i = 0x00000; i < 0xFFFFF; i += 0x1000) { m_process->getPagedir()->allocFrame(i, true, true); } u16int cs = V86::allocSeg(entry->size); //Alocate segments for the code to run in u8int* codeptr = (u8int*)(FP_TO_LINEAR(cs, 0)); - for (u32int i = ((u32int)(codeptr) & 0xFFFFF000); i < (u32int)(codeptr) + entry->size; i += 0x1000) { - m_process->getPagedir()->allocFrame(i, true, true); - } memcpy(codeptr, entry->data, entry->size); //Copy the code there u16int ss = V86::allocSeg(V86_STACKSIZE); - u8int* stackptr = (u8int*)(FP_TO_LINEAR(ss, 0)); - for (u32int i = ((u32int)stackptr & 0xFFFFF000); i < (u32int)stackptr + V86_STACKSIZE; i += 0x1000) { - m_process->getPagedir()->allocFrame(i, true, true); - } u32int* stack = (u32int*)((u32int)m_kernelStack.addr + m_kernelStack.size); stack--; *stack = cs; //Pass code segment (ip = 0) @@ -96,7 +89,7 @@ V86Thread::V86Thread(v86_function_t* entry, v86_retval_t* ret, u32int data) : Th bool V86Thread::handleV86GPF(registers_t *regs) { u8int* ip = (u8int*)FP_TO_LINEAR(regs->cs, regs->eip); u16int *ivt = 0; - u16int *stack = (u16int*)FP_TO_LINEAR(regs->ss, regs->useresp); + u16int *stack = (u16int*)FP_TO_LINEAR(regs->ss, (regs->useresp & 0xFFFF)); u32int *stack32 = (u32int*)stack; bool is_operand32 = false, is_address32 = false; @@ -112,7 +105,7 @@ bool V86Thread::handleV86GPF(registers_t *regs) { break; case 0x9C: // PUSHF if (is_operand32) { - regs->esp = ((regs->esp & 0xFFFF) - 4) & 0xFFFF; + regs->useresp = ((regs->useresp & 0xFFFF) - 4) & 0xFFFF; stack32--; *stack32 = regs->eflags & VALID_FLAGS; if (m_if) @@ -120,7 +113,7 @@ bool V86Thread::handleV86GPF(registers_t *regs) { else *stack32 &= ~EFLAGS_IF; } else { - regs->esp = ((regs->esp & 0xFFFF) - 2) & 0xFFFF; + regs->useresp = ((regs->useresp & 0xFFFF) - 2) & 0xFFFF; stack--; *stack = regs->eflags; if (m_if) @@ -134,11 +127,11 @@ bool V86Thread::handleV86GPF(registers_t *regs) { if (is_operand32) { regs->eflags = EFLAGS_IF | EFLAGS_VM | (stack32[0] & VALID_FLAGS); m_if = (stack32[0] & EFLAGS_IF) != 0; - regs->esp = ((regs->esp & 0xFFFF) + 4) & 0xFFFF; + regs->useresp = ((regs->useresp & 0xFFFF) + 4) & 0xFFFF; } else { regs->eflags = EFLAGS_IF | EFLAGS_VM | stack[0]; m_if = (stack[0] & EFLAGS_IF) != 0; - regs->esp = ((regs->esp & 0xFFFF) + 2) & 0xFFFF; + regs->useresp = ((regs->useresp & 0xFFFF) + 2) & 0xFFFF; } regs->eip = (u16int)(regs->eip + 1); return true; @@ -170,8 +163,8 @@ bool V86Thread::handleV86GPF(registers_t *regs) { regs->cs = stack[1]; regs->eflags = EFLAGS_IF | EFLAGS_VM | stack[2]; m_if = (stack[2] & EFLAGS_IF) != 0; - regs->esp = (u16int)(regs->esp + 6); - return true; + regs->useresp = ((regs->useresp & 0xFFFF) + 6) & 0xFFFF; + return false; case 0xFA: // CLI m_if = false; regs->eip = (u16int)(regs->eip + 1); |